mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 14:37:41 +00: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:
311
Sources/Plasma/PubUtilLib/plPhysX/plLOSDispatch.cpp
Normal file
311
Sources/Plasma/PubUtilLib/plPhysX/plLOSDispatch.cpp
Normal file
@ -0,0 +1,311 @@
|
||||
/*==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 "plLOSDispatch.h"
|
||||
#include "plSimulationMgr.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "../plMessage/plLOSRequestMsg.h"
|
||||
#include "../plMessage/plLOSHitMsg.h"
|
||||
#include "../pnKeyedObject/plFixedKey.h"
|
||||
#include "../pnSceneObject/plSceneObject.h"
|
||||
#include "../plModifier/plLogicModifier.h"
|
||||
#include "plPXPhysical.h"
|
||||
#include "plPXPhysicalControllerCore.h"
|
||||
#include "plPXConvert.h"
|
||||
|
||||
#include "../plAvatar/plAvatarMgr.h"
|
||||
#include "../plAvatar/plArmatureMod.h"
|
||||
|
||||
#include "NxPhysics.h"
|
||||
|
||||
#include "plProfile.h"
|
||||
plProfile_Extern(LineOfSight);
|
||||
|
||||
class myRaycastReport : public NxUserRaycastReport
|
||||
{
|
||||
public:
|
||||
void InitCast(plSimDefs::plLOSDB db, plLOSRequestMsg::TestType type)
|
||||
{
|
||||
fDB = db;
|
||||
fType = type;
|
||||
fHitObj = nil;
|
||||
fNormal.Set(0, 0, 0);
|
||||
fPoint.Set(0, 0, 0);
|
||||
fDist = FLT_MAX;
|
||||
}
|
||||
|
||||
bool GotHit() { return fDist != FLT_MAX; }
|
||||
plKey GetObj() { return fHitObj; }
|
||||
hsScalar GetDistance() { return fDist; }
|
||||
const hsVector3& GetNormal() { return fNormal; }
|
||||
const hsPoint3& GetPoint() { return fPoint; }
|
||||
void ResetHitObj(){fHitObj=nil;}
|
||||
private:
|
||||
virtual bool onHit(const NxRaycastHit& hit)
|
||||
{
|
||||
NxActor& hitActor = hit.shape->getActor();
|
||||
plPXPhysical* phys = (plPXPhysical*)hitActor.userData;
|
||||
|
||||
plKey objKey = nil;
|
||||
UInt16 objDB = plSimDefs::kLOSDBNone;
|
||||
|
||||
if (phys)
|
||||
{
|
||||
objKey = phys->GetObjectKey();
|
||||
objDB = phys->GetAllLOSDBs();
|
||||
}
|
||||
else
|
||||
{
|
||||
plPXPhysicalControllerCore* controller = plPXPhysicalControllerCore::GetController(hitActor);
|
||||
if (controller)
|
||||
{
|
||||
objKey = controller->GetOwner();
|
||||
objDB = controller->GetLOSDB();
|
||||
}
|
||||
}
|
||||
|
||||
// is the object's physic enabled and is it in the database that we are looking for?
|
||||
if ( !phys || !phys->GetProperty(plSimulationInterface::kDisable) )
|
||||
{
|
||||
if ( (fDB & objDB) != 0)
|
||||
{
|
||||
if (fType == plLOSRequestMsg::kTestAny || hit.distance < fDist)
|
||||
{
|
||||
// need one more test... if it is a clickable need to see if it is enabled
|
||||
bool disabled = false;
|
||||
if ( objKey )
|
||||
{
|
||||
plSceneObject* so = plSceneObject::ConvertNoRef( objKey->GetObjectPtr() );
|
||||
if (so)
|
||||
{
|
||||
int i;
|
||||
for ( i=0; i < so->GetNumModifiers(); i++)
|
||||
{
|
||||
plLogicModifier* lo = (plLogicModifier*)plLogicModifier::ConvertNoRef(so->GetModifier(i) );
|
||||
if (lo)
|
||||
{
|
||||
disabled = lo->Disabled();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!disabled)
|
||||
{
|
||||
fHitObj = objKey;
|
||||
fNormal.Set(hit.worldNormal.x, hit.worldNormal.y, hit.worldNormal.z);
|
||||
fPoint.Set(hit.worldImpact.x, hit.worldImpact.y, hit.worldImpact.z);
|
||||
fDist = hit.distance;
|
||||
|
||||
if (fType == plLOSRequestMsg::kTestAny)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
plSimDefs::plLOSDB fDB;
|
||||
plLOSRequestMsg::TestType fType;
|
||||
|
||||
plKey fHitObj;
|
||||
hsVector3 fNormal;
|
||||
hsPoint3 fPoint;
|
||||
hsScalar fDist;
|
||||
} gMyReport;
|
||||
|
||||
plLOSDispatch::plLOSDispatch()
|
||||
{
|
||||
RegisterAs(kLOSObject_KEY);
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plLOSRequestMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
plLOSDispatch::~plLOSDispatch()
|
||||
{
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plLOSRequestMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
hsBool plLOSDispatch::MsgReceive(plMessage* msg)
|
||||
{
|
||||
|
||||
plLOSRequestMsg* requestMsg = plLOSRequestMsg::ConvertNoRef(msg);
|
||||
if (requestMsg)
|
||||
{
|
||||
plProfile_BeginTiming(LineOfSight);
|
||||
|
||||
plSimulationMgr* sim = plSimulationMgr::GetInstance();
|
||||
|
||||
plKey worldKey = requestMsg->fWorldKey;
|
||||
if (!worldKey)
|
||||
{
|
||||
plArmatureMod* av = plAvatarMgr::GetInstance()->GetLocalAvatar();
|
||||
if ( av && av->GetController() )
|
||||
worldKey = av->GetController()->GetSubworld();
|
||||
}
|
||||
|
||||
hsPoint3 from = requestMsg->fFrom;
|
||||
hsPoint3 at = requestMsg->fTo;
|
||||
|
||||
// requests are always sent in world space, but they might
|
||||
// need to be converted to subworld space
|
||||
hsMatrix44 l2w, w2l;
|
||||
if (worldKey)
|
||||
{
|
||||
plSceneObject* so = plSceneObject::ConvertNoRef(worldKey->ObjectIsLoaded());
|
||||
if (so)
|
||||
{
|
||||
l2w = so->GetLocalToWorld();
|
||||
w2l = so->GetWorldToLocal();
|
||||
from = w2l * from;
|
||||
at = w2l * at;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
l2w.Reset();
|
||||
w2l.Reset();
|
||||
}
|
||||
|
||||
NxScene* scene = sim->GetScene(worldKey);
|
||||
|
||||
gMyReport.InitCast(requestMsg->GetRequestType(), requestMsg->GetTestType());
|
||||
|
||||
hsVector3 norm = hsVector3(at - from);
|
||||
hsScalar dist = norm.Magnitude();
|
||||
norm.Normalize();
|
||||
|
||||
NxRay worldRay;
|
||||
worldRay.dir = plPXConvert::Vector(norm);
|
||||
worldRay.orig = plPXConvert::Point(from);
|
||||
//PhysX will complain to log if ray distance is less than or equal to Zero, besides shouldn't bother throwing
|
||||
// a point, and if we have negative we have some serious problems
|
||||
if(dist>0.0f)
|
||||
{
|
||||
scene->raycastAllShapes(worldRay, gMyReport, NX_ALL_SHAPES, 0xffffffff, dist, NX_RAYCAST_DISTANCE | NX_RAYCAST_IMPACT | NX_RAYCAST_NORMAL);
|
||||
}
|
||||
else{
|
||||
SimLog("%s sent out a LOS request with a ray length of %d.", requestMsg->GetSender()->GetName(), dist);
|
||||
}
|
||||
if (gMyReport.GotHit())
|
||||
{
|
||||
// We got a hit, save off the info
|
||||
plMessage* hitMsg = ICreateHitMsg(requestMsg, l2w);
|
||||
|
||||
if (requestMsg->GetCullDB() != plSimDefs::kLOSDBNone)
|
||||
{
|
||||
// If we have a cull db, adjust the length of the raycast to be from the
|
||||
// original point to the object we hit. If we find anything from the cull
|
||||
// db in there, the cast fails.
|
||||
hsScalar dist = gMyReport.GetDistance();
|
||||
if(dist!=0.0)
|
||||
{
|
||||
gMyReport.InitCast(requestMsg->GetCullDB(), plLOSRequestMsg::kTestAny);
|
||||
scene->raycastAllShapes(worldRay, gMyReport, NX_ALL_SHAPES, 0xffffffff, dist, NX_RAYCAST_DISTANCE | NX_RAYCAST_IMPACT | NX_RAYCAST_NORMAL);
|
||||
|
||||
if (gMyReport.GotHit())
|
||||
{
|
||||
delete hitMsg;
|
||||
hitMsg = nil;
|
||||
|
||||
if (requestMsg->GetReportType() == plLOSRequestMsg::kReportMiss ||
|
||||
requestMsg->GetReportType() == plLOSRequestMsg::kReportHitOrMiss)
|
||||
{
|
||||
ICreateMissMsg(requestMsg)->Send();
|
||||
}
|
||||
}
|
||||
}
|
||||
else// we are right on top of the object I assume that means we hit it
|
||||
{// since PhysX would have complained we will log it anyways. Just so we have a better idea, where this
|
||||
//was happening previously
|
||||
SimLog("%s sent out a LOS request. The second cast for culling was of length 0. ABORTING and assuming hit.", requestMsg->GetSender()->GetName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (hitMsg &&
|
||||
(requestMsg->GetReportType() == plLOSRequestMsg::kReportHit ||
|
||||
requestMsg->GetReportType() == plLOSRequestMsg::kReportHitOrMiss))
|
||||
hitMsg->Send();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (requestMsg->GetReportType() == plLOSRequestMsg::kReportMiss ||
|
||||
requestMsg->GetReportType() == plLOSRequestMsg::kReportHitOrMiss)
|
||||
{
|
||||
ICreateMissMsg(requestMsg)->Send();
|
||||
}
|
||||
}
|
||||
|
||||
plProfile_EndTiming(LineOfSight);
|
||||
gMyReport.ResetHitObj();
|
||||
return true;
|
||||
}
|
||||
|
||||
return hsKeyedObject::MsgReceive(msg);
|
||||
}
|
||||
|
||||
plMessage* plLOSDispatch::ICreateHitMsg(plLOSRequestMsg* requestMsg, hsMatrix44& l2w)
|
||||
{
|
||||
plKey ourKey = GetKey();
|
||||
plKey rcvKey = requestMsg->GetSender();
|
||||
plLOSHitMsg* hitMsg = TRACKED_NEW plLOSHitMsg(ourKey, rcvKey, nil);
|
||||
hitMsg->fNoHit = false;
|
||||
hitMsg->fObj = gMyReport.GetObj();
|
||||
hitMsg->fDistance = gMyReport.GetDistance();
|
||||
hitMsg->fNormal = l2w * gMyReport.GetNormal();
|
||||
hitMsg->fHitPoint = l2w * gMyReport.GetPoint();
|
||||
hitMsg->fRequestID = requestMsg->GetRequestID();
|
||||
return hitMsg;
|
||||
}
|
||||
|
||||
plMessage* plLOSDispatch::ICreateMissMsg(plLOSRequestMsg* requestMsg)
|
||||
{
|
||||
plKey ourKey = GetKey();
|
||||
plKey rcvKey = requestMsg->GetSender();
|
||||
plLOSHitMsg* missMsg = TRACKED_NEW plLOSHitMsg(ourKey, rcvKey, nil);
|
||||
missMsg->fNoHit = true;
|
||||
missMsg->fObj = nil;
|
||||
missMsg->fRequestID = requestMsg->GetRequestID();
|
||||
return missMsg;
|
||||
}
|
67
Sources/Plasma/PubUtilLib/plPhysX/plLOSDispatch.h
Normal file
67
Sources/Plasma/PubUtilLib/plPhysX/plLOSDispatch.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*==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 "../pnKeyedObject/hsKeyedObject.h"
|
||||
|
||||
class plLOSRequestMsg;
|
||||
struct hsMatrix44;
|
||||
|
||||
/** \class plLOSDispatch
|
||||
Line-of-sight requests are sent to this guy, who then hands them
|
||||
to the appropriate solvers, which can vary depending on such
|
||||
criteria as which subworld the player is currently in.
|
||||
Eventually we will have more variants of requests, such as
|
||||
"search all subworlds," etc. */
|
||||
class plLOSDispatch : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
plLOSDispatch();
|
||||
~plLOSDispatch();
|
||||
|
||||
CLASSNAME_REGISTER(plLOSDispatch);
|
||||
GETINTERFACE_ANY(plLOSDispatch, hsKeyedObject);
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
protected:
|
||||
plMessage* ICreateHitMsg(plLOSRequestMsg* requestMsg, hsMatrix44& l2w);
|
||||
plMessage* ICreateMissMsg(plLOSRequestMsg* requestMsg);
|
||||
};
|
82
Sources/Plasma/PubUtilLib/plPhysX/plPXConvert.cpp
Normal file
82
Sources/Plasma/PubUtilLib/plPhysX/plPXConvert.cpp
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==*/
|
||||
#include "plPXConvert.h"
|
||||
|
||||
bool plPXConvert::Validate()
|
||||
{
|
||||
NxVec3 nxVec;
|
||||
hsVector3 plVec;
|
||||
|
||||
int nxVecXOffset = ((char*)&nxVec.x) - ((char*)&nxVec);
|
||||
int nxVecYOffset = ((char*)&nxVec.y) - ((char*)&nxVec);
|
||||
int nxVecZOffset = ((char*)&nxVec.z) - ((char*)&nxVec);
|
||||
|
||||
int plVecXOffset = ((char*)&plVec.fX) - ((char*)&plVec);
|
||||
int plVecYOffset = ((char*)&plVec.fY) - ((char*)&plVec);
|
||||
int plVecZOffset = ((char*)&plVec.fZ) - ((char*)&plVec);
|
||||
|
||||
NxQuat nxQuat;
|
||||
hsQuat plQuat;
|
||||
|
||||
int nxQuatXOffset = ((char*)&nxQuat.x) - ((char*)&nxQuat);
|
||||
int nxQuatYOffset = ((char*)&nxQuat.y) - ((char*)&nxQuat);
|
||||
int nxQuatZOffset = ((char*)&nxQuat.z) - ((char*)&nxQuat);
|
||||
int nxQuatWOffset = ((char*)&nxQuat.w) - ((char*)&nxQuat);
|
||||
|
||||
int plQuatXOffset = ((char*)&plQuat.fX) - ((char*)&plQuat);
|
||||
int plQuatYOffset = ((char*)&plQuat.fY) - ((char*)&plQuat);
|
||||
int plQuatZOffset = ((char*)&plQuat.fZ) - ((char*)&plQuat);
|
||||
int plQuatWOffset = ((char*)&plQuat.fW) - ((char*)&plQuat);
|
||||
|
||||
bool offsetsOK =
|
||||
nxVecXOffset == plVecXOffset &&
|
||||
nxVecYOffset == plVecYOffset &&
|
||||
nxVecZOffset == plVecZOffset &&
|
||||
nxQuatXOffset == plQuatXOffset &&
|
||||
nxQuatYOffset == plQuatYOffset &&
|
||||
nxQuatZOffset == plQuatZOffset &&
|
||||
nxQuatWOffset == plQuatWOffset;
|
||||
|
||||
hsAssert(offsetsOK, "PhysX or Plasma offsets have changed, need to rewrite conversion code");
|
||||
|
||||
return offsetsOK;
|
||||
}
|
79
Sources/Plasma/PubUtilLib/plPhysX/plPXConvert.h
Normal file
79
Sources/Plasma/PubUtilLib/plPhysX/plPXConvert.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*==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 plPXConvert_h_inc
|
||||
#define plPXConvert_h_inc
|
||||
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsQuat.h"
|
||||
#include "hsMatrix44.h"
|
||||
|
||||
#include "NxVec3.h"
|
||||
#include "NxQuat.h"
|
||||
#include "NxMat34.h"
|
||||
|
||||
// Converts to and from the PhysX types
|
||||
namespace plPXConvert
|
||||
{
|
||||
// The following conversions are just casts, due to the fact that the Plasma
|
||||
// and PhysX vector and quat classes don't have any virtual fuctions and have
|
||||
// all their data in the same offsets.
|
||||
inline NxVec3& Point(hsPoint3& vec) { return *((NxVec3*)&vec); }
|
||||
inline const NxVec3& Point(const hsPoint3& vec) { return *((NxVec3*)&vec); }
|
||||
inline hsPoint3& Point(NxVec3& vec) { return *((hsPoint3*)&vec); }
|
||||
inline const hsPoint3& Point(const NxVec3& vec) { return *((hsPoint3*)&vec); }
|
||||
|
||||
inline NxVec3& Vector(hsVector3& vel) { return *((NxVec3*)&vel); }
|
||||
inline const NxVec3& Vector(const hsVector3& vel){ return *((NxVec3*)&vel); }
|
||||
inline hsVector3& Vector(NxVec3& vec) { return *((hsVector3*)&vec); }
|
||||
inline const hsVector3& Vector(const NxVec3& vec) { return *((hsVector3*)&vec); }
|
||||
|
||||
inline const NxQuat& Quat(const hsQuat& quat) { return *((NxQuat*)&quat); }
|
||||
inline const hsQuat& Quat(const NxQuat& quat) { return *((hsQuat*)&quat); }
|
||||
|
||||
// The matrix data doesn't match up, so we have to convert it
|
||||
inline void Matrix(const hsMatrix44& fromMat, NxMat34& toMat) { toMat.setRowMajor44(&fromMat.fMap[0][0]); }
|
||||
inline void Matrix(const NxMat34& fromMat, hsMatrix44& toMat) { toMat.NotIdentity(); fromMat.getRowMajor44(&toMat.fMap[0][0]); }
|
||||
|
||||
bool Validate();
|
||||
};
|
||||
|
||||
#endif // plPXConvert_h_inc
|
1567
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.cpp
Normal file
1567
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.cpp
Normal file
File diff suppressed because it is too large
Load Diff
296
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.h
Normal file
296
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.h
Normal file
@ -0,0 +1,296 @@
|
||||
/*==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 plPXPhysical_h_inc
|
||||
#define plPXPhysical_h_inc
|
||||
|
||||
#include "plPhysical.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "../plPhysical/plSimDefs.h"
|
||||
#include "hsBitVector.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
class NxActor;
|
||||
class NxConvexMesh;
|
||||
class NxTriangleMesh;
|
||||
|
||||
struct hsPoint3;
|
||||
class hsQuat;
|
||||
class plPhysicalProxy;
|
||||
class plDrawableSpans;
|
||||
class hsGMaterial;
|
||||
struct hsPlane3;
|
||||
|
||||
class plMessage;
|
||||
class plLOSHit;
|
||||
class plSimulationMsg;
|
||||
class plSDLModifier;
|
||||
class plPhysicalSndGroup;
|
||||
class plGenRefMsg;
|
||||
class plSceneObject;
|
||||
class hsVectorStream;
|
||||
class NxCapsule;
|
||||
|
||||
class PhysRecipe
|
||||
{
|
||||
public:
|
||||
PhysRecipe();
|
||||
|
||||
hsScalar mass;
|
||||
hsScalar friction;
|
||||
hsScalar restitution;
|
||||
plSimDefs::Bounds bounds;
|
||||
plSimDefs::Group group;
|
||||
UInt32 reportsOn;
|
||||
plKey objectKey;
|
||||
plKey sceneNode;
|
||||
plKey worldKey;
|
||||
|
||||
// The local to subworld matrix (or local to world if worldKey is nil)
|
||||
hsMatrix44 l2s;
|
||||
|
||||
NxConvexMesh* convexMesh;
|
||||
NxTriangleMesh* triMesh;
|
||||
|
||||
// For spheres only
|
||||
hsScalar radius;
|
||||
hsPoint3 offset;
|
||||
|
||||
// For Boxes
|
||||
hsPoint3 bDimensions;
|
||||
hsPoint3 bOffset;
|
||||
|
||||
// For export time only. The original data used to create the mesh
|
||||
hsVectorStream* meshStream;
|
||||
};
|
||||
|
||||
class plPXPhysical : public plPhysical
|
||||
{
|
||||
public:
|
||||
friend class plSimulationMgr;
|
||||
|
||||
enum PhysRefType
|
||||
{
|
||||
kPhysRefWorld,
|
||||
kPhysRefSndGroup
|
||||
};
|
||||
|
||||
plPXPhysical();
|
||||
virtual ~plPXPhysical();
|
||||
|
||||
CLASSNAME_REGISTER(plPXPhysical);
|
||||
GETINTERFACE_ANY(plPXPhysical, plPhysical);
|
||||
|
||||
// Export time and internal use only
|
||||
hsBool Init(PhysRecipe& recipe);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
//
|
||||
// From plPhysical
|
||||
//
|
||||
virtual plPhysical& SetProperty(int prop, hsBool b);
|
||||
virtual hsBool GetProperty(int prop) const { return fProps.IsBitSet(prop) != 0; }
|
||||
|
||||
virtual void SetObjectKey(plKey key) { fObjectKey = key; }
|
||||
virtual plKey GetObjectKey() const { return fObjectKey; }
|
||||
|
||||
virtual void SetSceneNode(plKey node);
|
||||
virtual plKey GetSceneNode() const;
|
||||
|
||||
virtual hsBool GetLinearVelocitySim(hsVector3& vel) const;
|
||||
virtual void SetLinearVelocitySim(const hsVector3& vel);
|
||||
virtual void ClearLinearVelocity();
|
||||
|
||||
virtual hsBool GetAngularVelocitySim(hsVector3& vel) const;
|
||||
virtual void SetAngularVelocitySim(const hsVector3& vel);
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l, hsBool force=false);
|
||||
virtual void GetTransform(hsMatrix44& l2w, hsMatrix44& w2l);
|
||||
|
||||
virtual int GetGroup() const { return fGroup; }
|
||||
|
||||
virtual void AddLOSDB(UInt16 flag) { hsSetBits(fLOSDBs, flag); }
|
||||
virtual void RemoveLOSDB(UInt16 flag) { hsClearBits(fLOSDBs, flag); }
|
||||
virtual UInt16 GetAllLOSDBs() { return fLOSDBs; }
|
||||
virtual hsBool IsInLOSDB(UInt16 flag) { return hsCheckBits(fLOSDBs, flag); }
|
||||
|
||||
virtual hsBool DoDetectorHullWorkaround() { return fSaveTriangles ? true : false; }
|
||||
virtual hsBool Should_I_Trigger(hsBool enter, hsPoint3& pos);
|
||||
virtual hsBool IsObjectInsideHull(const hsPoint3& pos);
|
||||
virtual void SetInsideConvexHull(hsBool inside) { fInsideConvexHull = inside; }
|
||||
|
||||
virtual plKey GetWorldKey() const { return fWorldKey; }
|
||||
|
||||
virtual plPhysicalSndGroup* GetSoundGroup() const { return fSndGroup; }
|
||||
|
||||
virtual void GetPositionSim(hsPoint3& pos) const { IGetPositionSim(pos); }
|
||||
|
||||
virtual void SendNewLocation(hsBool synchTransform = false, hsBool isSynchUpdate = false);
|
||||
|
||||
virtual void SetHitForce(const hsVector3& force, const hsPoint3& pos) { fWeWereHit=true; fHitForce = force; fHitPos = pos; }
|
||||
virtual void ApplyHitForce();
|
||||
virtual void ResetHitForce() { fWeWereHit=false; fHitForce.Set(0,0,0); fHitPos.Set(0,0,0); }
|
||||
|
||||
virtual void GetSyncState(hsPoint3& pos, hsQuat& rot, hsVector3& linV, hsVector3& angV);
|
||||
virtual void SetSyncState(hsPoint3* pos, hsQuat* rot, hsVector3* linV, hsVector3* angV);
|
||||
|
||||
virtual void ExcludeRegionHack(hsBool cleared);
|
||||
|
||||
virtual plDrawableSpans* CreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo);
|
||||
|
||||
hsBool DoReportOn(plSimDefs::Group group) const { return hsCheckBits(fReportsOn, 1<<group); }
|
||||
|
||||
// Returns true if this object is *really* dynamic. We can have physicals
|
||||
// that are in the dynamic group but are actually animated or something.
|
||||
// This weeds those out.
|
||||
hsBool IsDynamic() const;
|
||||
|
||||
//Hack to check if there is an overlap with the capsule
|
||||
//this partially for exclude regions vs avatar capsule
|
||||
virtual hsBool OverlapWithCapsule(NxCapsule& cap);
|
||||
|
||||
virtual hsScalar GetMass() {return fMass;}
|
||||
protected:
|
||||
class NxConvexMesh* IReadHull(hsStream* s);
|
||||
class NxTriangleMesh* IReadTriMesh(hsStream* s);
|
||||
|
||||
void IGetPositionSim(hsPoint3& pos) const;
|
||||
void IGetRotationSim(hsQuat& rot) const;
|
||||
void ISetPositionSim(const hsPoint3& pos);
|
||||
void ISetRotationSim(const hsQuat& rot);
|
||||
|
||||
/** Handle messages about our references. */
|
||||
hsBool HandleRefMsg(plGenRefMsg * refM);
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WORLDS, SUBWORLDS && CONTEXTS
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
void IConvertGroups(UInt32 memberOf, UInt32 reportsOn, UInt32 collideWith);
|
||||
|
||||
/** See if the object is in a valid, non-overlapping position.
|
||||
A valid overlap is one which is approved by the collision
|
||||
masking code, i.e. my memberOf has no intersection with your
|
||||
bounceOff and vice-versa
|
||||
*/
|
||||
// Set overlapText to get a string naming all the overlapping physicals (that you must delete)
|
||||
hsBool CheckValidPosition(char** overlapText=nil);
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// NETWORK SYNCHRONIZATION
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
/** Remember that we need to do a synch soon. */
|
||||
hsBool DirtySynchState(const char* SDLStateName, UInt32 synchFlags );
|
||||
|
||||
double GetLastSyncTime() { return fLastSyncTime; }
|
||||
|
||||
/** Get the simulation transform of the physical, in world
|
||||
coordinates (factoring in the subworld if necessary */
|
||||
void IGetTransformGlobal(hsMatrix44 &l2w) const;
|
||||
void ISetTransformGlobal(const hsMatrix44& l2w);
|
||||
|
||||
// Enable/disable collisions and dynamic movement
|
||||
void IEnable(hsBool enable);
|
||||
|
||||
void IMakeHull(NxConvexMesh* convexMesh, hsMatrix44 l2w);
|
||||
|
||||
NxActor* fActor;
|
||||
plKey fWorldKey; // either a subworld or nil
|
||||
|
||||
plSimDefs::Bounds fBoundsType;
|
||||
plSimDefs::Group fGroup;
|
||||
UInt32 fReportsOn; // bit vector for groups we report interactions with
|
||||
UInt16 fLOSDBs; // Which LOS databases we get put into
|
||||
hsBitVector fProps; // plSimulationInterface::plSimulationProperties kept here
|
||||
float fMass;
|
||||
|
||||
plKey fObjectKey; // the key to our scene object
|
||||
plKey fSceneNode; // the room we're in
|
||||
|
||||
// PHYSX FIXME - need to create a plasma hull so that we can determine if inside
|
||||
hsPlane3* fWorldHull;
|
||||
UInt32 fHullNumberPlanes;
|
||||
hsPoint3* fSaveTriangles;
|
||||
hsBool fInsideConvexHull;
|
||||
void ISetHullToWorldWTriangles();
|
||||
inline hsBool ITestPlane(const hsPoint3 &pos, const hsPlane3 &plane)
|
||||
{
|
||||
hsScalar dis = plane.fN.InnerProduct(pos);
|
||||
dis += plane.fD;
|
||||
if (dis == 0.f)
|
||||
return false;
|
||||
if( dis >= 0.f )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// we need to remember the last matrices we sent to the coordinate interface
|
||||
// so that we can recognize them when we send them back and not reapply them,
|
||||
// which would reactivate our body. inelegant but effective
|
||||
hsMatrix44 fCachedLocal2World;
|
||||
|
||||
// Syncronization
|
||||
double fLastSyncTime;
|
||||
plSDLModifier* fSDLMod;
|
||||
|
||||
plPhysicalSndGroup* fSndGroup;
|
||||
|
||||
hsBool fWeWereHit;
|
||||
hsVector3 fHitForce;
|
||||
hsPoint3 fHitPos;
|
||||
|
||||
plPhysicalProxy* fProxyGen; // visual proxy for debugging
|
||||
|
||||
static int fNumberAnimatedPhysicals;
|
||||
static int fNumberAnimatedActivators;
|
||||
};
|
||||
|
||||
#endif
|
882
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysicalControllerCore.cpp
Normal file
882
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysicalControllerCore.cpp
Normal file
@ -0,0 +1,882 @@
|
||||
/*==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 "plPXPhysicalControllerCore.h"
|
||||
#include "plSimulationMgr.h"
|
||||
#include "plPXPhysical.h"
|
||||
#include "plPXConvert.h"
|
||||
#include "../pnSceneObject/plSimulationInterface.h"
|
||||
#include "../pnSceneObject/plSceneObject.h"
|
||||
#include "../plAvatar/plArmatureMod.h"
|
||||
#include "../pnSceneObject/plCoordinateInterface.h"
|
||||
#include "../plDrawable/plDrawableGenerator.h"
|
||||
#include "../plPhysical/plPhysicalProxy.h"
|
||||
#include "../pnMessage/plSetNetGroupIDMsg.h"
|
||||
#include "../plMessage/plCollideMsg.h"
|
||||
#include "../plModifier/plDetectorLog.h"
|
||||
|
||||
#include "../plSurface/hsGMaterial.h" // For our proxy
|
||||
#include "../plSurface/plLayerInterface.h" // For our proxy
|
||||
|
||||
#include "NxPhysics.h"
|
||||
#include "NxCapsuleController.h"
|
||||
#include "NxCapsuleShape.h"
|
||||
#include "ControllerManager.h"
|
||||
|
||||
static ControllerManager gControllerMgr;
|
||||
static std::vector<plPXPhysicalControllerCore*> gControllers;
|
||||
static bool gRebuildCache = false;
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
hsBool plPXPhysicalControllerCore::fDebugDisplay = false;
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
int plPXPhysicalControllerCore::fPXControllersMax = 0;
|
||||
|
||||
#define kCCTSkinWidth 0.1f
|
||||
#define kCCTStepOffset 0.7f
|
||||
#define kCCTZOffset ((fRadius + (fHeight / 2)) + kCCTSkinWidth)
|
||||
#define kPhysHeightCorrection 0.8f
|
||||
#define kPhysZOffset ((kCCTZOffset + (kPhysHeightCorrection / 2)) - 0.05f)
|
||||
#define kAvatarMass 200.0f
|
||||
|
||||
static class PXControllerHitReport : public NxUserControllerHitReport
|
||||
{
|
||||
public:
|
||||
virtual NxControllerAction onShapeHit(const NxControllerShapeHit& hit)
|
||||
{
|
||||
plPXPhysicalControllerCore* controller = (plPXPhysicalControllerCore*)hit.controller->getUserData();
|
||||
NxActor& actor = hit.shape->getActor();
|
||||
plPXPhysical* phys = (plPXPhysical*)actor.userData;
|
||||
hsVector3 normal = plPXConvert::Vector(hit.worldNormal);
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
plDbgCollisionInfo info;
|
||||
info.fNormal = normal;
|
||||
info.fSO = plSceneObject::ConvertNoRef(phys->GetObjectKey()->ObjectIsLoaded());
|
||||
|
||||
NxCapsule capsule;
|
||||
controller->GetWorldSpaceCapsule(capsule);
|
||||
info.fOverlap = hit.shape->checkOverlapCapsule(capsule);
|
||||
|
||||
controller->fDbgCollisionInfo.Append(info);
|
||||
#endif PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
// If the avatar hit a movable physical, apply some force to it.
|
||||
if (actor.isDynamic())
|
||||
{
|
||||
if (!actor.readBodyFlag(NX_BF_KINEMATIC) && !actor.readBodyFlag(NX_BF_FROZEN))
|
||||
{
|
||||
// Don't apply force when standing on top of an object.
|
||||
if (normal.fZ < 0.85f)
|
||||
{
|
||||
hsVector3 velocity = controller->GetLinearVelocity();
|
||||
velocity.fZ = 0.0f;
|
||||
float length = velocity.Magnitude();
|
||||
if (length > 0)
|
||||
{
|
||||
// Only allow horizontal pushes for now
|
||||
NxVec3 hitDir = hit.worldPos - hit.controller->getPosition();
|
||||
hitDir.z = 0.0f;
|
||||
hitDir.normalize();
|
||||
|
||||
// Get controller speed along the hitDir
|
||||
float cctProj = velocity.fX * hitDir.x + velocity.fY * hitDir.y;
|
||||
length = length + cctProj / 2.0f;
|
||||
|
||||
// Get hit actors speed along the hitDir
|
||||
float hitProj = actor.getLinearVelocity().dot(hitDir);
|
||||
if (hitProj > 0)
|
||||
length -= hitProj;
|
||||
|
||||
length *= kAvatarMass;
|
||||
|
||||
hsPoint3 pos((float)hit.worldPos.x, (float)hit.worldPos.y, (float)hit.worldPos.z);
|
||||
phys->SetHitForce(plPXConvert::Vector(hitDir * length), pos);
|
||||
controller->AddDynamicHit(phys);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // else if the avatar hit a static
|
||||
{
|
||||
controller->fMovementStrategy->AddContactNormals(normal);
|
||||
return NX_ACTION_NONE;
|
||||
}
|
||||
if (phys && phys->GetProperty(plSimulationInterface::kAvAnimPushable))
|
||||
{
|
||||
hsQuat inverseRotation = controller->fLocalRotation.Inverse();
|
||||
hsVector3 normal = plPXConvert::Vector(hit.worldNormal);
|
||||
controller->SetPushingPhysical(phys);
|
||||
controller->SetFacingPushingPhysical((inverseRotation.Rotate(&kAvatarForward).InnerProduct(normal) < 0 ? true : false));
|
||||
}
|
||||
return NX_ACTION_NONE;
|
||||
}
|
||||
virtual NxControllerAction onControllerHit(const NxControllersHit& hit)
|
||||
{
|
||||
return NX_ACTION_NONE;
|
||||
}
|
||||
} gControllerHitReport;
|
||||
|
||||
plPhysicalControllerCore* plPhysicalControllerCore::Create(plKey ownerSO, hsScalar height, hsScalar width, bool human)
|
||||
{
|
||||
if (!plPXPhysicalControllerCore::fPXControllersMax || gControllers.size() < plPXPhysicalControllerCore::fPXControllersMax)
|
||||
{
|
||||
hsScalar radius = width / 2.0f;
|
||||
hsScalar realHeight = height - width;
|
||||
return TRACKED_NEW plPXPhysicalControllerCore(ownerSO, realHeight, radius, human);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
plPXPhysicalControllerCore::plPXPhysicalControllerCore(plKey ownerSO, hsScalar height, hsScalar radius, bool human)
|
||||
: plPhysicalControllerCore(ownerSO, height, radius),
|
||||
fController(nil),
|
||||
fActor(nil),
|
||||
fProxyGen(nil),
|
||||
fKinematicCCT(true),
|
||||
fHuman(human)
|
||||
{
|
||||
ICreateController(fLocalPosition);
|
||||
fActor->raiseActorFlag(NX_AF_DISABLE_COLLISION);
|
||||
gControllers.push_back(this);
|
||||
}
|
||||
plPXPhysicalControllerCore::~plPXPhysicalControllerCore()
|
||||
{
|
||||
int numControllers = gControllers.size();
|
||||
for (int i = 0; i < numControllers; ++i)
|
||||
{
|
||||
if (gControllers[i] == this)
|
||||
{
|
||||
gControllers.erase(gControllers.begin()+i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
IDeleteController();
|
||||
|
||||
// Release any queued messages we may have
|
||||
int numMsgs = fQueuedCollideMsgs.size();
|
||||
if (numMsgs)
|
||||
{
|
||||
for (int i = 0; i < numMsgs; ++i)
|
||||
delete fQueuedCollideMsgs[i];
|
||||
|
||||
fQueuedCollideMsgs.clear();
|
||||
}
|
||||
|
||||
delete fProxyGen;
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::Enable(bool enable)
|
||||
{
|
||||
if (fEnabled != enable)
|
||||
{
|
||||
fEnabled = enable;
|
||||
if (fEnabled)
|
||||
{
|
||||
// Defer until the next physics update.
|
||||
fEnableChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fKinematicCCT)
|
||||
{
|
||||
// Dynamic controllers are forced kinematic
|
||||
fActor->raiseBodyFlag(NX_BF_KINEMATIC);
|
||||
NxShape* shape = fActor->getShapes()[0];
|
||||
shape->setGroup(plSimDefs::kGroupAvatarKinematic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::SetSubworld(plKey world)
|
||||
{
|
||||
if (fWorldKey != world)
|
||||
{
|
||||
SimLog("Changing subworlds!");
|
||||
|
||||
// Inform detectors in the old world that we are leaving
|
||||
IInformDetectors(false);
|
||||
IDeleteController();
|
||||
|
||||
// We need our real global location here, not the interpolated location
|
||||
fLocalRotation.MakeMatrix(&fLastGlobalLoc);
|
||||
fLastGlobalLoc.SetTranslate(&fLocalPosition);
|
||||
if (fWorldKey)
|
||||
{
|
||||
hsMatrix44 prevSubL2W;
|
||||
fPrevSubworldW2L.GetInverse(&prevSubL2W);
|
||||
fLastGlobalLoc = prevSubL2W * fLastGlobalLoc;
|
||||
}
|
||||
// Update our scene object so the change isn't wiped out
|
||||
plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
|
||||
if (so)
|
||||
{
|
||||
hsMatrix44 globalLocInv;
|
||||
fLastGlobalLoc.GetInverse(&globalLocInv);
|
||||
so->SetTransform(fLastGlobalLoc, globalLocInv);
|
||||
so->FlushTransform();
|
||||
}
|
||||
|
||||
// Update Local Position and rotation
|
||||
fWorldKey = world;
|
||||
const plCoordinateInterface* subworldCI = GetSubworldCI();
|
||||
if (subworldCI)
|
||||
{
|
||||
fPrevSubworldW2L = subworldCI->GetWorldToLocal();
|
||||
hsMatrix44 l2s = fPrevSubworldW2L * fLastGlobalLoc;
|
||||
l2s.GetTranslate(&fLocalPosition);
|
||||
fLocalRotation.SetFromMatrix44(l2s);
|
||||
}
|
||||
else
|
||||
{
|
||||
fPrevSubworldW2L.Reset();
|
||||
fLastGlobalLoc.GetTranslate(&fLocalPosition);
|
||||
fLocalRotation.SetFromMatrix44(fLastGlobalLoc);
|
||||
}
|
||||
|
||||
fLastLocalPosition = fLocalPosition;
|
||||
|
||||
// Create new controller
|
||||
ICreateController(fLocalPosition);
|
||||
RebuildCache();
|
||||
}
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::GetState(hsPoint3& pos, float& zRot)
|
||||
{
|
||||
// Temporarily use the position point while we get the z rotation
|
||||
fLocalRotation.NormalizeIfNeeded();
|
||||
fLocalRotation.GetAngleAxis(&zRot, (hsVector3*)&pos);
|
||||
|
||||
if (pos.fZ < 0)
|
||||
zRot = (2 * hsScalarPI) - zRot; // axis is backwards, so reverse the angle too
|
||||
|
||||
pos = fLocalPosition;
|
||||
}
|
||||
void plPXPhysicalControllerCore::SetState(const hsPoint3& pos, float zRot)
|
||||
{
|
||||
plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
|
||||
if (so)
|
||||
{
|
||||
hsQuat worldRot;
|
||||
hsVector3 zAxis(0.f, 0.f, 1.f);
|
||||
worldRot.SetAngleAxis(zRot, zAxis);
|
||||
|
||||
hsMatrix44 l2w, w2l;
|
||||
worldRot.MakeMatrix(&l2w);
|
||||
l2w.SetTranslate(&pos);
|
||||
|
||||
// Localize new position and rotation to global coords if we're in a subworld
|
||||
const plCoordinateInterface* ci = GetSubworldCI();
|
||||
if (ci)
|
||||
{
|
||||
const hsMatrix44& subworldL2W = ci->GetLocalToWorld();
|
||||
l2w = subworldL2W * l2w;
|
||||
}
|
||||
l2w.GetInverse(&w2l);
|
||||
so->SetTransform(l2w, w2l);
|
||||
so->FlushTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::SetMovementStrategy(plMovementStrategy* strategy)
|
||||
{
|
||||
if (fKinematicCCT != strategy->IsKinematic())
|
||||
{
|
||||
IDeleteController();
|
||||
fKinematicCCT = !fKinematicCCT;
|
||||
ICreateController(fLocalPosition);
|
||||
}
|
||||
|
||||
fMovementStrategy = strategy;
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::SetGlobalLoc(const hsMatrix44& l2w)
|
||||
{
|
||||
fLastGlobalLoc = l2w;
|
||||
|
||||
// Update our local position and rotation
|
||||
hsPoint3 prevPosition = fLocalPosition;
|
||||
const plCoordinateInterface* subworldCI = GetSubworldCI();
|
||||
if (subworldCI)
|
||||
{
|
||||
hsMatrix44 l2s = fPrevSubworldW2L * l2w;
|
||||
|
||||
l2s.GetTranslate(&fLocalPosition);
|
||||
fLocalRotation.SetFromMatrix44(l2s);
|
||||
}
|
||||
else
|
||||
{
|
||||
l2w.GetTranslate(&fLocalPosition);
|
||||
fLocalRotation.SetFromMatrix44(l2w);
|
||||
}
|
||||
|
||||
fLastLocalPosition = fLocalPosition;
|
||||
|
||||
if (fProxyGen)
|
||||
{
|
||||
hsMatrix44 w2l;
|
||||
l2w.GetInverse(&w2l);
|
||||
fProxyGen->SetTransform(l2w, w2l);
|
||||
}
|
||||
|
||||
// Update the physical position
|
||||
if (fKinematicCCT)
|
||||
{
|
||||
hsVector3 disp(&fLocalPosition, &prevPosition);
|
||||
if (disp.Magnitude() > 2.f)
|
||||
{
|
||||
// Teleport the underlying actor most of the way
|
||||
disp.Normalize();
|
||||
disp *= 0.001f;
|
||||
|
||||
hsPoint3 teleportPos = fLocalPosition - disp;
|
||||
NxVec3 pos(teleportPos.fX, teleportPos.fY, teleportPos.fZ + kPhysZOffset);
|
||||
fActor->setGlobalPosition(pos);
|
||||
}
|
||||
|
||||
NxExtendedVec3 extPos(fLocalPosition.fX, fLocalPosition.fY, fLocalPosition.fZ + kCCTZOffset);
|
||||
fController->setPosition(extPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
NxVec3 pos(fLocalPosition.fX, fLocalPosition.fY, fLocalPosition.fZ + kPhysZOffset);
|
||||
if (fActor->readBodyFlag(NX_BF_KINEMATIC))
|
||||
fActor->moveGlobalPosition(pos);
|
||||
else
|
||||
fActor->setGlobalPosition(pos);
|
||||
}
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::GetPositionSim(hsPoint3& pos)
|
||||
{
|
||||
if (fKinematicCCT)
|
||||
{
|
||||
const NxExtendedVec3& extPos = fController->getPosition();
|
||||
pos.Set((hsScalar)extPos.x, (hsScalar)extPos.y, (hsScalar)extPos.z - kCCTZOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
NxVec3 nxPos = fActor->getGlobalPosition();
|
||||
pos.Set(nxPos.x, nxPos.y, nxPos.z - kPhysZOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::Move(hsVector3 displacement, unsigned int collideWith, unsigned int &collisionResults)
|
||||
{
|
||||
NxU32 colFlags = 0;
|
||||
|
||||
fController->move(plPXConvert::Vector(displacement), collideWith, 0.00001f, colFlags);
|
||||
|
||||
collisionResults = 0;
|
||||
if (colFlags & NXCC_COLLISION_DOWN)
|
||||
collisionResults |= kBottom;
|
||||
if (colFlags & NXCC_COLLISION_UP)
|
||||
collisionResults |= kTop;
|
||||
if (colFlags & NXCC_COLLISION_SIDES)
|
||||
collisionResults |= kSides;
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::SetLinearVelocitySim(const hsVector3& linearVel)
|
||||
{
|
||||
if (!fKinematicCCT)
|
||||
{
|
||||
NxVec3 vel = plPXConvert::Vector(linearVel);
|
||||
fActor->setLinearVelocity(vel);
|
||||
}
|
||||
}
|
||||
|
||||
int plPXPhysicalControllerCore::SweepControllerPath(const hsPoint3& startPos, const hsPoint3& endPos, hsBool vsDynamics, hsBool vsStatics,
|
||||
UInt32& vsSimGroups, std::vector<plControllerSweepRecord>& hits)
|
||||
{
|
||||
NxSweepQueryHit queryHit[10];
|
||||
|
||||
unsigned int flags = NX_SF_ALL_HITS;
|
||||
if (vsDynamics)
|
||||
flags |= NX_SF_DYNAMICS;
|
||||
if (vsStatics)
|
||||
flags |= NX_SF_STATICS;
|
||||
|
||||
NxVec3 vec;
|
||||
vec.x = endPos.fX - startPos.fX;
|
||||
vec.y = endPos.fY - startPos.fY;
|
||||
vec.z = endPos.fZ - startPos.fZ;
|
||||
|
||||
NxShape* shape = fActor->getShapes()[0];
|
||||
NxCapsuleShape* capShape = shape->isCapsule();
|
||||
float radius = capShape->getRadius();
|
||||
float height = capShape->getHeight();
|
||||
|
||||
NxCapsule capsule;
|
||||
capsule.p0 = plPXConvert::Point(startPos);
|
||||
capsule.p0.z = capsule.p0.z + radius;
|
||||
capsule.radius = radius;
|
||||
capsule.p1 = capsule.p0;
|
||||
capsule.p1.z = capsule.p1.z + height;
|
||||
|
||||
NxScene *scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey);
|
||||
int numHits = scene->linearCapsuleSweep(capsule, vec, flags, nil, 10, queryHit, nil, vsSimGroups);
|
||||
if (numHits)
|
||||
{
|
||||
for (int i = 0; i < numHits; ++i)
|
||||
{
|
||||
plControllerSweepRecord currentHit;
|
||||
currentHit.ObjHit = (plPhysical*)queryHit[i].hitShape->getActor().userData;
|
||||
if (currentHit.ObjHit)
|
||||
{
|
||||
currentHit.Point = plPXConvert::Point(queryHit[i].point);
|
||||
currentHit.Normal = plPXConvert::Vector(queryHit[i].normal);
|
||||
hits.push_back(currentHit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hits.size();
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::LeaveAge()
|
||||
{
|
||||
SetPushingPhysical(nil);
|
||||
if (fWorldKey)
|
||||
SetSubworld(nil);
|
||||
|
||||
// Disable all collisions
|
||||
fActor->raiseActorFlag(NX_AF_DISABLE_COLLISION);
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::GetWorldSpaceCapsule(NxCapsule& cap) const
|
||||
{
|
||||
NxShape* shape = fActor->getShapes()[0];
|
||||
NxCapsuleShape* capShape = shape->isCapsule();
|
||||
capShape->getWorldCapsule(cap);
|
||||
}
|
||||
|
||||
plDrawableSpans* plPXPhysicalControllerCore::CreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo)
|
||||
{
|
||||
// FIXME
|
||||
plDrawableSpans* myDraw = addTo;
|
||||
hsBool blended = ((mat->GetLayer(0)->GetBlendFlags() & hsGMatState::kBlendMask));
|
||||
float radius = fRadius;
|
||||
myDraw = plDrawableGenerator::GenerateSphericalDrawable(fLocalPosition, radius,
|
||||
mat, fLastGlobalLoc, blended,
|
||||
nil, &idx, myDraw);
|
||||
|
||||
/*
|
||||
plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
|
||||
if (so)
|
||||
{
|
||||
hsBool blended = ((mat->GetLayer(0)->GetBlendFlags() & hsGMatState::kBlendMask));
|
||||
|
||||
myDraw = plDrawableGenerator::GenerateConicalDrawable(fRadius*10, fHeight*10,
|
||||
mat, so->GetLocalToWorld(), blended,
|
||||
nil, &idx, myDraw);
|
||||
}
|
||||
*/
|
||||
return myDraw;
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::AddDynamicHit(plPXPhysical* phys)
|
||||
{
|
||||
int numHits = fDynamicHits.size();
|
||||
for (int i = 0; i < numHits; ++i)
|
||||
{
|
||||
if (fDynamicHits[i] == phys)
|
||||
return;
|
||||
}
|
||||
|
||||
fDynamicHits.push_back(phys);
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::Apply(hsScalar delSecs)
|
||||
{
|
||||
plPXPhysicalControllerCore* controller;
|
||||
int numControllers = gControllers.size();
|
||||
for (int i = 0; i < numControllers; ++i)
|
||||
{
|
||||
controller = gControllers[i];
|
||||
if (gRebuildCache && controller->fController)
|
||||
controller->fController->reportSceneChanged();
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
controller->fDbgCollisionInfo.SetCount(0);
|
||||
#endif
|
||||
|
||||
controller->IDispatchQueuedMsgs();
|
||||
controller->IApply(delSecs);
|
||||
controller->IProcessDynamicHits();
|
||||
}
|
||||
|
||||
gRebuildCache = false;
|
||||
}
|
||||
void plPXPhysicalControllerCore::Update(int numSubSteps, hsScalar alpha)
|
||||
{
|
||||
gControllerMgr.updateControllers();
|
||||
|
||||
plPXPhysicalControllerCore* controller;
|
||||
int numControllers = gControllers.size();
|
||||
for (int i = 0; i < numControllers; ++i)
|
||||
{
|
||||
controller = gControllers[i];
|
||||
|
||||
controller->IUpdate(numSubSteps, alpha);
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
if (fDebugDisplay)
|
||||
controller->IDrawDebugDisplay();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
void plPXPhysicalControllerCore::UpdateNonPhysical(hsScalar alpha)
|
||||
{
|
||||
plPXPhysicalControllerCore* controller;
|
||||
int numControllers = gControllers.size();
|
||||
for (int i = 0; i < numControllers; ++i)
|
||||
{
|
||||
controller = gControllers[i];
|
||||
controller->IUpdateNonPhysical(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::RebuildCache() { gRebuildCache = true; }
|
||||
|
||||
plPXPhysicalControllerCore* plPXPhysicalControllerCore::GetController(NxActor& actor)
|
||||
{
|
||||
plPXPhysicalControllerCore* controller;
|
||||
int numControllers = gControllers.size();
|
||||
for (int i = 0; i < numControllers; ++i)
|
||||
{
|
||||
controller = gControllers[i];
|
||||
if (controller->fActor == &actor)
|
||||
return controller;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool plPXPhysicalControllerCore::AnyControllersInThisWorld(plKey world)
|
||||
{
|
||||
plPXPhysicalControllerCore* controller;
|
||||
int numControllers = gControllers.size();
|
||||
for (int i = 0; i < numControllers; ++i)
|
||||
{
|
||||
controller = gControllers[i];
|
||||
if (controller->GetSubworld() == world)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
int plPXPhysicalControllerCore::GetNumberOfControllersInThisSubWorld(plKey world)
|
||||
{
|
||||
int count = 0;
|
||||
plPXPhysicalControllerCore* controller;
|
||||
int numControllers = gControllers.size();
|
||||
for (int i = 0; i < numControllers; ++i)
|
||||
{
|
||||
controller = gControllers[i];
|
||||
if (controller->GetSubworld() == world)
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
int plPXPhysicalControllerCore::GetControllersInThisSubWorld(plKey world, int maxToReturn, plPXPhysicalControllerCore** bufferout)
|
||||
{
|
||||
int count = 0;
|
||||
plPXPhysicalControllerCore* controller;
|
||||
int numControllers = gControllers.size();
|
||||
for (int i = 0; i < numControllers; ++i)
|
||||
{
|
||||
controller = gControllers[i];
|
||||
if (controller->GetSubworld() == world)
|
||||
{
|
||||
if (count < maxToReturn)
|
||||
{
|
||||
bufferout[count] = controller;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int plPXPhysicalControllerCore::NumControllers() { return gControllers.size(); }
|
||||
|
||||
void plPXPhysicalControllerCore::IHandleEnableChanged()
|
||||
{
|
||||
// Defered enable
|
||||
fEnableChanged = false;
|
||||
|
||||
if (!fKinematicCCT)
|
||||
{
|
||||
// Restore dynamic controller
|
||||
fActor->clearBodyFlag(NX_BF_KINEMATIC);
|
||||
NxShape* shape = fActor->getShapes()[0];
|
||||
shape->setGroup(plSimDefs::kGroupAvatar);
|
||||
}
|
||||
|
||||
// Enable actor collisions
|
||||
if (fActor->readActorFlag(NX_AF_DISABLE_COLLISION))
|
||||
fActor->clearActorFlag(NX_AF_DISABLE_COLLISION);
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::IInformDetectors(bool entering)
|
||||
{
|
||||
static const NxU32 kDetectorFlag = 1<<plSimDefs::kGroupDetector;
|
||||
static const int kNumShapes = 30;
|
||||
|
||||
DetectorLog("Informing from plPXPhysicalControllerCore::IInformDetectors");
|
||||
|
||||
NxShape* shapes[kNumShapes];
|
||||
NxCapsule capsule;
|
||||
GetWorldSpaceCapsule(capsule);
|
||||
NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey);
|
||||
int numCollided = scene->overlapCapsuleShapes(capsule, NX_ALL_SHAPES, kNumShapes, shapes, NULL, kDetectorFlag, NULL, true);
|
||||
for (int i = 0; i < numCollided; ++i)
|
||||
{
|
||||
plPXPhysical* physical = (plPXPhysical*)shapes[i]->getActor().userData;
|
||||
if (physical && physical->DoReportOn(plSimDefs::kGroupAvatar))
|
||||
{
|
||||
plCollideMsg* msg = TRACKED_NEW plCollideMsg();
|
||||
msg->fOtherKey = fOwner;
|
||||
msg->fEntering = entering;
|
||||
msg->AddReceiver(physical->GetObjectKey());
|
||||
|
||||
// Queue until the next sim step
|
||||
fQueuedCollideMsgs.push_back(msg);
|
||||
}
|
||||
}
|
||||
|
||||
DetectorLog("Done informing from plPXPhysicalControllerCore::IInformDetectors");
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::ICreateController(const hsPoint3& pos)
|
||||
{
|
||||
NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey);
|
||||
|
||||
if (fKinematicCCT)
|
||||
{
|
||||
// Use PhysX character controller
|
||||
NxCapsuleControllerDesc desc;
|
||||
desc.position.x = pos.fX;
|
||||
desc.position.y = pos.fY;
|
||||
desc.position.z = pos.fZ + kCCTZOffset;
|
||||
desc.upDirection = NX_Z;
|
||||
desc.slopeLimit = kSlopeLimit;
|
||||
desc.skinWidth = kCCTSkinWidth;
|
||||
desc.stepOffset = kCCTStepOffset;
|
||||
desc.callback = &gControllerHitReport;
|
||||
desc.userData = this;
|
||||
desc.radius = fRadius;
|
||||
desc.height = fHeight;
|
||||
desc.interactionFlag = NXIF_INTERACTION_EXCLUDE;
|
||||
fController = (NxCapsuleController*)gControllerMgr.createController(scene, desc);
|
||||
fActor = fController->getActor();
|
||||
|
||||
// Set the actor group - Dynamics are in group 1 and will report on everything in group 0.
|
||||
// We don't want notifications
|
||||
fActor->setGroup(2);
|
||||
|
||||
// Set the shape group. Not used by the NxController itself,
|
||||
// But required for correct group interactions in the simulation.
|
||||
NxShape* shape = fActor->getShapes()[0];
|
||||
shape->setGroup(plSimDefs::kGroupAvatarKinematic);
|
||||
|
||||
// In PhysX 2, the kinematic actors scale factor isn't exposed.
|
||||
// It is hardcoded at 0.8 which doesn't suit, so we have to manually adjust its dimensions.
|
||||
float kineRadius = fRadius + kCCTSkinWidth;
|
||||
float kineHeight = fHeight;
|
||||
NxCapsuleShape* capShape = shape->isCapsule();
|
||||
if (fHuman)
|
||||
{
|
||||
kineHeight += kPhysHeightCorrection;
|
||||
capShape->setLocalPosition(NxVec3(0.0f, (kPhysHeightCorrection / 2.0f), 0.0f));
|
||||
}
|
||||
capShape->setDimensions(kineRadius, kineHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use dynamic actor for the character controller
|
||||
NxCapsuleShapeDesc capDesc;
|
||||
capDesc.materialIndex = plSimulationMgr::GetInstance()->GetMaterialIdx(scene, 0.0f, 0.0f);
|
||||
capDesc.radius = fRadius + kCCTSkinWidth;
|
||||
capDesc.height = fHeight + kPhysHeightCorrection;
|
||||
|
||||
NxBodyDesc bodyDesc;
|
||||
bodyDesc.mass = kAvatarMass;
|
||||
bodyDesc.flags = NX_BF_DISABLE_GRAVITY;
|
||||
bodyDesc.flags |= NX_BF_FROZEN_ROT;
|
||||
|
||||
if (fEnabled)
|
||||
capDesc.group = plSimDefs::kGroupAvatar;
|
||||
else
|
||||
{
|
||||
bodyDesc.flags |= NX_BF_KINEMATIC;
|
||||
capDesc.group = plSimDefs::kGroupAvatarKinematic;
|
||||
}
|
||||
|
||||
NxActorDesc actorDesc;
|
||||
actorDesc.shapes.pushBack(&capDesc);
|
||||
actorDesc.body = &bodyDesc;
|
||||
actorDesc.group = 2;
|
||||
|
||||
actorDesc.globalPose.M.rotX(NxHalfPiF32);
|
||||
actorDesc.globalPose.t.x = pos.fX;
|
||||
actorDesc.globalPose.t.y = pos.fY;
|
||||
actorDesc.globalPose.t.z = pos.fZ + kPhysZOffset;
|
||||
|
||||
fActor = scene->createActor(actorDesc);
|
||||
}
|
||||
|
||||
fSeeking = false;
|
||||
|
||||
// Create proxy for the debug display
|
||||
/* FIXME
|
||||
// the avatar proxy doesn't seem to work... not sure why?
|
||||
hsColorRGBA physColor;
|
||||
hsScalar opac = 1.0f;
|
||||
|
||||
// local avatar is light purple and transparent
|
||||
physColor.Set(.2f, .1f, .2f, 1.f);
|
||||
opac = 0.8f;
|
||||
|
||||
fProxyGen = TRACKED_NEW plPhysicalProxy(hsColorRGBA().Set(0,0,0,1.f), physColor, opac);
|
||||
fProxyGen->Init(this);
|
||||
*/
|
||||
}
|
||||
void plPXPhysicalControllerCore::IDeleteController()
|
||||
{
|
||||
if (fKinematicCCT)
|
||||
{
|
||||
gControllerMgr.releaseController(*fController);
|
||||
fController = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey);
|
||||
scene->releaseActor(*fActor);
|
||||
}
|
||||
|
||||
fActor = nil;
|
||||
plSimulationMgr::GetInstance()->ReleaseScene(fWorldKey);
|
||||
}
|
||||
|
||||
void plPXPhysicalControllerCore::IDispatchQueuedMsgs()
|
||||
{
|
||||
int numMsgs = fQueuedCollideMsgs.size();
|
||||
if (numMsgs)
|
||||
{
|
||||
plSimulationMgr* simMgr = plSimulationMgr::GetInstance();
|
||||
for (int i = 0; i < numMsgs; ++i)
|
||||
simMgr->AddCollisionMsg(fQueuedCollideMsgs[i]);
|
||||
|
||||
fQueuedCollideMsgs.clear();
|
||||
}
|
||||
}
|
||||
void plPXPhysicalControllerCore::IProcessDynamicHits()
|
||||
{
|
||||
int numHits = fDynamicHits.size();
|
||||
if (numHits)
|
||||
{
|
||||
plPXPhysical* phys;
|
||||
plSimulationMgr* simMgr = plSimulationMgr::GetInstance();
|
||||
for (int i = 0; i < numHits; ++i)
|
||||
{
|
||||
phys = fDynamicHits[i];
|
||||
|
||||
// If this is the local avatar, we need to take ownership of this dynamic if we haven't already
|
||||
if (fLOSDB == plSimDefs::kLOSDBLocalAvatar && !phys->IsLocallyOwned() && !phys->GetProperty(plSimulationInterface::kNoOwnershipChange))
|
||||
{
|
||||
plSynchedObject* obj = plSynchedObject::ConvertNoRef(phys->GetObjectKey()->ObjectIsLoaded());
|
||||
obj->SetNetGroupConstant(plNetGroup::kNetGroupLocalPhysicals);
|
||||
|
||||
plSetNetGroupIDMsg* setNetGroupID = TRACKED_NEW plSetNetGroupIDMsg;
|
||||
setNetGroupID->fId = plNetGroup::kNetGroupRemotePhysicals;
|
||||
setNetGroupID->SetBCastFlag(plMessage::kNetPropagate | plMessage::kNetForce);
|
||||
setNetGroupID->SetBCastFlag(plMessage::kLocalPropagate, false);
|
||||
setNetGroupID->Send(obj->GetKey());
|
||||
}
|
||||
|
||||
phys->ApplyHitForce();
|
||||
simMgr->ConsiderSynch(phys, nil);
|
||||
}
|
||||
fDynamicHits.clear();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
#include "../plPipeline/plDebugText.h"
|
||||
|
||||
void plPXPhysicalControllerCore::IDrawDebugDisplay()
|
||||
{
|
||||
plDebugText &debugTxt = plDebugText::Instance();
|
||||
char strBuf[ 2048 ];
|
||||
int lineHeight = debugTxt.GetFontSize() + 4;
|
||||
UInt32 scrnWidth, scrnHeight;
|
||||
|
||||
debugTxt.GetScreenSize( &scrnWidth, &scrnHeight );
|
||||
int y = 10;
|
||||
int x = 10;
|
||||
|
||||
sprintf(strBuf, "Controller Count: %d", gControllers.size());
|
||||
debugTxt.DrawString(x, y, strBuf);
|
||||
y += lineHeight;
|
||||
|
||||
debugTxt.DrawString(x, y, "Avatar Collisions:");
|
||||
y += lineHeight;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < fDbgCollisionInfo.GetCount(); i++)
|
||||
{
|
||||
hsVector3 normal = fDbgCollisionInfo[i].fNormal;
|
||||
char *overlapStr = fDbgCollisionInfo[i].fOverlap ? "yes" : "no";
|
||||
hsScalar angle = hsScalarRadToDeg(hsACosine(normal * hsVector3(0, 0, 1)));
|
||||
sprintf(strBuf, " Obj: %s, Normal: (%.2f, %.2f, %.2f), Angle(%.1f), Overlap(%3s)",
|
||||
fDbgCollisionInfo[i].fSO->GetKeyName(),
|
||||
normal.fX, normal.fY, normal.fZ, angle, overlapStr);
|
||||
debugTxt.DrawString(x, y, strBuf);
|
||||
y += lineHeight;
|
||||
}
|
||||
}
|
||||
#endif PLASMA_EXTERNAL_RELEASE
|
||||
|
173
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysicalControllerCore.h
Normal file
173
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysicalControllerCore.h
Normal file
@ -0,0 +1,173 @@
|
||||
/*==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 "../plAvatar/plPhysicalControllerCore.h"
|
||||
|
||||
class NxCapsuleController;
|
||||
class NxActor;
|
||||
class NxCapsule;
|
||||
class PXControllerHitReport;
|
||||
class plPhysicalProxy;
|
||||
class plDrawableSpans;
|
||||
class hsGMaterial;
|
||||
class plSceneObject;
|
||||
class plPXPhysical;
|
||||
class plCollideMsg;
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
class plDbgCollisionInfo
|
||||
{
|
||||
public:
|
||||
plSceneObject *fSO;
|
||||
hsVector3 fNormal;
|
||||
hsBool fOverlap;
|
||||
};
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
class plPXPhysicalControllerCore: public plPhysicalControllerCore
|
||||
{
|
||||
public:
|
||||
plPXPhysicalControllerCore(plKey ownerSO, hsScalar height, hsScalar radius, bool human);
|
||||
~plPXPhysicalControllerCore();
|
||||
|
||||
// An ArmatureMod has its own idea about when physics should be enabled/disabled.
|
||||
// Use plArmatureModBase::EnablePhysics() instead.
|
||||
virtual void Enable(bool enable);
|
||||
|
||||
// Subworld
|
||||
virtual void SetSubworld(plKey world);
|
||||
|
||||
// For the avatar SDL only
|
||||
virtual void GetState(hsPoint3& pos, float& zRot);
|
||||
virtual void SetState(const hsPoint3& pos, float zRot);
|
||||
|
||||
// Movement strategy
|
||||
virtual void SetMovementStrategy(plMovementStrategy* strategy);
|
||||
|
||||
// Global location
|
||||
virtual void SetGlobalLoc(const hsMatrix44& l2w);
|
||||
|
||||
// Local Sim Position
|
||||
virtual void GetPositionSim(hsPoint3& pos);
|
||||
|
||||
// Move kinematic controller
|
||||
virtual void Move(hsVector3 displacement, unsigned int collideWith, unsigned int &collisionResults);
|
||||
|
||||
// Set linear velocity on dynamic controller
|
||||
virtual void SetLinearVelocitySim(const hsVector3& linearVel);
|
||||
|
||||
// Sweep the controller path from startPos through endPos
|
||||
virtual int SweepControllerPath(const hsPoint3& startPos, const hsPoint3& endPos, hsBool vsDynamics,
|
||||
hsBool vsStatics, UInt32& vsSimGroups, std::vector<plControllerSweepRecord>& hits);
|
||||
|
||||
// any clean up for the controller should go here
|
||||
virtual void LeaveAge();
|
||||
|
||||
// Capsule
|
||||
void GetWorldSpaceCapsule(NxCapsule& cap) const;
|
||||
|
||||
// Create Proxy for debug rendering
|
||||
plDrawableSpans* CreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo);
|
||||
|
||||
// Dynamic hits
|
||||
void AddDynamicHit(plPXPhysical* phys);
|
||||
|
||||
//////////////////////////////////////////
|
||||
//Static Helper Functions
|
||||
////////////////////////////////////////
|
||||
|
||||
// Call pre-sim to apply movement to controllers
|
||||
static void Apply(hsScalar delSecs);
|
||||
|
||||
// Call post-sim to update controllers
|
||||
static void Update(int numSubSteps, hsScalar alpha);
|
||||
|
||||
// Update controllers when not performing a physics step
|
||||
static void UpdateNonPhysical(hsScalar alpha);
|
||||
|
||||
// Rebuild the controller cache, required when a static actor in the scene has changed.
|
||||
static void RebuildCache();
|
||||
|
||||
// Returns the plPXPhysicalControllerCore associated with the given NxActor
|
||||
static plPXPhysicalControllerCore* GetController(NxActor& actor);
|
||||
|
||||
// Subworld controller queries
|
||||
static bool AnyControllersInThisWorld(plKey world);
|
||||
static int GetNumberOfControllersInThisSubWorld(plKey world);
|
||||
static int GetControllersInThisSubWorld(plKey world, int maxToReturn, plPXPhysicalControllerCore** bufferout);
|
||||
|
||||
// Controller count
|
||||
static int NumControllers();
|
||||
static void SetMaxNumberOfControllers(int max) { fPXControllersMax = max; }
|
||||
static int fPXControllersMax;
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
static hsBool fDebugDisplay;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
friend class PXControllerHitReport;
|
||||
|
||||
virtual void IHandleEnableChanged();
|
||||
|
||||
void IInformDetectors(bool entering);
|
||||
|
||||
void ICreateController(const hsPoint3& pos);
|
||||
void IDeleteController();
|
||||
|
||||
void IDispatchQueuedMsgs();
|
||||
void IProcessDynamicHits();
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
void IDrawDebugDisplay();
|
||||
hsTArray<plDbgCollisionInfo> fDbgCollisionInfo;
|
||||
#endif
|
||||
|
||||
std::vector<plCollideMsg*> fQueuedCollideMsgs;
|
||||
std::vector<plPXPhysical*> fDynamicHits;
|
||||
|
||||
NxCapsuleController* fController;
|
||||
NxActor* fActor;
|
||||
|
||||
plPhysicalProxy* fProxyGen;
|
||||
bool fKinematicCCT;
|
||||
bool fHuman;
|
||||
};
|
73
Sources/Plasma/PubUtilLib/plPhysX/plPXStream.h
Normal file
73
Sources/Plasma/PubUtilLib/plPhysX/plPXStream.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 plPXStream_h_inc
|
||||
#define plPXStream_h_inc
|
||||
|
||||
#include "hsStream.h"
|
||||
#include "NxPhysics.h"
|
||||
#include "NxStream.h"
|
||||
|
||||
// A super simple wrapper to convert a Plasma stream into a PhysX one
|
||||
class plPXStream : public NxStream
|
||||
{
|
||||
public:
|
||||
plPXStream(hsStream* s) : fStream(s) {}
|
||||
|
||||
virtual NxU8 readByte() const { return fStream->ReadByte(); }
|
||||
virtual NxU16 readWord() const { return fStream->ReadSwap16(); }
|
||||
virtual NxU32 readDword() const { return fStream->ReadSwap32(); }
|
||||
virtual float readFloat() const { return fStream->ReadSwapScalar(); }
|
||||
virtual double readDouble() const { return fStream->ReadSwapDouble(); }
|
||||
virtual void readBuffer(void* buffer, NxU32 size) const { fStream->Read(size, buffer); }
|
||||
|
||||
virtual NxStream& storeByte(NxU8 b) { fStream->WriteByte(b); return *this; }
|
||||
virtual NxStream& storeWord(NxU16 w) { fStream->WriteSwap16(w); return *this; }
|
||||
virtual NxStream& storeDword(NxU32 d) { fStream->WriteSwap32(d); return *this; }
|
||||
virtual NxStream& storeFloat(NxReal f) { fStream->WriteSwapScalar(f); return *this; }
|
||||
virtual NxStream& storeDouble(NxF64 f) { fStream->WriteSwapDouble(f); return *this; }
|
||||
virtual NxStream& storeBuffer(const void* buffer, NxU32 size) { fStream->Write(size, buffer); return *this; }
|
||||
|
||||
protected:
|
||||
hsStream* fStream;
|
||||
};
|
||||
|
||||
#endif // plPXStream_h_inc
|
71
Sources/Plasma/PubUtilLib/plPhysX/plPhysXCreatable.h
Normal file
71
Sources/Plasma/PubUtilLib/plPhysX/plPhysXCreatable.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*==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 plPhysXCreatable_inc
|
||||
#define plPhysXCreatable_inc
|
||||
|
||||
#include "../pnFactory/plCreator.h"
|
||||
|
||||
#include "plPXPhysical.h"
|
||||
|
||||
REGISTER_CREATABLE(plPXPhysical);
|
||||
|
||||
//#include "plHKSimulationSynchMsg.h"
|
||||
//REGISTER_CREATABLE(plHKSimulationSynchMsg);
|
||||
|
||||
//#include "plHavokConstraintTools.h"
|
||||
//REGISTER_NONCREATABLE(plHavokConstraintsMod);
|
||||
//REGISTER_CREATABLE(plHingeConstraintMod);
|
||||
//REGISTER_CREATABLE(plStrongSpringConstraintMod);
|
||||
//REGISTER_CREATABLE(plWheelConstraintMod);
|
||||
|
||||
|
||||
#include "plLOSDispatch.h"
|
||||
REGISTER_CREATABLE( plLOSDispatch );
|
||||
|
||||
#include "plSimulationMgr.h"
|
||||
REGISTER_CREATABLE( plSimulationMgr );
|
||||
|
||||
//#include "plVehicleModifier.h"
|
||||
//REGISTER_CREATABLE(plVehicleModifier);
|
||||
|
||||
|
||||
#endif // plPhysXCreatable_inc
|
1009
Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.cpp
Normal file
1009
Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.cpp
Normal file
File diff suppressed because it is too large
Load Diff
212
Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.h
Normal file
212
Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.h
Normal file
@ -0,0 +1,212 @@
|
||||
/*==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 plSimulationMgr_H
|
||||
#define plSimulationMgr_H
|
||||
|
||||
#include "hsStlUtils.h"
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
#include "hsTemplates.h"
|
||||
|
||||
class plPXPhysical;
|
||||
class plLOSDispatch;
|
||||
class plStatusLog;
|
||||
class plPhysicsSoundMgr;
|
||||
class NxPhysicsSDK;
|
||||
class NxScene;
|
||||
class plCollideMsg;
|
||||
struct hsPoint3;
|
||||
|
||||
class plSimulationMgr : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
CLASSNAME_REGISTER(plSimulationMgr);
|
||||
GETINTERFACE_ANY(plSimulationMgr, hsKeyedObject);
|
||||
|
||||
static plSimulationMgr* GetInstance();
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
|
||||
static bool fExtraProfile;
|
||||
static bool fSubworldOptimization;
|
||||
static bool fDoClampingOnStep;
|
||||
|
||||
// initialiation of the PhysX simulation
|
||||
virtual bool InitSimulation();
|
||||
|
||||
// Advance the simulation by the given number of seconds
|
||||
void Advance(float delSecs);
|
||||
|
||||
// The simulation won't run at all if it is suspended
|
||||
void Suspend() { fSuspended = true; }
|
||||
void Resume() { fSuspended = false; }
|
||||
bool IsSuspended() { return fSuspended; }
|
||||
|
||||
// Output the given debug text to the simulation log.
|
||||
static void Log(const char* formatStr, ...);
|
||||
static void LogV(const char* formatStr, va_list args);
|
||||
static void ClearLog();
|
||||
|
||||
// We've detected a collision, which may be grounds for synchronizing the involved
|
||||
// physicals over the network.
|
||||
void ConsiderSynch(plPXPhysical *physical, plPXPhysical *other);
|
||||
|
||||
NxPhysicsSDK* GetSDK() const { return fSDK; }
|
||||
NxScene* GetScene(plKey world);
|
||||
// Called when an actor is removed from a scene, checks if it's time to delete
|
||||
// the scene
|
||||
void ReleaseScene(plKey world);
|
||||
|
||||
int GetMaterialIdx(NxScene* scene, hsScalar friction, hsScalar restitution);
|
||||
|
||||
UInt32 GetStepCount() { return fStepCount; }
|
||||
|
||||
// PHYSX FIXME - walk thru all the convex hull detector regions to see if we are in any... we're either coming or going
|
||||
void UpdateDetectorsInScene(plKey world, plKey avatar, hsPoint3& pos, bool entering);
|
||||
void UpdateAvatarInDetector(plKey world, plPXPhysical* detector);
|
||||
//Fix to Move collision messages and their handling out of the simulation step
|
||||
void AddCollisionMsg(plCollideMsg* msg);
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
static bool fDisplayAwakeActors;
|
||||
#endif //PLASMA_EXTERNAL_RELEASE
|
||||
protected:
|
||||
friend class ContactReport;
|
||||
|
||||
void ISendUpdates();
|
||||
|
||||
plSimulationMgr();
|
||||
virtual ~plSimulationMgr();
|
||||
|
||||
// Set the maximum amount of time (in seconds) that the physics will advance
|
||||
// between frames. If a frame-to-frame delta is bigger than this, we'll
|
||||
// clamp it to this value.
|
||||
// WARNING: animation doesn't do this, so if we clamp the time animated
|
||||
// physicals and the avatar may move at a faster rate than usual.
|
||||
void SetMaxDelta(float maxDelta);
|
||||
float GetMaxDelta() const;
|
||||
|
||||
// Set the number of steps per second that physics will advance.
|
||||
// The more steps per second, the less fallthough and more accurate
|
||||
// simulation response.
|
||||
void SetStepsPerSecond(int stepsPerSecond);
|
||||
int GetStepsPerSecond();
|
||||
|
||||
// Walk through the synchronization requests and send them as appropriate.
|
||||
void IProcessSynchs();
|
||||
|
||||
// PHYSX FIXME send a collision message - should only be used with UpdateDetectorsInScene
|
||||
void ISendCollisionMsg(plKey receiver, plKey hitter, hsBool entering);
|
||||
|
||||
NxPhysicsSDK* fSDK;
|
||||
|
||||
plPhysicsSoundMgr* fSoundMgr;
|
||||
|
||||
//a list of collision messages generated by the simulation steps. Added to by AddCollisionMsg(plCollideMsg* msg)
|
||||
//cleared by IDispatchCollisionMessages when done
|
||||
hsTArray<plCollideMsg*> fCollisionMessages;
|
||||
|
||||
void IDispatchCollisionMessages();
|
||||
|
||||
// A mapping from a key to a PhysX scene. The key is either the
|
||||
// SimulationMgr key, for the main world, or a SceneObject key if it's a
|
||||
// subworld.
|
||||
typedef std::map<plKey, NxScene*> SceneMap;
|
||||
SceneMap fScenes;
|
||||
|
||||
plLOSDispatch* fLOSDispatch;
|
||||
|
||||
// Is the entire physics world suspended? If so, the clock can still advance
|
||||
// but nothing will move.
|
||||
bool fSuspended;
|
||||
|
||||
float fMaxDelta;
|
||||
float fStepSize;
|
||||
float fAccumulator;
|
||||
|
||||
UInt32 fStepCount;
|
||||
|
||||
// A utility class to keep track of a request for a physical synchronization.
|
||||
// These requests must pass a certain criteria (see the code for the latest)
|
||||
// before they are actually either sent over the network or rejected.
|
||||
class SynchRequest
|
||||
{
|
||||
public:
|
||||
double fTime; // when to synch
|
||||
plKey fKey; // key of the object to be synched, so we can make sure it still lives
|
||||
|
||||
static const double kDefaultTime;
|
||||
SynchRequest() : fTime(kDefaultTime) {};
|
||||
};
|
||||
|
||||
// All currently pending synch requests. Keyed by the physical in question
|
||||
// so we can quickly eliminate redundant requests, which are very common.
|
||||
typedef std::map<plPXPhysical*, SynchRequest> PhysSynchMap;
|
||||
PhysSynchMap fPendingSynchs;
|
||||
|
||||
plStatusLog *fLog;
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
void IDrawActiveActorList();
|
||||
#endif //PLASMA_EXTERNAL_RELEASE
|
||||
};
|
||||
|
||||
#define SIM_VERBOSE
|
||||
|
||||
#ifdef SIM_VERBOSE
|
||||
#include <stdarg.h> // only include when we need to call plSimulationMgr::Log
|
||||
|
||||
inline void SimLog(const char *str, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, str);
|
||||
plSimulationMgr::LogV(str, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline void SimLog(const char *str, ...)
|
||||
{
|
||||
// will get stripped out
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user