/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NPHYSICWORLD__ #define __NPHYSICWORLD__ #include "physic/physic_world_interface.h" #include "physic/physic_message.h" #include "math/vector.h" #include "timing/benchmark.h" #include "container/nlist.h" #include "nstring/nstring.h" namespace GS { namespace Core { class Camera; } namespace Render { class Renderer; class RasterFont; } namespace S3D { class PhysicItem; class PhysicConstraint; struct PhysicShape; using Core::Camera; using Render::Renderer; using Render::RasterFont; /// Raytrace hit result structure. struct PhysicTrace { Vector4 n, p; ///< Intersection normal and point in world space. String m; ///< Material name at intersection point. PhysicShape *s; PhysicItem *i; PhysicTrace() : m(0), s(0), i(0) {} }; /// Collision pair. struct CollisionPair { PhysicItem *a, *b; uint contact_count; Vector4 contact[4], normal[4]; CollisionPair() : a(0), b(0), contact_count(0) {} }; /* @short Abstract physic world. @author Emmanuel Julien (ejulien@gsworks.fr) */ class PhysicWorld { protected: float timestep, substep_dt; Vector4 gravity; IPhysicWorld *world_interface; public: Benchmark bench_step; virtual PhysicItem *NewItem() = 0; virtual PhysicConstraint *NewConstraint() = 0; /// Clear convex/mesh cache. virtual void ClearConvexMeshCache() = 0; virtual bool HasDebugger() const { return false; } virtual void CreateDebugger(Renderer * = 0) {} /// Draw debug informations (native library display). virtual void DrawDebug(Renderer &, Camera *, RasterFont *, bool xray_first_pass) {} void SetWorldInterface(IPhysicWorld *i) { world_interface = i; } IPhysicWorld *GetWorldInterface() const { return world_interface; } void SetTimestep(float t = 1.f / 60.f) { timestep = t; } float GetTimestep() const { return timestep; } void SetGravity(const Vector4 &g) { gravity = g; } const Vector4 &GetGravity() const { return gravity; } virtual bool Create() = 0; virtual void Delete() = 0; /// Raytrace world. virtual bool Raytrace(const Vector4 &s, const Vector4 &d, PhysicTrace &hit, int collision_mask = ~0, int shape_mask = ~0, float max_distance = -1.f) = 0; /// Return the number of collision pair in the previous step. virtual uint GetCollisionPairCount() = 0; /// Return the number of collision pair in the previous step. virtual bool GetCollisionPair(uint n, CollisionPair &) = 0; virtual void Step(const Time &dt) = 0; /*! @name Low-level message broadcasting system. @{ */ protected: /// Physics message listener. List listener_list; public: bool RegisterMessageListener(nPhysicListener *listener) { return asbool(listener_list.Add(listener)); } bool UnregisterMessageListener(nPhysicListener *listener) { return listener_list.Remove(listener); } void BroadcastMessage(nPhysicMessage msg, void *parm = 0) { ListForeachPtr(nPhysicListener *, listener, listener_list) listener->ProcessMessage(msg, parm); } /// @} PhysicWorld(); virtual ~PhysicWorld() {} }; } // S3D } // GS #endif // __NPHYSICWORLD__