Show Model.cpp syntax highlighted
////////////////////////////////////////////////////////////////////////////////
// Scorched3D (c) 2000-2004
//
// This file is part of Scorched3D.
//
// Scorched3D is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Scorched3D is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Scorched3D; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////
#include <3dsparse/Model.h>
#include <3dsparse/ModelMaths.h>
#include <common/Defines.h>
Model::Model() : startFrame_(0), totalFrames_(0)
{
}
Model::~Model()
{
while (!meshes_.empty())
{
Mesh *mesh = meshes_.back();
meshes_.pop_back();
delete mesh;
}
while (!bones_.empty())
{
Bone *bone = bones_.back();
bones_.pop_back();
delete bone;
}
while (!baseBoneTypes_.empty())
{
BoneType *boneType = baseBoneTypes_.back();
baseBoneTypes_.pop_back();
delete boneType;
}
}
void Model::centre()
{
max_ = meshes_.front()->getMax();
min_ = meshes_.front()->getMin();
DIALOG_ASSERT(!meshes_.empty());
std::vector<Mesh *>::iterator itor;
for (itor = meshes_.begin();
itor != meshes_.end();
itor++)
{
max_[0] = MAX(max_[0], (*itor)->getMax()[0]);
max_[1] = MAX(max_[1], (*itor)->getMax()[1]);
max_[2] = MAX(max_[2], (*itor)->getMax()[2]);
min_[0] = MIN(min_[0], (*itor)->getMin()[0]);
min_[1] = MIN(min_[1], (*itor)->getMin()[1]);
min_[2] = MIN(min_[2], (*itor)->getMin()[2]);
}
Vector centre = (max_ + min_) / -2.0f;
for (itor = meshes_.begin();
itor != meshes_.end();
itor++)
{
(*itor)->move(centre);
}
min_ += centre;
max_ += centre;
}
int Model::getNumberTriangles()
{
int tris = 0;
std::vector<Mesh *>::iterator itor;
for (itor = meshes_.begin();
itor != meshes_.end();
itor++)
{
Mesh *mesh = *itor;
tris += (int) mesh->getFaces().size();
}
return tris;
}
void Model::setup()
{
centre();
setupBones();
setupColor();
}
void Model::setupColor()
{
Vector lightpos(-0.3f, -0.2f, 1.0f);
lightpos.StoreNormalize();
std::vector<Mesh *>::iterator itor;
for (itor = meshes_.begin();
itor != meshes_.end();
itor++)
{
Mesh *mesh = (*itor);
std::vector<Face *>::iterator itor;
for (itor = mesh->getFaces().begin();
itor != mesh->getFaces().end();
itor++)
{
Face *face = *itor;
for (int i=0; i<3; i++)
{
Vertex *vertex = mesh->getVertex(face->v[i]);
Vector &normal = face->normal[i];
const float ambientLight = 0.2f;
const float diffuseLight = 0.8f;
float diffuseLightMult =
(((lightpos.dotP(normal.Normalize())) / 2.0f) + 0.5f);
float intense = diffuseLightMult * diffuseLight + ambientLight;
if (intense > 1.0f) intense = 1.0f;
vertex->lightintense[0] = intense;
vertex->lightintense[1] = intense;
vertex->lightintense[2] = intense;
}
}
}
}
void Model::setupBones()
{
for (unsigned int b=0; b<bones_.size(); b++)
{
baseBoneTypes_.push_back(new BoneType());
}
for (unsigned int b=0; b<bones_.size(); b++)
{
Bone *bone = bones_[b];
BoneType *type = baseBoneTypes_[b];
// Find the parent bone
for (unsigned int p=0; p<bones_.size(); p++)
{
Bone *parent = bones_[p];
if (0 == strcmp(bone->getParentName(), parent->getName()))
{
type->parent_ = p;
break;
}
}
// Set rotation and position
Vector rot;
rot[0] = bone->getRotation()[0] * 180.0f / PI;
rot[1] = bone->getRotation()[1] * 180.0f / PI;
rot[2] = bone->getRotation()[2] * 180.0f / PI;
ModelMaths::angleMatrix(rot, type->relative_);
type->relative_[0][3] = bone->getPosition()[0];
type->relative_[1][3] = bone->getPosition()[1];
type->relative_[2][3] = bone->getPosition()[2];
// Setup child relations
if (type->parent_ != -1)
{
BoneType *parent = baseBoneTypes_[type->parent_];
ModelMaths::concatTransforms(parent->absolute_, type->relative_, type->absolute_);
memcpy(type->final_, type->absolute_, sizeof(BoneMatrixType));
}
else // No parent
{
memcpy(type->absolute_, type->relative_, sizeof(BoneMatrixType));
memcpy(type->final_, type->relative_, sizeof(BoneMatrixType));
}
}
// Move vertexes to align with the bones
for (unsigned int i=0; i<meshes_.size(); i++)
{
Mesh *mesh = meshes_[i];
for (unsigned int j=0; j<mesh->getVertexes().size(); j++)
{
Vertex *vertex = mesh->getVertex(j);
if (vertex->boneIndex != -1)
{
BoneType *type = baseBoneTypes_[vertex->boneIndex];
mesh->getReferencesBones() = true;
// Note: Translation of MS to S3D coords
// Translation
vertex->position[0] -= type->absolute_[0][3];
vertex->position[1] -= type->absolute_[2][3];
vertex->position[2] -= type->absolute_[1][3];
// Rotation
Vector tmpPos;
tmpPos[0] = vertex->position[0];
tmpPos[1] = vertex->position[2];
tmpPos[2] = vertex->position[1];
Vector tmp;
ModelMaths::vectorIRotate(tmpPos, type->absolute_, tmp);
vertex->position[0] = tmp[0];
vertex->position[1] = tmp[2];
vertex->position[2] = tmp[1];
}
}
}
}
See more files for this project here