286 lines
7.6 KiB
C++
Executable File
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;
|
|
} |