Model.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <3dsparse/Model.h>
00022 #include <3dsparse/ModelMaths.h>
00023 #include <common/Defines.h>
00024 
00025 Model::Model() : startFrame_(0), totalFrames_(0)
00026 {
00027 }
00028 
00029 Model::~Model()
00030 {
00031         while (!meshes_.empty())
00032         {
00033                 Mesh *mesh = meshes_.back();
00034                 meshes_.pop_back();
00035                 delete mesh;
00036         }
00037         while (!bones_.empty())
00038         {
00039                 Bone *bone = bones_.back();
00040                 bones_.pop_back();
00041                 delete bone;
00042         }
00043         while (!baseBoneTypes_.empty())
00044         {
00045                 BoneType *boneType = baseBoneTypes_.back();
00046                 baseBoneTypes_.pop_back();
00047                 delete boneType;
00048         }
00049 }
00050 
00051 void Model::centre()
00052 {
00053         max_ = meshes_.front()->getMax();
00054         min_ = meshes_.front()->getMin();
00055         DIALOG_ASSERT(!meshes_.empty());
00056 
00057         std::vector<Mesh *>::iterator itor;
00058         for (itor = meshes_.begin();
00059                 itor != meshes_.end();
00060                 itor++)
00061         {
00062                 max_[0] = MAX(max_[0], (*itor)->getMax()[0]);
00063                 max_[1] = MAX(max_[1], (*itor)->getMax()[1]);
00064                 max_[2] = MAX(max_[2], (*itor)->getMax()[2]);
00065 
00066                 min_[0] = MIN(min_[0], (*itor)->getMin()[0]);
00067                 min_[1] = MIN(min_[1], (*itor)->getMin()[1]);
00068                 min_[2] = MIN(min_[2], (*itor)->getMin()[2]);
00069         }
00070 
00071         Vector centre = (max_ + min_) / -2.0f;
00072         for (itor = meshes_.begin();
00073                 itor != meshes_.end();
00074                 itor++)
00075         {
00076                 (*itor)->move(centre);
00077         }
00078         min_ += centre;
00079         max_ += centre;
00080 }
00081 
00082 int Model::getNumberTriangles()
00083 {
00084         int tris = 0;
00085         std::vector<Mesh *>::iterator itor;
00086         for (itor = meshes_.begin();
00087                 itor != meshes_.end();
00088                 itor++)
00089         {
00090                 Mesh *mesh = *itor;
00091                 tris += (int) mesh->getFaces().size();
00092         }
00093         return tris;
00094 }
00095 
00096 void Model::setup()
00097 {
00098         centre();
00099         setupBones();
00100         setupColor();
00101 }
00102 
00103 void Model::setupColor()
00104 {
00105         Vector lightpos(-0.3f, -0.2f, 1.0f);
00106         lightpos.StoreNormalize();
00107 
00108         std::vector<Mesh *>::iterator itor;
00109         for (itor = meshes_.begin();
00110                 itor != meshes_.end();
00111                 itor++)
00112         {
00113                 Mesh *mesh = (*itor);
00114         
00115                 std::vector<Face *>::iterator itor;
00116                 for (itor = mesh->getFaces().begin();
00117                         itor != mesh->getFaces().end();
00118                         itor++)
00119                 {
00120                         Face *face = *itor;
00121                         for (int i=0; i<3; i++)
00122                         {
00123                                 Vertex *vertex = mesh->getVertex(face->v[i]);
00124                                 Vector &normal = face->normal[i];
00125 
00126                                 const float ambientLight = 0.2f;
00127                                 const float diffuseLight = 0.8f;
00128                                 float diffuseLightMult = 
00129                                         (((lightpos.dotP(normal.Normalize())) / 2.0f) + 0.5f);
00130                                 float intense = diffuseLightMult * diffuseLight + ambientLight;
00131                                 if (intense > 1.0f) intense = 1.0f; 
00132                                 vertex->lightintense[0] = intense;
00133                                 vertex->lightintense[1] = intense;
00134                                 vertex->lightintense[2] = intense;
00135                         }
00136                 }
00137         }
00138 }
00139 
00140 void Model::setupBones()
00141 {
00142         for (unsigned int b=0; b<bones_.size(); b++)
00143         {
00144                 baseBoneTypes_.push_back(new BoneType());
00145         }
00146 
00147         for (unsigned int b=0; b<bones_.size(); b++)
00148         {
00149                 Bone *bone = bones_[b];
00150                 BoneType *type = baseBoneTypes_[b];
00151 
00152                 // Find the parent bone
00153                 for (unsigned int p=0; p<bones_.size(); p++)
00154                 {
00155                         Bone *parent = bones_[p];
00156                         if (0 == strcmp(bone->getParentName(), parent->getName()))
00157                         {
00158                                 type->parent_ = p;
00159                                 break;
00160                         }
00161                 }
00162 
00163                 // Set rotation and position
00164                 Vector rot;
00165                 rot[0] = bone->getRotation()[0] * 180.0f / PI;
00166                 rot[1] = bone->getRotation()[1] * 180.0f / PI;
00167                 rot[2] = bone->getRotation()[2] * 180.0f / PI;
00168 
00169                 ModelMaths::angleMatrix(rot, type->relative_);
00170                 type->relative_[0][3] = bone->getPosition()[0];
00171                 type->relative_[1][3] = bone->getPosition()[1];
00172                 type->relative_[2][3] = bone->getPosition()[2];
00173 
00174                 // Setup child relations
00175                 if (type->parent_ != -1)
00176                 {
00177                         BoneType *parent = baseBoneTypes_[type->parent_];
00178 
00179                         ModelMaths::concatTransforms(parent->absolute_, type->relative_, type->absolute_);
00180                         memcpy(type->final_, type->absolute_, sizeof(BoneMatrixType));
00181                 }
00182                 else // No parent
00183                 {
00184                         memcpy(type->absolute_, type->relative_, sizeof(BoneMatrixType));
00185                         memcpy(type->final_, type->relative_, sizeof(BoneMatrixType));
00186                 }
00187         }
00188 
00189         // Move vertexes to align with the bones
00190         for (unsigned int i=0; i<meshes_.size(); i++)
00191         {
00192                 Mesh *mesh = meshes_[i];
00193                 for (unsigned int j=0; j<mesh->getVertexes().size(); j++)
00194                 {
00195                         Vertex *vertex = mesh->getVertex(j);
00196                         if (vertex->boneIndex != -1)
00197                         {
00198                                 DIALOG_ASSERT(vertex->boneIndex < int(bones_.size()));
00199 
00200                                 BoneType *type = baseBoneTypes_[vertex->boneIndex];
00201                                 mesh->getReferencesBones() = true;
00202 
00203                                 // Note: Translation of MS to S3D coords
00204 
00205                                 // Translation
00206                                 vertex->position[0] -= type->absolute_[0][3];
00207                                 vertex->position[1] -= type->absolute_[2][3];
00208                                 vertex->position[2] -= type->absolute_[1][3];
00209 
00210                                 // Rotation
00211                                 Vector tmpPos;
00212                                 tmpPos[0] = vertex->position[0];
00213                                 tmpPos[1] = vertex->position[2];
00214                                 tmpPos[2] = vertex->position[1];
00215 
00216                                 Vector tmp;
00217                                 ModelMaths::vectorIRotate(tmpPos, type->absolute_, tmp);
00218                                 vertex->position[0] = tmp[0];
00219                                 vertex->position[1] = tmp[2];
00220                                 vertex->position[2] = tmp[1];
00221                         }
00222                 }
00223         }
00224 }

Generated on Mon Feb 16 15:14:48 2009 for Scorched3D by  doxygen 1.5.3