ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

actor.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/visual/actor.h"
00024 
00025 #include "engines/stark/model/model.h"
00026 #include "engines/stark/model/animhandler.h"
00027 #include "engines/stark/gfx/driver.h"
00028 #include "engines/stark/gfx/texture.h"
00029 #include "engines/stark/scene.h"
00030 #include "engines/stark/services/services.h"
00031 
00032 namespace Stark {
00033 
00034 VisualActor::VisualActor() :
00035         Visual(TYPE),
00036         _animHandler(nullptr),
00037         _model(nullptr),
00038         _textureSet(nullptr),
00039         _textureSetFacial(nullptr),
00040         _time(0),
00041         _modelIsDirty(true),
00042         _faceTextureName(' '),
00043         _castsShadow(false) {
00044 }
00045 
00046 VisualActor::~VisualActor() {
00047 }
00048 
00049 void VisualActor::setModel(Model *model) {
00050     if (_model == model) {
00051         return; // Nothing to do
00052     }
00053 
00054     _model = model;
00055     _modelIsDirty = true;
00056 }
00057 
00058 void VisualActor::setAnimHandler(AnimHandler *animHandler) {
00059     _animHandler = animHandler;
00060 }
00061 
00062 void VisualActor::setTexture(Gfx::TextureSet *texture) {
00063     _textureSet = texture;
00064 }
00065 
00066 void VisualActor::setTextureFacial(Gfx::TextureSet *textureFacial) {
00067     _textureSetFacial = textureFacial;
00068 }
00069 
00070 void VisualActor::setNewFace(char shape) {
00071     _faceTextureName = shape;
00072 }
00073 
00074 const Gfx::Texture *VisualActor::resolveTexture(const Material *material) const {
00075     const Gfx::Texture *texture = nullptr;
00076     if (_textureSetFacial && material->name == "face") {
00077         texture = _textureSetFacial->getTexture(Common::String::format("%c.bmp", _faceTextureName));
00078 
00079         if (!texture) {
00080             // Default face texture in case the requested shape was not found
00081             texture = _textureSetFacial->getTexture("i.bmp");
00082         }
00083     }
00084 
00085     if (!texture) {
00086         texture = _textureSet->getTexture(material->texture);
00087     }
00088 
00089     return texture;
00090 }
00091 
00092 void VisualActor::setTime(uint32 time) {
00093     _time = time;
00094 }
00095 
00096 Math::Matrix4 VisualActor::getModelMatrix(const Math::Vector3d &position, float direction) const {
00097     Math::Matrix4 modelMatrix;
00098     modelMatrix.setPosition(position);
00099 
00100     Math::Angle swayAngle = StarkScene->getSwayAngle();
00101     if (swayAngle != 0) {
00102         Math::Quaternion swayRotation = Math::Quaternion(StarkScene->getSwayDirection(), swayAngle / 2.0);
00103         modelMatrix = modelMatrix * swayRotation.toMatrix();
00104     }
00105 
00106     float floatOffset = StarkScene->getFloatOffset();
00107     if (floatOffset != 0) {
00108         Math::Matrix4 floatTranslation;
00109         floatTranslation.setPosition(Math::Vector3d(0, 0, floatOffset));
00110         modelMatrix = modelMatrix * floatTranslation;
00111     }
00112 
00113     Math::Matrix4 rot1;
00114     rot1.buildAroundX(90);
00115 
00116     Math::Matrix4 rot2;
00117     rot2.buildAroundY(270 - direction);
00118 
00119     Math::Matrix4 scale;
00120     scale.setValue(2, 2, -1.0f);
00121 
00122     return modelMatrix * rot1 * rot2 * scale;
00123 }
00124 
00125 bool VisualActor::intersectRay(const Math::Ray &ray, const Math::Vector3d &position, float direction) {
00126     Math::Matrix4 inverseModelMatrix = getModelMatrix(position, direction);
00127     inverseModelMatrix.inverse();
00128 
00129     // Build an object local ray from the world ray
00130     Math::Ray localRay = ray;
00131     localRay.transform(inverseModelMatrix);
00132 
00133     return _model->intersectRay(localRay);
00134 }
00135 
00136 Common::Rect VisualActor::getBoundingRect(const Math::Vector3d &position3d, float direction) const {
00137     Math::Matrix4 modelMatrix = getModelMatrix(position3d, direction);
00138 
00139     Math::AABB modelSpaceBB = _model->getBoundingBox();
00140     Math::Vector3d min = modelSpaceBB.getMin();
00141     Math::Vector3d max = modelSpaceBB.getMax();
00142 
00143     Math::Vector3d verts[8];
00144     verts[0].set(min.x(), min.y(), min.z());
00145     verts[1].set(max.x(), min.y(), min.z());
00146     verts[2].set(min.x(), max.y(), min.z());
00147     verts[3].set(min.x(), min.y(), max.z());
00148     verts[4].set(max.x(), max.y(), min.z());
00149     verts[5].set(max.x(), min.y(), max.z());
00150     verts[6].set(min.x(), max.y(), max.z());
00151     verts[7].set(max.x(), max.y(), max.z());
00152 
00153     Common::Rect boundingRect;
00154     for (int i = 0; i < 8; ++i) {
00155         modelMatrix.transform(&verts[i], true);
00156         Common::Point point = StarkScene->convertPosition3DToGameScreenOriginal(verts[i]);
00157 
00158         if (i == 0) {
00159             boundingRect.top = point.y;
00160             boundingRect.bottom = point.y;
00161             boundingRect.left = point.x;
00162             boundingRect.right = point.x;
00163         } else {
00164             if (boundingRect.left > point.x) {
00165                 boundingRect.left = point.x;
00166             }
00167             if (boundingRect.right < point.x) {
00168                 boundingRect.right = point.x;
00169             }
00170             if (boundingRect.top > point.y) {
00171                 boundingRect.top = point.y;
00172             }
00173             if (boundingRect.bottom < point.y) {
00174                 boundingRect.bottom = point.y;
00175             }
00176         }
00177     }
00178 
00179     return boundingRect;
00180 }
00181 
00182 } // End of namespace Stark


Generated on Sat Jul 13 2019 05:01:01 for ResidualVM by doxygen 1.7.1
curved edge   curved edge