void plCoordinateInterface::WarpToLocal(const hsMatrix44& l2p, const hsMatrix44& p2l) { fReason |= kReasonUnknown; SetLocalToParent(l2p, p2l); // update physical state when an object is warped if (IGetOwner()) IGetOwner()->DirtySynchState(kSDLPhysical, 0); }
void plCoordinateInterface::IRegisterForTransformMessage(hsBool delayed) { if( IGetOwner() ) { if ((delayed || fTransformPhase == kTransformPhaseDelayed) && fDelayedTransformsEnabled) plgDispatch::Dispatch()->RegisterForExactType(plDelayedTransformMsg::Index(), IGetOwner()->GetKey()); else plgDispatch::Dispatch()->RegisterForExactType(plTransformMsg::Index(), IGetOwner()->GetKey()); } }
void plCoordinateInterface::ITransformChanged(hsBool force, uint16_t reasons, hsBool checkForDelay) { plProfile_IncCount(CITrans, 1); plProfile_BeginTiming(CITransT); // inherit reasons for transform change from our parents fReason |= reasons; uint16_t propagateReasons = fReason; hsBool process = !(checkForDelay && GetProperty(kDelayedTransformEval)) || !fDelayedTransformsEnabled; if (process) { if( fState & kTransformDirty ) force = true; } if( force ) { IRecalcTransforms(); plProfile_IncCount(CISet, 1); plProfile_BeginTiming(CISetT); if( IGetOwner() ) { IGetOwner()->ISetTransform(fLocalToWorld, fWorldToLocal); } plProfile_EndTiming(CISetT); fState &= ~kTransformDirty; } plProfile_EndTiming(CITransT); if (process) { int i; for( i = 0; i < fChildren.GetCount(); i++ ) { if( fChildren[i] && fChildren[i]->GetVolatileCoordinateInterface() ) fChildren[i]->GetVolatileCoordinateInterface()->ITransformChanged(force, propagateReasons, checkForDelay); } } else if (force) { plProfile_IncCount(CIDirty, 1); plProfile_BeginTiming(CITransT); // Our parent is dirty and we're bailing out on evaluating right now. // Need to ensure we'll be evaluated in the delay pass plProfile_BeginTiming(CIDirtyT); IDirtyTransform(); plProfile_EndTiming(CIDirtyT); plProfile_EndTiming(CITransT); } }
plCoordinateInterface::~plCoordinateInterface() { if( fParent ) fParent->IRemoveChild(IGetOwner()); int i; for( i = fChildren.GetCount()-1; i >= 0; i-- ) IRemoveChild(i); }
void plCoordinateInterface::ISetNetGroupRecur(plNetGroupId netGroup) { if( !IGetOwner() ) return; if( IGetOwner()->GetSynchFlags() & kHasConstantNetGroup ) return; IGetOwner()->plSynchedObject::SetNetGroup(netGroup); int i; for( i = 0; i < GetNumChildren(); i++ ) { if( GetChild(i) ) { GetChild(i)->ISetNetGroupRecur(netGroup); } } }
void plCoordinateInterface::IDetachChild(plSceneObject* child, uint8_t flags) { hsAssert(child, "Detaching a nil child"); plCoordinateInterface* childCI = child->GetVolatileCoordinateInterface(); hsAssert(childCI, "Owner without CoordinateInterface being attached"); hsMatrix44 l2w = childCI->GetLocalToWorld(); hsMatrix44 w2l = childCI->GetWorldToLocal(); GetKey()->Release(child->GetKey()); if( IGetOwner() && IGetOwner()->GetKey() ) IGetOwner()->GetKey()->Release(child->GetKey()); IRemoveChild(child); if( flags & kMaintainWorldPosition ) childCI->WarpToWorld(l2w,w2l); // If the child was keeping us from delaying our transform, // maybe we can, now that it's gone. if (!childCI->GetProperty(kDelayedTransformEval)) IUpdateDelayProp(); }
void plDispatch::ICheckDeferred(double secs) { while( fFutureMsgQueue && (fFutureMsgQueue->fMsg->fTimeStamp < secs) ) { plMsgWrap* send = IDequeue(&fFutureMsgQueue, nil); MsgSend(send->fMsg); delete send; } int timeIdx = plTimeMsg::Index(); if( IGetOwner() && !fFutureMsgQueue && ( (timeIdx >= fRegisteredExactTypes.GetCount()) || !fRegisteredExactTypes[plTimeMsg::Index()] ) ) plgDispatch::Dispatch()->UnRegisterForExactType(plTimeMsg::Index(), IGetOwnerKey()); }
bool plDispatch::ISortToDeferred(plMessage* msg) { plMsgWrap* msgWrap = new plMsgWrap(msg); if( !fFutureMsgQueue ) { if( IGetOwner() ) plgDispatch::Dispatch()->RegisterForExactType(plTimeMsg::Index(), IGetOwnerKey()); IInsertToQueue(&fFutureMsgQueue, msgWrap); return false; } if( fFutureMsgQueue->fMsg->fTimeStamp > msgWrap->fMsg->fTimeStamp ) { IInsertToQueue(&fFutureMsgQueue, msgWrap); return false; } plMsgWrap* after = fFutureMsgQueue; while( after->fNext && (after->fNext->fMsg->fTimeStamp < msgWrap->fMsg->fTimeStamp) ) after = after->fNext; IInsertToQueue(&after->fNext, msgWrap); return false; }
hsBool plCoordinateInterface::MsgReceive(plMessage* msg) { hsBool retVal = false; plIntRefMsg* intRefMsg; plCorrectionMsg* corrMsg; // warp message plWarpMsg* pWarpMsg = plWarpMsg::ConvertNoRef(msg); if (pWarpMsg) { hsMatrix44 l2w = pWarpMsg->GetTransform(); hsMatrix44 inv; l2w.GetInverse(&inv); WarpToWorld(l2w,inv); if (pWarpMsg->GetWarpFlags() & plWarpMsg::kFlushTransform) ITransformChanged(false, kReasonUnknown, false); return true; } else if((intRefMsg = plIntRefMsg::ConvertNoRef(msg))) { switch( intRefMsg->fType ) { case plIntRefMsg::kChildObject: case plIntRefMsg::kChild: { plSceneObject* co = nil; if( intRefMsg->fType == plIntRefMsg::kChildObject ) { co = plSceneObject::ConvertNoRef(intRefMsg->GetRef()); } else { plCoordinateInterface* ci = plCoordinateInterface::ConvertNoRef(intRefMsg->GetRef()); co = ci ? ci->IGetOwner() : nil; } if( intRefMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnReplace) ) { ISetChild(co, intRefMsg->fWhich); } else if( intRefMsg->GetContext() & plRefMsg::kOnDestroy ) { IRemoveChild(co); } else if( intRefMsg->GetContext() & plRefMsg::kOnRequest ) { IAttachChild(co, kMaintainWorldPosition|kMaintainSceneNode); } else if( intRefMsg->GetContext() & plRefMsg::kOnRemove ) { IDetachChild(co, kMaintainWorldPosition|kMaintainSceneNode); } } return true; default: break; } } else if((corrMsg = plCorrectionMsg::ConvertNoRef(msg))) { SetTransformPhysical(corrMsg->fLocalToWorld, corrMsg->fWorldToLocal); if(corrMsg->fDirtySynch) { if (IGetOwner()) IGetOwner()->DirtySynchState(kSDLPhysical, 0); } return true; } return plObjInterface::MsgReceive(msg); }
void plCoordinateInterface::IUnRegisterForTransformMessage() { if( IGetOwner() ) plgDispatch::Dispatch()->UnRegisterForExactType(plTransformMsg::Index(), IGetOwner()->GetKey()); }