tge/engine/collision/optimizedPolyList.cc
2025-02-17 23:17:30 -06:00

286 lines
7.6 KiB
C++
Executable File

//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "dgl/dgl.h"
#include "math/mMath.h"
#include "console/console.h"
#include "collision/optimizedPolyList.h"
#include "core/color.h"
//----------------------------------------------------------------------------
OptimizedPolyList::OptimizedPolyList()
{
VECTOR_SET_ASSOCIATION(mPolyList);
VECTOR_SET_ASSOCIATION(mVertexList);
VECTOR_SET_ASSOCIATION(mIndexList);
VECTOR_SET_ASSOCIATION(mPlaneList);
VECTOR_SET_ASSOCIATION(mEdgeList);
mIndexList.reserve(100);
}
OptimizedPolyList::~OptimizedPolyList()
{
mPolyList.clear();
mVertexList.clear();
mIndexList.clear();
mPlaneList.clear();
mEdgeList.clear();
}
//----------------------------------------------------------------------------
void OptimizedPolyList::clear()
{
// Only clears internal data
mPolyList.clear();
mVertexList.clear();
mIndexList.clear();
mPlaneList.clear();
mEdgeList.clear();
mPolyPlaneList.clear();
}
//----------------------------------------------------------------------------
U32 OptimizedPolyList::addPoint(const Point3F& p)
{
Point3F v;
v.x = p.x * mScale.x;
v.y = p.y * mScale.y;
v.z = p.z * mScale.z;
mMatrix.mulP(v);
for (U32 i = 0; i < mVertexList.size(); i++)
{
if (isEqual(v, mVertexList[i]))
return i;
}
// If we make it to here then we didn't find the vertex
mVertexList.push_back(v);
return mVertexList.size() - 1;
}
U32 OptimizedPolyList::addPlane(const PlaneF& plane)
{
PlaneF pln;
mPlaneTransformer.transform(plane, pln);
for (U32 i = 0; i < mPlaneList.size(); i++)
{
// The PlaneF == operator uses the Point3F == operator and
// doesn't check the d
if (isEqual(pln, mPlaneList[i]) &&
mFabs(pln.d - mPlaneList[i].d) < DEV)
return i;
}
// If we made it here then we didin't find the vertex
mPlaneList.push_back(pln);
return mPlaneList.size() - 1;
}
//----------------------------------------------------------------------------
void OptimizedPolyList::begin(U32 material,U32 surfaceKey)
{
mPolyList.increment();
Poly& poly = mPolyList.last();
poly.object = mCurrObject;
poly.material = material;
poly.vertexStart = mIndexList.size();
poly.surfaceKey = surfaceKey;
}
//----------------------------------------------------------------------------
void OptimizedPolyList::plane(U32 v1,U32 v2,U32 v3)
{
AssertFatal(v1 < mVertexList.size() && v2 < mVertexList.size() && v3 < mVertexList.size(),
"OptimizedPolyList::plane(): Vertex indices are larger than vertex list size");
mPolyList.last().plane = addPlane(PlaneF(mVertexList[v1], mVertexList[v2],mVertexList[v3]));
}
void OptimizedPolyList::plane(const PlaneF& p)
{
mPolyList.last().plane = addPlane(p);
}
void OptimizedPolyList::plane(const U32 index)
{
AssertFatal(index < mPlaneList.size(), "Out of bounds index!");
mPolyList.last().plane = index;
}
const PlaneF& OptimizedPolyList::getIndexedPlane(const U32 index)
{
AssertFatal(index < mPlaneList.size(), "Out of bounds index!");
return mPlaneList[index];
}
//----------------------------------------------------------------------------
void OptimizedPolyList::vertex(U32 vi)
{
mIndexList.push_back(vi);
}
//----------------------------------------------------------------------------
bool OptimizedPolyList::isEmpty() const
{
return !mPolyList.size();
}
void OptimizedPolyList::end()
{
Poly& poly = mPolyList.last();
poly.vertexCount = mIndexList.size() - poly.vertexStart;
}
void OptimizedPolyList::render()
{
if (mPolyList.size() == 0 || mVertexList.size() == 0)
return;
//glVertexPointer(3, GL_FLOAT,sizeof(Point3F), mVertexList.address());
//glEnableClientState(GL_VERTEX_ARRAY);
//Poly * p;
//for (p = mPolyList.begin(); p < mPolyList.end(); p++)
// glDrawElements(GL_POLYGON,p->vertexCount, GL_UNSIGNED_INT, &mIndexList[p->vertexStart]);
//glDisableClientState(GL_VERTEX_ARRAY);
// If you need normals
for (U32 i = 0; i < mPolyList.size(); i++)
{
if (mPolyList[i].vertexCount < 3)
continue;
ColorF color(gRandGen.randF(0.0f, 1.0f), gRandGen.randF(0.0f, 1.0f), gRandGen.randF(0.0f, 1.0f));
glColor3f(color.red, color.green, color.blue);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
glBegin(GL_TRIANGLES);
for (U32 j = 1; j < mPolyList[i].vertexCount - 1; j++)
{
U32 i0 = mIndexList[mPolyList[i].vertexStart];
U32 i1 = mIndexList[mPolyList[i].vertexStart + j];
U32 i2 = mIndexList[mPolyList[i].vertexStart + j + 1];
Point3F p0 = mVertexList[i0];
Point3F p1 = mVertexList[i1];
Point3F p2 = mVertexList[i2];
PlaneF normal = mPlaneList[mPolyList[i].plane];
glNormal3f(normal.x, normal.y, normal.z);
glVertex3f(p0.x, p0.y, p0.z);
glVertex3f(p1.x, p1.y, p1.z);
glVertex3f(p2.x, p2.y, p2.z);
}
glEnd();
}
}
void OptimizedPolyList::copyPolyToList(OptimizedPolyList* target, U32 pdx) const
{
target->mPolyList.increment();
OptimizedPolyList::Poly& tpoly = target->mPolyList.last();
tpoly.material = mPolyList[pdx].material;
tpoly.object = mPolyList[pdx].object;
tpoly.surfaceKey = mPolyList[pdx].surfaceKey;
tpoly.vertexCount = mPolyList[pdx].vertexCount;
PlaneF pln = mPlaneList[mPolyList[pdx].plane];
tpoly.plane = target->addPlane(pln);
tpoly.vertexStart = target->mIndexList.size();
for (U32 i = 0; i < mPolyList[pdx].vertexCount; i++)
{
U32 idx = mIndexList[mPolyList[pdx].vertexStart + i];
Point3F pt = mVertexList[idx];
target->mIndexList.increment();
target->mIndexList.last() = target->addPoint(pt);
}
}
void OptimizedPolyList::copyPolyToList(OptimizedPolyList* target, const FullPoly& poly) const
{
target->mPolyList.increment();
OptimizedPolyList::Poly& tpoly = target->mPolyList.last();
tpoly.material = poly.material;
tpoly.object = poly.object;
tpoly.surfaceKey = poly.surfaceKey;
tpoly.vertexCount = poly.indexes.size();
PlaneF pln = poly.plane;
tpoly.plane = target->addPlane(pln);
tpoly.vertexStart = target->mIndexList.size();
for (U32 i = 0; i < poly.indexes.size(); i++)
{
Point3F pt = poly.vertexes[poly.indexes[i]];
target->mIndexList.increment();
target->mIndexList.last() = target->addPoint(pt);
}
}
OptimizedPolyList::FullPoly OptimizedPolyList::getFullPoly(U32 pdx)
{
FullPoly ret;
OptimizedPolyList::Poly& poly = mPolyList[pdx];
ret.material = poly.material;
ret.object = poly.object;
ret.surfaceKey = poly.surfaceKey;
for (U32 i = 0; i < poly.vertexCount; i++)
{
U32 idx = mIndexList[poly.vertexStart + i];
Point3F& pt = mVertexList[idx];
S32 pdx = -1;
for (U32 j = 0; j < ret.vertexes.size(); j++)
{
if (pt == ret.vertexes[j])
{
pdx = j;
break;
}
}
if (pdx == -1)
{
pdx = ret.vertexes.size();
ret.vertexes.push_back(pt);
}
ret.indexes.push_back(pdx);
}
return ret;
}