Torque3D/Engine/source/collision/concretePolyList.cpp

223 lines
6.1 KiB
C++
Raw Normal View History

2012-09-19 15:15:01 +00:00
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "collision/concretePolyList.h"
#include "math/mMath.h"
#include "console/console.h"
#include "gfx/gfxDevice.h"
#include "gfx/primBuilder.h"
#include "gfx/gfxStateBlock.h"
//----------------------------------------------------------------------------
ConcretePolyList::ConcretePolyList()
{
VECTOR_SET_ASSOCIATION(mPolyList);
VECTOR_SET_ASSOCIATION(mVertexList);
VECTOR_SET_ASSOCIATION(mIndexList);
VECTOR_SET_ASSOCIATION(mPolyPlaneList);
mIndexList.reserve(100);
}
ConcretePolyList::~ConcretePolyList()
{
}
//----------------------------------------------------------------------------
void ConcretePolyList::clear()
{
// Only clears internal data
mPolyList.clear();
mVertexList.clear();
mIndexList.clear();
mPolyPlaneList.clear();
}
//----------------------------------------------------------------------------
U32 ConcretePolyList::addPoint(const Point3F& p)
{
mVertexList.increment();
Point3F& v = mVertexList.last();
v.x = p.x * mScale.x;
v.y = p.y * mScale.y;
v.z = p.z * mScale.z;
mMatrix.mulP(v);
return mVertexList.size() - 1;
}
U32 ConcretePolyList::addPlane(const PlaneF& plane)
{
mPolyPlaneList.increment();
mPlaneTransformer.transform(plane, mPolyPlaneList.last());
return mPolyPlaneList.size() - 1;
}
//----------------------------------------------------------------------------
void ConcretePolyList::begin(BaseMatInstance* material,U32 surfaceKey)
{
mPolyList.increment();
Poly& poly = mPolyList.last();
poly.object = mCurrObject;
poly.material = material;
poly.vertexStart = mIndexList.size();
poly.surfaceKey = surfaceKey;
}
//----------------------------------------------------------------------------
void ConcretePolyList::plane(U32 v1,U32 v2,U32 v3)
{
mPolyList.last().plane.set(mVertexList[v1],
mVertexList[v2],mVertexList[v3]);
}
void ConcretePolyList::plane(const PlaneF& p)
{
mPlaneTransformer.transform(p, mPolyList.last().plane);
}
void ConcretePolyList::plane(const U32 index)
{
AssertFatal(index < mPolyPlaneList.size(), "Out of bounds index!");
mPolyList.last().plane = mPolyPlaneList[index];
}
const PlaneF& ConcretePolyList::getIndexedPlane(const U32 index)
{
AssertFatal(index < mPolyPlaneList.size(), "Out of bounds index!");
return mPolyPlaneList[index];
}
//----------------------------------------------------------------------------
void ConcretePolyList::vertex(U32 vi)
{
mIndexList.push_back(vi);
}
//----------------------------------------------------------------------------
bool ConcretePolyList::isEmpty() const
{
return mPolyList.empty();
}
void ConcretePolyList::end()
{
Poly& poly = mPolyList.last();
poly.vertexCount = mIndexList.size() - poly.vertexStart;
}
void ConcretePolyList::render()
{
GFXStateBlockDesc solidZDisable;
solidZDisable.setCullMode( GFXCullNone );
solidZDisable.setZReadWrite( false, false );
GFXStateBlockRef sb = GFX->createStateBlock( solidZDisable );
GFX->setStateBlock( sb );
PrimBuild::color3i( 255, 0, 255 );
Poly *p;
Point3F *pnt;
for ( p = mPolyList.begin(); p < mPolyList.end(); p++ )
{
PrimBuild::begin( GFXLineStrip, p->vertexCount + 1 );
for ( U32 i = 0; i < p->vertexCount; i++ )
{
pnt = &mVertexList[mIndexList[p->vertexStart + i]];
PrimBuild::vertex3fv( pnt );
}
pnt = &mVertexList[mIndexList[p->vertexStart]];
PrimBuild::vertex3fv( pnt );
PrimBuild::end();
}
}
void ConcretePolyList::triangulate()
{
PROFILE_SCOPE( ConcretePolyList_Triangulate );
// Build into a new polylist and index list.
//
// TODO: There are potential performance issues
// here as we're not reserving enough space for
// new generated triangles.
//
// We need to either over estimate and shrink or
// better yet fix vector to internally grow in
// large chunks.
//
PolyList polyList;
polyList.reserve( mPolyList.size() );
IndexList indexList;
indexList.reserve( mIndexList.size() );
U32 j, numTriangles;
//
PolyList::const_iterator polyIter = mPolyList.begin();
for ( ; polyIter != mPolyList.end(); polyIter++ )
{
const Poly &poly = *polyIter;
// How many triangles in this poly?
numTriangles = poly.vertexCount - 2;
// Build out the triangles.
for ( j = 0; j < numTriangles; j++ )
{
polyList.increment();
Poly &triangle = polyList.last();
triangle = poly;
triangle.vertexCount = 3;
triangle.vertexStart = indexList.size();
indexList.push_back( mIndexList[ poly.vertexStart ] );
indexList.push_back( mIndexList[ poly.vertexStart + 1 + j ] );
indexList.push_back( mIndexList[ poly.vertexStart + 2 + j ] );
}
}
mPolyList = polyList;
mIndexList = indexList;
}