Initial commit
This commit is contained in:
623
Torque/SDK/engine/interior/pathedInterior.cc
Normal file
623
Torque/SDK/engine/interior/pathedInterior.cc
Normal file
@@ -0,0 +1,623 @@
|
||||
//--------------------------------------------------------------------------
|
||||
// PathedInterior.cc:
|
||||
//
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#include "interior/pathedInterior.h"
|
||||
#include "core/stream.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "sceneGraph/sceneState.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "core/bitStream.h"
|
||||
#include "interior/interior.h"
|
||||
#include "sim/simPath.h"
|
||||
#include "sim/pathManager.h"
|
||||
#include "core/frameAllocator.h"
|
||||
#include "sceneGraph/sceneGraph.h"
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(PathedInterior);
|
||||
IMPLEMENT_CO_DATABLOCK_V1(PathedInteriorData);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
PathedInteriorData::PathedInteriorData()
|
||||
{
|
||||
for(U32 i = 0; i < MaxSounds; i++)
|
||||
sound[i] = NULL;
|
||||
}
|
||||
|
||||
void PathedInteriorData::initPersistFields()
|
||||
{
|
||||
addField("StartSound", TypeAudioProfilePtr, Offset(sound[StartSound], PathedInteriorData));
|
||||
addField("SustainSound", TypeAudioProfilePtr, Offset(sound[SustainSound], PathedInteriorData));
|
||||
addField("StopSound", TypeAudioProfilePtr, Offset(sound[StopSound], PathedInteriorData));
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void PathedInteriorData::packData(BitStream *stream)
|
||||
{
|
||||
for (S32 i = 0; i < MaxSounds; i++)
|
||||
{
|
||||
if (stream->writeFlag(sound[i]))
|
||||
stream->writeRangedU32(packed? SimObjectId(sound[i]):
|
||||
sound[i]->getId(),DataBlockObjectIdFirst,DataBlockObjectIdLast);
|
||||
}
|
||||
Parent::packData(stream);
|
||||
}
|
||||
|
||||
void PathedInteriorData::unpackData(BitStream* stream)
|
||||
{
|
||||
for (S32 i = 0; i < MaxSounds; i++) {
|
||||
sound[i] = NULL;
|
||||
if (stream->readFlag())
|
||||
sound[i] = (AudioProfile*)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
}
|
||||
Parent::unpackData(stream);
|
||||
}
|
||||
|
||||
bool PathedInteriorData::preload(bool server, char errorBuffer[256])
|
||||
{
|
||||
if(!Parent::preload(server, errorBuffer))
|
||||
return false;
|
||||
|
||||
// Resolve objects transmitted from server
|
||||
if (!server)
|
||||
{
|
||||
for (S32 i = 0; i < MaxSounds; i++)
|
||||
if (sound[i])
|
||||
Sim::findObject(SimObjectId(sound[i]),sound[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PathedInterior::PathedInterior()
|
||||
{
|
||||
mNetFlags.set(Ghostable);
|
||||
mTypeMask = InteriorObjectType;
|
||||
|
||||
mCurrentPosition = 0;
|
||||
mTargetPosition = 0;
|
||||
mPathKey = 0xFFFFFFFF;
|
||||
mStopped = false;
|
||||
mSustainHandle = 0;
|
||||
}
|
||||
|
||||
PathedInterior::~PathedInterior()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
PathedInterior *PathedInterior::mClientPathedInteriors = NULL;
|
||||
//--------------------------------------------------------------------------
|
||||
void PathedInterior::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
||||
addField("interiorResource", TypeFilename, Offset(mInteriorResName, PathedInterior));
|
||||
addField("interiorIndex", TypeS32, Offset(mInteriorResIndex, PathedInterior));
|
||||
addField("basePosition", TypeMatrixPosition, Offset(mBaseTransform, PathedInterior));
|
||||
addField("baseRotation", TypeMatrixRotation, Offset(mBaseTransform, PathedInterior));
|
||||
addField("baseScale", TypePoint3F, Offset(mBaseScale, PathedInterior));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool PathedInterior::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
// Load the interior resource and extract the interior that is us.
|
||||
char buffer[256];
|
||||
mInteriorRes = ResourceManager->load(mInteriorResName);
|
||||
if (bool(mInteriorRes) == false)
|
||||
return false;
|
||||
mInterior = mInteriorRes->getSubObject(mInteriorResIndex);
|
||||
if (mInterior == NULL)
|
||||
return false;
|
||||
|
||||
// Setup bounding information
|
||||
mObjBox = mInterior->getBoundingBox();
|
||||
resetWorldBox();
|
||||
|
||||
setScale(mBaseScale);
|
||||
setTransform(mBaseTransform);
|
||||
|
||||
if (isClientObject()) {
|
||||
mNextClientPI = mClientPathedInteriors;
|
||||
mClientPathedInteriors = this;
|
||||
mInterior->prepForRendering(mInteriorRes.getFilePath());
|
||||
// gInteriorLMManager.addInstance(mInterior->getLMHandle(), mLMHandle, NULL, this);
|
||||
}
|
||||
|
||||
if(isClientObject())
|
||||
{
|
||||
Point3F initialPos;
|
||||
mBaseTransform.getColumn(3, &initialPos);
|
||||
Point3F pathPos;
|
||||
//gClientPathManager->getPathPosition(mPathKey, 0, pathPos);
|
||||
mOffset = initialPos - pathPos;
|
||||
//gClientPathManager->getPathPosition(mPathKey, mCurrentPosition, pathPos);
|
||||
MatrixF mat = getTransform();
|
||||
mat.setColumn(3, pathPos + mOffset);
|
||||
setTransform(mat);
|
||||
}
|
||||
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PathedInterior::onSceneAdd(SceneGraph *g)
|
||||
{
|
||||
if(!Parent::onSceneAdd(g))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PathedInterior::onSceneRemove()
|
||||
{
|
||||
Parent::onSceneRemove();
|
||||
}
|
||||
|
||||
bool PathedInterior::onNewDataBlock(GameBaseData* dptr)
|
||||
{
|
||||
mDataBlock = dynamic_cast<PathedInteriorData*>(dptr);
|
||||
return Parent::onNewDataBlock(dptr);
|
||||
}
|
||||
|
||||
void PathedInterior::onRemove()
|
||||
{
|
||||
if(isClientObject())
|
||||
{
|
||||
if(mSustainHandle)
|
||||
{
|
||||
alxStop(mSustainHandle);
|
||||
mSustainHandle = 0;
|
||||
}
|
||||
PathedInterior **walk = &mClientPathedInteriors;
|
||||
while(*walk)
|
||||
{
|
||||
if(*walk == this)
|
||||
{
|
||||
*walk = mNextClientPI;
|
||||
break;
|
||||
}
|
||||
walk = &((*walk)->mNextClientPI);
|
||||
}
|
||||
/* if(bool(mInteriorRes) && mLMHandle != 0xFFFFFFFF)
|
||||
{
|
||||
if (mInterior->getLMHandle() != 0xFFFFFFFF)
|
||||
gInteriorLMManager.removeInstance(mInterior->getLMHandle(), mLMHandle);
|
||||
}*/
|
||||
}
|
||||
removeFromScene();
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool PathedInterior::buildPolyList(AbstractPolyList* list, const Box3F& wsBox, const SphereF&)
|
||||
{
|
||||
if (bool(mInteriorRes) == false)
|
||||
return false;
|
||||
|
||||
// Setup collision state data
|
||||
list->setTransform(&getTransform(), getScale());
|
||||
list->setObject(this);
|
||||
|
||||
return mInterior->buildPolyList(list, wsBox, mWorldToObj, getScale());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool PathedInterior::prepRenderImage(SceneState* state, const U32 stateKey,
|
||||
const U32 /*startZone*/, const bool /*modifyBaseState*/)
|
||||
{
|
||||
if (isLastState(state, stateKey))
|
||||
return false;
|
||||
setLastState(state, stateKey);
|
||||
|
||||
if (mPathKey == Path::NoPathIndex)
|
||||
return false;
|
||||
|
||||
// This should be sufficient for most objects that don't manage zones, and
|
||||
// don't need to return a specialized RenderImage...
|
||||
bool render = false;
|
||||
for (U32 i = 0; i < getNumCurrZones(); i++)
|
||||
if (state->getZoneState(getCurrZone(i)).render == true)
|
||||
render = true;
|
||||
|
||||
if (render == true) {
|
||||
SceneRenderImage* image = new SceneRenderImage;
|
||||
image->obj = this;
|
||||
state->insertRenderImage(image);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
extern ColorF gInteriorFogColor;
|
||||
|
||||
void PathedInterior::renderObject(SceneState* state, SceneRenderImage*)
|
||||
{
|
||||
U32 storedWaterMark = FrameAllocator::getWaterMark();
|
||||
Point3F worldOrigin;
|
||||
getRenderTransform().getColumn(3, &worldOrigin);
|
||||
|
||||
// Set up the model view and the global render state...
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
ColorF oneColor(1,1,1,1);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, oneColor);
|
||||
|
||||
installLights();
|
||||
|
||||
// dglMultMatrix(&newMat);
|
||||
dglMultMatrix(&mRenderObjToWorld);
|
||||
glScalef(mObjScale.x, mObjScale.y, mObjScale.z);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// We need to decide if we're going to use the low-res textures
|
||||
|
||||
//mInterior->setupFog(state);
|
||||
//gInteriorFogColor = state->getFogColor();
|
||||
mInterior->renderAsShape();
|
||||
|
||||
//mInterior->clearFog();
|
||||
uninstallLights();
|
||||
glDisable(GL_CULL_FACE);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
|
||||
|
||||
FrameAllocator::setWaterMark(storedWaterMark);
|
||||
dglSetRenderPrimType(0);
|
||||
|
||||
// Reset the small textures...
|
||||
TextureManager::setSmallTexturesActive(false);
|
||||
|
||||
}
|
||||
|
||||
void PathedInterior::resolvePathKey()
|
||||
{
|
||||
if(mPathKey == 0xFFFFFFFF && !isGhost())
|
||||
{
|
||||
mPathKey = getPathKey();
|
||||
Point3F pathPos;
|
||||
Point3F initialPos;
|
||||
mBaseTransform.getColumn(3, &initialPos);
|
||||
//gServerPathManager->getPathPosition(mPathKey, 0, pathPos);
|
||||
mOffset = initialPos - pathPos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
U32 PathedInterior::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
|
||||
{
|
||||
U32 retMask = Parent::packUpdate(con, mask, stream);
|
||||
resolvePathKey();
|
||||
|
||||
if (stream->writeFlag(mask & InitialUpdateMask))
|
||||
{
|
||||
// Inital update...
|
||||
stream->writeString(mInteriorResName);
|
||||
stream->write(mInteriorResIndex);
|
||||
|
||||
stream->writeAffineTransform(mBaseTransform);
|
||||
mathWrite(*stream, mBaseScale);
|
||||
|
||||
stream->write(mPathKey);
|
||||
}
|
||||
if(stream->writeFlag((mask & NewPositionMask) && mPathKey != Path::NoPathIndex))
|
||||
stream->writeInt(S32(mCurrentPosition), gServerPathManager->getPathTimeBits(mPathKey));
|
||||
if(stream->writeFlag((mask & NewTargetMask) && mPathKey != Path::NoPathIndex))
|
||||
{
|
||||
if(stream->writeFlag(mTargetPosition < 0))
|
||||
{
|
||||
stream->writeFlag(mTargetPosition == -1);
|
||||
}
|
||||
else
|
||||
stream->writeInt(S32(mTargetPosition), gServerPathManager->getPathTimeBits(mPathKey));
|
||||
}
|
||||
return retMask;
|
||||
}
|
||||
|
||||
void PathedInterior::unpackUpdate(NetConnection* con, BitStream* stream)
|
||||
{
|
||||
Parent::unpackUpdate(con, stream);
|
||||
|
||||
MatrixF tempXForm;
|
||||
Point3F tempScale;
|
||||
|
||||
if (stream->readFlag())
|
||||
{
|
||||
// Initial
|
||||
mInteriorResName = stream->readSTString();
|
||||
stream->read(&mInteriorResIndex);
|
||||
|
||||
stream->readAffineTransform(&tempXForm);
|
||||
mathRead(*stream, &tempScale);
|
||||
mBaseTransform = tempXForm;
|
||||
mBaseScale = tempScale;
|
||||
|
||||
stream->read(&mPathKey);
|
||||
}
|
||||
if(stream->readFlag())
|
||||
{
|
||||
Point3F pathPos;
|
||||
mCurrentPosition = stream->readInt(gClientPathManager->getPathTimeBits(mPathKey));
|
||||
if(isProperlyAdded())
|
||||
{
|
||||
//gClientPathManager->getPathPosition(mPathKey, mCurrentPosition, pathPos);
|
||||
MatrixF mat = getTransform();
|
||||
mat.setColumn(3, pathPos + mOffset);
|
||||
setTransform(mat);
|
||||
}
|
||||
}
|
||||
if(stream->readFlag())
|
||||
{
|
||||
if(stream->readFlag())
|
||||
{
|
||||
mTargetPosition = stream->readFlag() ? -1 : -2;
|
||||
}
|
||||
else
|
||||
mTargetPosition = stream->readInt(gClientPathManager->getPathTimeBits(mPathKey));
|
||||
}
|
||||
}
|
||||
|
||||
void PathedInterior::processTick(const Move* move)
|
||||
{
|
||||
if(isServerObject())
|
||||
{
|
||||
U32 timeMs = 32;
|
||||
if(mCurrentPosition != mTargetPosition)
|
||||
{
|
||||
S32 delta;
|
||||
if(mTargetPosition == -1)
|
||||
delta = timeMs;
|
||||
else if(mTargetPosition == -2)
|
||||
delta = -timeMs;
|
||||
else
|
||||
{
|
||||
delta = mTargetPosition - mCurrentPosition;
|
||||
if(delta < -timeMs)
|
||||
delta = -timeMs;
|
||||
else if(delta > timeMs)
|
||||
delta = timeMs;
|
||||
}
|
||||
mCurrentPosition += delta;
|
||||
U32 totalTime = gClientPathManager->getPathTotalTime(mPathKey);
|
||||
while(mCurrentPosition > totalTime)
|
||||
mCurrentPosition -= totalTime;
|
||||
while(mCurrentPosition < 0)
|
||||
mCurrentPosition += totalTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PathedInterior::computeNextPathStep(U32 timeDelta)
|
||||
{
|
||||
S32 timeMs = timeDelta;
|
||||
mStopped = false;
|
||||
|
||||
if(mCurrentPosition == mTargetPosition)
|
||||
{
|
||||
mExtrudedBox = getWorldBox();
|
||||
mCurrentVelocity.set(0,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 delta;
|
||||
if(mTargetPosition < 0)
|
||||
{
|
||||
if(mTargetPosition == -1)
|
||||
delta = timeMs;
|
||||
else if(mTargetPosition == -2)
|
||||
delta = -timeMs;
|
||||
mCurrentPosition += delta;
|
||||
U32 totalTime = gClientPathManager->getPathTotalTime(mPathKey);
|
||||
while(mCurrentPosition >= totalTime)
|
||||
mCurrentPosition -= totalTime;
|
||||
while(mCurrentPosition < 0)
|
||||
mCurrentPosition += totalTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = mTargetPosition - mCurrentPosition;
|
||||
if(delta < -timeMs)
|
||||
delta = -timeMs;
|
||||
else if(delta > timeMs)
|
||||
delta = timeMs;
|
||||
mCurrentPosition += delta;
|
||||
}
|
||||
|
||||
Point3F curPoint;
|
||||
Point3F newPoint = Point3F(0,0,0); //BJGNOTE - this shuts up the compiler, three lines down will actually set it.
|
||||
MatrixF mat = getTransform();
|
||||
mat.getColumn(3, &curPoint);
|
||||
//gClientPathManager->getPathPosition(mPathKey, mCurrentPosition, newPoint);
|
||||
newPoint += mOffset;
|
||||
|
||||
Point3F displaceDelta = newPoint - curPoint;
|
||||
mExtrudedBox = getWorldBox();
|
||||
|
||||
if(displaceDelta.x < 0)
|
||||
mExtrudedBox.min.x += displaceDelta.x;
|
||||
else
|
||||
mExtrudedBox.max.x += displaceDelta.x;
|
||||
if(displaceDelta.y < 0)
|
||||
mExtrudedBox.min.y += displaceDelta.y;
|
||||
else
|
||||
mExtrudedBox.max.y += displaceDelta.y;
|
||||
if(displaceDelta.z < 0)
|
||||
mExtrudedBox.min.z += displaceDelta.z;
|
||||
else
|
||||
mExtrudedBox.max.z += displaceDelta.z;
|
||||
|
||||
mCurrentVelocity = displaceDelta * 1000 / F32(timeDelta);
|
||||
}
|
||||
Point3F pos;
|
||||
mExtrudedBox.getCenter(&pos);
|
||||
MatrixF mat = getTransform();
|
||||
mat.setColumn(3, pos);
|
||||
if(!mSustainHandle && mDataBlock->sound[PathedInteriorData::SustainSound])
|
||||
{
|
||||
//F32 volSave = mDataBlock->sound[PathedInteriorData::SustainSound]->mDescriptionObject->mDescription.mVolume;
|
||||
//mDataBlock->sound[PathedInteriorData::SustainSound]->mDescriptionObject->mDescription.mVolume = 0;
|
||||
mSustainHandle = alxPlay(mDataBlock->sound[PathedInteriorData::SustainSound], &mat);
|
||||
//mDataBlock->sound[PathedInteriorData::SustainSound]->mDescriptionObject->mDescription.mVolume = volSave;
|
||||
}
|
||||
if(mSustainHandle)
|
||||
{
|
||||
Point3F pos;
|
||||
mExtrudedBox.getCenter(&pos);
|
||||
MatrixF mat = getTransform();
|
||||
mat.setColumn(3, pos);
|
||||
alxSourceMatrixF(mSustainHandle, &mat);
|
||||
}
|
||||
}
|
||||
|
||||
Point3F PathedInterior::getVelocity()
|
||||
{
|
||||
return mCurrentVelocity;
|
||||
}
|
||||
|
||||
void PathedInterior::advance(F64 timeDelta)
|
||||
{
|
||||
if(mStopped)
|
||||
return;
|
||||
|
||||
F64 timeMs = timeDelta;
|
||||
if(mCurrentVelocity.len() == 0)
|
||||
{
|
||||
// if(mSustainHandle)
|
||||
// {
|
||||
// alxStop(mSustainHandle);
|
||||
// mSustainHandle = 0;
|
||||
// }
|
||||
return;
|
||||
}
|
||||
MatrixF mat = getTransform();
|
||||
Point3F newPoint;
|
||||
mat.getColumn(3, &newPoint);
|
||||
newPoint += mCurrentVelocity * timeDelta / 1000.0f;
|
||||
//gClientPathManager->getPathPosition(mPathKey, mCurrentPosition, newPoint);
|
||||
mat.setColumn(3, newPoint);// + mOffset);
|
||||
setTransform(mat);
|
||||
setRenderTransform(mat);
|
||||
}
|
||||
|
||||
U32 PathedInterior::getPathKey()
|
||||
{
|
||||
AssertFatal(isServerObject(), "Error, must be a server object to call this...");
|
||||
|
||||
SimGroup* myGroup = getGroup();
|
||||
AssertFatal(myGroup != NULL, "No group for this object?");
|
||||
|
||||
for (SimGroup::iterator itr = myGroup->begin(); itr != myGroup->end(); itr++) {
|
||||
Path* pPath = dynamic_cast<Path*>(*itr);
|
||||
if (pPath != NULL) {
|
||||
U32 pathKey = pPath->getPathIndex();
|
||||
AssertFatal(pathKey != Path::NoPathIndex, "Error, path must have event over at this point...");
|
||||
return pathKey;
|
||||
}
|
||||
}
|
||||
|
||||
return Path::NoPathIndex;
|
||||
}
|
||||
|
||||
void PathedInterior::setPathPosition(S32 newPosition)
|
||||
{
|
||||
resolvePathKey();
|
||||
if(newPosition < 0)
|
||||
newPosition = 0;
|
||||
if(newPosition > gServerPathManager->getPathTotalTime(mPathKey))
|
||||
newPosition = gServerPathManager->getPathTotalTime(mPathKey);
|
||||
mCurrentPosition = mTargetPosition = newPosition;
|
||||
setMaskBits(NewPositionMask | NewTargetMask);
|
||||
}
|
||||
|
||||
void PathedInterior::setTargetPosition(S32 newPosition)
|
||||
{
|
||||
resolvePathKey();
|
||||
if(newPosition < -2)
|
||||
newPosition = 0;
|
||||
if(newPosition > S32(gServerPathManager->getPathTotalTime(mPathKey)))
|
||||
newPosition = gServerPathManager->getPathTotalTime(mPathKey);
|
||||
if(mTargetPosition != newPosition)
|
||||
{
|
||||
mTargetPosition = newPosition;
|
||||
setMaskBits(NewTargetMask);
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleMethod(PathedInterior, setPathPosition, void, 3, 3, "")
|
||||
{
|
||||
object->setPathPosition(dAtoi(argv[2]));
|
||||
}
|
||||
|
||||
ConsoleMethod(PathedInterior, setTargetPosition, void, 3, 3, "")
|
||||
{
|
||||
object->setTargetPosition(dAtoi(argv[2]));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool PathedInterior::readPI(Stream& stream)
|
||||
{
|
||||
mName = stream.readSTString();
|
||||
mInteriorResName = stream.readSTString();
|
||||
stream.read(&mInteriorResIndex);
|
||||
stream.read(&mPathIndex);
|
||||
mathRead(stream, &mOffset);
|
||||
|
||||
U32 numTriggers;
|
||||
stream.read(&numTriggers);
|
||||
mTriggers.setSize(numTriggers);
|
||||
for (U32 i = 0; i < mTriggers.size(); i++)
|
||||
mTriggers[i] = stream.readSTString();
|
||||
|
||||
return (stream.getStatus() == Stream::Ok);
|
||||
}
|
||||
|
||||
bool PathedInterior::writePI(Stream& stream) const
|
||||
{
|
||||
stream.writeString(mName);
|
||||
stream.writeString(mInteriorResName);
|
||||
stream.write(mInteriorResIndex);
|
||||
stream.write(mPathIndex);
|
||||
mathWrite(stream, mOffset);
|
||||
|
||||
stream.write(mTriggers.size());
|
||||
for (U32 i = 0; i < mTriggers.size(); i++)
|
||||
stream.writeString(mTriggers[i]);
|
||||
|
||||
return (stream.getStatus() == Stream::Ok);
|
||||
}
|
||||
|
||||
PathedInterior* PathedInterior::clone() const
|
||||
{
|
||||
PathedInterior* pClone = new PathedInterior;
|
||||
|
||||
pClone->mName = mName;
|
||||
pClone->mInteriorResName = mInteriorResName;
|
||||
pClone->mInteriorResIndex = mInteriorResIndex;
|
||||
pClone->mPathIndex = mPathIndex;
|
||||
pClone->mOffset = mOffset;
|
||||
|
||||
return pClone;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user