📄 pathedinterior.cc
字号:
//--------------------------------------------------------------------------
// 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()
{
//#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
// if(mPathKey == 0xFFFFFFFF)
//#else
if(mPathKey == 0xFFFFFFFF && !isGhost())
//#endif
{
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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -