241 lines
7.0 KiB
C++
Executable File
241 lines
7.0 KiB
C++
Executable File
//-----------------------------------------------------------------------------
|
|
// Torque Game Engine
|
|
// Copyright (C) GarageGames.com, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(disable : 4786)
|
|
#endif
|
|
|
|
#include "appMesh.h"
|
|
#include "appTime.h"
|
|
#include "dtsUtil.h"
|
|
#include "appIfl.h"
|
|
#include "appConfig.h"
|
|
|
|
namespace DTS
|
|
{
|
|
|
|
AppMesh::AppMesh()
|
|
{
|
|
mLocked = false;
|
|
mSkinDataFetched = false;
|
|
}
|
|
|
|
AppMesh::~AppMesh()
|
|
{
|
|
assert(!mLocked && "Mesh is locked");
|
|
S32 i;
|
|
for (i=0; i<mBones.size(); i++)
|
|
delete mBones[i];
|
|
for (i=0; i<mWeights.size(); i++)
|
|
delete mWeights[i];
|
|
for (i=0; i<mIfls.size(); i++)
|
|
delete mIfls[i];
|
|
}
|
|
|
|
S32 __cdecl compareFaces( void const *e1, void const *e2 )
|
|
{
|
|
const Primitive * face1 = (const Primitive*)e1;
|
|
const Primitive * face2 = (const Primitive*)e2;
|
|
|
|
if (face1->type < face2->type)
|
|
return -1;
|
|
else if (face2->type < face1->type)
|
|
return 1;
|
|
else return 0;
|
|
}
|
|
|
|
void AppMesh::sortFaceList()
|
|
{
|
|
if (mFaces.size() != 0)
|
|
qsort(&mFaces[0],mFaces.size(),sizeof(Primitive),compareFaces);
|
|
}
|
|
|
|
Box AppMesh::getBounds(const Matrix<4,4,F32> & objectOffset)
|
|
{
|
|
assert(!mLocked && "Mesh is locked");
|
|
|
|
AppMeshLock lock((AppMeshLock&)lockMesh(AppTime::DefaultTime(),objectOffset));
|
|
|
|
Box bounds(Point3D( 10E30f, 10E30f, 10E30f),Point3D(-10E30f,-10E30f,-10E30f));
|
|
|
|
const Point3D * verts = getVerts();
|
|
for (S32 i=0; i<getNumVerts(); i++)
|
|
{
|
|
if (bounds.min.x() > verts[i].x())
|
|
bounds.min.x(verts[i].x());
|
|
if (bounds.min.y() > verts[i].y())
|
|
bounds.min.y(verts[i].y());
|
|
if (bounds.min.z() > verts[i].z())
|
|
bounds.min.z(verts[i].z());
|
|
|
|
if (bounds.max.x() < verts[i].x())
|
|
bounds.max.x(verts[i].x());
|
|
if (bounds.max.y() < verts[i].y())
|
|
bounds.max.y(verts[i].y());
|
|
if (bounds.max.z() < verts[i].z())
|
|
bounds.max.z(verts[i].z());
|
|
}
|
|
|
|
return bounds;
|
|
}
|
|
|
|
F32 AppMesh::getRadius(const Matrix<4,4,F32> & objectOffset)
|
|
{
|
|
Box bounds = getBounds(objectOffset);
|
|
Point3D diameter = bounds.max-bounds.min;
|
|
return diameter.length() * 0.5f;
|
|
}
|
|
|
|
F32 AppMesh::getTubeRadius(const Matrix<4,4,F32> & objectOffset)
|
|
{
|
|
Box bounds = getBounds(objectOffset);
|
|
Point2D diameter(bounds.max.x()-bounds.min.x(),bounds.max.y()-bounds.min.y());
|
|
return diameter.length() * 0.5f;
|
|
}
|
|
|
|
bool AppMesh::isBillboard()
|
|
{
|
|
return !strncmp(getName(),"BB::",4) || !strncmp(getName(),"BB_",3);
|
|
}
|
|
|
|
bool AppMesh::isBillboardZAxis()
|
|
{
|
|
return !strncmp(getName(),"BBZ::",5) || !strncmp(getName(),"BBZ_",4);
|
|
}
|
|
|
|
bool AppMesh::isSorted()
|
|
{
|
|
return !strncmp(getName(),"SORT::",6) || !strncmp(getName(),"SORT_",5);
|
|
}
|
|
|
|
bool AppMesh::isDummy()
|
|
{
|
|
return !strnicmp(getName(), "dummy", 5);
|
|
}
|
|
|
|
bool AppMesh::animatesVis(const AppSequenceData & seqData)
|
|
{
|
|
F32 defaultVis = getVisValue(AppTime::DefaultTime());
|
|
AppTime time = seqData.startTime;
|
|
for (S32 frame=0; frame<seqData.numFrames; frame++, time += seqData.delta)
|
|
if (!isEqual(defaultVis,getVisValue(time),0.01f))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool AppMesh::animatesMatFrame(const AppSequenceData & seqData)
|
|
{
|
|
// don't necessarily want to support this type of animation anymore
|
|
return false;
|
|
}
|
|
|
|
bool AppMesh::animatesFrame(const AppSequenceData & seqData)
|
|
{
|
|
// don't necessarily want to support this type of animation anymore
|
|
return false;
|
|
}
|
|
|
|
U16 AppMesh::addVertex(const Point3D & vert, const Point3D & norm, Point2D & tvert, U32 vertId)
|
|
{
|
|
assert(mVerts.size() == mTVerts.size() && "Verts and TVerts unbalanced");
|
|
assert(mVerts.size() == mNormals.size() && "Verts and Normals unbalanced");
|
|
assert(mVerts.size() == mVertId.size() && "Verts and vertIds unbalanced");
|
|
for (S32 i=0; i<mVerts.size(); i++)
|
|
{
|
|
if (vertId != mVertId[i])
|
|
continue;
|
|
if (!isEqual(vert,mVerts[i],AppConfig::SameVertTOL()))
|
|
continue;
|
|
if (!isEqual(tvert,mTVerts[i],AppConfig::SameTVertTOL()))
|
|
continue;
|
|
if (!isEqual(norm,mNormals[i],AppConfig::SameNormTOL()))
|
|
continue;
|
|
return i;
|
|
}
|
|
mVerts.push_back(vert);
|
|
mTVerts.push_back(tvert);
|
|
mNormals.push_back(norm);
|
|
mVertId.push_back(vertId);
|
|
return mVerts.size()-1;
|
|
}
|
|
|
|
U16 AppMesh::addVertex(const Point3D & vert, Point2D & tvert, U32 vertId, U32 smooth)
|
|
{
|
|
assert(mVerts.size() == mTVerts.size() && "Verts and TVerts unbalanced");
|
|
assert(mVerts.size() == mSmooth.size() && "Verts and smooth unbalanced");
|
|
assert(mVerts.size() == mVertId.size() && "Verts and vertIds unbalanced");
|
|
for (S32 i=0; i<mVerts.size(); i++)
|
|
{
|
|
if (vertId != mVertId[i])
|
|
continue;
|
|
if (smooth != mSmooth[i])
|
|
continue;
|
|
if (!isEqual(vert,mVerts[i],AppConfig::SameVertTOL()))
|
|
continue;
|
|
if (!isEqual(tvert,mTVerts[i],AppConfig::SameTVertTOL()))
|
|
continue;
|
|
return i;
|
|
}
|
|
mVerts.push_back(vert);
|
|
mTVerts.push_back(tvert);
|
|
mSmooth.push_back(smooth);
|
|
mVertId.push_back(vertId);
|
|
return mVerts.size()-1;
|
|
}
|
|
|
|
void AppMesh::generateFaces(std::vector<Primitive> & faces,
|
|
std::vector<Point3D> & verts,
|
|
std::vector<Point2D> & tverts,
|
|
std::vector<U16> & indices,
|
|
std::vector<U32> & smooth,
|
|
std::vector<Point3D> & normals,
|
|
std::vector<U32> * vertId)
|
|
{
|
|
assert(mLocked && "Mesh isn't locked");
|
|
faces = mFaces;
|
|
verts = mVerts;
|
|
tverts = mTVerts;
|
|
indices = mIndices;
|
|
normals = mNormals;
|
|
smooth = mSmooth;
|
|
if (vertId)
|
|
*vertId = mVertId;
|
|
}
|
|
|
|
AppMeshLock AppMesh::lockMesh(const AppTime & time, const Matrix<4,4,F32> & objectOffset)
|
|
{
|
|
assert(!mLocked && "Mesh is already locked");
|
|
|
|
time,objectOffset;
|
|
|
|
// if more than one mat type, make mats consecutive
|
|
sortFaceList();
|
|
|
|
mLocked = true;
|
|
AppMeshLock lock(this);
|
|
return lock;
|
|
//return AppMeshLock(this);
|
|
}
|
|
|
|
void AppMesh::unlockMesh()
|
|
{
|
|
assert(mLocked && "Mesh isn't locked");
|
|
|
|
mFaces.clear();
|
|
mVerts.clear();
|
|
mTVerts.clear();
|
|
mIndices.clear();
|
|
mNormals.clear();
|
|
mSmooth.clear();
|
|
mVertId.clear();
|
|
|
|
mLocked = false;
|
|
}
|
|
|
|
void AppMeshLock::doit() { if (mObj) mObj->unlockMesh(); }
|
|
|
|
|
|
}; // namespace DTS
|