//--------------------------------------------------------------------------- void TankCamera::attachSelfToTank(Ogre::Vector3 *pos) { mSceneNode = mTank->getTurret()->getSceneNode()->createChildSceneNode(); mSceneNode->lookAt(Ogre::Vector3(0, 0, 0), Ogre::Node::TS_PARENT); // detatch from its original scene node and attach to the new scene node. auto parentNode = mRenderCamera->getParentSceneNode(); if (parentNode) { parentNode->detachObject(mRenderCamera); } mSceneNode->attachObject(mRenderCamera); mRenderCamera->setNearClipDistance(2); mSceneNode->setPosition(*pos); mSceneNode->yaw(Ogre::Degree(90)); mSceneNode->pitch(Ogre::Degree(-15)); }
void GhostConnection::writePacket(BitStream *bstream, PacketNotify *pnotify) { Parent::writePacket(bstream, pnotify); GhostPacketNotify *notify = static_cast<GhostPacketNotify *>(pnotify); if(mConnectionParameters.mDebugObjectSizes) bstream->writeInt(DebugChecksum, 32); notify->ghostList = NULL; if(!doesGhostFrom()) return; if(!bstream->writeFlag(mGhosting && mScopeObject.isValid())) return; // fill a packet (or two) with ghosting data // 2. call scoped objects' priority functions if the flag set is nonzero // A removed ghost is assumed to have a high priority // 3. call updates based on sorted priority until the packet is // full. set flags to zero for all updated objects GhostInfo *walk; for(S32 i = mGhostZeroUpdateIndex - 1; i >= 0; i--) { if(!(mGhostArray[i]->flags & GhostInfo::InScope)) detachObject(mGhostArray[i]); } U32 maxIndex = 0; for(S32 i = mGhostZeroUpdateIndex - 1; i >= 0; i--) { walk = mGhostArray[i]; if(walk->index > maxIndex) maxIndex = walk->index; // clear out any kill objects that haven't been ghosted yet if((walk->flags & GhostInfo::KillGhost) && (walk->flags & GhostInfo::NotYetGhosted)) { freeGhostInfo(walk); continue; } // don't do any ghost processing on objects that are being killed // or in the process of ghosting else if(!(walk->flags & (GhostInfo::KillingGhost | GhostInfo::Ghosting))) { if(walk->flags & GhostInfo::KillGhost) walk->priority = 10000; else walk->priority = walk->obj->getUpdatePriority(mScopeObject, walk->updateMask, walk->updateSkipCount); } else walk->priority = 0; } GhostRef *updateList = NULL; qsort(mGhostArray, mGhostZeroUpdateIndex, sizeof(GhostInfo *), UQECompare); // reset the array indices... for(S32 i = mGhostZeroUpdateIndex - 1; i >= 0; i--) mGhostArray[i]->arrayIndex = i; S32 sendSize = 1; while(maxIndex >>= 1) sendSize++; if(sendSize < 3) sendSize = 3; bstream->writeInt(sendSize - 3, 3); // 0-7 3 bit number U32 count = 0; // for(S32 i = mGhostZeroUpdateIndex - 1; i >= 0 && !bstream->isFull(); i--) { GhostInfo *walk = mGhostArray[i]; if(walk->flags & (GhostInfo::KillingGhost | GhostInfo::Ghosting)) continue; size_t updateStart = bstream->getBitPosition(); U32 updateMask = walk->updateMask; U32 retMask = 0; bstream->writeFlag(true); bstream->writeInt(walk->index, sendSize); if(!bstream->writeFlag(walk->flags & GhostInfo::KillGhost)) { // this is an update of some kind: if(mConnectionParameters.mDebugObjectSizes) bstream->advanceBitPosition(BitStreamPosBitSize); size_t startPos = bstream->getBitPosition(); if(walk->flags & GhostInfo::NotYetGhosted) { S32 classId = walk->obj->getClassId(getNetClassGroup()); bstream->writeClassId(classId, NetClassTypeObject, getNetClassGroup()); NetObject::mIsInitialUpdate = true; } // update the object retMask = walk->obj->packUpdate(this, updateMask, bstream); if(NetObject::mIsInitialUpdate) { NetObject::mIsInitialUpdate = false; walk->obj->getClassRep()->addInitialUpdate(bstream->getBitPosition() - startPos); } else walk->obj->getClassRep()->addPartialUpdate(bstream->getBitPosition() - startPos); if(mConnectionParameters.mDebugObjectSizes){ size_t bpL = bstream->getBitPosition(); U32 bp = static_cast<U32>(bpL); TNLAssert(bp == bpL, "This stream position is too long"); bstream->writeIntAt(bp, BitStreamPosBitSize, startPos - BitStreamPosBitSize); } TNLLogMessageV(LogGhostConnection, ("GhostConnection %s GHOST %d", walk->obj->getClassName(), bstream->getBitPosition() - 16 - startPos)); TNLAssert((retMask & (~updateMask)) == 0, "Cannot set new bits in packUpdate return"); } // check for packet overrun, and rewind this update if there // was one: if(bstream->getBitSpaceAvailable() < MinimumPaddingBits) { bstream->setBitPosition(updateStart); bstream->clearError(); break; } // otherwise, create a record of this ghost update and // attach it to the packet. GhostRef *upd = new GhostRef; upd->nextRef = updateList; updateList = upd; if(walk->lastUpdateChain) walk->lastUpdateChain->updateChain = upd; walk->lastUpdateChain = upd; upd->ghost = walk; upd->ghostInfoFlags = 0; upd->updateChain = NULL; if(walk->flags & GhostInfo::KillGhost) { walk->flags &= ~GhostInfo::KillGhost; walk->flags |= GhostInfo::KillingGhost; walk->updateMask = 0; upd->mask = updateMask; ghostPushToZero(walk); upd->ghostInfoFlags = GhostInfo::KillingGhost; } else { if(walk->flags & GhostInfo::NotYetGhosted) { walk->flags &= ~GhostInfo::NotYetGhosted; walk->flags |= GhostInfo::Ghosting; upd->ghostInfoFlags = GhostInfo::Ghosting; } walk->updateMask = retMask; if(!retMask) ghostPushToZero(walk); upd->mask = updateMask & ~retMask; walk->updateSkipCount = 0; count++; } } // count # of ghosts have been updated, // mGhostZeroUpdateIndex # of ghosts remain to be updated. // no more objects... bstream->writeFlag(false); notify->ghostList = updateList; }
SceneNode::~SceneNode() { detachObject(); }