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();
}
Beispiel #7
0
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());
}
Beispiel #8
0
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());
}