Initial commit
This commit is contained in:
635
Torque/SDK/engine/game/tsStatic.cc
Normal file
635
Torque/SDK/engine/game/tsStatic.cc
Normal file
@@ -0,0 +1,635 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "game/tsStatic.h"
|
||||
#include "core/bitStream.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "sceneGraph/sceneState.h"
|
||||
#include "sceneGraph/sceneGraph.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "ts/tsShapeInstance.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "game/shapeBase.h"
|
||||
#include "game/shadow.h"
|
||||
#include "sceneGraph/detailManager.h"
|
||||
#include "sim/netConnection.h"
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(TSStatic);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
TSStatic::TSStatic()
|
||||
{
|
||||
mNetFlags.set(Ghostable | ScopeAlways);
|
||||
|
||||
mTypeMask |= StaticObjectType | StaticTSObjectType | StaticRenderedObjectType;
|
||||
|
||||
mShapeName = "";
|
||||
mShapeInstance = NULL;
|
||||
mShadow = NULL;
|
||||
|
||||
mConvexList = new Convex;
|
||||
}
|
||||
|
||||
TSStatic::~TSStatic()
|
||||
{
|
||||
delete mConvexList;
|
||||
mConvexList = NULL;
|
||||
delete mShadow;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void TSStatic::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
||||
addGroup("Media");
|
||||
addField("shapeName", TypeFilename, Offset(mShapeName, TSStatic));
|
||||
endGroup("Media");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool TSStatic::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
if (!mShapeName || mShapeName[0] == '\0') {
|
||||
Con::errorf("TSStatic::onAdd: no shape name!");
|
||||
return false;
|
||||
}
|
||||
mShapeHash = _StringTable::hashString(mShapeName);
|
||||
|
||||
mShape = ResourceManager->load(mShapeName);
|
||||
|
||||
if (bool(mShape) == false)
|
||||
{
|
||||
Con::errorf("TSStatic::onAdd: unable to load shape: %s", mShapeName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(isClientObject() && !mShape->preloadMaterialList() && NetConnection::filesWereDownloaded())
|
||||
return false;
|
||||
|
||||
mObjBox = mShape->bounds;
|
||||
resetWorldBox();
|
||||
setRenderTransform(mObjToWorld);
|
||||
|
||||
mShapeInstance = new TSShapeInstance(mShape, isClientObject());
|
||||
|
||||
// Scan out the collision hulls...
|
||||
U32 i;
|
||||
for (i = 0; i < mShape->details.size(); i++)
|
||||
{
|
||||
char* name = (char*)mShape->names[mShape->details[i].nameIndex];
|
||||
|
||||
if (dStrstr((const char*)dStrlwr(name), "collision-"))
|
||||
{
|
||||
mCollisionDetails.push_back(i);
|
||||
|
||||
// The way LOS works is that it will check to see if there is a LOS detail that matches
|
||||
// the the collision detail + 1 + MaxCollisionShapes (this variable name should change in
|
||||
// the future). If it can't find a matching LOS it will simply use the collision instead.
|
||||
// We check for any "unmatched" LOS's further down
|
||||
mLOSDetails.increment();
|
||||
|
||||
char buff[128];
|
||||
dSprintf(buff, sizeof(buff), "LOS-%d", i + 1 + MaxCollisionShapes);
|
||||
U32 los = mShape->findDetail(buff);
|
||||
if (los == -1)
|
||||
mLOSDetails.last() = i;
|
||||
else
|
||||
mLOSDetails.last() = los;
|
||||
}
|
||||
}
|
||||
|
||||
// Snag any "unmatched" LOS details
|
||||
for (i = 0; i < mShape->details.size(); i++)
|
||||
{
|
||||
char* name = (char*)mShape->names[mShape->details[i].nameIndex];
|
||||
|
||||
if (dStrstr((const char*)dStrlwr(name), "los-"))
|
||||
{
|
||||
// See if we already have this LOS
|
||||
bool found = false;
|
||||
for (U32 j = 0; j < mLOSDetails.size(); j++)
|
||||
{
|
||||
if (mLOSDetails[j] == i)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
mLOSDetails.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the hull accelerators (actually, just force the shape to compute them)
|
||||
for (i = 0; i < mCollisionDetails.size(); i++)
|
||||
mShapeInstance->getShape()->getAccelerator(mCollisionDetails[i]);
|
||||
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void TSStatic::onRemove()
|
||||
{
|
||||
mConvexList->nukeList();
|
||||
|
||||
removeFromScene();
|
||||
|
||||
delete mShapeInstance;
|
||||
mShapeInstance = NULL;
|
||||
delete mShadow;
|
||||
mShadow = NULL;
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool TSStatic::prepRenderImage(SceneState* state, const U32 stateKey,
|
||||
const U32 /*startZone*/, const bool /*modifyBaseState*/)
|
||||
{
|
||||
if (isLastState(state, stateKey))
|
||||
return false;
|
||||
setLastState(state, stateKey);
|
||||
|
||||
// This should be sufficient for most objects that don't manage zones, and
|
||||
// don't need to return a specialized RenderImage...
|
||||
if (mShapeInstance && state->isObjectRendered(this)) {
|
||||
Point3F cameraOffset;
|
||||
getRenderTransform().getColumn(3,&cameraOffset);
|
||||
cameraOffset -= state->getCameraPosition();
|
||||
F32 dist = cameraOffset.len();
|
||||
if (dist < 0.01)
|
||||
dist = 0.01;
|
||||
F32 fogAmount = state->getHazeAndFog(dist,cameraOffset.z);
|
||||
if (fogAmount>0.99f)
|
||||
return false;
|
||||
|
||||
F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z));
|
||||
DetailManager::selectPotentialDetails(mShapeInstance,dist,invScale);
|
||||
if (mShapeInstance->getCurrentDetail()<0)
|
||||
return false;
|
||||
|
||||
if (mShapeInstance->hasSolid())
|
||||
{
|
||||
SceneRenderImage* image = new SceneRenderImage;
|
||||
image->obj = this;
|
||||
image->isTranslucent = false;
|
||||
image->textureSortKey = mShapeHash;
|
||||
state->insertRenderImage(image);
|
||||
}
|
||||
|
||||
if (mShapeInstance->hasTranslucency())
|
||||
{
|
||||
SceneRenderImage* image = new SceneRenderImage;
|
||||
image->obj = this;
|
||||
image->isTranslucent = true;
|
||||
image->sortType = SceneRenderImage::Point;
|
||||
image->textureSortKey = mShapeHash;
|
||||
state->setImageRefPoint(this, image);
|
||||
|
||||
state->insertRenderImage(image);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void TSStatic::setTransform(const MatrixF & mat)
|
||||
{
|
||||
Parent::setTransform(mat);
|
||||
|
||||
// Since the interior is a static object, it's render transform changes 1 to 1
|
||||
// with it's collision transform
|
||||
setRenderTransform(mat);
|
||||
}
|
||||
|
||||
|
||||
void TSStatic::renderObject(SceneState* state, SceneRenderImage* image)
|
||||
{
|
||||
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on entry");
|
||||
|
||||
if (!DetailManager::selectCurrentDetail(mShapeInstance))
|
||||
// we were detailed out
|
||||
return;
|
||||
|
||||
RectI viewport;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
dglGetViewport(&viewport);
|
||||
|
||||
installLights();
|
||||
|
||||
// Uncomment this if this is a "simple" (non-zone managing) object
|
||||
state->setupObjectProjection(this);
|
||||
|
||||
// This is something of a hack, but since the 3space objects don't have a
|
||||
// clear conception of texels/meter like the interiors do, we're sorta
|
||||
// stuck. I can't even claim this is anything more scientific than eyeball
|
||||
// work. DMM
|
||||
F32 axis = (getObjBox().len_x() + getObjBox().len_y() + getObjBox().len_z()) / 3.0;
|
||||
F32 dist = (getRenderWorldBox().getClosestPoint(state->getCameraPosition()) - state->getCameraPosition()).len();
|
||||
if (dist != 0)
|
||||
{
|
||||
F32 projected = dglProjectRadius(dist, axis) / 25;
|
||||
if (projected < (1.0 / 16.0))
|
||||
{
|
||||
TextureManager::setSmallTexturesActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
dglMultMatrix(&mObjToWorld);
|
||||
glScalef(mObjScale.x, mObjScale.y, mObjScale.z);
|
||||
|
||||
// RENDER CODE HERE
|
||||
mShapeInstance->setEnvironmentMap(state->getEnvironmentMap());
|
||||
mShapeInstance->setEnvironmentMapOn(true,1);
|
||||
mShapeInstance->setAlphaAlways(1.0);
|
||||
|
||||
Point3F cameraOffset;
|
||||
mObjToWorld.getColumn(3,&cameraOffset);
|
||||
cameraOffset -= state->getCameraPosition();
|
||||
dist = cameraOffset.len();
|
||||
F32 fogAmount = state->getHazeAndFog(dist,cameraOffset.z);
|
||||
|
||||
if (image->isTranslucent == true)
|
||||
{
|
||||
TSShapeInstance::smNoRenderNonTranslucent = true;
|
||||
TSShapeInstance::smNoRenderTranslucent = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TSShapeInstance::smNoRenderNonTranslucent = false;
|
||||
TSShapeInstance::smNoRenderTranslucent = true;
|
||||
}
|
||||
|
||||
mShapeInstance->setupFog(fogAmount,state->getFogColor());
|
||||
mShapeInstance->animate();
|
||||
mShapeInstance->render();
|
||||
|
||||
renderShadow(dist,fogAmount);
|
||||
|
||||
TSShapeInstance::smNoRenderNonTranslucent = false;
|
||||
TSShapeInstance::smNoRenderTranslucent = false;
|
||||
TextureManager::setSmallTexturesActive(false);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
uninstallLights();
|
||||
dglSetCanonicalState();
|
||||
|
||||
if (GameBase::gShowBoundingBox) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
Point3F box;
|
||||
glPushMatrix();
|
||||
dglMultMatrix(&getTransform());
|
||||
box = (mObjBox.min + mObjBox.max) * 0.5;
|
||||
glTranslatef(box.x,box.y,box.z);
|
||||
box = (mObjBox.max - mObjBox.min) * 0.5;
|
||||
glScalef(box.x,box.y,box.z);
|
||||
glColor3f(1, 0, 1);
|
||||
ShapeBase::wireCube(Point3F(1,1,1),Point3F(0,0,0));
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
box = (mWorldBox.min + mWorldBox.max) * 0.5;
|
||||
glTranslatef(box.x,box.y,box.z);
|
||||
box = (mWorldBox.max - mWorldBox.min) * 0.5;
|
||||
glScalef(box.x,box.y,box.z);
|
||||
glColor3f(0, 1, 1);
|
||||
ShapeBase::wireCube(Point3F(1,1,1),Point3F(0,0,0));
|
||||
glPopMatrix();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
dglSetViewport(viewport);
|
||||
|
||||
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
|
||||
}
|
||||
|
||||
void TSStatic::renderShadow(F32 dist, F32 fogAmount)
|
||||
{
|
||||
if (Shadow::getGlobalShadowDetailLevel()<StaticShape_NoShadowLevel)
|
||||
return;
|
||||
if (mShapeInstance->getShape()->subShapeFirstTranslucentObject.empty() || mShapeInstance->getShape()->subShapeFirstTranslucentObject[0]==0)
|
||||
return;
|
||||
|
||||
if (!mShadow)
|
||||
mShadow = new Shadow();
|
||||
mShadow->setGeneric(Shadow::getGlobalShadowDetailLevel() < StaticShape_GenericShadowLevel);
|
||||
mShadow->setMoving(false);
|
||||
mShadow->setAnimating(false);
|
||||
|
||||
Point3F lightDir = gClientSceneGraph->getLightManager()->getShadowLightDirection();
|
||||
|
||||
F32 shadowLen = 10.0f * mShapeInstance->getShape()->radius;
|
||||
Point3F pos = mShapeInstance->getShape()->center;
|
||||
|
||||
// this is a bit of a hack...move generic shadows towards feet/base of shape
|
||||
if (Shadow::getGlobalShadowDetailLevel() < StaticShape_GenericShadowLevel)
|
||||
pos *= 0.5f;
|
||||
pos.convolve(mObjScale);
|
||||
mObjToWorld.mulP(pos);
|
||||
|
||||
// pos is where shadow will be centered (in world space)
|
||||
mShadow->setRadius(mShapeInstance,mObjScale);
|
||||
if (!mShadow->prepare(pos,lightDir,shadowLen,mObjScale,dist,fogAmount,mShapeInstance))
|
||||
return;
|
||||
|
||||
F32 maxScale = getMax(mObjScale.x,getMax(mObjScale.y,mObjScale.z));
|
||||
|
||||
if (mShadow->needBitmap())
|
||||
{
|
||||
mShadow->beginRenderToBitmap();
|
||||
mShadow->selectShapeDetail(mShapeInstance,dist,maxScale);
|
||||
mShadow->renderToBitmap(mShapeInstance,mObjToWorld,pos,mObjScale);
|
||||
mShadow->endRenderToBitmap();
|
||||
}
|
||||
|
||||
mShadow->render();
|
||||
}
|
||||
|
||||
U32 TSStatic::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
|
||||
{
|
||||
U32 retMask = Parent::packUpdate(con, mask, stream);
|
||||
|
||||
mathWrite(*stream, getTransform());
|
||||
mathWrite(*stream, getScale());
|
||||
stream->writeString(mShapeName);
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
|
||||
void TSStatic::unpackUpdate(NetConnection *con, BitStream *stream)
|
||||
{
|
||||
Parent::unpackUpdate(con, stream);
|
||||
|
||||
MatrixF mat;
|
||||
Point3F scale;
|
||||
mathRead(*stream, &mat);
|
||||
mathRead(*stream, &scale);
|
||||
setScale(scale);
|
||||
setTransform(mat);
|
||||
|
||||
mShapeName = stream->readSTString();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
bool TSStatic::castRay(const Point3F &start, const Point3F &end, RayInfo* info)
|
||||
{
|
||||
if (mShapeInstance)
|
||||
{
|
||||
RayInfo shortest;
|
||||
shortest.t = 1e8;
|
||||
|
||||
info->object = NULL;
|
||||
for (U32 i = 0; i < mLOSDetails.size(); i++)
|
||||
{
|
||||
mShapeInstance->animate(mLOSDetails[i]);
|
||||
if (mShapeInstance->castRay(start, end, info, mLOSDetails[i]))
|
||||
{
|
||||
info->object = this;
|
||||
if (info->t < shortest.t)
|
||||
shortest = *info;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->object == this) {
|
||||
// Copy out the shortest time...
|
||||
*info = shortest;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool TSStatic::buildPolyList(AbstractPolyList* polyList, const Box3F &, const SphereF &)
|
||||
{
|
||||
if (mShapeInstance) {
|
||||
bool ret = false;
|
||||
|
||||
polyList->setTransform(&mObjToWorld, mObjScale);
|
||||
polyList->setObject(this);
|
||||
|
||||
for (U32 i = 0; i < mCollisionDetails.size(); i++)
|
||||
{
|
||||
mShapeInstance->buildPolyList(polyList, mCollisionDetails[i]);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void TSStatic::buildConvex(const Box3F& box, Convex* convex)
|
||||
{
|
||||
if (mShapeInstance == NULL)
|
||||
return;
|
||||
|
||||
// These should really come out of a pool
|
||||
mConvexList->collectGarbage();
|
||||
|
||||
Box3F realBox = box;
|
||||
mWorldToObj.mul(realBox);
|
||||
realBox.min.convolveInverse(mObjScale);
|
||||
realBox.max.convolveInverse(mObjScale);
|
||||
|
||||
if (realBox.isOverlapped(getObjBox()) == false)
|
||||
return;
|
||||
|
||||
for (U32 i = 0; i < mCollisionDetails.size(); i++)
|
||||
{
|
||||
// If there is no convex "accelerator" for this detail,
|
||||
// there's nothing to collide with.
|
||||
TSShape::ConvexHullAccelerator* pAccel =
|
||||
mShapeInstance->getShape()->getAccelerator(mCollisionDetails[i]);
|
||||
if (!pAccel || !pAccel->numVerts)
|
||||
continue;
|
||||
|
||||
// See if this hull exists in the working set already...
|
||||
Convex* cc = 0;
|
||||
CollisionWorkingList& wl = convex->getWorkingList();
|
||||
for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext) {
|
||||
if (itr->mConvex->getType() == TSStaticConvexType &&
|
||||
(static_cast<TSStaticConvex*>(itr->mConvex)->pStatic == this &&
|
||||
static_cast<TSStaticConvex*>(itr->mConvex)->hullId == i)) {
|
||||
cc = itr->mConvex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cc)
|
||||
continue;
|
||||
|
||||
// Create a new convex.
|
||||
TSStaticConvex* cp = new TSStaticConvex;
|
||||
mConvexList->registerObject(cp);
|
||||
convex->addToWorkingList(cp);
|
||||
cp->mObject = this;
|
||||
cp->pStatic = this;
|
||||
cp->hullId = i;
|
||||
cp->box = mObjBox;
|
||||
cp->findNodeTransform();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
void TSStaticConvex::findNodeTransform()
|
||||
{
|
||||
S32 dl = pStatic->mCollisionDetails[hullId];
|
||||
|
||||
TSShapeInstance* si = pStatic->mShapeInstance;
|
||||
TSShape* shape = si->getShape();
|
||||
|
||||
const TSShape::Detail* detail = &shape->details[dl];
|
||||
S32 subs = detail->subShapeNum;
|
||||
S32 start = shape->subShapeFirstObject[subs];
|
||||
S32 end = start + shape->subShapeNumObjects[subs];
|
||||
|
||||
// Find the first object that contains a mesh for this
|
||||
// detail level. There should only be one mesh per
|
||||
// collision detail level.
|
||||
for (S32 i = start; i < end; i++) {
|
||||
const TSShape::Object* obj = &shape->objects[i];
|
||||
if (obj->numMeshes && detail->objectDetailNum < obj->numMeshes) {
|
||||
nodeTransform = &si->mNodeTransforms[obj->nodeIndex];
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const MatrixF& TSStaticConvex::getTransform() const
|
||||
{
|
||||
// Multiply on the mesh shape offset
|
||||
// tg: Returning this static here is not really a good idea, but
|
||||
// all this Convex code needs to be re-organized.
|
||||
if (nodeTransform) {
|
||||
static MatrixF mat;
|
||||
mat.mul(mObject->getTransform(),*nodeTransform);
|
||||
return mat;
|
||||
}
|
||||
return mObject->getTransform();
|
||||
}
|
||||
|
||||
Box3F TSStaticConvex::getBoundingBox() const
|
||||
{
|
||||
return getBoundingBox(mObject->getTransform(), mObject->getScale());
|
||||
}
|
||||
|
||||
Box3F TSStaticConvex::getBoundingBox(const MatrixF& mat, const Point3F& scale) const
|
||||
{
|
||||
Box3F newBox = box;
|
||||
newBox.min.convolve(scale);
|
||||
newBox.max.convolve(scale);
|
||||
mat.mul(newBox);
|
||||
return newBox;
|
||||
}
|
||||
|
||||
Point3F TSStaticConvex::support(const VectorF& v) const
|
||||
{
|
||||
TSShape::ConvexHullAccelerator* pAccel =
|
||||
pStatic->mShapeInstance->getShape()->getAccelerator(pStatic->mCollisionDetails[hullId]);
|
||||
AssertFatal(pAccel != NULL, "Error, no accel!");
|
||||
|
||||
F32 currMaxDP = mDot(pAccel->vertexList[0], v);
|
||||
U32 index = 0;
|
||||
for (U32 i = 1; i < pAccel->numVerts; i++) {
|
||||
F32 dp = mDot(pAccel->vertexList[i], v);
|
||||
if (dp > currMaxDP) {
|
||||
currMaxDP = dp;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return pAccel->vertexList[index];
|
||||
}
|
||||
|
||||
|
||||
void TSStaticConvex::getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf)
|
||||
{
|
||||
cf->material = 0;
|
||||
cf->object = mObject;
|
||||
|
||||
TSShape::ConvexHullAccelerator* pAccel =
|
||||
pStatic->mShapeInstance->getShape()->getAccelerator(pStatic->mCollisionDetails[hullId]);
|
||||
AssertFatal(pAccel != NULL, "Error, no accel!");
|
||||
|
||||
F32 currMaxDP = mDot(pAccel->vertexList[0], n);
|
||||
U32 index = 0;
|
||||
U32 i;
|
||||
for (i = 1; i < pAccel->numVerts; i++) {
|
||||
F32 dp = mDot(pAccel->vertexList[i], n);
|
||||
if (dp > currMaxDP) {
|
||||
currMaxDP = dp;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
const U8* emitString = pAccel->emitStrings[index];
|
||||
U32 currPos = 0;
|
||||
U32 numVerts = emitString[currPos++];
|
||||
for (i = 0; i < numVerts; i++) {
|
||||
cf->mVertexList.increment();
|
||||
U32 index = emitString[currPos++];
|
||||
mat.mulP(pAccel->vertexList[index], &cf->mVertexList.last());
|
||||
}
|
||||
|
||||
U32 numEdges = emitString[currPos++];
|
||||
for (i = 0; i < numEdges; i++) {
|
||||
U32 ev0 = emitString[currPos++];
|
||||
U32 ev1 = emitString[currPos++];
|
||||
cf->mEdgeList.increment();
|
||||
cf->mEdgeList.last().vertex[0] = ev0;
|
||||
cf->mEdgeList.last().vertex[1] = ev1;
|
||||
}
|
||||
|
||||
U32 numFaces = emitString[currPos++];
|
||||
for (i = 0; i < numFaces; i++) {
|
||||
cf->mFaceList.increment();
|
||||
U32 plane = emitString[currPos++];
|
||||
mat.mulV(pAccel->normalList[plane], &cf->mFaceList.last().normal);
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
cf->mFaceList.last().vertex[j] = emitString[currPos++];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TSStaticConvex::getPolyList(AbstractPolyList* list)
|
||||
{
|
||||
list->setTransform(&pStatic->getTransform(), pStatic->getScale());
|
||||
list->setObject(pStatic);
|
||||
|
||||
pStatic->mShapeInstance->animate(pStatic->mCollisionDetails[hullId]);
|
||||
pStatic->mShapeInstance->buildPolyList(list, pStatic->mCollisionDetails[hullId]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user