Files
Webcam/include/engine/physic/physic_world.h
2026-06-22 11:49:35 +02:00

138 lines
3.3 KiB
C++

/* -----------------------------------------------------------------------------
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 <nPhysicListener *> 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__