//----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- #ifndef _PHYSICSSHAPE_H_ #define _PHYSICSSHAPE_H_ #ifndef _GAMEBASE_H_ #include "T3D/gameBase/gameBase.h" #endif #ifndef __RESOURCE_H__ #include "core/resource.h" #endif #ifndef _TSSHAPE_H_ #include "ts/tsShape.h" #endif #ifndef _T3D_PHYSICSCOMMON_H_ #include "T3D/physics/physicsCommon.h" #endif #ifndef _DYNAMIC_CONSOLETYPES_H_ #include "console/dynamicTypes.h" #endif #ifndef _SIMOBJECTREF_H_ #include "console/simObjectRef.h" #endif #include "T3D/assets/ShapeAsset.h" class TSShapeInstance; class PhysicsBody; class PhysicsWorld; class PhysicsDebrisData; class ExplosionData; class PhysicsShapeData : public GameBaseData { typedef GameBaseData Parent; void _onResourceChanged( const Torque::Path &path ); public: PhysicsShapeData(); virtual ~PhysicsShapeData(); DECLARE_CONOBJECT(PhysicsShapeData); static void initPersistFields(); bool onAdd(); void onRemove(); // GameBaseData void packData(BitStream* stream); void unpackData(BitStream* stream); bool preload(bool server, String &errorBuffer ); public: DECLARE_SHAPEASSET(PhysicsShapeData, Shape, onShapeChanged); DECLARE_ASSET_SETGET(PhysicsShapeData, Shape); /// The shared unscaled collision shape. PhysicsCollisionRef colShape; /// F32 mass; /// F32 dynamicFriction; /// F32 staticFriction; /// F32 restitution; /// F32 linearDamping; /// F32 angularDamping; /// F32 linearSleepThreshold; /// F32 angularSleepThreshold; // A scale applied to the normal linear and angular damping // when the object enters a water volume. F32 waterDampingScale; // The density of this object used for water buoyancy effects. F32 buoyancyDensity; enum SimType { /// This physics representation only exists on the client /// world and the server only does ghosting. SimType_ClientOnly, /// The physics representation only exists on the server world /// and the client gets delta updates for rendering. SimType_ServerOnly, /// The physics representation exists on the client and the server /// worlds with corrections occuring when the client gets out of sync. SimType_ClientServer, /// The bits used to pack the SimType field. SimType_Bits = 3, } simType; SimObjectRef< PhysicsDebrisData > debris; SimObjectRef< ExplosionData > explosion; SimObjectRef< PhysicsShapeData > destroyedShape; void onShapeChanged() {} }; typedef PhysicsShapeData::SimType PhysicsSimType; DefineEnumType( PhysicsSimType ); class TSThread; /// A simple single body dynamic physics object. class PhysicsShape : public GameBase { typedef GameBase Parent; protected: /// The abstracted physics actor. PhysicsBody *mPhysicsRep; /// PhysicsWorld *mWorld; /// The starting position to place the shape when /// the level begins or is reset. MatrixF mResetPos; //VectorF mBuildScale; //F32 mBuildAngDrag; //F32 mBuildLinDrag; /// The rendered shape. TSShapeInstance *mShapeInst; /// The current physics state. PhysicsState mState; /// The previous and current render states. PhysicsState mRenderState[2]; /// True if the PhysicsShape has been destroyed ( gameplay ). bool mDestroyed; /// Enables automatic playing of the animation named "ambient" (if it exists) /// when the PhysicsShape is loaded. bool mPlayAmbient; S32 mAmbientSeq; TSThread* mAmbientThread; /// If a specified to create one in the PhysicsShape data, this is the /// subshape created when this PhysicsShape is destroyed. /// Is only assigned (non null) on the serverside PhysicsShape. SimObjectPtr< PhysicsShape > mDestroyedShape; /// enum MaskBits { StateMask = Parent::NextFreeMask << 0, ResetPosMask = Parent::NextFreeMask << 1, DamageMask = Parent::NextFreeMask << 2, NextFreeMask = Parent::NextFreeMask << 3 }; bool _createShape(); void _initAmbient(); /// void _applyCorrection( const MatrixF &mat ); void _onPhysicsReset( PhysicsResetEvent reset ); void _updateContainerForces(); /// If true then no corrections are sent from the server /// and/or applied from the client. /// /// This is only ment for debugging. /// static bool smNoCorrections; /// If true then no smoothing is done on the client when /// applying server corrections. /// /// This is only ment for debugging. /// static bool smNoSmoothing; public: PhysicsShape(); virtual ~PhysicsShape(); DECLARE_CONOBJECT( PhysicsShape ); /// Returns the PhysicsShapeData datablock. PhysicsShapeData* getDataBlock() { return static_cast( Parent::getDataBlock() ); } // SimObject static void consoleInit(); static void initPersistFields(); void inspectPostApply(); bool onAdd(); void onRemove(); // SceneObject void prepRenderImage( SceneRenderState *state ); void setTransform( const MatrixF &mat ); F32 getMass() const; Point3F getVelocity() const { return mState.linVelocity; } void applyImpulse( const Point3F &pos, const VectorF &vec ); void applyRadialImpulse( const Point3F &origin, F32 radius, F32 magnitude ); void applyTorque( const Point3F &torque ); void applyForce( const Point3F &force ); void setScale(const VectorF & scale); // GameBase bool onNewDataBlock( GameBaseData *dptr, bool reload ); void interpolateTick( F32 delta ); void processTick( const Move *move ); void advanceTime( F32 timeDelta ); U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream ); void unpackUpdate( NetConnection *conn, BitStream *stream ); bool isDestroyed() const { return mDestroyed; } void destroy(); void restore(); /// Save the current transform as where we return to when a physics reset /// event occurs. This is automatically set in onAdd but some manipulators /// such as Prefab need to make use of this. void storeRestorePos(); }; #endif // _PHYSICSSHAPE_H_