//----------------------------------------------------------------------------- // 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; }