You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
8.4 KiB
277 lines
8.4 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
#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: |
|
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
|
|
|