tge/lib/dtsSDKPlus/appMesh.cpp
2025-02-17 23:17:30 -06:00

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