You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
6.4 KiB
195 lines
6.4 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
#include "plAGMasterSDLModifier.h" |
|
#include "plSDL/plSDL.h" |
|
#include "plInterp/plAnimTimeConvert.h" |
|
#include "pnSceneObject/plSceneObject.h" |
|
#include "plAGMasterMod.h" |
|
#include "plAGAnimInstance.h" |
|
#include "plgDispatch.h" |
|
#include "pnMessage/plTimeMsg.h" |
|
#include "hsTimer.h" |
|
#include "plMessage/plAnimCmdMsg.h" |
|
|
|
// static vars |
|
char plAGMasterSDLModifier::AGMasterVarNames::kStrAtcs[]="atcs"; |
|
char plAGMasterSDLModifier::AGMasterVarNames::kStrBlends[]="blends"; |
|
|
|
UInt32 plAGMasterSDLModifier::IApplyModFlags(UInt32 sendFlags) |
|
{ |
|
// ugly hack so bug light animation state isn't stored on the server |
|
if (stricmp(GetTarget()->GetKeyName(), "RTOmni-BugLightTest") == 0) |
|
return (sendFlags | plSynchedObject::kDontPersistOnServer | plSynchedObject::kIsAvatarState); |
|
// ditto for the KI light |
|
if (stricmp(GetTarget()->GetKeyName(), "RTOmniKILight") == 0) |
|
return (sendFlags | plSynchedObject::kDontPersistOnServer | plSynchedObject::kIsAvatarState); |
|
|
|
return sendFlags; |
|
} |
|
|
|
// |
|
// copy blends values from current state into sdl |
|
// |
|
void plAGMasterSDLModifier::IPutBlends(plStateDataRecord* state, plAGMasterMod* agMaster) |
|
{ |
|
int numBlends = agMaster->GetNumPrivateAnimations(); // each private anim has a blend value |
|
plSimpleStateVariable* blendsVar = state->FindVar(AGMasterVarNames::kStrBlends); |
|
if (blendsVar->GetCount() != numBlends) |
|
blendsVar->Alloc(numBlends); |
|
|
|
// sdl copy |
|
int i; |
|
for(i=0;i<numBlends; i++) |
|
{ |
|
blendsVar->Set((UInt8)(agMaster->GetAnimInstance(i)->GetBlend() * 255), i); |
|
} |
|
} |
|
|
|
|
|
// |
|
// Copy atcs from current state into sdl |
|
// |
|
void plAGMasterSDLModifier::IPutCurrentStateIn(plStateDataRecord* dstState) |
|
{ |
|
plSceneObject* sobj=GetTarget(); |
|
hsAssert(sobj, "plAGMasterSDLModifier, nil target"); |
|
|
|
plAGMasterMod* agMaster=IGetObjectsAGMasterMod(sobj); |
|
hsAssert(agMaster, "nil AGMasterMod"); |
|
|
|
if (agMaster) |
|
{ |
|
IPutBlends(dstState, agMaster); |
|
|
|
int numAnims = agMaster->GetNumATCAnimations(); |
|
plSDStateVariable* atcsVar = dstState->FindSDVar(AGMasterVarNames::kStrAtcs); |
|
if (atcsVar->GetCount() != numAnims) |
|
atcsVar->Resize(numAnims); |
|
|
|
// copy atcs to sdl |
|
int i; |
|
for(i=0;i<numAnims; i++) |
|
{ |
|
plStateDataRecord* atcStateDataRec = atcsVar->GetStateDataRecord(i); |
|
plAnimTimeConvert* animTimeConvert = agMaster->GetATCAnimInstance(i)->GetTimeConvert(); |
|
|
|
IPutATC(atcStateDataRec, animTimeConvert); |
|
} |
|
} |
|
} |
|
|
|
// |
|
// Given a scene object, find and return it's AGMasterMod |
|
// |
|
plAGMasterMod* plAGMasterSDLModifier::IGetObjectsAGMasterMod(plSceneObject* obj) |
|
{ |
|
int count = obj->GetNumModifiers(); |
|
|
|
for (int i = 0; i < count; i++) |
|
{ |
|
plAGMasterMod * avMod = const_cast<plAGMasterMod*>(plAGMasterMod::ConvertNoRef(obj->GetModifier(i))); |
|
if(avMod) |
|
return avMod; |
|
} |
|
|
|
return nil; |
|
} |
|
|
|
// |
|
// Apply state in SDL record to current animation state |
|
// |
|
void plAGMasterSDLModifier::ISetCurrentBlends(const plStateDataRecord* state, plAGMasterMod* objAGMaster) |
|
{ |
|
// Check Blends |
|
plSimpleStateVariable* blendsVar = state->FindVar(AGMasterVarNames::kStrBlends); |
|
if (blendsVar->IsUsed()) |
|
{ |
|
int i; |
|
if (blendsVar->GetCount() != objAGMaster->GetNumPrivateAnimations()) |
|
return; // bogus state |
|
|
|
for (i=0;i<blendsVar->GetCount();i++) |
|
{ |
|
UInt8 blend; |
|
blendsVar->Get(&blend, i); |
|
objAGMaster->GetAnimInstance(i)->SetBlend(blend / 255.f); |
|
} |
|
} |
|
} |
|
|
|
// |
|
// Change the object's animation state to reflect what is specified in the |
|
// stateDataRecord. |
|
// |
|
void plAGMasterSDLModifier::ISetCurrentStateFrom(const plStateDataRecord* srcState) |
|
{ |
|
plSceneObject* sobj=GetTarget(); |
|
hsAssert(sobj, "plAGMasterSDLModifier, nil target"); |
|
|
|
plAGMasterMod* objAGMaster=IGetObjectsAGMasterMod(sobj); |
|
hsAssert(objAGMaster, "can't find object's AGMasterSDLState"); |
|
|
|
ISetCurrentBlends(srcState, objAGMaster); |
|
|
|
plSDStateVariable* atcsVar = srcState->FindSDVar(AGMasterVarNames::kStrAtcs); |
|
if (atcsVar->IsUsed()) |
|
{ |
|
if (objAGMaster->GetNumATCAnimations() != atcsVar->GetCount()) |
|
return; |
|
|
|
int i; |
|
for(i=0;i<atcsVar->GetCount(); i++) |
|
{ |
|
plStateDataRecord* atcStateDataRec = atcsVar->GetStateDataRecord(i); |
|
plAnimTimeConvert* objAtc = objAGMaster->GetATCAnimInstance(i)->GetTimeConvert(); // dst |
|
ISetCurrentATC(atcStateDataRec, objAtc); |
|
objAtc->EnableCallbacks(false); |
|
} |
|
objAGMaster->IRegForEval(objAGMaster->HasRunningAnims()); |
|
|
|
// Force one eval, then re-enable all the callbacks |
|
double time = (hsTimer::GetSysSeconds() - hsTimer::GetDelSysSeconds()); |
|
|
|
if (objAGMaster->fIsGrouped && objAGMaster->fMsgForwarder) |
|
{ |
|
hsScalar animTimeFromWorldTime = (objAGMaster->GetNumATCAnimations() > 0) ? objAGMaster->GetATCAnimInstance(0)->GetTimeConvert()->WorldToAnimTimeNoUpdate(time) : 0.0f; |
|
|
|
plAGCmdMsg *msg = TRACKED_NEW plAGCmdMsg(); |
|
msg->SetCmd(plAGCmdMsg::kSetAnimTime); |
|
msg->fAnimTime = animTimeFromWorldTime; |
|
msg->AddReceiver(objAGMaster->fMsgForwarder->GetKey()); |
|
plgDispatch::MsgSend(msg); |
|
} |
|
else |
|
{ |
|
objAGMaster->AdvanceAnimsToTime(time); |
|
} |
|
|
|
for (i = 0; i < objAGMaster->GetNumATCAnimations(); i++) |
|
objAGMaster->GetATCAnimInstance(i)->GetTimeConvert()->EnableCallbacks(true); |
|
} |
|
} |
|
|
|
|