mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
CWE Directory Reorganization
Rearrange directory structure of CWE to be loosely equivalent to the H'uru Plasma repository. Part 1: Movement of directories and files.
This commit is contained in:
922
Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp
Normal file
922
Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp
Normal file
@ -0,0 +1,922 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plCollisionDetector.h"
|
||||
#include "../plMessage/plCollideMsg.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "../plMessage/plActivatorMsg.h"
|
||||
#include "../pnMessage/plCameraMsg.h"
|
||||
#include "../pnMessage/plTimeMsg.h"
|
||||
#include "../plMessage/plInputIfaceMgrMsg.h"
|
||||
#include "../pnInputCore/plControlEventCodes.h"
|
||||
#include "../pnNetCommon/plNetApp.h"
|
||||
#include "../pnSceneObject/plSceneObject.h"
|
||||
#include "../pnNetCommon/plNetApp.h"
|
||||
#include "../plNetClient/plNetLinkingMgr.h"
|
||||
|
||||
#include "plPhysical.h"
|
||||
|
||||
#include "../pnMessage/plPlayerPageMsg.h"
|
||||
#include "../plMessage/plSimStateMsg.h"
|
||||
|
||||
#include "../pnSceneObject/plCoordinateInterface.h"
|
||||
#include "../plAvatar/plArmatureMod.h"
|
||||
#include "../plAvatar/plAvatarMgr.h"
|
||||
#include "../plAvatar/plAvBrainHuman.h"
|
||||
#include "../plAvatar/plAvBrainDrive.h"
|
||||
#include "../plAvatar/plPhysicalControllerCore.h"
|
||||
|
||||
#include "../plModifier/plDetectorLog.h"
|
||||
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
#include "../plPhysX/plSimulationMgr.h"
|
||||
#endif
|
||||
|
||||
plArmatureMod* plCollisionDetector::IGetAvatarModifier(plKey key)
|
||||
{
|
||||
plSceneObject* avObj = plSceneObject::ConvertNoRef(key->ObjectIsLoaded());
|
||||
if (avObj)
|
||||
{
|
||||
// search through its modifiers to see if one of them is an avatar modifier
|
||||
plArmatureMod* avMod = nil;
|
||||
for (int i = 0; i < avObj->GetNumModifiers(); i++)
|
||||
{
|
||||
const plModifier* mod = avObj->GetModifier(i);
|
||||
// see if it is an avatar mod base class
|
||||
avMod = const_cast<plArmatureMod*>(plArmatureMod::ConvertNoRef(mod));
|
||||
if (avMod)
|
||||
return avMod;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool plCollisionDetector::IIsDisabledAvatar(plKey key)
|
||||
{
|
||||
plArmatureMod* avMod = IGetAvatarModifier(key);
|
||||
plArmatureBrain* avBrain = avMod ? avMod->GetCurrentBrain() : nil;
|
||||
return (plAvBrainDrive::ConvertNoRef(avBrain) != nil);
|
||||
}
|
||||
|
||||
hsBool plCollisionDetector::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
||||
|
||||
if (pCollMsg)
|
||||
{
|
||||
// If the avatar is disabled (flying around), don't trigger
|
||||
if (IIsDisabledAvatar(pCollMsg->fOtherKey))
|
||||
return false;
|
||||
|
||||
if (fType & kTypeBump)
|
||||
{
|
||||
if (!fBumped && !fTriggered)
|
||||
{
|
||||
for (int i = 0; i < fReceivers.Count(); i++)
|
||||
{
|
||||
plActivatorMsg* pMsg = TRACKED_NEW plActivatorMsg;
|
||||
pMsg->AddReceiver( fReceivers[i] );
|
||||
|
||||
if (fProxyKey)
|
||||
pMsg->fHiteeObj = fProxyKey;
|
||||
else
|
||||
pMsg->fHiteeObj = GetTarget()->GetKey();
|
||||
pMsg->fHitterObj = pCollMsg->fOtherKey;
|
||||
pMsg->SetSender(GetKey());
|
||||
pMsg->SetTriggerType( plActivatorMsg::kCollideContact );
|
||||
plgDispatch::MsgSend( pMsg );
|
||||
}
|
||||
fBumped = true;
|
||||
fTriggered = true;
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||
return true;
|
||||
}
|
||||
if (fTriggered)
|
||||
{
|
||||
fBumped = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fReceivers.Count(); i++)
|
||||
{
|
||||
plActivatorMsg* pMsg = TRACKED_NEW plActivatorMsg;
|
||||
pMsg->AddReceiver( fReceivers[i] );
|
||||
if (fProxyKey)
|
||||
pMsg->fHiteeObj = fProxyKey;
|
||||
else
|
||||
pMsg->fHiteeObj = GetTarget()->GetKey();
|
||||
pMsg->fHitterObj = pCollMsg->fOtherKey;
|
||||
pMsg->SetSender(GetKey());
|
||||
|
||||
if (fType & kTypeEnter && pCollMsg->fEntering)
|
||||
{
|
||||
pMsg->SetTriggerType( plActivatorMsg::kCollideEnter );
|
||||
plgDispatch::MsgSend( pMsg );
|
||||
continue;
|
||||
}
|
||||
if (fType & kTypeUnEnter && pCollMsg->fEntering)
|
||||
{
|
||||
pMsg->SetTriggerType( plActivatorMsg::kEnterUnTrigger );
|
||||
plgDispatch::MsgSend( pMsg );
|
||||
continue;
|
||||
}
|
||||
if(fType & kTypeExit && !pCollMsg->fEntering)
|
||||
{
|
||||
pMsg->SetTriggerType( plActivatorMsg::kCollideExit );
|
||||
plgDispatch::MsgSend( pMsg );
|
||||
continue;
|
||||
}
|
||||
if(fType & kTypeUnExit && !pCollMsg->fEntering)
|
||||
{
|
||||
pMsg->SetTriggerType( plActivatorMsg::kExitUnTrigger );
|
||||
plgDispatch::MsgSend( pMsg );
|
||||
continue;
|
||||
}
|
||||
if (fType & kTypeAny)
|
||||
{
|
||||
pMsg->SetTriggerType( plActivatorMsg::kCollideContact );
|
||||
plgDispatch::MsgSend( pMsg );
|
||||
continue;
|
||||
}
|
||||
|
||||
delete (pMsg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
plEvalMsg* pEval = plEvalMsg::ConvertNoRef(msg);
|
||||
if (pEval)
|
||||
{
|
||||
if (!fBumped && fTriggered)
|
||||
{
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||
for (int i = 0; i < fReceivers.Count(); i++)
|
||||
{
|
||||
plActivatorMsg* pMsg = TRACKED_NEW plActivatorMsg;
|
||||
pMsg->AddReceiver( fReceivers[i] );
|
||||
if (fProxyKey)
|
||||
pMsg->fHiteeObj = fProxyKey;
|
||||
else
|
||||
pMsg->fHiteeObj = GetTarget()->GetKey();
|
||||
pMsg->SetSender(GetKey());
|
||||
pMsg->SetTriggerType( plActivatorMsg::kCollideUnTrigger );
|
||||
plgDispatch::MsgSend( pMsg );
|
||||
fTriggered = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (fTriggered && fBumped)
|
||||
{
|
||||
fBumped = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return plDetectorModifier::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plCollisionDetector::Read(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plDetectorModifier::Read(stream, mgr);
|
||||
stream->ReadSwap(&fType);
|
||||
}
|
||||
void plCollisionDetector::Write(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plDetectorModifier::Write(stream, mgr);
|
||||
stream->WriteSwap(fType);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
/////////////////////////////////
|
||||
/////////////////////////////////
|
||||
/////////////////////////////////
|
||||
// camera region detector
|
||||
|
||||
plCameraRegionDetector::~plCameraRegionDetector()
|
||||
{
|
||||
for(int i = 0; i < fMessages.Count(); i++)
|
||||
{
|
||||
plMessage* pMsg = fMessages[i];
|
||||
fMessages.Remove(i);
|
||||
delete(pMsg);
|
||||
}
|
||||
fMessages.SetCountAndZero(0);
|
||||
}
|
||||
|
||||
void plCameraRegionDetector::ISendTriggerMsg()
|
||||
{
|
||||
for (int i = 0; i < fMessages.Count(); ++i)
|
||||
{
|
||||
hsRefCnt_SafeRef(fMessages[i]);
|
||||
if (fIsInside)
|
||||
fMessages[i]->SetCmd(plCameraMsg::kEntering);
|
||||
else
|
||||
fMessages[i]->ClearCmd(plCameraMsg::kEntering);
|
||||
|
||||
plgDispatch::MsgSend(fMessages[i]);
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plCameraRegionDetector::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
||||
if (pCollMsg)
|
||||
{
|
||||
// camera collisions are only for the local player
|
||||
if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey)
|
||||
return true;
|
||||
|
||||
if (!fWaitingForEval)
|
||||
IRegisterForEval();
|
||||
|
||||
fEntering = (pCollMsg->fEntering != 0);
|
||||
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
return plObjectInVolumeDetector::MsgReceive(msg);
|
||||
}
|
||||
void plCameraRegionDetector::Read(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plDetectorModifier::Read(stream, mgr);
|
||||
int n = stream->ReadSwap32();
|
||||
fMessages.SetCountAndZero(n);
|
||||
for(int i = 0; i < n; i++ )
|
||||
{
|
||||
plCameraMsg* pMsg = plCameraMsg::ConvertNoRef(mgr->ReadCreatable(stream));
|
||||
fMessages[i] = pMsg;
|
||||
}
|
||||
|
||||
}
|
||||
void plCameraRegionDetector::Write(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plDetectorModifier::Write(stream, mgr);
|
||||
stream->WriteSwap32(fMessages.GetCount());
|
||||
for(int i = 0; i < fMessages.GetCount(); i++ )
|
||||
mgr->WriteCreatable( stream, fMessages[i] );
|
||||
|
||||
}
|
||||
|
||||
void plCameraRegionDetector::IHandleEval(plEvalMsg*)
|
||||
{
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
if (plSimulationMgr::GetInstance()->GetStepCount() - fLastStep > 1)
|
||||
{
|
||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
if (fIsInside != fEntering)
|
||||
{
|
||||
fIsInside = fEntering;
|
||||
DetectorLog("%s CameraRegion: %s", fIsInside ? "Entering" : "Exiting", GetKeyName());
|
||||
ISendTriggerMsg();
|
||||
}
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||
fWaitingForEval = false;
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
/////////////////////////////////
|
||||
/////////////////////////////////
|
||||
/////////////////////////////////
|
||||
// object-in-volume detector
|
||||
|
||||
void plObjectInVolumeDetector::ITrigger(plKey hitter, bool entering)
|
||||
{
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
for (bookKeepingList::iterator it = fCollisionList.begin(); it != fCollisionList.end(); ++it)
|
||||
{
|
||||
plCollisionBookKeepingInfo* collisionInfo = *it;
|
||||
if (collisionInfo->fHitter == hitter)
|
||||
{
|
||||
collisionInfo->fEntering = entering;
|
||||
collisionInfo->fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
|
||||
plCollisionBookKeepingInfo* collisionInfo = new plCollisionBookKeepingInfo(hitter, entering);
|
||||
fCollisionList.push_back(collisionInfo);
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
collisionInfo->fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
|
||||
#endif
|
||||
}
|
||||
|
||||
void plObjectInVolumeDetector::IRegisterForEval()
|
||||
{
|
||||
fWaitingForEval = true;
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plObjectInVolumeDetector::ISendTriggerMsg(plKey hitter, bool entering)
|
||||
{
|
||||
plActivatorMsg* activatorMsg = new plActivatorMsg();
|
||||
activatorMsg->SetSender(GetKey());
|
||||
activatorMsg->AddReceivers(fReceivers);
|
||||
activatorMsg->fHiteeObj = fProxyKey ? fProxyKey : GetTarget()->GetKey();
|
||||
activatorMsg->fHitterObj = hitter;
|
||||
if (entering)
|
||||
activatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
|
||||
else
|
||||
activatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit);
|
||||
|
||||
plgDispatch::MsgSend(activatorMsg);
|
||||
}
|
||||
|
||||
hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
||||
if (pCollMsg)
|
||||
{
|
||||
// If the avatar is disabled (flying around), don't trigger
|
||||
if (IIsDisabledAvatar(pCollMsg->fOtherKey))
|
||||
return false;
|
||||
|
||||
if (!fWaitingForEval)
|
||||
IRegisterForEval();
|
||||
|
||||
ITrigger(pCollMsg->fOtherKey, (pCollMsg->fEntering != 0));
|
||||
return true;
|
||||
}
|
||||
|
||||
plEvalMsg* pEval = plEvalMsg::ConvertNoRef(msg);
|
||||
if (pEval)
|
||||
IHandleEval(pEval);
|
||||
|
||||
plPlayerPageMsg* pageMsg = plPlayerPageMsg::ConvertNoRef(msg);
|
||||
if (pageMsg && pageMsg->fUnload)
|
||||
{
|
||||
ITrigger(pageMsg->fPlayer, false);
|
||||
}
|
||||
|
||||
return plCollisionDetector::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plObjectInVolumeDetector::IHandleEval(plEvalMsg*)
|
||||
{
|
||||
bookKeepingList::iterator it = fCollisionList.begin();
|
||||
while (it != fCollisionList.end())
|
||||
{
|
||||
plCollisionBookKeepingInfo* collisionInfo = *it;
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
if (plSimulationMgr::GetInstance()->GetStepCount() - collisionInfo->fLastStep > 1)
|
||||
{
|
||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
bool wasInside = fCurrentResidents.find(collisionInfo->fHitter) != fCurrentResidents.end();
|
||||
if (collisionInfo->fEntering != wasInside)
|
||||
{
|
||||
if (collisionInfo->fEntering)
|
||||
{
|
||||
fCurrentResidents.insert(collisionInfo->fHitter);
|
||||
DetectorLog("%s: Sending Volume Enter ActivatorMsg", GetKeyName());
|
||||
ISendTriggerMsg(collisionInfo->fHitter, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
fCurrentResidents.erase(collisionInfo->fHitter);
|
||||
DetectorLog("%s: Sending Volume Exit ActivatorMsg", GetKeyName());
|
||||
ISendTriggerMsg(collisionInfo->fHitter, false);
|
||||
}
|
||||
}
|
||||
|
||||
delete collisionInfo;
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
it = fCollisionList.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
#else
|
||||
++it;
|
||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
}
|
||||
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
if (fCollisionList.empty())
|
||||
{
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||
fWaitingForEval = false;
|
||||
}
|
||||
#else
|
||||
fCollisionList.clear();
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||
fWaitingForEval = false;
|
||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
}
|
||||
|
||||
void plObjectInVolumeDetector::SetTarget(plSceneObject* so)
|
||||
{
|
||||
plCollisionDetector::SetTarget(so);
|
||||
|
||||
if (so)
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plPlayerPageMsg::Index(), GetKey());
|
||||
else
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plPlayerPageMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plObjectInVolumeDetector::Read(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plCollisionDetector::Read(stream, mgr);
|
||||
}
|
||||
|
||||
void plObjectInVolumeDetector::Write(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plCollisionDetector::Write(stream, mgr);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
plObjectInVolumeAndFacingDetector::plObjectInVolumeAndFacingDetector() :
|
||||
fFacingTolerance(0),
|
||||
fNeedWalkingForward(false),
|
||||
fAvatarInVolume(false),
|
||||
fTriggered(false)
|
||||
{
|
||||
}
|
||||
|
||||
plObjectInVolumeAndFacingDetector::~plObjectInVolumeAndFacingDetector()
|
||||
{
|
||||
}
|
||||
|
||||
void plObjectInVolumeAndFacingDetector::SetFacingTolerance(int degrees)
|
||||
{
|
||||
fFacingTolerance = hsCosine(hsScalarDegToRad(degrees));
|
||||
}
|
||||
|
||||
void plObjectInVolumeAndFacingDetector::ICheckForTrigger()
|
||||
{
|
||||
plArmatureMod* armMod = plAvatarMgr::GetInstance()->GetLocalAvatar();
|
||||
plSceneObject* avatar = armMod ? armMod->GetTarget(0) : nil;
|
||||
plSceneObject* target = GetTarget();
|
||||
|
||||
if (armMod && target)
|
||||
{
|
||||
hsVector3 playerView = avatar->GetCoordinateInterface()->GetLocalToWorld().GetAxis(hsMatrix44::kView);
|
||||
hsVector3 objView = target->GetCoordinateInterface()->GetLocalToWorld().GetAxis(hsMatrix44::kView);
|
||||
|
||||
playerView.Normalize();
|
||||
objView.Normalize();
|
||||
|
||||
hsScalar dot = playerView * objView;
|
||||
// hsStatusMessageF("Dot: %f Tolerance: %f", dot, fFacingTolerance);
|
||||
bool facing = dot >= fFacingTolerance;
|
||||
|
||||
bool movingForward = false;
|
||||
if (fNeedWalkingForward)
|
||||
{
|
||||
// And are we walking towards it?
|
||||
plArmatureBrain* abrain = armMod->FindBrainByClass(plAvBrainHuman::Index()); //armMod->GetCurrentBrain();
|
||||
plAvBrainHuman* brain = plAvBrainHuman::ConvertNoRef(abrain);
|
||||
if (brain && brain->IsMovingForward() && brain->fWalkingStrategy->IsOnGround())
|
||||
movingForward = true;
|
||||
}
|
||||
else
|
||||
movingForward = true;
|
||||
|
||||
if (facing && movingForward && !fTriggered)
|
||||
{
|
||||
DetectorLog("%s: Trigger InVolume&Facing", GetKeyName());
|
||||
fTriggered = true;
|
||||
ISendTriggerMsg(avatar->GetKey(), true);
|
||||
}
|
||||
else if (!facing && fTriggered)
|
||||
{
|
||||
DetectorLog("%s: Untrigger InVolume&Facing", GetKeyName());
|
||||
fTriggered = false;
|
||||
ISendTriggerMsg(avatar->GetKey(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plObjectInVolumeAndFacingDetector::MsgReceive(plMessage* msg)
|
||||
{
|
||||
// Avatar is entering or exiting our detector box
|
||||
plCollideMsg* collMsg = plCollideMsg::ConvertNoRef(msg);
|
||||
if (collMsg)
|
||||
{
|
||||
// make sure this is the local player... the notify will be the thing that propagates over the network
|
||||
if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != collMsg->fOtherKey)
|
||||
return true;
|
||||
|
||||
// If the avatar is disabled (flying around), don't trigger
|
||||
if (IIsDisabledAvatar(collMsg->fOtherKey))
|
||||
return false;
|
||||
|
||||
fAvatarInVolume = (collMsg->fEntering != 0);
|
||||
|
||||
if (fAvatarInVolume)
|
||||
{
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||
ICheckForTrigger();
|
||||
}
|
||||
else
|
||||
{
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||
|
||||
// Avatar is leaving the volume, make sure to untrigger if we haven't already
|
||||
if (fTriggered)
|
||||
{
|
||||
fTriggered = false;
|
||||
ISendTriggerMsg(plNetClientApp::GetInstance()->GetLocalPlayerKey(), false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Avatar is inside our detector box, so every frame we check if we need to trigger
|
||||
plEvalMsg* evalMsg = plEvalMsg::ConvertNoRef(msg);
|
||||
if (evalMsg)
|
||||
{
|
||||
ICheckForTrigger();
|
||||
return true;
|
||||
}
|
||||
|
||||
return plObjectInVolumeDetector::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plObjectInVolumeAndFacingDetector::Read(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plObjectInVolumeDetector::Read(stream, mgr);
|
||||
|
||||
fFacingTolerance = stream->ReadSwapScalar();
|
||||
fNeedWalkingForward = stream->Readbool();
|
||||
}
|
||||
|
||||
void plObjectInVolumeAndFacingDetector::Write(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plObjectInVolumeDetector::Write(stream, mgr);
|
||||
|
||||
stream->WriteSwapScalar(fFacingTolerance);
|
||||
stream->Writebool(fNeedWalkingForward);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
/////////////////////////////////
|
||||
/////////////////////////////////
|
||||
/////////////////////////////////
|
||||
// subworld region detector
|
||||
|
||||
plSubworldRegionDetector::~plSubworldRegionDetector()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
hsBool plSubworldRegionDetector::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
||||
|
||||
if (pCollMsg)
|
||||
{
|
||||
if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey)
|
||||
return true;
|
||||
|
||||
plArmatureMod* avMod = IGetAvatarModifier(pCollMsg->fOtherKey);
|
||||
if (avMod)
|
||||
{
|
||||
DetectorLog("%s subworld detector %s", pCollMsg->fEntering ? "Entering" : "Exiting", GetKeyName());
|
||||
|
||||
if ((pCollMsg->fEntering && !fOnExit) ||
|
||||
(!pCollMsg->fEntering && fOnExit))
|
||||
{
|
||||
if (fSub)
|
||||
{
|
||||
plSceneObject* SO = plSceneObject::ConvertNoRef(fSub->ObjectIsLoaded());
|
||||
if (SO)
|
||||
{
|
||||
DetectorLogSpecial("Switching to subworld %s", fSub->GetName());
|
||||
|
||||
plKey nilKey;
|
||||
plSubWorldMsg* msg = TRACKED_NEW plSubWorldMsg(GetKey(), avMod->GetKey(), fSub);
|
||||
msg->Send();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DetectorLogSpecial("Switching to main subworld");
|
||||
plSubWorldMsg* msg = TRACKED_NEW plSubWorldMsg(GetKey(), avMod->GetKey(), nil);
|
||||
msg->Send();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return plCollisionDetector::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plSubworldRegionDetector::Read(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plDetectorModifier::Read(stream, mgr);
|
||||
fSub = mgr->ReadKey(stream);
|
||||
fOnExit = stream->ReadBool();
|
||||
}
|
||||
void plSubworldRegionDetector::Write(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plDetectorModifier::Write(stream, mgr);
|
||||
mgr->WriteKey(stream, fSub);
|
||||
stream->WriteBool(fOnExit);
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
///////////////////////////////////
|
||||
/// plPanicLinkDetector
|
||||
///////////////////////////////////
|
||||
hsBool plPanicLinkRegion::MsgReceive(plMessage* msg)
|
||||
{
|
||||
|
||||
if (plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg))
|
||||
{
|
||||
if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey)
|
||||
return true;
|
||||
|
||||
if (pCollMsg->fEntering)
|
||||
{
|
||||
plArmatureMod* avMod = IGetAvatarModifier(pCollMsg->fOtherKey);
|
||||
if (avMod)
|
||||
{
|
||||
if (avMod->IsLinkedIn())
|
||||
{
|
||||
hsPoint3 kinPos;
|
||||
if (avMod->GetController())
|
||||
{
|
||||
avMod->GetController()->GetPositionSim(kinPos);
|
||||
DetectorLogSpecial("Avatar is panic linking. KinPos at %f,%f,%f and is %s", kinPos.fX, kinPos.fY, kinPos.fZ, avMod->GetController()->IsEnabled() ? "enabled" : "disabled");
|
||||
}
|
||||
avMod->PanicLink(fPlayLinkOutAnim);
|
||||
} else
|
||||
DetectorLogRed("PANIC LINK %s before we actually linked in!", GetKey()->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return plCollisionDetector::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plPanicLinkRegion::Read(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plCollisionDetector::Read(stream, mgr);
|
||||
|
||||
fPlayLinkOutAnim = stream->ReadBool();
|
||||
}
|
||||
|
||||
void plPanicLinkRegion::Write(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plCollisionDetector::Write(stream, mgr);
|
||||
|
||||
stream->WriteBool(fPlayLinkOutAnim);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PLSIMPLEREGIONSENSOR
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// ctor default
|
||||
plSimpleRegionSensor::plSimpleRegionSensor()
|
||||
: fEnterMsg(nil), fExitMsg(nil)
|
||||
{
|
||||
}
|
||||
|
||||
// ctor canonical
|
||||
plSimpleRegionSensor::plSimpleRegionSensor(plMessage *enterMsg, plMessage *exitMsg)
|
||||
: fEnterMsg(enterMsg), fExitMsg(exitMsg)
|
||||
{
|
||||
}
|
||||
|
||||
// dtor
|
||||
plSimpleRegionSensor::~plSimpleRegionSensor()
|
||||
{
|
||||
if(fEnterMsg)
|
||||
fEnterMsg->UnRef();
|
||||
if(fExitMsg)
|
||||
fExitMsg->UnRef();
|
||||
}
|
||||
|
||||
// WRITE
|
||||
void plSimpleRegionSensor::Write(hsStream *stream, hsResMgr *mgr)
|
||||
{
|
||||
plSingleModifier::Write(stream, mgr);
|
||||
if(fEnterMsg)
|
||||
{
|
||||
stream->Writebool(true);
|
||||
mgr->WriteCreatable(stream, fEnterMsg);
|
||||
} else {
|
||||
stream->Writebool(false);
|
||||
}
|
||||
if(fExitMsg)
|
||||
{
|
||||
stream->Writebool(true);
|
||||
mgr->WriteCreatable(stream, fExitMsg);
|
||||
} else {
|
||||
stream->Writebool(false);
|
||||
}
|
||||
}
|
||||
|
||||
// READ
|
||||
void plSimpleRegionSensor::Read(hsStream *stream, hsResMgr *mgr)
|
||||
{
|
||||
plSingleModifier::Read(stream, mgr);
|
||||
if(stream->Readbool())
|
||||
{
|
||||
fEnterMsg = plMessage::ConvertNoRef(mgr->ReadCreatable(stream));
|
||||
} else {
|
||||
fEnterMsg = nil;
|
||||
}
|
||||
|
||||
if(stream->Readbool())
|
||||
{
|
||||
fExitMsg = plMessage::ConvertNoRef(mgr->ReadCreatable(stream));
|
||||
hsAssert(fExitMsg, "Corrupted plSimpleRegionSensor during read.");
|
||||
} else {
|
||||
fExitMsg = nil;
|
||||
}
|
||||
}
|
||||
|
||||
// MSGRECEIVE
|
||||
hsBool plSimpleRegionSensor::MsgReceive(plMessage *msg)
|
||||
{
|
||||
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
||||
|
||||
if (pCollMsg)
|
||||
{
|
||||
// make sure this is the local player... the notify will be the thing that propagates over the network
|
||||
if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey)
|
||||
return true;
|
||||
|
||||
plKey theThingWhatDoneHitUs = pCollMsg->fOtherKey;
|
||||
|
||||
if(pCollMsg->fEntering)
|
||||
{
|
||||
if(fEnterMsg)
|
||||
{
|
||||
fEnterMsg->ClearReceivers();
|
||||
fEnterMsg->AddReceiver(theThingWhatDoneHitUs);
|
||||
fEnterMsg->Ref();
|
||||
fEnterMsg->Send();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(fExitMsg)
|
||||
{
|
||||
fExitMsg->ClearReceivers();
|
||||
fExitMsg->AddReceiver(theThingWhatDoneHitUs);
|
||||
fExitMsg->Ref();
|
||||
fExitMsg->Send();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return plSingleModifier::MsgReceive(msg);
|
||||
}
|
||||
|
||||
// IEVAL
|
||||
hsBool plSimpleRegionSensor::IEval(double secs, hsScalar del, UInt32 dirty)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Nuke the Read/Write functions on the next file format change
|
||||
void plSwimDetector::Write(hsStream *stream, hsResMgr *mgr)
|
||||
{
|
||||
plSimpleRegionSensor::Write(stream, mgr);
|
||||
|
||||
stream->WriteByte(0);
|
||||
stream->WriteSwapScalar(0);
|
||||
stream->WriteSwapScalar(0);
|
||||
}
|
||||
|
||||
void plSwimDetector::Read(hsStream *stream, hsResMgr *mgr)
|
||||
{
|
||||
plSimpleRegionSensor::Read(stream, mgr);
|
||||
|
||||
stream->ReadByte();
|
||||
stream->ReadSwapScalar();
|
||||
stream->ReadSwapScalar();
|
||||
}
|
||||
hsBool plSwimDetector::MsgReceive(plMessage *msg)
|
||||
{
|
||||
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
||||
|
||||
if (pCollMsg)
|
||||
{
|
||||
//removed local player check because this will apply the brain to the local
|
||||
//controller of the foreign avatar which we still want.
|
||||
//and if we prop swim state by notify messages we still have a chance of missing it from players
|
||||
//who were in the region before we linked in
|
||||
plKey theThingWhatDoneHitUs = pCollMsg->fOtherKey;
|
||||
if(pCollMsg->fEntering)
|
||||
{
|
||||
if(fEnterMsg)
|
||||
{
|
||||
fEnterMsg->ClearReceivers();
|
||||
fEnterMsg->AddReceiver(theThingWhatDoneHitUs);
|
||||
fEnterMsg->Ref();
|
||||
fEnterMsg->Send();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(fExitMsg)
|
||||
{
|
||||
fExitMsg->ClearReceivers();
|
||||
fExitMsg->AddReceiver(theThingWhatDoneHitUs);
|
||||
fExitMsg->Ref();
|
||||
fExitMsg->Send();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return plSimpleRegionSensor::MsgReceive(msg);
|
||||
}
|
||||
hsBool plRidingAnimatedPhysicalDetector::MsgReceive(plMessage *msg)
|
||||
{
|
||||
|
||||
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
||||
|
||||
if (pCollMsg)
|
||||
{
|
||||
//removed local player check because this will apply the brain to the local
|
||||
//controller of the foreign avatar which we still want.
|
||||
//and if we prop state by notify messages we still have a chance of missing it from players
|
||||
//who were in the region before we linked in
|
||||
plKey theThingWhatDoneHitUs = pCollMsg->fOtherKey;
|
||||
if(pCollMsg->fEntering)
|
||||
{
|
||||
if(fEnterMsg)
|
||||
{
|
||||
fEnterMsg->ClearReceivers();
|
||||
fEnterMsg->AddReceiver(theThingWhatDoneHitUs);
|
||||
fEnterMsg->Ref();
|
||||
fEnterMsg->Send();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(fExitMsg)
|
||||
{
|
||||
fExitMsg->ClearReceivers();
|
||||
fExitMsg->AddReceiver(theThingWhatDoneHitUs);
|
||||
fExitMsg->Ref();
|
||||
fExitMsg->Send();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return plSimpleRegionSensor::MsgReceive(msg);
|
||||
}
|
300
Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.h
Normal file
300
Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.h
Normal file
@ -0,0 +1,300 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
|
||||
#ifndef plCollisionDetector_inc
|
||||
#define plCollisionDetector_inc
|
||||
|
||||
#include "plDetectorModifier.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include <list>
|
||||
#include <set>
|
||||
class plMessage;
|
||||
class plCameraMsg;
|
||||
class plArmatureMod;
|
||||
class plActivatorMsg;
|
||||
class plEvalMsg;
|
||||
|
||||
#define USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
|
||||
class plCollisionDetector : public plDetectorModifier
|
||||
{
|
||||
protected:
|
||||
Int8 fType;
|
||||
hsBool fBumped, fTriggered;
|
||||
|
||||
plArmatureMod* IGetAvatarModifier(plKey key);
|
||||
bool IIsDisabledAvatar(plKey key);
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kTypeEnter = 0x01,
|
||||
kTypeExit = 0x02,
|
||||
kTypeAny = 0x04,
|
||||
kTypeUnEnter = 0x08,
|
||||
kTypeUnExit = 0x10,
|
||||
kTypeBump = 0x20,
|
||||
};
|
||||
|
||||
plCollisionDetector() : fType(0), fTriggered(false), fBumped(false){;}
|
||||
virtual ~plCollisionDetector(){;}
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
CLASSNAME_REGISTER( plCollisionDetector );
|
||||
GETINTERFACE_ANY( plCollisionDetector, plDetectorModifier );
|
||||
|
||||
virtual void SetType(Int8 i) { fType |= i; }
|
||||
|
||||
void Read(hsStream* stream, hsResMgr* mgr);
|
||||
void Write(hsStream* stream, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
// sub type for object-in-volume detectors
|
||||
class plObjectInVolumeDetector : public plCollisionDetector
|
||||
{
|
||||
protected:
|
||||
class plCollisionBookKeepingInfo
|
||||
{
|
||||
public:
|
||||
plCollisionBookKeepingInfo(plKey& key, bool entering)
|
||||
: fHitter(key), fEntering(entering) { }
|
||||
|
||||
plKey fHitter;
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
UInt32 fLastStep;
|
||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
bool fEntering;
|
||||
};
|
||||
|
||||
virtual void ITrigger(plKey hitter, bool entering);
|
||||
virtual void ISendTriggerMsg(plKey hitter, bool entering);
|
||||
virtual void IRegisterForEval();
|
||||
virtual void IHandleEval(plEvalMsg* pEval);
|
||||
bool fWaitingForEval;
|
||||
|
||||
typedef std::list<plCollisionBookKeepingInfo*> bookKeepingList;
|
||||
bookKeepingList fCollisionList;
|
||||
typedef std::set<plKey> ResidentSet;
|
||||
ResidentSet fCurrentResidents;
|
||||
|
||||
public:
|
||||
|
||||
plObjectInVolumeDetector()
|
||||
: plCollisionDetector(), fWaitingForEval(false) { }
|
||||
|
||||
plObjectInVolumeDetector(Int8 i)
|
||||
: plCollisionDetector(), fWaitingForEval(false) { fType = i; }
|
||||
|
||||
virtual ~plObjectInVolumeDetector() { }
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
CLASSNAME_REGISTER(plObjectInVolumeDetector);
|
||||
GETINTERFACE_ANY(plObjectInVolumeDetector, plCollisionDetector);
|
||||
|
||||
virtual void SetTarget(plSceneObject* so);
|
||||
|
||||
void Read(hsStream* stream, hsResMgr* mgr);
|
||||
void Write(hsStream* stream, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
class plObjectInVolumeAndFacingDetector : public plObjectInVolumeDetector
|
||||
{
|
||||
protected:
|
||||
hsScalar fFacingTolerance;
|
||||
bool fNeedWalkingForward;
|
||||
|
||||
bool fAvatarInVolume;
|
||||
bool fTriggered;
|
||||
|
||||
void ICheckForTrigger();
|
||||
|
||||
public:
|
||||
plObjectInVolumeAndFacingDetector();
|
||||
virtual ~plObjectInVolumeAndFacingDetector();
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
CLASSNAME_REGISTER(plObjectInVolumeAndFacingDetector);
|
||||
GETINTERFACE_ANY(plObjectInVolumeAndFacingDetector, plObjectInVolumeDetector);
|
||||
|
||||
void Read(hsStream* stream, hsResMgr* mgr);
|
||||
void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
// Export only
|
||||
void SetFacingTolerance(int degrees);
|
||||
void SetNeedWalkingForward(bool v) { fNeedWalkingForward = v; }
|
||||
};
|
||||
|
||||
// sub-type for camera command regions
|
||||
|
||||
class plCameraRegionDetector : public plObjectInVolumeDetector
|
||||
{
|
||||
protected:
|
||||
hsTArray<plCameraMsg*> fMessages;
|
||||
|
||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
UInt32 fLastStep;
|
||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
||||
bool fIsInside;
|
||||
bool fEntering;
|
||||
|
||||
virtual void ISendTriggerMsg();
|
||||
virtual void IHandleEval(plEvalMsg* pEval);
|
||||
public:
|
||||
plCameraRegionDetector()
|
||||
: plObjectInVolumeDetector(), fIsInside(false) { }
|
||||
|
||||
~plCameraRegionDetector();
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
void AddMessage(plCameraMsg* pMsg) { fMessages.Append(pMsg); }
|
||||
|
||||
CLASSNAME_REGISTER( plCameraRegionDetector );
|
||||
GETINTERFACE_ANY( plCameraRegionDetector, plCollisionDetector );
|
||||
|
||||
void Read(hsStream* stream, hsResMgr* mgr);
|
||||
void Write(hsStream* stream, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
|
||||
// sub-type for subworld regions
|
||||
|
||||
class plSubworldRegionDetector : public plCollisionDetector
|
||||
{
|
||||
protected:
|
||||
plKey fSub;
|
||||
hsBool fOnExit;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kSubworld = 0,
|
||||
};
|
||||
plSubworldRegionDetector() : fSub(nil), fOnExit(false){;}
|
||||
~plSubworldRegionDetector();
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
void SetSubworldKey(plKey pKey) { fSub = pKey; }
|
||||
void SetTriggerOnExit(hsBool b) { fOnExit = b; }
|
||||
|
||||
CLASSNAME_REGISTER( plSubworldRegionDetector );
|
||||
GETINTERFACE_ANY( plSubworldRegionDetector, plCollisionDetector );
|
||||
|
||||
void Read(hsStream* stream, hsResMgr* mgr);
|
||||
void Write(hsStream* stream, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
// sub-type for panic link regions
|
||||
|
||||
class plPanicLinkRegion : public plCollisionDetector
|
||||
{
|
||||
public:
|
||||
hsBool fPlayLinkOutAnim;
|
||||
|
||||
plPanicLinkRegion() : fPlayLinkOutAnim(true) { }
|
||||
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
CLASSNAME_REGISTER( plPanicLinkRegion );
|
||||
GETINTERFACE_ANY( plPanicLinkRegion, plCollisionDetector );
|
||||
|
||||
void Read(hsStream* stream, hsResMgr* mgr);
|
||||
void Write(hsStream* stream, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
|
||||
/** \Class plSimpleRegionSensor
|
||||
A dead-simple interface for a collision region. Holds one message that it
|
||||
sends to anyone who enters, and another message that it sends to anyone
|
||||
who exits.
|
||||
We may want to tie this into the plCollisionDetector so that it could be
|
||||
integrated with responders.
|
||||
*/
|
||||
class plSimpleRegionSensor : public plSingleModifier
|
||||
{
|
||||
public:
|
||||
plSimpleRegionSensor();
|
||||
plSimpleRegionSensor(plMessage *enterMsg, plMessage *exitMsg);
|
||||
virtual ~plSimpleRegionSensor();
|
||||
|
||||
virtual hsBool MsgReceive(plMessage *msg);
|
||||
CLASSNAME_REGISTER( plSimpleRegionSensor );
|
||||
GETINTERFACE_ANY( plSimpleRegionSensor, plSingleModifier);
|
||||
|
||||
virtual void Write(hsStream *stream, hsResMgr *mgr);
|
||||
virtual void Read(hsStream *stream, hsResMgr *mgr);
|
||||
|
||||
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty);
|
||||
protected:
|
||||
plMessage *fEnterMsg;
|
||||
plMessage *fExitMsg;
|
||||
};
|
||||
|
||||
// This class really just exists so that I can hunt for it specifically by index
|
||||
// (and not accidentally get some other SimpleRegionSensor).
|
||||
class plSwimDetector : public plSimpleRegionSensor
|
||||
{
|
||||
public:
|
||||
plSwimDetector() {}
|
||||
plSwimDetector(plMessage *enterMsg, plMessage *exitMsg) : plSimpleRegionSensor(enterMsg, exitMsg) {}
|
||||
virtual ~plSwimDetector() {}
|
||||
|
||||
CLASSNAME_REGISTER( plSwimDetector );
|
||||
GETINTERFACE_ANY( plSwimDetector, plSimpleRegionSensor);
|
||||
|
||||
virtual void Write(hsStream *stream, hsResMgr *mgr);
|
||||
virtual void Read(hsStream *stream, hsResMgr *mgr);
|
||||
hsBool MsgReceive(plMessage *msg);
|
||||
};
|
||||
class plRidingAnimatedPhysicalDetector: public plSimpleRegionSensor
|
||||
{
|
||||
public:
|
||||
plRidingAnimatedPhysicalDetector(){}
|
||||
plRidingAnimatedPhysicalDetector(plMessage *enterMsg, plMessage *exitMsg) : plSimpleRegionSensor(enterMsg, exitMsg) {}
|
||||
virtual ~plRidingAnimatedPhysicalDetector(){}
|
||||
virtual hsBool MsgReceive(plMessage *msg);
|
||||
CLASSNAME_REGISTER( plRidingAnimatedPhysicalDetector );
|
||||
GETINTERFACE_ANY( plRidingAnimatedPhysicalDetector, plSimpleRegionSensor);
|
||||
};
|
||||
#endif plCollisionDetector_inc
|
101
Sources/Plasma/PubUtilLib/plPhysical/plDetectorModifier.h
Normal file
101
Sources/Plasma/PubUtilLib/plPhysical/plDetectorModifier.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
|
||||
#ifndef plDetectorModifier_inc
|
||||
#define plDetectorModifier_inc
|
||||
|
||||
#include "../pnModifier/plSingleModifier.h"
|
||||
#include "../pnMessage/plObjRefMsg.h"
|
||||
#include "hsStream.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
class plDetectorModifier : public plSingleModifier
|
||||
{
|
||||
protected:
|
||||
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty){ return true; }
|
||||
|
||||
hsTArray<plKey> fReceivers;
|
||||
plModifier* fRemoteMod;
|
||||
plKey fProxyKey;
|
||||
|
||||
public:
|
||||
plDetectorModifier() : fRemoteMod(nil),fProxyKey(nil){;}
|
||||
virtual ~plDetectorModifier(){;}
|
||||
|
||||
// virtual hsBool MsgReceive(plMessage* msg) = 0;
|
||||
|
||||
CLASSNAME_REGISTER( plDetectorModifier );
|
||||
GETINTERFACE_ANY( plDetectorModifier, plSingleModifier );
|
||||
void AddLogicObj(plKey pKey) { fReceivers.Append(pKey); }
|
||||
void SetRemote(plModifier* p) { fRemoteMod = p; }
|
||||
plModifier* RemoteMod() { return fRemoteMod; }
|
||||
virtual void SetType(Int8 i) {;}
|
||||
int GetNumReceivers() const { return fReceivers.Count(); }
|
||||
plKey GetReceiver(int i) const { return fReceivers[i]; }
|
||||
void SetProxyKey(const plKey &k) { fProxyKey = k; }
|
||||
void Read(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plSingleModifier::Read(stream, mgr);
|
||||
int n = stream->ReadSwap32();
|
||||
fReceivers.Reset();
|
||||
for(int i = 0; i < n; i++ )
|
||||
{
|
||||
fReceivers.Append(mgr->ReadKey(stream));
|
||||
}
|
||||
mgr->ReadKeyNotifyMe(stream, TRACKED_NEW plObjRefMsg(GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kModifier), plRefFlags::kActiveRef);
|
||||
fProxyKey = mgr->ReadKey(stream);
|
||||
}
|
||||
|
||||
void Write(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plSingleModifier::Write(stream, mgr);
|
||||
stream->WriteSwap32(fReceivers.GetCount());
|
||||
for( int i = 0; i < fReceivers.GetCount(); i++ )
|
||||
mgr->WriteKey(stream, fReceivers[i]);
|
||||
|
||||
mgr->WriteKey(stream, fRemoteMod);
|
||||
mgr->WriteKey(stream, fProxyKey);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif plDetectorModifier_inc
|
92
Sources/Plasma/PubUtilLib/plPhysical/plEnvEffectDetector.cpp
Normal file
92
Sources/Plasma/PubUtilLib/plPhysical/plEnvEffectDetector.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plEnvEffectDetector.h"
|
||||
#include "../plMessage/plCollideMsg.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "../pnMessage/plEnvEffectMsg.h"
|
||||
|
||||
/*
|
||||
hsBool plEnvEffectDetector::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
||||
|
||||
if (pCollMsg)
|
||||
{
|
||||
for (int i = 0; i < fEffectMsg.Count(); i++)
|
||||
{
|
||||
fEffectMsg[i]->ClearReceivers();
|
||||
if(pCollMsg->fEntering)
|
||||
{
|
||||
fEffectMsg[i]->Enable( true );
|
||||
} else {
|
||||
fEffectMsg[i]->Enable( false );
|
||||
}
|
||||
fEffectMsg[i]->AddReceiver( pCollMsg->fOtherKey );
|
||||
hsRefCnt_SafeRef(fEffectMsg[i]);
|
||||
plgDispatch::MsgSend( fEffectMsg[i] );
|
||||
}
|
||||
}
|
||||
return plDetectorModifier::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plEnvEffectDetector::Read(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plDetectorModifier::Read(stream, mgr);
|
||||
int n = stream->ReadSwap32();
|
||||
fEffectMsg.SetCountAndZero(n);
|
||||
for(int i = 0; i < n; i++ )
|
||||
{
|
||||
plEnvEffectMsg* pMsg = plEnvEffectMsg::ConvertNoRef(mgr->ReadCreatable(stream));
|
||||
fEffectMsg[i] = pMsg;
|
||||
}
|
||||
}
|
||||
|
||||
void plEnvEffectDetector::Write(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
plDetectorModifier::Write(stream, mgr);
|
||||
stream->WriteSwap32(fEffectMsg.GetCount());
|
||||
for(int i = 0; i < fEffectMsg.GetCount(); i++ )
|
||||
mgr->WriteCreatable( stream, fEffectMsg[i] );
|
||||
|
||||
}
|
||||
*/
|
73
Sources/Plasma/PubUtilLib/plPhysical/plEnvEffectDetector.h
Normal file
73
Sources/Plasma/PubUtilLib/plPhysical/plEnvEffectDetector.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
|
||||
#ifndef plEnvEffectDetector_inc
|
||||
#define plEnvEffectDetector_inc
|
||||
|
||||
#include "plDetectorModifier.h"
|
||||
|
||||
class plEnvEffectMsg;
|
||||
class plMessage;
|
||||
class hsStream;
|
||||
class hsResMgr;
|
||||
|
||||
class plEnvEffectDetector : public plDetectorModifier
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
plEnvEffectDetector(){;}
|
||||
virtual ~plEnvEffectDetector(){;}
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
CLASSNAME_REGISTER( plEnvEffectDetector );
|
||||
GETINTERFACE_ANY( plEnvEffectDetector, plDetectorModifier );
|
||||
|
||||
hsTArray<plEnvEffectMsg*> fEffectMsg;
|
||||
|
||||
void Read(hsStream* stream, hsResMgr* mgr);
|
||||
void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
};
|
||||
|
||||
#endif plEnvEffectDetector_inc
|
74
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalCreatable.h
Normal file
74
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalCreatable.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
|
||||
#ifndef plPhysicalCreatable_inc
|
||||
#define plPhysicalCreatable_inc
|
||||
|
||||
#include "../pnFactory/plCreator.h"
|
||||
|
||||
#include "plDetectorModifier.h"
|
||||
|
||||
REGISTER_NONCREATABLE( plDetectorModifier );
|
||||
|
||||
#include "plPickingDetector.h"
|
||||
|
||||
REGISTER_CREATABLE( plPickingDetector );
|
||||
|
||||
#include "plCollisionDetector.h"
|
||||
|
||||
REGISTER_CREATABLE( plCollisionDetector );
|
||||
REGISTER_CREATABLE( plCameraRegionDetector );
|
||||
REGISTER_CREATABLE( plObjectInVolumeDetector );
|
||||
REGISTER_CREATABLE( plObjectInVolumeAndFacingDetector );
|
||||
REGISTER_CREATABLE( plSubworldRegionDetector );
|
||||
REGISTER_CREATABLE( plPanicLinkRegion );
|
||||
REGISTER_CREATABLE( plSimpleRegionSensor );
|
||||
REGISTER_CREATABLE( plSwimDetector );
|
||||
REGISTER_CREATABLE( plRidingAnimatedPhysicalDetector );
|
||||
|
||||
#include "plPhysicalSDLModifier.h"
|
||||
REGISTER_CREATABLE( plPhysicalSDLModifier );
|
||||
|
||||
#include "plPhysicalSndGroup.h"
|
||||
REGISTER_CREATABLE(plPhysicalSndGroup);
|
||||
|
||||
#endif // plPhysicalCreatable_inc
|
111
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalProxy.cpp
Normal file
111
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalProxy.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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 "plPhysicalProxy.h"
|
||||
#include "plPhysical.h"
|
||||
#include "../plPhysX/plPXPhysicalControllerCore.h"
|
||||
#include "../plDrawable/plDrawableSpans.h"
|
||||
#include "../plDrawable/plDrawableGenerator.h"
|
||||
#include "../pnMessage/plProxyDrawMsg.h"
|
||||
|
||||
#include "../plSurface/hsGMaterial.h"
|
||||
#include "../plSurface/plLayer.h"
|
||||
|
||||
plPhysicalProxy::plPhysicalProxy()
|
||||
: plProxyGen(hsColorRGBA().Set(0,0,0,1.f), hsColorRGBA().Set(1.f,0.8f,0.2f,1.f), 0.5f),
|
||||
fOwner(nil)
|
||||
{
|
||||
}
|
||||
|
||||
plPhysicalProxy::plPhysicalProxy(const hsColorRGBA& amb, const hsColorRGBA& dif, hsScalar opac)
|
||||
: plProxyGen(amb, dif, opac),
|
||||
fOwner(nil),
|
||||
fController(nil)
|
||||
{
|
||||
}
|
||||
|
||||
plPhysicalProxy::~plPhysicalProxy()
|
||||
{
|
||||
}
|
||||
|
||||
bool plPhysicalProxy::Init(plPhysical* liInfo)
|
||||
{
|
||||
plProxyGen::Init(liInfo);
|
||||
|
||||
fOwner = liInfo;
|
||||
fProxyMsgType = plProxyDrawMsg::kPhysical;
|
||||
|
||||
return fOwner != nil;
|
||||
}
|
||||
|
||||
bool plPhysicalProxy::Init(plPXPhysicalControllerCore* controller)
|
||||
{
|
||||
if (controller)
|
||||
if (controller->GetOwner())
|
||||
plProxyGen::Init(controller->GetOwner()->GetObjectPtr());
|
||||
|
||||
fController = controller;
|
||||
fProxyMsgType = plProxyDrawMsg::kPhysical;
|
||||
|
||||
return fController != nil;
|
||||
}
|
||||
|
||||
plKey plPhysicalProxy::IGetNode() const
|
||||
{
|
||||
if (fOwner)
|
||||
return fOwner->GetSceneNode();
|
||||
if (fController)
|
||||
return fController->GetOwner();
|
||||
return nil;
|
||||
}
|
||||
|
||||
plDrawableSpans* plPhysicalProxy::ICreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo)
|
||||
{
|
||||
if (fOwner)
|
||||
{
|
||||
return fOwner->CreateProxy(mat, idx, addTo);
|
||||
}
|
||||
if (fController)
|
||||
{
|
||||
return fController->CreateProxy(mat,idx,addTo);
|
||||
}
|
||||
return nil;
|
||||
}
|
70
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalProxy.h
Normal file
70
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalProxy.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
#ifndef plPhysicalProxy_inc
|
||||
#define plPhysicalProxy_inc
|
||||
|
||||
#include "../plDrawable/plProxyGen.h"
|
||||
|
||||
class plDrawableSpans;
|
||||
class hsGMaterial;
|
||||
class plPhysical;
|
||||
class plPXPhysicalControllerCore;
|
||||
|
||||
class plPhysicalProxy : public plProxyGen
|
||||
{
|
||||
public:
|
||||
plPhysicalProxy();
|
||||
plPhysicalProxy(const hsColorRGBA& amb, const hsColorRGBA& dif, hsScalar opac);
|
||||
virtual ~plPhysicalProxy();
|
||||
|
||||
bool Init(plPhysical* phys);
|
||||
bool Init(plPXPhysicalControllerCore* controller);
|
||||
|
||||
protected:
|
||||
plPhysical* fOwner;
|
||||
plPXPhysicalControllerCore* fController;
|
||||
|
||||
virtual plDrawableSpans* ICreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo=nil);
|
||||
virtual plKey IGetNode() const;
|
||||
};
|
||||
|
||||
#endif // plPhysicalProxy_inc
|
272
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalSDLModifier.cpp
Normal file
272
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalSDLModifier.cpp
Normal file
@ -0,0 +1,272 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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 "plPhysicalSDLModifier.h"
|
||||
|
||||
#include "hsGeometry3.h"
|
||||
#include "plPhysical.h"
|
||||
#include "../plSDL/plSDL.h"
|
||||
#include "../pnSceneObject/plSceneObject.h"
|
||||
#include "../pnSceneObject/plSimulationInterface.h"
|
||||
#include "../pnNetCommon/plNetApp.h"
|
||||
#include "hsQuat.h"
|
||||
//#include "../plHavok1/plSimulationMgr.h"
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
|
||||
// static vars
|
||||
static const char* kStrLinear = "linear";
|
||||
static const char* kStrAngular = "angular";
|
||||
static const char* kStrPosition = "position";
|
||||
static const char* kStrOrientation = "orientation";
|
||||
|
||||
int plPhysicalSDLModifier::fLogLevel = 0;
|
||||
|
||||
static void IGetVars(plStateDataRecord::SimpleVarsList& vars,
|
||||
hsPoint3& pos, bool& isPosSet,
|
||||
hsQuat& rot, bool& isRotSet,
|
||||
hsVector3& linV, bool& isLinVSet,
|
||||
hsVector3& angV, bool& isAngVSet);
|
||||
|
||||
//
|
||||
// get current state from physical
|
||||
// fill out state data rec
|
||||
//
|
||||
void plPhysicalSDLModifier::IPutCurrentStateIn(plStateDataRecord* dstState)
|
||||
{
|
||||
plPhysical* phys = IGetPhysical();
|
||||
|
||||
// get latest state
|
||||
hsPoint3 curPos;
|
||||
hsQuat curOrientation;
|
||||
hsVector3 curLinear, curAngular;
|
||||
phys->GetSyncState(curPos, curOrientation, curLinear, curAngular);
|
||||
|
||||
// put it in sdl state record
|
||||
dstState->FindVar(kStrPosition)->Set(&curPos.fX);
|
||||
dstState->FindVar(kStrOrientation)->Set(&curOrientation.fX);
|
||||
dstState->FindVar(kStrLinear)->Set(&curLinear.fX);
|
||||
dstState->FindVar(kStrAngular)->Set(&curAngular.fX);
|
||||
|
||||
if (fLogLevel > 1)
|
||||
ILogState(dstState, false, "PUT", plStatusLog::kWhite);
|
||||
}
|
||||
|
||||
void plPhysicalSDLModifier::ISetCurrentStateFrom(const plStateDataRecord* srcState)
|
||||
{
|
||||
plPhysical* phys = IGetPhysical();
|
||||
|
||||
// FIXME PHYSX
|
||||
|
||||
// if(phys->GetBody()->isFixed())
|
||||
// {
|
||||
// plSimulationMgr::Log("Received synch for fixed body %s", phys->GetKey()->GetName());
|
||||
// return;
|
||||
// }
|
||||
// else if (phys->GetProperty(plSimulationInterface::kPinned))
|
||||
// {
|
||||
// // This is mainly intended for avatars. When pinning them (like in a multistage),
|
||||
// // we don't want physical updates to sneak in due to network lag. If necessary,
|
||||
// // this could be made a separate property on the physical, orthagonal to kPinned.
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
{
|
||||
hsPoint3 pos;
|
||||
bool isPosSet;
|
||||
hsQuat rot;
|
||||
bool isRotSet;
|
||||
hsVector3 linV;
|
||||
bool isLinVSet;
|
||||
hsVector3 angV;
|
||||
bool isAngVSet;
|
||||
|
||||
plStateDataRecord::SimpleVarsList vars;
|
||||
srcState->GetUsedVars(&vars);
|
||||
IGetVars(vars, pos, isPosSet, rot, isRotSet, linV, isLinVSet, angV, isAngVSet);
|
||||
|
||||
if (fLogLevel > 0)
|
||||
ILogState(srcState, false, "RCV", plStatusLog::kGreen);
|
||||
|
||||
phys->SetSyncState(
|
||||
isPosSet ? &pos : nil,
|
||||
isRotSet ? &rot : nil,
|
||||
isLinVSet ? &linV : nil,
|
||||
isAngVSet ? &angV : nil);
|
||||
}
|
||||
}
|
||||
|
||||
void plPhysicalSDLModifier::ISentState(const plStateDataRecord* sentState)
|
||||
{
|
||||
if (fLogLevel > 0)
|
||||
{
|
||||
ILogState(sentState, true, "SND", plStatusLog::kYellow);
|
||||
|
||||
// plPhysical* phys = IGetPhysical();
|
||||
// if (!phys->GetBody()->isActive())
|
||||
// IGetLog()->AddLineF("Phys %s sent state because it deactivated", phys->GetKeyName());
|
||||
}
|
||||
}
|
||||
|
||||
static void IGetVars(plStateDataRecord::SimpleVarsList& vars,
|
||||
hsPoint3& pos, bool& isPosSet,
|
||||
hsQuat& rot, bool& isRotSet,
|
||||
hsVector3& linV, bool& isLinVSet,
|
||||
hsVector3& angV, bool& isAngVSet)
|
||||
{
|
||||
isPosSet = false;
|
||||
isRotSet = false;
|
||||
isLinVSet = false;
|
||||
isAngVSet = false;
|
||||
|
||||
int num = vars.size();
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
if (vars[i]->IsNamed(kStrPosition))
|
||||
{
|
||||
vars[i]->Get(&pos.fX);
|
||||
isPosSet= true;
|
||||
}
|
||||
else
|
||||
if (vars[i]->IsNamed(kStrOrientation))
|
||||
{
|
||||
vars[i]->Get(&rot.fX);
|
||||
isRotSet = true;
|
||||
}
|
||||
else
|
||||
if (vars[i]->IsNamed(kStrLinear))
|
||||
{
|
||||
vars[i]->Get(&linV.fX);
|
||||
isLinVSet = true;
|
||||
}
|
||||
else
|
||||
if (vars[i]->IsNamed(kStrAngular))
|
||||
{
|
||||
vars[i]->Get(&angV.fX);
|
||||
isAngVSet = true;
|
||||
}
|
||||
else
|
||||
if (vars[i]->IsNamed("subworld"))
|
||||
{
|
||||
// Unused
|
||||
}
|
||||
else
|
||||
{
|
||||
hsAssert(false, "Unknown var name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plPhysicalSDLModifier::ILogState(const plStateDataRecord* state, bool useDirty, const char* prefix, UInt32 color)
|
||||
{
|
||||
hsPoint3 pos;
|
||||
bool isPosSet;
|
||||
hsQuat rot;
|
||||
bool isRotSet;
|
||||
hsVector3 linV;
|
||||
bool isLinVSet;
|
||||
hsVector3 angV;
|
||||
bool isAngVSet;
|
||||
|
||||
plStateDataRecord::SimpleVarsList vars;
|
||||
if (useDirty)
|
||||
state->GetDirtyVars(&vars);
|
||||
else
|
||||
state->GetUsedVars(&vars);
|
||||
|
||||
IGetVars(vars, pos, isPosSet, rot, isRotSet, linV, isLinVSet, angV, isAngVSet);
|
||||
|
||||
plPhysical* phys = IGetPhysical();
|
||||
|
||||
std::string log = xtl::format("%s: %s", phys->GetKeyName(), prefix);
|
||||
|
||||
if (isPosSet)
|
||||
log += xtl::format(" Pos=%.1f %.1f %.1f", pos.fX, pos.fY, pos.fZ);
|
||||
else
|
||||
log += " Pos=None";
|
||||
|
||||
if (isLinVSet)
|
||||
log += xtl::format(" LinV=%.1f %.1f %.1f", linV.fX, linV.fY, linV.fZ);
|
||||
else
|
||||
log += " LinV=None";
|
||||
|
||||
if (isAngVSet)
|
||||
log += xtl::format(" AngV=%.1f %.1f %.1f", angV.fX, angV.fY, angV.fZ);
|
||||
else
|
||||
log += " AngV=None";
|
||||
|
||||
if (isRotSet)
|
||||
log += xtl::format(" Rot=%.1f %.1f %.1f %.1f", rot.fX, rot.fY, rot.fZ, rot.fW);
|
||||
else
|
||||
log += " Rot=None";
|
||||
|
||||
IGetLog()->AddLine(log.c_str(), color);
|
||||
}
|
||||
|
||||
plStatusLog* plPhysicalSDLModifier::IGetLog()
|
||||
{
|
||||
static plStatusLog* gLog = nil;
|
||||
if (!gLog)
|
||||
{
|
||||
gLog = plStatusLogMgr::GetInstance().CreateStatusLog(20, "PhysicsSDL.log",
|
||||
plStatusLog::kFilledBackground |
|
||||
plStatusLog::kTimestamp |
|
||||
plStatusLog::kDeleteForMe |
|
||||
plStatusLog::kAlignToTop);
|
||||
}
|
||||
|
||||
return gLog;
|
||||
}
|
||||
|
||||
plPhysical* plPhysicalSDLModifier::IGetPhysical()
|
||||
{
|
||||
plPhysical* phys = nil;
|
||||
|
||||
plSceneObject* sobj = GetTarget();
|
||||
if (sobj)
|
||||
{
|
||||
const plSimulationInterface* si = sobj->GetSimulationInterface();
|
||||
if (si)
|
||||
phys = si->GetPhysical();
|
||||
}
|
||||
|
||||
hsAssert(phys, "nil hkPhysical");
|
||||
return phys;
|
||||
}
|
77
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalSDLModifier.h
Normal file
77
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalSDLModifier.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
#ifndef plPhysicalSDLModifier_inc
|
||||
#define plPhysicalSDLModifier_inc
|
||||
|
||||
#include "../plModifier/plSDLModifier.h"
|
||||
|
||||
class plStateDataRecord;
|
||||
class plStatusLog;
|
||||
class plPhysical;
|
||||
|
||||
//
|
||||
// This modifier is responsible for sending and recving
|
||||
// an object's physical state.
|
||||
//
|
||||
class plPhysicalSDLModifier : public plSDLModifier
|
||||
{
|
||||
public:
|
||||
CLASSNAME_REGISTER( plPhysicalSDLModifier );
|
||||
GETINTERFACE_ANY( plPhysicalSDLModifier, plSDLModifier);
|
||||
|
||||
const char* GetSDLName() const { return kSDLPhysical; }
|
||||
|
||||
// For the console
|
||||
static void SetLogLevel(int level) { fLogLevel = level; }
|
||||
|
||||
protected:
|
||||
static int fLogLevel;
|
||||
static plStatusLog* IGetLog();
|
||||
void ILogState(const plStateDataRecord* state, bool useDirty, const char* prefix, UInt32 color);
|
||||
|
||||
plPhysical* IGetPhysical();
|
||||
virtual void IPutCurrentStateIn(plStateDataRecord* dstState);
|
||||
virtual void ISetCurrentStateFrom(const plStateDataRecord* srcState);
|
||||
virtual void ISentState(const plStateDataRecord* sentState);
|
||||
};
|
||||
|
||||
#endif // plPhysicalSDLModifier_inc
|
183
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalSndGroup.cpp
Normal file
183
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalSndGroup.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plPhysicalSndGroup Class //
|
||||
// Simplistic container class to store the matchup info for a given //
|
||||
// physical sound group. Assigning one of these objects to a physical //
|
||||
// specifies the sound group it's in as well as the sounds it should make //
|
||||
// when colliding against objects of other sound groups. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsResMgr.h"
|
||||
#include "plPhysicalSndGroup.h"
|
||||
#include "../plAudio/plSound.h"
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
#include "../plMessage/plAnimCmdMsg.h"
|
||||
|
||||
|
||||
plPhysicalSndGroup::plPhysicalSndGroup() : fPlayingSlideSound(false)
|
||||
{
|
||||
fGroup = kNone;
|
||||
}
|
||||
|
||||
plPhysicalSndGroup::plPhysicalSndGroup( UInt32 grp ) : fPlayingSlideSound(false)
|
||||
{
|
||||
fGroup = grp;
|
||||
}
|
||||
|
||||
plPhysicalSndGroup::~plPhysicalSndGroup()
|
||||
{
|
||||
}
|
||||
|
||||
bool plPhysicalSndGroup::HasSlideSound(UInt32 against)
|
||||
{
|
||||
return against < fSlideSounds.GetCount();
|
||||
}
|
||||
|
||||
bool plPhysicalSndGroup::HasImpactSound(UInt32 against)
|
||||
{
|
||||
return against < fImpactSounds.GetCount();
|
||||
}
|
||||
|
||||
hsBool plPhysicalSndGroup::MsgReceive( plMessage *pMsg )
|
||||
{
|
||||
return hsKeyedObject::MsgReceive( pMsg );
|
||||
}
|
||||
|
||||
void plPhysicalSndGroup::Read( hsStream *s, hsResMgr *mgr )
|
||||
{
|
||||
hsKeyedObject::Read( s, mgr );
|
||||
|
||||
s->ReadSwap( &fGroup );
|
||||
|
||||
UInt32 i, count = s->ReadSwap32();
|
||||
fImpactSounds.Reset();
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
fImpactSounds.Append( mgr->ReadKey( s ) );
|
||||
|
||||
count = s->ReadSwap32();
|
||||
fSlideSounds.Reset();
|
||||
for( i = 0; i < count; i++ )
|
||||
fSlideSounds.Append( mgr->ReadKey( s ) );
|
||||
|
||||
}
|
||||
|
||||
void plPhysicalSndGroup::Write( hsStream *s, hsResMgr *mgr )
|
||||
{
|
||||
hsKeyedObject::Write( s, mgr );
|
||||
|
||||
s->WriteSwap( fGroup );
|
||||
|
||||
UInt32 i;
|
||||
s->WriteSwap32( fImpactSounds.GetCount() );
|
||||
for( i = 0; i < fImpactSounds.GetCount(); i++ )
|
||||
mgr->WriteKey( s, fImpactSounds[ i ] );
|
||||
|
||||
s->WriteSwap32( fSlideSounds.GetCount() );
|
||||
for( i = 0; i < fSlideSounds.GetCount(); i++ )
|
||||
mgr->WriteKey( s, fSlideSounds[ i ] );
|
||||
}
|
||||
|
||||
void plPhysicalSndGroup::AddImpactSound( UInt32 against, plKey receiver )
|
||||
{
|
||||
if( fImpactSounds.GetCount() <= against )
|
||||
{
|
||||
fImpactSounds.Expand( against + 1 );
|
||||
fImpactSounds.SetCount( against + 1 );
|
||||
}
|
||||
|
||||
fImpactSounds[ against ] = receiver;
|
||||
}
|
||||
|
||||
void plPhysicalSndGroup::AddSlideSound( UInt32 against, plKey receiver )
|
||||
{
|
||||
if( fSlideSounds.GetCount() <= against )
|
||||
{
|
||||
fSlideSounds.Expand( against + 1 );
|
||||
fSlideSounds.SetCount( against + 1 );
|
||||
}
|
||||
|
||||
fSlideSounds[ against ] = receiver;
|
||||
}
|
||||
|
||||
void plPhysicalSndGroup::PlaySlideSound(UInt32 against)
|
||||
{
|
||||
if(against >= fSlideSounds.Count())
|
||||
return;
|
||||
plAnimCmdMsg* animMsg = TRACKED_NEW plAnimCmdMsg;
|
||||
animMsg->SetCmd(plAnimCmdMsg::kContinue);
|
||||
animMsg->Send(fSlideSounds[against]);
|
||||
fPlayingSlideSound = true;
|
||||
}
|
||||
|
||||
void plPhysicalSndGroup::StopSlideSound(UInt32 against)
|
||||
{
|
||||
if(against >= fSlideSounds.Count())
|
||||
return;
|
||||
plAnimCmdMsg *animMsg = TRACKED_NEW plAnimCmdMsg;
|
||||
animMsg->SetCmd(plAnimCmdMsg::kStop);
|
||||
animMsg->Send(fSlideSounds[against]);
|
||||
fPlayingSlideSound = false;
|
||||
}
|
||||
|
||||
void plPhysicalSndGroup::PlayImpactSound(UInt32 against)
|
||||
{
|
||||
if(against >= fImpactSounds.Count())
|
||||
return;
|
||||
plAnimCmdMsg* animMsg = TRACKED_NEW plAnimCmdMsg;
|
||||
animMsg->SetCmd(plAnimCmdMsg::kContinue);
|
||||
animMsg->Send(fImpactSounds[against]);
|
||||
}
|
||||
|
||||
void plPhysicalSndGroup::SetSlideSoundVolume(UInt32 against, hsScalar volume)
|
||||
{
|
||||
if(against >= fSlideSounds.Count())
|
||||
return;
|
||||
plAnimCmdMsg* animMsg = TRACKED_NEW plAnimCmdMsg;
|
||||
animMsg->SetCmd(plAnimCmdMsg::kSetSpeed);
|
||||
animMsg->fSpeed = volume;
|
||||
animMsg->Send(fSlideSounds[against]);
|
||||
|
||||
}
|
119
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalSndGroup.h
Normal file
119
Sources/Plasma/PubUtilLib/plPhysical/plPhysicalSndGroup.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
#ifndef _plPhysicalSndGroup_h
|
||||
#define _plPhysicalSndGroup_h
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plPhysicalSndGroup Class //
|
||||
// Simplistic container class to store the matchup info for a given //
|
||||
// physical sound group. Assigning one of these objects to a physical //
|
||||
// specifies the sound group it's in as well as the sounds it should make //
|
||||
// when colliding against objects of other sound groups. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsTemplates.h"
|
||||
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
#include "../pnKeyedObject/plUoid.h"
|
||||
|
||||
class plSound;
|
||||
class plPhysicalSndGroup : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
|
||||
// The group enums
|
||||
enum SoundGroup
|
||||
{
|
||||
kNone = 0,
|
||||
kMetal,
|
||||
kGrass,
|
||||
kWood
|
||||
};
|
||||
|
||||
plPhysicalSndGroup();
|
||||
plPhysicalSndGroup( UInt32 grp );
|
||||
virtual ~plPhysicalSndGroup();
|
||||
|
||||
CLASSNAME_REGISTER( plPhysicalSndGroup );
|
||||
GETINTERFACE_ANY( plPhysicalSndGroup, hsKeyedObject );
|
||||
|
||||
// Our required virtual
|
||||
virtual hsBool MsgReceive( plMessage *pMsg );
|
||||
|
||||
virtual void Read( hsStream *s, hsResMgr *mgr );
|
||||
virtual void Write( hsStream *s, hsResMgr *mgr );
|
||||
|
||||
void PlaySlideSound(UInt32 against);
|
||||
void StopSlideSound(UInt32 against);
|
||||
void PlayImpactSound(UInt32 against);
|
||||
void SetSlideSoundVolume(UInt32 against, hsScalar volume);
|
||||
bool HasSlideSound(UInt32 against);
|
||||
bool HasImpactSound(UInt32 against);
|
||||
|
||||
UInt32 GetGroup( void ) const { return fGroup; }
|
||||
|
||||
// Export only
|
||||
void AddImpactSound( UInt32 against, plKey receiver );
|
||||
void AddSlideSound( UInt32 against, plKey receiver );
|
||||
bool IsSliding() { return fPlayingSlideSound; }
|
||||
|
||||
protected:
|
||||
|
||||
enum Refs
|
||||
{
|
||||
kRefImpactSound,
|
||||
kRefSlideSound
|
||||
};
|
||||
|
||||
UInt32 fGroup;
|
||||
bool fPlayingSlideSound;
|
||||
|
||||
// Sound key arrays for, well, our sounds!
|
||||
hsTArray<plKey> fImpactSounds;
|
||||
hsTArray<plKey> fSlideSounds;
|
||||
};
|
||||
|
||||
|
||||
#endif //_plPhysicalSndGroup_h
|
233
Sources/Plasma/PubUtilLib/plPhysical/plPhysicsSoundMgr.cpp
Normal file
233
Sources/Plasma/PubUtilLib/plPhysical/plPhysicsSoundMgr.cpp
Normal file
@ -0,0 +1,233 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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 <algorithm>
|
||||
#include <iterator>
|
||||
#include "hsTimer.h"
|
||||
#include "plPhysicsSoundMgr.h"
|
||||
#include "plPhysicalSndGroup.h"
|
||||
#include "../pnKeyedObject/plFixedKey.h"
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
#include "../plMessage/plAnimCmdMsg.h"
|
||||
#include "../FeatureLib/pfAudio/plRandomSoundMod.h"
|
||||
|
||||
#define MIN_VOLUME 0.0001f
|
||||
|
||||
void plPhysicsSoundMgr::AddContact(plPhysical* phys1, plPhysical* phys2, const hsPoint3& hitPoint, const hsVector3& hitNormal)
|
||||
{
|
||||
CollidePair cp(phys1->GetKey(), phys2->GetKey(), hitPoint, hitNormal);
|
||||
fCurCollisions.insert(cp);
|
||||
}
|
||||
|
||||
void plPhysicsSoundMgr::Update()
|
||||
{
|
||||
// Get all the physicals that only in the new list (started colliding)
|
||||
CollideSet startedColliding;
|
||||
std::set_difference(fCurCollisions.begin(), fCurCollisions.end(),
|
||||
fPrevCollisions.begin(), fPrevCollisions.end(),
|
||||
std::inserter(startedColliding, startedColliding.begin()));
|
||||
|
||||
for (CollideSet::iterator it = startedColliding.begin(); it != startedColliding.end(); it++)
|
||||
IStartCollision(*it);
|
||||
|
||||
for (CollideSet::iterator it = fPrevCollisions.begin(); it != fPrevCollisions.end(); it++)
|
||||
{
|
||||
CollideSet::iterator old = fCurCollisions.find(*it);
|
||||
if (old != fCurCollisions.end())
|
||||
{
|
||||
IUpdateCollision(*it);
|
||||
}
|
||||
else
|
||||
{
|
||||
IStopCollision(*it);
|
||||
}
|
||||
}
|
||||
|
||||
fPrevCollisions = fCurCollisions;
|
||||
fCurCollisions.clear();
|
||||
}
|
||||
|
||||
void plPhysicsSoundMgr::IStartCollision(const CollidePair& cp)
|
||||
{
|
||||
hsVector3 v1, v2;
|
||||
const hsScalar strengthThreshold = 20.0f;
|
||||
|
||||
plPhysical* physicalA = cp.FirstPhysical();
|
||||
plPhysical* physicalB = cp.SecondPhysical();
|
||||
if (!physicalA || !physicalB)
|
||||
return;
|
||||
|
||||
plPhysicalSndGroup* sndA = physicalA->GetSoundGroup();
|
||||
plPhysicalSndGroup* sndB = physicalB->GetSoundGroup();
|
||||
|
||||
// If no impact sounds were specified in max don't do anything here.
|
||||
if (!sndA->HasImpactSound(sndB->GetGroup()) &&
|
||||
!sndB->HasImpactSound(sndA->GetGroup()))
|
||||
return;
|
||||
|
||||
physicalA->GetLinearVelocitySim(v1);
|
||||
physicalB->GetLinearVelocitySim(v2);
|
||||
hsVector3 vel = v1 - v2;
|
||||
hsScalar strength = vel.MagnitudeSquared();
|
||||
|
||||
if (strength >= strengthThreshold)
|
||||
{
|
||||
if (sndA->HasImpactSound(sndB->GetGroup()))
|
||||
{
|
||||
sndA->PlayImpactSound(sndB->GetGroup());
|
||||
}
|
||||
else
|
||||
{
|
||||
sndB->PlayImpactSound(sndA->GetGroup());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plPhysicsSoundMgr::IStopCollision(const CollidePair& cp)
|
||||
{
|
||||
plPhysical* physicalA = cp.FirstPhysical();
|
||||
plPhysical* physicalB = cp.SecondPhysical();
|
||||
if (physicalA && physicalB)
|
||||
{
|
||||
plPhysicalSndGroup* sndA = physicalA->GetSoundGroup();
|
||||
plPhysicalSndGroup* sndB = physicalB->GetSoundGroup();
|
||||
|
||||
if (sndA->HasSlideSound(sndB->GetGroup()))
|
||||
{
|
||||
if(sndA->IsSliding())
|
||||
{
|
||||
sndA->StopSlideSound(sndB->GetGroup());
|
||||
}
|
||||
}
|
||||
if (sndB->HasSlideSound(sndA->GetGroup()))
|
||||
{
|
||||
if(sndB->IsSliding())
|
||||
{
|
||||
sndB->StopSlideSound(sndA->GetGroup());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plPhysicsSoundMgr::IUpdateCollision(const CollidePair& cp)
|
||||
{
|
||||
const hsScalar slideThreshhold = 0.f;
|
||||
hsVector3 v1, v2;
|
||||
plPhysical* physicalA = cp.FirstPhysical();
|
||||
plPhysical* physicalB = cp.SecondPhysical();
|
||||
if (!physicalA || !physicalB)
|
||||
return;
|
||||
|
||||
plPhysicalSndGroup* sndA = physicalA->GetSoundGroup();
|
||||
plPhysicalSndGroup* sndB = physicalB->GetSoundGroup();
|
||||
|
||||
physicalA->GetLinearVelocitySim(v1);
|
||||
physicalB->GetLinearVelocitySim(v2);
|
||||
hsVector3 vel = v1 - v2;
|
||||
hsScalar strength = vel.MagnitudeSquared();
|
||||
|
||||
// scale strength to use as volume
|
||||
strength /= 16*8;
|
||||
if(strength < MIN_VOLUME)
|
||||
strength = 0;
|
||||
|
||||
if (sndA->HasSlideSound(sndB->GetGroup()))
|
||||
IProcessSlide(sndA, sndB, strength);
|
||||
else
|
||||
IProcessSlide(sndB, sndA, strength);
|
||||
}
|
||||
|
||||
void plPhysicsSoundMgr::IProcessSlide(plPhysicalSndGroup* sndA, plPhysicalSndGroup* sndB, hsScalar strength)
|
||||
{
|
||||
sndA->SetSlideSoundVolume(sndB->GetGroup(), strength);
|
||||
|
||||
if(strength > MIN_VOLUME)
|
||||
{
|
||||
if(!sndA->IsSliding())
|
||||
{
|
||||
sndA->PlaySlideSound(sndB->GetGroup());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plPhysicsSoundMgr::CollidePair::CollidePair(const plKey& firstPhys, const plKey& secondPhys, const hsPoint3& point, const hsVector3& normal)
|
||||
{
|
||||
// To simplify searching and sorting, all pairs are set up with the pointer value of the
|
||||
// first element greater than the pointer value of the second.
|
||||
if (firstPhys->GetObjectPtr() < secondPhys->GetObjectPtr())
|
||||
{
|
||||
this->firstPhysKey = secondPhys;
|
||||
this->secondPhysKey = firstPhys;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->firstPhysKey = firstPhys;
|
||||
this->secondPhysKey = secondPhys;
|
||||
}
|
||||
|
||||
this->point = point;
|
||||
this->normalForce = normal;
|
||||
}
|
||||
|
||||
bool plPhysicsSoundMgr::CollidePair::operator<(const CollidePair& rhs) const
|
||||
{
|
||||
return (firstPhysKey->GetObjectPtr() < rhs.firstPhysKey->GetObjectPtr()
|
||||
|| (rhs.firstPhysKey->GetObjectPtr() == firstPhysKey->GetObjectPtr() && secondPhysKey->GetObjectPtr() < rhs.secondPhysKey->GetObjectPtr()));
|
||||
}
|
||||
|
||||
bool plPhysicsSoundMgr::CollidePair::operator==(const CollidePair& rhs) const
|
||||
{
|
||||
if (firstPhysKey == rhs.firstPhysKey && secondPhysKey == rhs.secondPhysKey)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
plPhysical* plPhysicsSoundMgr::CollidePair::FirstPhysical() const
|
||||
{
|
||||
return firstPhysKey ? static_cast<plPhysical*>(firstPhysKey->GetObjectPtr()) : nil;
|
||||
}
|
||||
|
||||
plPhysical* plPhysicsSoundMgr::CollidePair::SecondPhysical() const
|
||||
{
|
||||
return secondPhysKey ? static_cast<plPhysical*>(secondPhysKey->GetObjectPtr()) : nil;
|
||||
}
|
94
Sources/Plasma/PubUtilLib/plPhysical/plPhysicsSoundMgr.h
Normal file
94
Sources/Plasma/PubUtilLib/plPhysical/plPhysicsSoundMgr.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
#ifndef plPhysicsSoundMgr_h_inc
|
||||
#define plPhysicsSoundMgr_h_inc
|
||||
|
||||
#include "hsStlUtils.h"
|
||||
#include "plPhysical.h"
|
||||
#include "hsGeometry3.h"
|
||||
|
||||
class plPhysicsSoundMgr
|
||||
{
|
||||
public:
|
||||
void AddContact(plPhysical* phys1, plPhysical* phys2, const hsPoint3& hitPoint, const hsVector3& hitNormal);
|
||||
void Update();
|
||||
|
||||
private:
|
||||
enum EventType
|
||||
{
|
||||
kSlide,
|
||||
kContact,
|
||||
kEndSlide
|
||||
};
|
||||
|
||||
enum EventStopType
|
||||
{
|
||||
kStopFromImpact = 0,
|
||||
kStopFromEndSlide = 2
|
||||
};
|
||||
|
||||
class CollidePair
|
||||
{
|
||||
public:
|
||||
plKey firstPhysKey;
|
||||
plKey secondPhysKey;
|
||||
hsPoint3 point;
|
||||
hsVector3 normalForce;
|
||||
|
||||
CollidePair(const plKey& firstPhys, const plKey& secondPhys, const hsPoint3& point, const hsVector3& normal);
|
||||
bool operator<(const CollidePair& rhs) const;
|
||||
bool operator==(const CollidePair& rhs) const;
|
||||
plPhysical* FirstPhysical() const;
|
||||
plPhysical* SecondPhysical() const;
|
||||
};
|
||||
|
||||
void IStartCollision(const CollidePair& cp);
|
||||
void IStopCollision(const CollidePair& cp);
|
||||
void IUpdateCollision(const CollidePair& cp);
|
||||
void IProcessSlide(plPhysicalSndGroup* sndA, plPhysicalSndGroup* sndB, hsScalar strength);
|
||||
|
||||
typedef std::set<CollidePair> CollideSet;
|
||||
CollideSet fPrevCollisions;
|
||||
CollideSet fCurCollisions;
|
||||
};
|
||||
|
||||
#endif // plPhysicsSoundMgr_h_inc
|
111
Sources/Plasma/PubUtilLib/plPhysical/plPickingDetector.cpp
Normal file
111
Sources/Plasma/PubUtilLib/plPhysical/plPickingDetector.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plPickingDetector.h"
|
||||
#include "../plMessage/plActivatorMsg.h"
|
||||
#include "../plMessage/plPickedMsg.h"
|
||||
#include "../pnNetCommon/plNetApp.h"
|
||||
#include "../pnSceneObject/plSceneObject.h"
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
#include "../pnMessage/plObjRefMsg.h"
|
||||
#include "../pnMessage/plFakeOutMsg.h"
|
||||
#include "../pnNetCommon/plNetApp.h"
|
||||
#include "plgDispatch.h"
|
||||
|
||||
|
||||
hsBool plPickingDetector::MsgReceive(plMessage* msg)
|
||||
{
|
||||
|
||||
plObjRefMsg* refMsg = plObjRefMsg::ConvertNoRef(msg);
|
||||
if( refMsg )
|
||||
{
|
||||
if( refMsg->fType == plObjRefMsg::kModifier)
|
||||
{
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
|
||||
{
|
||||
plModifier* mod = plModifier::ConvertNoRef(refMsg->GetRef());
|
||||
SetRemote(mod);
|
||||
}
|
||||
else if( refMsg->GetContext() & (plRefMsg::kOnDestroy|plRefMsg::kOnRemove) )
|
||||
{
|
||||
SetRemote(nil);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
plPickedMsg* pPMsg = plPickedMsg::ConvertNoRef(msg);
|
||||
if (pPMsg)
|
||||
{
|
||||
for (int i = 0; i < fReceivers.Count(); i++)
|
||||
{
|
||||
plActivatorMsg* pMsg = TRACKED_NEW plActivatorMsg;
|
||||
pMsg->AddReceiver( fReceivers[i] );
|
||||
if (pPMsg->fPicked)
|
||||
pMsg->SetTriggerType( plActivatorMsg::kPickedTrigger );
|
||||
else
|
||||
pMsg->SetTriggerType( plActivatorMsg::kUnPickedTrigger );
|
||||
// pass on the hit point
|
||||
pMsg->fHitPoint = pPMsg->fHitPoint;
|
||||
|
||||
if (fProxyKey)
|
||||
pMsg->fPickedObj = fProxyKey;
|
||||
else
|
||||
pMsg->fPickedObj = GetTarget()->GetKey();
|
||||
|
||||
// assume that since this is something that was PICKED that it was done by the local player.
|
||||
plKey locPlayerKey = plNetClientApp::GetInstance()->GetLocalPlayerKey();
|
||||
if (locPlayerKey)
|
||||
pMsg->fHitterObj = locPlayerKey;
|
||||
|
||||
pMsg->SetSender(GetKey());
|
||||
plgDispatch::MsgSend( pMsg );
|
||||
hsStatusMessageF("%s sending activate message to %s\n",GetKey()->GetName(), fReceivers[i]->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
if (RemoteMod() && RemoteMod()->MsgReceive(msg))
|
||||
return true;
|
||||
|
||||
return plDetectorModifier::MsgReceive(msg);
|
||||
}
|
||||
|
82
Sources/Plasma/PubUtilLib/plPhysical/plPickingDetector.h
Normal file
82
Sources/Plasma/PubUtilLib/plPhysical/plPickingDetector.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
|
||||
#ifndef plPickingDetector_inc
|
||||
#define plPickingDetector_inc
|
||||
|
||||
#include "plDetectorModifier.h"
|
||||
|
||||
class plMessage;
|
||||
|
||||
class plPickingDetector : public plDetectorModifier
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
plPickingDetector(){;}
|
||||
virtual ~plPickingDetector(){;}
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
CLASSNAME_REGISTER( plPickingDetector );
|
||||
GETINTERFACE_ANY( plPickingDetector, plDetectorModifier );
|
||||
|
||||
};
|
||||
/*
|
||||
class plClickDragDetector : public plDetectorModifier
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
plPickingDetector(){;}
|
||||
virtual ~plPickingDetector(){;}
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
CLASSNAME_REGISTER( plPickingDetector );
|
||||
GETINTERFACE_ANY( plPickingDetector, plDetectorModifier );
|
||||
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
#endif plPickingDetector_inc
|
122
Sources/Plasma/PubUtilLib/plPhysical/plSimDefs.h
Normal file
122
Sources/Plasma/PubUtilLib/plPhysical/plSimDefs.h
Normal file
@ -0,0 +1,122 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
#ifndef PLSIMDEFS_H
|
||||
#define PLSIMDEFS_H
|
||||
#pragma once
|
||||
|
||||
namespace plSimDefs
|
||||
{
|
||||
// Groups are used to determine what a physical collides with, and what a
|
||||
// detector detects
|
||||
enum Group
|
||||
{
|
||||
// A physical that blocks avatars and dynamics
|
||||
kGroupStatic,
|
||||
// Blocks only avatars
|
||||
kGroupAvatarBlocker,
|
||||
// Blocks only dynamics
|
||||
kGroupDynamicBlocker,
|
||||
// No physical should actually be set to this, since the avatar is
|
||||
// controlled by a special kind of physical. However, you can use this
|
||||
// for detecting.
|
||||
kGroupAvatar,
|
||||
// A physical that can be pushed around by the avatar or other dynamics
|
||||
kGroupDynamic,
|
||||
// A physical that doesn't block anything, but reports on any physical
|
||||
// that enters it
|
||||
kGroupDetector,
|
||||
// Blocks nothing, for los checks only
|
||||
kGroupLOSOnly,
|
||||
//kExcludeRegion setting up so only blocks avatars and only when not in seek mode
|
||||
kGroupExcludeRegion,
|
||||
// A kinematic avatar only interacts with dynamics and detectors
|
||||
kGroupAvatarKinematic,
|
||||
// Just for error checking
|
||||
kGroupMax
|
||||
};
|
||||
|
||||
/** Different types of line-of-sight requests. */
|
||||
enum LOSReqType
|
||||
{
|
||||
// these are MASKS -- keep powers of two
|
||||
kLOS_IgnoreCameraRequest = 0x1,
|
||||
kLOS_IgnoreUIRequest = 0x2,
|
||||
kLOS_CameraAvoidObject = 0x4,
|
||||
|
||||
kLOS_Max = 0xffff // force 16-bit
|
||||
};
|
||||
|
||||
/** Different types of physics shapes. In most cases they dictate how we intepret
|
||||
the raw vertices. In some cases (sphere) they explain why there aren't any vertices */
|
||||
enum Bounds {
|
||||
kBoxBounds = 0x01, // bounding box
|
||||
kSphereBounds, // bounding sphere
|
||||
kHullBounds, // convex hull
|
||||
kProxyBounds, // use alternate proxy geometry
|
||||
kExplicitBounds, // use the primary geometry
|
||||
kNumBounds, // the number of bounds types
|
||||
|
||||
kBoundsMax = 0xff // force 8-bit
|
||||
};
|
||||
|
||||
enum plLOSDB {
|
||||
kLOSDBNone = 0x0000,
|
||||
|
||||
kLOSDBUIBlockers = 0x0001, // things that block ui probes
|
||||
kLOSDBUIItems = 0x0002, // ui items -- we check these first for a hit before checking blockers
|
||||
kLOSDBCameraBlockers = 0x0004, // things that block camera probes
|
||||
kLOSDBCustom = 0x0008, // special things. only the user knows
|
||||
kLOSDBLocalAvatar = 0x0010, // yes, this is silly. it's transitional :)
|
||||
kLOSDBShootableItems = 0x0020, // shootable items, like from the VaporMiner gun
|
||||
|
||||
kLOSDBAvatarWalkable = 0x0040, // stuff the avatar is expected to walk on. Used to prevent sliding and allow
|
||||
// jumping. All terrain automatically goes here.
|
||||
|
||||
kLOSDBSwimRegion = 0x0080,
|
||||
|
||||
kLOSDBMax = 0x0100, // MOVE THIS UP if you add new classes under it. we need it to iterate through the DBs
|
||||
kLOSDBForce16 = 0xffff
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif PLSIMDEFS_H
|
42
Sources/Plasma/PubUtilLib/plPhysical/plSittingModifier.cpp
Normal file
42
Sources/Plasma/PubUtilLib/plPhysical/plSittingModifier.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
// Obsolete
|
42
Sources/Plasma/PubUtilLib/plPhysical/plSittingModifier.h
Normal file
42
Sources/Plasma/PubUtilLib/plPhysical/plSittingModifier.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
// Obsolete
|
Reference in New Issue
Block a user