/*==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 .
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& idx, plDrawableSpans* addTo);
hsBool DoReportOn(plSimDefs::Group group) const { return hsCheckBits(fReportsOn, 1<= 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