Professional Documents
Culture Documents
Mesh Road
Mesh Road
//-----------------------------------------------------------------------------
// MeshRoadNodeList Struct
//-----------------------------------------------------------------------------
struct MeshRoadNodeList : public NodeListManager::NodeList
{
Vector<Point3F> mPositions;
Vector<F32> mWidths;
Vector<F32> mDepths;
Vector<VectorF> mNormals;
MeshRoadNodeList() { }
virtual ~MeshRoadNodeList() { }
};
//-----------------------------------------------------------------------------
// MeshRoadNodeEvent Class
//-----------------------------------------------------------------------------
class MeshRoadNodeEvent : public NodeListEvent
{
typedef NodeListEvent Parent;
public:
Vector<Point3F> mPositions;
Vector<F32> mWidths;
Vector<F32> mDepths;
Vector<VectorF> mNormals;
public:
MeshRoadNodeEvent() { mNodeList = NULL; }
virtual ~MeshRoadNodeEvent() { }
virtual void pack(NetConnection*, BitStream*);
virtual void unpack(NetConnection*, BitStream*);
virtual void copyIntoList(NodeListManager::NodeList* copyInto);
virtual void padListToSize();
DECLARE_CONOBJECT(MeshRoadNodeEvent);
};
void MeshRoadNodeEvent::pack(NetConnection* conn, BitStream* stream)
{
Parent::pack( conn, stream );
stream->writeInt( mPositions.size(), 16 );
for (U32 i=0; i<mPositions.size(); ++i)
{
mathWrite( *stream, mPositions[i] );
stream->write( mWidths[i] );
stream->write( mDepths[i] );
mathWrite( *stream, mNormals[i] );
}
}
void MeshRoadNodeEvent::unpack(NetConnection* conn, BitStream* stream)
{
mNodeList = new MeshRoadNodeList();
Parent::unpack( conn, stream );
U32 count = stream->readInt( 16 );
Point3F pos;
F32 width, depth;
VectorF normal;
MeshRoadNodeList* list = static_cast<MeshRoadNodeList*>(mNodeList);
for (U32 i=0; i<count; ++i)
{
mathRead( *stream, &pos );
stream->read( &width );
stream->read( &depth );
mathRead( *stream, &normal );
list->mPositions.push_back( pos );
list->mWidths.push_back( width );
list->mDepths.push_back( depth );
list->mNormals.push_back( normal );
}
list->mTotalValidNodes = count;
// Do we have a complete list?
if (list->mPositions.size() >= mTotalNodes)
list->mListComplete = true;
}
void MeshRoadNodeEvent::copyIntoList(NodeListManager::NodeList* copyInto)
{
MeshRoadNodeList* prevList = dynamic_cast<MeshRoadNodeList*>(copyInto);
MeshRoadNodeList* list = static_cast<MeshRoadNodeList*>(mNodeList);
// Merge our list with the old list.
for (U32 i=mLocalListStart, index=0; i<mLocalListStart+list->mPositions.size(
); ++i, ++index)
{
prevList->mPositions[i] = list->mPositions[index];
prevList->mWidths[i] = list->mWidths[index];
prevList->mDepths[i] = list->mDepths[index];
prevList->mNormals[i] = list->mNormals[index];
}
}
void MeshRoadNodeEvent::padListToSize()
{
MeshRoadNodeList* list = static_cast<MeshRoadNodeList*>(mNodeList);
U32 totalValidNodes = list->mTotalValidNodes;
// Pad our list front?
if (mLocalListStart)
{
MeshRoadNodeList* newlist = new MeshRoadNodeList();
newlist->mPositions.increment(mLocalListStart);
newlist->mWidths.increment(mLocalListStart);
newlist->mDepths.increment(mLocalListStart);
newlist->mNormals.increment(mLocalListStart);
newlist->mPositions.merge(list->mPositions);
newlist->mWidths.merge(list->mWidths);
newlist->mDepths.merge(list->mDepths);
newlist->mNormals.merge(list->mNormals);
delete list;
mNodeList = list = newlist;
}
// Pad our list end?
if (list->mPositions.size() < mTotalNodes)
{
U32 delta = mTotalNodes - list->mPositions.size();
list->mPositions.increment(delta);
list->mWidths.increment(delta);
list->mDepths.increment(delta);
list->mNormals.increment(delta);
}
list->mTotalValidNodes = totalValidNodes;
}
IMPLEMENT_CO_NETEVENT_V1(MeshRoadNodeEvent);
ConsoleDocClass( MeshRoadNodeEvent,
"@brief Sends messages to the Mesh Road Editor\n\n"
"Editor use only.\n\n"
"@internal"
);
//-----------------------------------------------------------------------------
// MeshRoadNodeListNotify Class
//-----------------------------------------------------------------------------
class MeshRoadNodeListNotify : public NodeListNotify
{
typedef NodeListNotify Parent;
protected:
SimObjectPtr<MeshRoad> mRoad;
public:
MeshRoadNodeListNotify( MeshRoad* road, U32 listId ) { mRoad = road; mListId
= listId; }
virtual ~MeshRoadNodeListNotify() { mRoad = NULL; }
virtual void sendNotification( NodeListManager::NodeList* list );
};
void MeshRoadNodeListNotify::sendNotification( NodeListManager::NodeList* list )
{
if (mRoad.isValid())
{
// Build the road's nodes
MeshRoadNodeList* roadList = dynamic_cast<MeshRoadNodeList*>( list );
if (roadList)
mRoad->buildNodesFromList( roadList );
}
}
//------------------------------------------------------------------------------
// MeshRoadConvex Class
//------------------------------------------------------------------------------
const MatrixF& MeshRoadConvex::getTransform() const
{
return MatrixF::Identity; //mObject->getTransform();
}
Box3F MeshRoadConvex::getBoundingBox() const
{
return box;
}
Box3F MeshRoadConvex::getBoundingBox(const MatrixF& mat, const Point3F& scale) c
onst
{
Box3F newBox = box;
newBox.minExtents.convolve(scale);
newBox.maxExtents.convolve(scale);
mat.mul(newBox);
return newBox;
}
Point3F MeshRoadConvex::support(const VectorF& vec) const
{
F32 bestDot = mDot( verts[0], vec );
const Point3F *bestP = &verts[0];
for(S32 i=1; i<4; i++)
{
F32 newD = mDot(verts[i], vec);
if(newD > bestDot)
{
bestDot = newD;
bestP = &verts[i];
}
}
return *bestP;
}
void MeshRoadConvex::getFeatures(const MatrixF& mat, const VectorF& n, ConvexFea
ture* cf)
{
cf->material = 0;
cf->object = mObject;
// For a tetrahedron this is pretty easy... first
// convert everything into world space.
Point3F tverts[4];
mat.mulP(verts[0], &tverts[0]);
mat.mulP(verts[1], &tverts[1]);
mat.mulP(verts[2], &tverts[2]);
mat.mulP(verts[3], &tverts[3]);
// Points...
S32 firstVert = cf->mVertexList.size();
cf->mVertexList.increment(); cf->mVertexList.last() = tverts[0];
cf->mVertexList.increment(); cf->mVertexList.last() = tverts[1];
cf->mVertexList.increment(); cf->mVertexList.last() = tverts[2];
cf->mVertexList.increment(); cf->mVertexList.last() = tverts[3];
// Edges...
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = firstVert+0;
cf->mEdgeList.last().vertex[1] = firstVert+1;
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = firstVert+1;
cf->mEdgeList.last().vertex[1] = firstVert+2;
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = firstVert+2;
cf->mEdgeList.last().vertex[1] = firstVert+0;
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = firstVert+3;
cf->mEdgeList.last().vertex[1] = firstVert+0;
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = firstVert+3;
cf->mEdgeList.last().vertex[1] = firstVert+1;
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = firstVert+3;
cf->mEdgeList.last().vertex[1] = firstVert+2;
// Triangles...
cf->mFaceList.increment();
cf->mFaceList.last().normal = PlaneF(tverts[2], tverts[1], tverts[0]);
cf->mFaceList.last().vertex[0] = firstVert+2;
cf->mFaceList.last().vertex[1] = firstVert+1;
cf->mFaceList.last().vertex[2] = firstVert+0;
cf->mFaceList.increment();
cf->mFaceList.last().normal = PlaneF(tverts[1], tverts[0], tverts[3]);
cf->mFaceList.last().vertex[0] = firstVert+1;
cf->mFaceList.last().vertex[1] = firstVert+0;
cf->mFaceList.last().vertex[2] = firstVert+3;
cf->mFaceList.increment();
cf->mFaceList.last().normal = PlaneF(tverts[2], tverts[1], tverts[3]);
cf->mFaceList.last().vertex[0] = firstVert+2;
cf->mFaceList.last().vertex[1] = firstVert+1;
cf->mFaceList.last().vertex[2] = firstVert+3;
cf->mFaceList.increment();
cf->mFaceList.last().normal = PlaneF(tverts[0], tverts[2], tverts[3]);
cf->mFaceList.last().vertex[0] = firstVert+0;
cf->mFaceList.last().vertex[1] = firstVert+2;
cf->mFaceList.last().vertex[2] = firstVert+3;
}