/* Crystal Space Entity Layer Copyright (C) 2005 by Jorrit Tyberghein This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CEL_PF_MECHANICS_SYSTEM__ #define __CEL_PF_MECHANICS_SYSTEM__ #include "cstypes.h" #include "csutil/scf.h" #include "propclass/mechcommon.h" #include "csgeom/vector3.h" class csBox3; class csOrthoTransform; class csPlane3; struct iDynamicSystem; struct iRigidBody; struct iSector; struct iPcMesh; struct iPcLight; struct iPcCamera; struct iPcMechanicsObject; struct iJoint; /** * Property class representing a dynamic system. * * This property class supports the following actions (add prefix * 'cel.action.' to get the ID of the action and add prefix 'cel.parameter.' * to get the ID of the parameter): * - SetSystem: parameters 'dynsys' (string). * - SetGravity: parameters 'gravity' (float). * - SetStepTime: parameters 'time' (float). * - QuickStep: no parameters. * - EnableStepFast: no parameters. * - DisableStepFast: no parameters. */ struct iPcMechanicsSystem : public virtual iBase { SCF_INTERFACE (iPcMechanicsSystem, 0, 0, 1); /** * Set the dynamic system. * \param dynsys a pointer to the iDynamicSystem that this iPcMechanicsSystem * represents. */ virtual void SetDynamicSystem (iDynamicSystem* dynsys) = 0; /** * Set the dynamic system. * \param dynsysname the name of the iDynamicSystem that this * iPcMechanicsSystem represents. */ virtual void SetDynamicSystem (const char *dynsysname) = 0; /** * Get the dynamic system. */ virtual iDynamicSystem* GetDynamicSystem () = 0; /** * Define the time we want for one step. By default this is 0.01 milliseconds. * \param delta the time (in milliseconds) that one step represents. */ virtual void SetStepTime (float delta) = 0; /** * Get the current step time. */ virtual float GetStepTime () const = 0; /** * Define the how fast we want the simulation to go. Default is 1.0. * Less is slower, more is faster * \param dsimulationspeed factor of speed. */ virtual void SetSimulationSpeed (float simulationspeed) = 0; /** * Get the current simulation speed. */ virtual float GetSimulationSpeed () = 0; /** * Define the gravity for the system. By default this is (0,-9.8,0). * \param grav a vector representing the force of gravity for this system. */ virtual void SetGravity (const csVector3& grav) = 0; /** * Get the current gravity. */ virtual const csVector3 GetGravity () = 0; /** * During the specified time (in milliseconds) add the force every * step to the given body. This function is called by * iPcMechanicsObject::AddForceDuration(). * \param pcobject a pointer to the object that will receive this force every * step until the end of the given time. * \param force a vector representing the force to add to this object. * \param relative if set to true, the given force and position are both in * object space; otherwise they are in world space. * \param position the position of the force. * \param seconds the number of seconds that this force should last. */ virtual void AddForceDuration (iPcMechanicsObject* pcobject, const csVector3& force, bool relative, const csVector3& position, float seconds) = 0; /** * During the next frame add the force every step. This function is called * by iPcMechanicsObject::AddForceFrame(). * \param pcobject a pointer to the object that will receive this force every * step until the end of the frame. * \param force a vector representing the force to add to this object. * \param relative if set to true, the given force and position are both in * object space; otherwise they are in world space. * \param position the position of the force. */ virtual void AddForceFrame (iPcMechanicsObject* pcobject, const csVector3& force, bool relative, const csVector3& position) = 0; /** * Add a force with the given tag, to be manually removed later. This * function is called by iPcMechanicsObject::AddForceTagged(). * \param pcobject a pointer to the object that will receive this force every * step until it is removed. * \param force a vector representing the force to add to this object. * \param relative if set to true, the given force and position are both in * object space; otherwise they are in world space. * \param position the position of the force. * \param forceid the tag for this force. (use * iCelPlLayer::FetchStringID() to get this.) */ virtual void AddForceTagged (iPcMechanicsObject* pcobject, const csVector3& force, bool relative, const csVector3& position, uint32 forceid) = 0; /** * Remove the force with the given tag. This function is called by * iPcMechanicsObject::RemoveForceTagged(). * \param pcobject a pointer to the object that is currently being affected * by the given force. * \param forceid the tag of the desired force. */ virtual void RemoveForceTagged (iPcMechanicsObject* pcobject, uint32 forceid) = 0; /** * Remove the given body from the force queues (filled with AddForceFrame() * and AddForceDuration()). * \param pcobject a pointer to the iPcMechanicsObject to remove all forces * from. */ virtual void ClearForces (iPcMechanicsObject* pcobject) = 0; /** * Clear all forces. */ virtual void ClearAllForces () = 0; /** * Create an iRigidBody and add it to the system. */ virtual csPtr CreateBody () = 0; /** * Remove a given iRigidBody from the system. * \param body the body to remove from the system. */ virtual void RemoveBody (iRigidBody* body) = 0; /** * Add a body to the specified group. * \param body the body to add to the group. * \param group the name of the group to add the body to. Creates the group if * it does not exist. */ virtual void AddBodyToGroup (iRigidBody* body, const char* group) = 0; /** * Remove a body from the specified group. * \param body the body to remove from the group. * \param group the name of the group to remove the body from. */ virtual void RemoveBodyFromGroup (iRigidBody* body, const char* group) = 0; /** * Create a joint between the two given bodies. */ virtual iJoint* CreateJoint (iRigidBody* body1, iRigidBody* body2) = 0; /** * Remove a given joint from the system. */ virtual void RemoveJoint (iJoint* joint) = 0; /** * Disable fast stepping. This is very accurate but can quickly * break with lots of objects. */ virtual void DisableStepFast () = 0; /** * Enable fast stepping. This is a lot faster then DisableStepFast(). * Default. */ virtual void EnableStepFast () = 0; /** * Very fast but not accurate. */ virtual void EnableQuickStep () = 0; }; /** * A dynamic body. * * This property class can send out the following messages * to the behaviour (add prefix 'cel.parameter.' to get the ID for parameters): * - pcdynamicbody_collision: an entity has collided with this entity. * Parameters are 'otherbody' (string: entity name), 'position' (vector3: * point of collision, 'normal' (vector3: normal of collision), and * 'depth' (float: penetration depth). * * This property class supports the following actions (add prefix * 'cel.action.' to get the ID of the action and add prefix 'cel.parameter.' * to get the ID of the parameter): * - InitPhys: parameters 'mass' (float), 'friction' (float), * 'elasticity' (float), 'density' (float), 'softness' (float), * 'lift' (vector3), and 'drag' (float). * - MakeStatic: parameters 'static' (bool). * - SetSystem: parameters 'syspcent' (string) and 'syspctag' (string). * - SetMesh: parameters 'mechpctag' (string). * - SetColliderSphere: parameters 'radius' (float) and 'offset' (vector3). * - SetColliderCylinder: parameters 'length' (float), 'radius' (float) * 'axis' (vector3), 'offset' (vector3), and 'angle' (float). * - SetColliderBox: parameters 'size' (vector3), 'axis' (vector3), * 'angle' (float), and 'offset' (vector3). * - SetColliderPlane: parameters 'normal' (vector3) and 'offset' (float). * - SetColliderMesh: no parameters. * - SetLinearVelocity: parameters 'velocity' (vector3). * - SetAngularVelocity: parameters 'velocity' (vector3). * - AddForceOnce: parameters 'force' (vector3), 'relative' (bool), * and 'position' (vector3). * - AddForceDuration: parameters 'force' (vector3), 'relative' (bool), * 'position' (vector3), and 'seconds' (float). * - AddForceFrame: parameters 'force' (vector3), 'relative' (bool), * and 'position' (vector3). * - AddForceTagged: parameters 'force' (vector3), 'relative' (bool), * and 'position' (vector3). The tag will be set in the property * 'cel.property.lasttag'. * - RemoveForceTagged: parameters 'tag' (long). * - ClearForces: no parameters. * - SetPosition: parameters 'position' (vector3). * - ClearRotation: no parameters. * - Rotate: parameters 'rotation' (vector3). * - LookAt: parameters 'forward' (vector3) and 'up' (vector3). * * This property class supports the following properties (add prefix * 'cel.property.' to get the ID of the property: * - lasttag (long, read): last tag returned by AddForceTagged action. * - linearvelocity (vector3, read/write): get current linear velocity. * - angularvelocity (vector3, read/write): get current angular velocity. * - static (bool, read/write): is static or not. * - cdcallback (bool, read/write): enable/disable the collision callback. */ struct iPcMechanicsObject : public virtual iBase { SCF_INTERFACE (iPcMechanicsObject, 0, 0, 1); /** * Set the mesh which this body will control. * If this is used then this overrides the default behaviour of * trying to find 'pcmesh', 'pclight', and 'pccamera' in that order. * \param mesh a pointer to the iPcMesh to control. */ virtual void SetMesh (iPcMesh* mesh) = 0; /** * Get the associated mesh property class. */ virtual iPcMesh* GetMesh () = 0; /** * Set the light which this body will control. * If this is used then this overrides the default behaviour of * trying to find 'pcmesh', 'pclight', and 'pccamera' in that order. * \param light a pointer to the iPcLight to control. */ virtual void SetLight (iPcLight* light) = 0; /** * Get the associated light property class. */ virtual iPcLight* GetLight () = 0; /** * Set the camera which this body will control. * If this is used then this overrides the default behaviour of * trying to find 'pcmesh', 'pclight', and 'pccamera' in that order. * \param camera a pointer to the iPcCamera to control. */ virtual void SetCamera (iPcCamera* camera) = 0; /** * Get the associated camera property class. */ virtual iPcCamera* GetCamera () = 0; /** * Set the mechanics system to use. If you don't do this then the * object will look in the object registry for a suitable mechanics * system. * \param mechsys a pointer to the iPcMechanicsSystem to use. */ virtual void SetMechanicsSystem (iPcMechanicsSystem* mechsys) = 0; /** * Get the associated mechanics system. */ virtual iPcMechanicsSystem* GetMechanicsSystem () = 0; /** * Get the associated rigid body. */ virtual iRigidBody* GetBody () = 0; //// //Object properties. /** * Set the object's friction. Must be called before Attach..., otherwise * defaults to 1. * \param friction the friction coefficient for this object. */ virtual void SetFriction (float friction) = 0; /** * Set the object's mass. Must be called before Attach..., otherwise * defaults to 1. * \param mass the mass of this object. */ virtual void SetMass (float mass) = 0; /** * Set the object's elasticity. Must be called before Attach..., otherwise * defaults to 0. * \param elasticity the elasticity of this object. */ virtual void SetElasticity (float elasticity) = 0; /** * Set the object's density. Must be called before Attach..., otherwise * defaults to 1. * \param density the density of this object. */ virtual void SetDensity (float density) = 0; /** * Set the object's softness. Must be called before Attach..., otherwise * defaults to 0. * \param softness the softness of this object. */ virtual void SetSoftness (float softness) = 0; /** * Set the object's lift. Must be called before Attach..., otherwise * defaults to 0. * \param lift the lift generated by this object in a fluid. */ virtual void SetLift (const csVector3& lift) = 0; /** * Set the object's drag. Must be called before Attach..., otherwise * defaults to 0. * \param drag the drag generated by this object in a fluid. */ virtual void SetDrag (float drag) = 0; /** * Get the object's friction. Must be called before Attach..., otherwise * defaults to 1. */ virtual float GetFriction () = 0; /** * Get the object's mass. Must be called before Attach..., otherwise * defaults to 1. */ virtual float GetMass () = 0; /** * Get the object's elasticity. Must be called before Attach..., otherwise * defaults to 0. */ virtual float GetElasticity () = 0; /** * Get the object's density. Must be called before Attach..., otherwise * defaults to 1. */ virtual float GetDensity () = 0; /** * Get the object's softness. Must be called before Attach..., otherwise * defaults to 0. */ virtual float GetSoftness () = 0; /** * Get the object's lift. Must be called before Attach..., otherwise * defaults to 0. */ virtual const csVector3& GetLift () = 0; /** * Get the object's drag. Must be called before Attach..., otherwise * defaults to 0. */ virtual float GetDrag () = 0; //// //Initial velocities /** * Set the initial linear velocity (movement) of the object. * \param vel the linear velocity to apply to the object. */ virtual void SetLinearVelocity (const csVector3& vel) = 0; /** * Set the initial angular velocity (rotation) of the object. * \param vel the angular velocity to apply to the object */ virtual void SetAngularVelocity (const csVector3& vel) = 0; //// //Reading velocities /** * Get the current linear velocity (movement) of the object. */ virtual const csVector3 GetLinearVelocity () = 0; /** * Get the current angular velocity (rotation) of the object. */ virtual const csVector3 GetAngularVelocity () = 0; /** * Make static. * \param stat if true, the object is static; otherwise it is affected * by forces. */ virtual void MakeStatic (bool stat) = 0; /** * Return true if static. */ virtual bool IsStatic () const = 0; /** * Set to true if you want to receive collision detection events * (pcdynamicbody_collision). By default this is true. */ virtual void SetCollisionCallbackEnabled (bool en) = 0; /// Return true if collision callback is enabled. virtual bool IsCollisionCallbackEnabled () const = 0; //// //Colliders /** * Create a sphere collider for this object, automatically sized * and positioned from it's mesh. * \param radiusadjustment Amount to vary the radius from actual bounding radius. */ virtual void AttachColliderBoundingSphere (float radiusadjustment = 0.0f) = 0; /** * Create a sphere collider for this object. * \param radius the radius of the sphere. * \param offset the offset from the center of the object to the center of * the sphere. */ virtual void AttachColliderSphere (float radius, const csVector3& offset) = 0; /** * Create a cylinder collider for this object. * \param length the length of the cylinder. * \param radius the radius of the cylinder. * \param trans the transformation to apply to the cylinder. */ virtual void AttachColliderCylinder (float length, float radius, const csOrthoTransform& trans) = 0; /** * Create a box collider for this object, automatically sized and positioned from it's mesh. * \param sizeadjustment Amount to vary the size from actual bounding size. */ virtual void AttachColliderBoundingBox (const csVector3& sizeadjustment = csVector3(0)) = 0; /** * Create a box collider for this object. * \param size the size of the box in each direction. * \param trans the transformation to apply to the box. */ virtual void AttachColliderBox (const csVector3& size, const csOrthoTransform& trans) = 0; /** * Create a plane collider for this object. * \param plane the definition of the plane to use. */ virtual void AttachColliderPlane (const csPlane3& plane) = 0; /** * Create a mesh collider for this object from the attached iPcMesh. */ virtual void AttachColliderMesh () = 0; //// //Forces /** * Add a force once to the given object. * \param force a vector representing the force to add to this object. * \param relative if set to true, the given force and position are both in * object space; otherwise they are in world space. * \param position the position of the force. */ virtual void AddForceOnce (const csVector3& force, bool relative, const csVector3& position) = 0; /** * During the specified time (in seconds) add the force every step. * \param force a vector representing the force to add to this object. * \param relative if set to true, the given force and position are both in * object space; otherwise they are in world space. * \param position the position of the force. * \param seconds the number of seconds that this force should last. */ virtual void AddForceDuration (const csVector3& force, bool relative, const csVector3& position, float seconds) = 0; /** * During the next frame add the force every step. * \param force a vector representing the force to add to this object. * \param relative if set to true, the given force and position are both in * object space; otherwise they are in world space. * \param position the position of the force. */ virtual void AddForceFrame (const csVector3& force, bool relative, const csVector3& position) = 0; /** * Add a force with the given tag, to be manually removed later. * \param force a vector representing the force to add to this object. * \param relative if set to true, the given force and position are both in * object space; otherwise they are in world space. * \param position the position of the force. * return value is the force id tag (use it to remove the force later). */ virtual uint32 AddForceTagged (const csVector3& force, bool relative, const csVector3& position) = 0; /** * Remove the force with the given tag. * \param forceid the tag of the desired force. */ virtual void RemoveForceTagged (uint32 forceid) = 0; /** * Clear the permanent forces on this body. */ virtual void ClearForces () = 0; //// //Groups and Joints /** * Add this body to the specified group. * \param group the name of the group to add the body to. Creates the group if * it does not exist. */ virtual void AddToGroup (const char* group) = 0; /** * Remove this body from the specified group. * \param group the name of the group to remove the body from. */ virtual void RemoveFromGroup (const char* group) = 0; /** * Create a joint between this object and another. */ virtual iJoint* CreateJoint (iPcMechanicsObject* other) = 0; /** * Convert a vector from this objects local system to world coord system */ virtual csVector3 LocalToWorld(csVector3 local) = 0; /** * Convert a vector from world coord system to this objects local system */ virtual csVector3 WorldToLocal(csVector3 world) = 0; }; /** * A joint. * * This property class supports the following actions (add prefix * 'cel.action.' to get the ID of the action and add prefix 'cel.parameter.' * to get the ID of the parameter): * - SetParentBody: parameters 'body' (string). * - SetPosition: parameters 'position' (vector3). * - SetConstrainDist: parameters 'x' (bool), 'y' (bool), and 'z' (bool). * - SetDistances: parameters 'min' (vector3) and 'max' (vector3). * - SetConstrainAngle: parameters 'x' (bool), 'y' (bool), and 'z' (bool). * - SetAngles: parameters 'min' (vector3) and 'max' (vector3). */ struct iPcMechanicsJoint : public virtual iBase { SCF_INTERFACE (iPcMechanicsJoint, 0, 0, 1); /** * Get the joint corresponding with this. */ virtual iJoint* GetJoint () = 0; }; #endif // __CEL_PF_MECHANICS_SYSTEM__