📄 interiorinstance.cc
字号:
if (pDetail->mMinPixels < projRadius)
{
final = i;
break;
}
}
// Ok, that's it.
return final;
}
//--------------------------------------------------------------------------
bool InteriorInstance::prepRenderImage(SceneState* state, const U32 stateKey,
const U32 startZone, const bool modifyBaseState)
{
if (isLastState(state, stateKey))
return false;
PROFILE_START(InteriorPrepRenderImage);
setLastState(state, stateKey);
U32 realStartZone;
if (startZone != 0xFFFFFFFF)
{
AssertFatal(startZone != 0, "Hm. This really shouldn't happen. Should only get inside zones here");
AssertFatal(isManagingZones(), "Must be managing zones if we're here...");
realStartZone = startZone - mZoneRangeStart + 1;
}
else
{
realStartZone = getPointZone(state->getCameraPosition());
if (realStartZone != 0)
realStartZone = realStartZone - mZoneRangeStart + 1;
}
bool render = true;
if (modifyBaseState == false)
{
// Regular query. We only return a render zone if our parent zone is rendered.
// Otherwise, we always render
if (state->isObjectRendered(this) == false)
{
PROFILE_END();
return false;
}
}
else
{
if (mShowTerrainInside == true)
state->enableTerrainOverride();
}
U32 detailLevel = 0;
if (startZone == 0xFFFFFFFF)
detailLevel = calcDetailLevel(state, state->getCameraPosition());
if (!Interior::smUseVertexLighting)
{
// Since we're rendering: update the lights and the alarm state
U32 msSinceLightsUpdated = Platform::getVirtualMilliseconds() - getLightUpdatedTime();
if (msSinceLightsUpdated > smLightUpdatePeriod)
{
setLightUpdatedTime(Platform::getVirtualMilliseconds());
updateAllLights(msSinceLightsUpdated);
}
}
U32 baseZoneForPrep = getCurrZone(0);
bool multipleZones = false;
if (getNumCurrZones() > 1)
{
U32 numRenderedZones = 0;
baseZoneForPrep = 0xFFFFFFFF;
for (U32 i = 0; i < getNumCurrZones(); i++)
{
if (state->getZoneState(getCurrZone(i)).render == true)
{
numRenderedZones++;
if (baseZoneForPrep == 0xFFFFFFFF)
baseZoneForPrep = getCurrZone(i);
}
}
if (numRenderedZones > 1)
multipleZones = true;
}
bool continueOut = mInteriorRes->getDetailLevel(0)->prepRender(state,
baseZoneForPrep,
realStartZone, mZoneRangeStart,
mRenderObjToWorld, mObjScale,
modifyBaseState & !smDontRestrictOutside,
smDontRestrictOutside | multipleZones,
state->mFlipCull);
if (smDontRestrictOutside)
continueOut = true;
InteriorRenderImage* image = new InteriorRenderImage;
image->obj = this;
image->mDetailLevel = detailLevel;
image->mBaseZone = realStartZone;
image->textureSortKey = mInteriorFileHash;
state->insertRenderImage(image);
// Add renderimages for any sub-objects, first the independant subs, then the dependants
// for this detail...
Point3F osPoint = state->getCameraPosition();
mRenderWorldToObj.mulP(osPoint);
osPoint.convolveInverse(mObjScale);
U32 i;
for (i = 0; i < mInteriorSubObjects[0].size(); i++)
{
InteriorSubObject* iso = (mInteriorSubObjects[0])[i];
if (iso->renderDetailDependant() == false)
{
// We want to check the zone that this object is in. If we are traversing upwards
// though, we have no information about our parent zone, and must return the
// render image regardless.
if (modifyBaseState && iso->getZone() == 0)
{
// Must return
}
else
{
U32 realZone;
if (iso->getZone() == 0)
realZone = getCurrZone(0);
else
realZone = iso->getZone() + mZoneRangeStart - 1;
if (state->getZoneState(realZone).render == false)
{
// Nuke it...
continue;
}
}
// Register the render image, if any, for this ISO.
SubObjectRenderImage* sri = iso->getRenderImage(state, osPoint);
if (sri)
{
sri->mDetailLevel = 0;
state->insertRenderImage(sri);
}
}
}
// Condier any ISOs from the current LOD.
for (i = 0; i < mInteriorSubObjects[detailLevel].size(); i++)
{
InteriorSubObject* iso = (mInteriorSubObjects[detailLevel])[i];
if (iso->renderDetailDependant() == true)
{
// We want to check the zone that this object is in. If we are traversing upwards
// though, we have no information about our parent zone, and must return the
// render image regardless.
if (modifyBaseState && iso->getZone() == 0)
{
// Must return
}
else
{
U32 realZone;
if (iso->getZone() == 0)
realZone = getCurrZone(0);
else
realZone = iso->getZone() + mZoneRangeStart - 1;
if (state->getZoneState(realZone).render == false)
{
// Nuke it...
continue;
}
}
SubObjectRenderImage* sri = iso->getRenderImage(state, osPoint);
if (sri)
{
sri->mDetailLevel = detailLevel;
state->insertRenderImage(sri);
}
}
}
PROFILE_END();
return continueOut;
}
//--------------------------------------------------------------------------
bool InteriorInstance::castRay(const Point3F& s, const Point3F& e, RayInfo* info)
{
info->object = this;
return mInteriorRes->getDetailLevel(0)->castRay(s, e, info);
}
//------------------------------------------------------------------------------
void InteriorInstance::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);
// Notify subobjects that care about the transform change...
if (bool(mInteriorRes))
{
for (U32 i = 0; i < mInteriorSubObjects.size(); i++)
{
for (U32 j = 0; j < mInteriorSubObjects[i].size(); j++)
(mInteriorSubObjects[i])[j]->noteTransformChange();
}
}
if (isServerObject())
setMaskBits(TransformMask);
}
//------------------------------------------------------------------------------
bool InteriorInstance::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 mInteriorRes->getDetailLevel(0)->buildPolyList(list, wsBox, mWorldToObj, getScale());
}
void InteriorInstance::buildConvex(const Box3F& box, Convex* convex)
{
if (bool(mInteriorRes) == false)
return;
mConvexList->collectGarbage();
Box3F realBox = box;
mWorldToObj.mul(realBox);
realBox.min.convolveInverse(mObjScale);
realBox.max.convolveInverse(mObjScale);
if (realBox.isOverlapped(getObjBox()) == false)
return;
U32 waterMark = FrameAllocator::getWaterMark();
if ((convex->getObject()->getType() & VehicleObjectType) &&
mInteriorRes->getDetailLevel(0)->mVehicleConvexHulls.size() > 0)
{
// Can never have more hulls than there are hulls in the interior...
U16* hulls = (U16*)FrameAllocator::alloc(mInteriorRes->getDetailLevel(0)->mVehicleConvexHulls.size() * sizeof(U16));
U32 numHulls = 0;
Interior* pInterior = mInteriorRes->getDetailLevel(0);
if (pInterior->getIntersectingVehicleHulls(realBox, hulls, &numHulls) == false)
{
FrameAllocator::setWaterMark(waterMark);
return;
}
for (U32 i = 0; i < numHulls; i++)
{
// 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() == InteriorConvexType &&
(static_cast<InteriorConvex*>(itr->mConvex)->getObject() == this &&
static_cast<InteriorConvex*>(itr->mConvex)->hullId == -S32(hulls[i] + 1)))
{
cc = itr->mConvex;
break;
}
}
if (cc)
continue;
// Create a new convex.
InteriorConvex* cp = new InteriorConvex;
mConvexList->registerObject(cp);
convex->addToWorkingList(cp);
cp->mObject = this;
cp->pInterior = pInterior;
cp->hullId = -S32(hulls[i] + 1);
cp->box.min.x = pInterior->mVehicleConvexHulls[hulls[i]].minX;
cp->box.min.y = pInterior->mVehicleConvexHulls[hulls[i]].minY;
cp->box.min.z = pInterior->mVehicleConvexHulls[hulls[i]].minZ;
cp->box.max.x = pInterior->mVehicleConvexHulls[hulls[i]].maxX;
cp->box.max.y = pInterior->mVehicleConvexHulls[hulls[i]].maxY;
cp->box.max.z = pInterior->mVehicleConvexHulls[hulls[i]].maxZ;
}
}
else
{
// Can never have more hulls than there are hulls in the interior...
U16* hulls = (U16*)FrameAllocator::alloc(mInteriorRes->getDetailLevel(0)->mConvexHulls.size() * sizeof(U16));
U32 numHulls = 0;
Interior* pInterior = mInteriorRes->getDetailLevel(0);
if (pInterior->getIntersectingHulls(realBox, hulls, &numHulls) == false)
{
FrameAllocator::setWaterMark(waterMark);
return;
}
for (U32 i = 0; i < numHulls; i++)
{
// 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() == InteriorConvexType &&
(static_cast<InteriorConvex*>(itr->mConvex)->getObject() == this &&
static_cast<InteriorConvex*>(itr->mConvex)->hullId == hulls[i]))
{
cc = itr->mConvex;
break;
}
}
if (cc)
continue;
// Create a new convex.
InteriorConvex* cp = new InteriorConvex;
mConvexList->registerObject(cp);
convex->addToWorkingList(cp);
cp->mObject = this;
cp->pInterior = pInterior;
cp->hullId = hulls[i];
cp->box.min.x = pInterior->mConvexHulls[hulls[i]].minX;
cp->box.min.y = pInterior->mConvexHulls[hulls[i]].minY;
cp->box.min.z = pInterior->mConvexHulls[hulls[i]].minZ;
cp->box.max.x = pInterior->mConvexHulls[hulls[i]].maxX;
cp->box.max.y = pInterior->mConvexHulls[hulls[i]].maxY;
cp->box.max.z = pInterior->mConvexHulls[hulls[i]].maxZ;
}
}
FrameAllocator::setWaterMark(waterMark);
}
//------------------------------------------------------------------------------
U32 InteriorInstance::packUpdate(NetConnection* c, U32 mask, BitStream* stream)
{
U32 retMask = Parent::packUpdate(c, mask, stream);
if (stream->writeFlag((mask & InitMask) != 0))
{
// Initial update, write the whole kit and kaboodle
stream->write(mCRC);
stream->writeString(mInteriorFileName);
stream->writeFlag(mShowTerrainInside);
// Write the transform (do _not_ use writeAffineTransform. Since this is a static
// object, the transform must be RIGHT THE *&)*$&^ ON or it will goof up the
// synchronization between the client and the server.
mathWrite(*stream, mObjToWorld);
mathWrite(*stream, mObjScale);
// Write the alarm state
stream->writeFlag(mAlarmState);
// Write the skinbase
stream->writeString(mSkinBase);
// audio profile
if(stream->writeFlag(mAudioProfile))
stream->writeRangedU32(mAudioProfile->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast);
// audio environment:
if(stream->writeFlag(mAudioEnvironment))
stream->writeRangedU32(mAudioEnvironment->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast);
// Lighting behavior.
stream->writeFlag(mUseGLLighting);
}
else
{
if (stream->writeFlag((mask & TransformMask) != 0))
{
mathWrite(*stream, mObjToWorld);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -