/*==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 plPXPhysicalController_h_inc #define plPXPhysicalController_h_inc #include "plAvatar/plAvCallbackAction.h" #include "hsQuat.h" #define PHYSX_ONLY_TRIGGER_FROM_KINEMATIC 1 class NxController; class NxCapsuleController; class NxActor; class plCoordinateInterface; class plPhysicalProxy; class plDrawableSpans; class hsGMaterial; class NxCapsule; #ifndef PLASMA_EXTERNAL_RELEASE class plDbgCollisionInfo { public: plSceneObject *fSO; hsVector3 fNormal; hsBool fOverlap; }; #endif // PLASMA_EXTERNAL_RELEASE class plPXPhysicalController : public plPhysicalController { public: plPXPhysicalController(plKey ownerSO, hsScalar height, hsScalar radius); virtual ~plPXPhysicalController(); virtual void Enable(bool enable); virtual bool IsEnabled() const { return fEnable; } virtual void SetLOSDB(plSimDefs::plLOSDB losDB) { fLOSDB = losDB; } plSimDefs::plLOSDB GetLOSDB() const { return fLOSDB; } virtual void SetVelocities(const hsVector3& linearVel, hsScalar angVel) { fLinearVelocity = linearVel; fAngularVelocity = angVel; } virtual const hsVector3& GetLinearVelocity() const { return fAchievedLinearVelocity; } virtual void ResetAchievedLinearVelocity() { fAchievedLinearVelocity.Set(0.f, 0.f, 0.f); } virtual plKey GetSubworld() const { return fWorldKey; } virtual void SetSubworld(plKey world); virtual bool IsOnGround() const { return fTimeInAir < kAirTimeThreshold || fFalseGround; } virtual bool IsOnFalseGround() const { return fFalseGround && !fGroundHit; } virtual void GroundHit() { fGroundHit = true; } virtual hsScalar GetAirTime() const { return fTimeInAir; } virtual void ResetAirTime() { fTimeInAir = 0.f; } virtual void AddSlidingNormal(hsVector3 vec); virtual hsTArray* GetSlidingNormals() { return &fSlidingNormals; } virtual plPhysical* GetPushingPhysical() const { return fPushingPhysical; } virtual bool GetFacingPushingPhysical() const { return fFacingPushingPhysical; } virtual const plCoordinateInterface* GetSubworldCI() const; virtual void GetState(hsPoint3& pos, float& zRot); virtual void SetState(const hsPoint3& pos, float zRot); plKey GetOwner() const { return fOwner; } // Called by the simulation mgr each frame static void Update(bool prestep, hsScalar delSecs); // Used by the LOS mgr to find the controller for an actor it hit static plPXPhysicalController* GetController(NxActor& actor, bool* isController); // test to see if there are any controllers (i.e. avatars) in this subworld static bool plPXPhysicalController::AnyControllersInThisWorld(plKey world); static int plPXPhysicalController::NumControllers(); static int plPXPhysicalController::GetControllersInThisSubWorld(plKey world, int maxToReturn, plPXPhysicalController** bufferout); static int plPXPhysicalController::GetNumberOfControllersInThisSubWorld(plKey world); // Call this if a static physical in the scene has changed (unloaded, // collision enabled/disabled, etc) static void RebuildCache(); virtual void GetPositionSim(hsPoint3& pos) const { IGetPositionSim(pos); } virtual void Kinematic(bool state); virtual bool IsKinematic(); virtual void GetKinematicPosition(hsPoint3& pos); virtual plDrawableSpans* CreateProxy(hsGMaterial* mat, hsTArray& idx, plDrawableSpans* addTo); virtual const hsMatrix44& GetPrevSubworldW2L() { return fPrevSubworldW2L; } virtual void SetSeek(bool seek){fSeeking=seek;} virtual void GetWorldSpaceCapsule(NxCapsule& cap); #ifndef PLASMA_EXTERNAL_RELEASE static hsBool fDebugDisplay; #endif // PLASMA_EXTERNAL_RELEASE protected: static const hsScalar kAirTimeThreshold; friend class PXControllerHitReport; static plPXPhysicalController* FindController(NxController* controller); void IApply(hsScalar delSecs); void ISendUpdates(hsScalar delSecs); void ICheckForFalseGround(); void ISetGlobalLoc(const hsMatrix44& l2w); void IMatchKinematicToController(); void IMoveKinematicToController(hsPoint3& pos); void ISetKinematicLoc(const hsMatrix44& l2w); void IGetPositionSim(hsPoint3& pos) const; void ICreateController(); void IDeleteController(); void IInformDetectors(bool entering); plKey fOwner; plKey fWorldKey; hsScalar fRadius, fHeight; NxCapsuleController* fController; // this is the kinematic actor for triggering things when the avatar is collision-less during behaviors NxActor* fKinematicActor; hsVector3 fLinearVelocity; hsScalar fAngularVelocity; hsVector3 fAchievedLinearVelocity; // The global position and rotation of the avatar last time we set it (so we // can detect if someone else moves him) hsMatrix44 fLastGlobalLoc; // hsPoint3 fLocalPosition; hsQuat fLocalRotation; hsMatrix44 fPrevSubworldW2L; bool fEnable; bool fEnableChanged; plSimDefs::plLOSDB fLOSDB; bool fKinematic; bool fKinematicChanged; bool fKinematicEnableNextUpdate; bool fGroundHit; bool fFalseGround; hsScalar fTimeInAir; hsTArray fSlidingNormals; hsTArray fPrevSlidingNormals; #ifndef PLASMA_EXTERNAL_RELEASE hsTArray fDbgCollisionInfo; void IDrawDebugDisplay(); #endif // PLASMA_EXTERNAL_RELEASE plPhysical* fPushingPhysical; bool fFacingPushingPhysical; plPhysicalProxy* fProxyGen; // visual proxy for debugging bool fHitHead; bool fSeeking; }; #endif // plPXPhysicalController_h_inc