Преглед изворни кода

Do not pass around Unit pointers, use UnitId instead.

Daniele Bartolini пре 12 година
родитељ
комит
e8844c9031

+ 40 - 41
engine/physics/Actor.cpp

@@ -36,6 +36,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "SceneGraph.h"
 #include "Unit.h"
 #include "Vector3.h"
+#include "World.h"
+#include "PhysicsWorld.h"
 #include "PxCooking.h"
 #include "PxDefaultStreams.h"
 
@@ -77,20 +79,35 @@ namespace crown
 {
 
 //-----------------------------------------------------------------------------
-Actor::Actor(const PhysicsResource* res, const PhysicsConfigResource* config, uint32_t index, PxPhysics* physics, PxCooking* cooking,
-				PxScene* scene, SceneGraph& sg, int32_t node, Unit* unit, const Vector3& pos, const Quaternion& rot)
-	: m_resource(res)
-	, m_config(config)
-	, m_index(index)
-	, m_unit(unit)
-	, m_scene(scene)
+Actor::Actor(PhysicsWorld& pw, const PhysicsResource* res, uint32_t actor_idx, SceneGraph& sg, int32_t node, UnitId unit_id)
+	: m_world(pw)
+	, m_resource(res)
+	, m_index(actor_idx)
 	, m_scene_graph(sg)
 	, m_node(node)
+	, m_unit(unit_id)
+{
+	create_objects();
+}
+
+//-----------------------------------------------------------------------------
+Actor::~Actor()
+{
+	destroy_objects();
+}
+
+//-----------------------------------------------------------------------------
+void Actor::create_objects()
 {
 	const PhysicsActor& actor = m_resource->actor(m_index);
+
+	PxScene* scene = m_world.physx_scene();
+	PxPhysics* physics = m_world.physx_physics();
+	const PhysicsConfigResource* config = m_world.resource();
 	const PhysicsActor2& actor_class = config->actor(actor.actor_class);
 
-	const PxMat44 pose((PxReal*) (sg.world_pose(node).to_float_ptr()));
+	// Create rigid body
+	const PxMat44 pose((PxReal*) (m_scene_graph.world_pose(m_node).to_float_ptr()));
 
 	if (actor_class.flags & PhysicsActor2::DYNAMIC)
 	{
@@ -110,32 +127,7 @@ Actor::Actor(const PhysicsResource* res, const PhysicsConfigResource* config, ui
 		m_actor = physics->createRigidStatic(PxTransform(pose));
 	}
 
-	m_actor->userData = this;
-
-	create_shapes(res, config, physics, cooking);
-
-	// FIXME collisions works only if enable_collision() is called here first
-	// collision enabled by default
-	enable_collision();
-
-	m_actor->setActorFlag(PxActorFlag::eSEND_SLEEP_NOTIFIES, true);
-	m_scene->addActor(*m_actor);
-}
-
-//-----------------------------------------------------------------------------
-Actor::~Actor()
-{
-	if (m_actor)
-	{
-		m_scene->removeActor(*m_actor);
-		m_actor->release();
-	}
-}
-
-//-----------------------------------------------------------------------------
-void Actor::create_shapes(const PhysicsResource* res, const PhysicsConfigResource* config, PxPhysics* physics, PxCooking* cooking)
-{
-	const PhysicsActor& actor = m_resource->actor(m_index);
+	// Create shapes
 	uint32_t shape_index = m_resource->shape_index(m_index);
 	for (uint32_t i = 0; i < actor.num_shapes; i++)
 	{
@@ -183,13 +175,12 @@ void Actor::create_shapes(const PhysicsResource* res, const PhysicsConfigResourc
 				convex_mesh_desc.vertexLimit		= MAX_PHYSX_VERTICES;
 
 				PxDefaultMemoryOutputStream buf;
-				if(!cooking->cookConvexMesh(convex_mesh_desc, buf))
+				if(!m_world.physx_cooking()->cookConvexMesh(convex_mesh_desc, buf))
 					CE_FATAL();
 				PxDefaultMemoryInputData input(buf.getData(), buf.getSize());
 				PxConvexMesh* convex_mesh = physics->createConvexMesh(input);
 
 				px_shape = m_actor->createShape(PxConvexMeshGeometry(convex_mesh), *mat);
-
 				break;
 			}
 			default:
@@ -207,10 +198,18 @@ void Actor::create_shapes(const PhysicsResource* res, const PhysicsConfigResourc
 		shape_index++;
 	}
 
-	// PxFilterData filter;
-	// filter.word0 = (PxU32) m_group;
-	// filter.word1 = (PxU32) m_mask;
-	// shape->SetSimulationFilterData()
+	m_actor->userData = this;
+	scene->addActor(*m_actor);
+}
+
+//-----------------------------------------------------------------------------
+void Actor::destroy_objects()
+{
+	if (m_actor)
+	{
+		m_world.physx_scene()->removeActor(*m_actor);
+		m_actor->release();
+	}
 }
 
 //-----------------------------------------------------------------------------
@@ -434,7 +433,7 @@ StringId32 Actor::name()
 //-----------------------------------------------------------------------------
 Unit* Actor::unit()
 {
-	return m_unit;
+	return (m_unit.id == INVALID_ID) ? NULL : m_world.world().lookup_unit(m_unit);
 }
 
 //-----------------------------------------------------------------------------

+ 48 - 54
engine/physics/Actor.h

@@ -27,11 +27,10 @@ OTHER DEALINGS IN THE SOFTWARE.
 #pragma once
 
 #include "Types.h"
-#include "IdArray.h"
+#include "MathTypes.h"
 #include "PhysicsTypes.h"
-#include "Vector3.h"
-#include "Matrix4x4.h"
-#include "Quaternion.h"
+#include "IdArray.h"
+#include "WorldTypes.h"
 
 #include "PxPhysics.h"
 #include "PxScene.h"
@@ -39,10 +38,6 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "PxCooking.h"
 
 using physx::PxRigidActor;
-using physx::PxMaterial;
-using physx::PxScene;
-using physx::PxPhysics;
-using physx::PxCooking;
 
 namespace crown
 {
@@ -56,132 +51,131 @@ struct Matrix4x4;
 struct Unit;
 class SceneGraph;
 
+/// Represents a rigid body.
 ///
 /// @ingroup Physics
 struct Actor
 {
-	/// Constructor
-						Actor(const PhysicsResource* res, const PhysicsConfigResource* config, uint32_t index, PxPhysics* physics, PxCooking* cooking,
-								PxScene* scene, SceneGraph& sg, int32_t node, Unit* unit, const Vector3& pos, const Quaternion& rot);
-	/// Destructor
-						~Actor();
+	Actor(PhysicsWorld& pw, const PhysicsResource* res, uint32_t actor_idx, SceneGraph& sg, int32_t node, UnitId unit_id);
+	~Actor();
 
 	/// Makes the actor subject to gravity
-	void				enable_gravity();
+	void enable_gravity();
 
 	/// Makes the actor unsubject to gravity
-	void				disable_gravity();
+	void disable_gravity();
 
-	void				enable_collision();
-	void				disable_collision();
+	void enable_collision();
+	void disable_collision();
 
 	/// Makes the actor kinematic (keyframed)
 	/// @note
 	/// Works only for dynamic actors
-	void				set_kinematic();
+	void set_kinematic();
 
 	/// Makes the actor dynamic
 	/// @note
 	/// Works only for kinematic actors
-	void				clear_kinematic();
+	void clear_kinematic();
 
 	/// Moves the actor to @a pos
 	/// @note
 	/// Works only for kinematic actors
-	void				move(const Vector3& pos);
+	void move(const Vector3& pos);
 
 	/// Returns whether the actor is static (i.e. immovable).
-	bool				is_static() const;
+	bool is_static() const;
 
 	/// Returns whether the actor is dynamic (i.e. driven dy physics).
-	bool				is_dynamic() const;
+	bool is_dynamic() const;
 
 	/// Returns whether the actor is kinematic (i.e. driven by the user).
-	bool				is_kinematic() const;
+	bool is_kinematic() const;
 
 	/// Returns the rate at which rigid bodies dissipate linear momentum
-	float				linear_damping() const;
+	float linear_damping() const;
 
 	/// Sets the rate at which rigid bodies dissipate linear momentum
-	void				set_linear_damping(float rate);
+	void set_linear_damping(float rate);
 
 	/// Returns the rate at which rigid bodies dissipate angular momentum
-	float				angular_damping() const;
+	float angular_damping() const;
 
 	/// Sets the rate at which rigid bodies dissipate angular momentum
-	void				set_angular_damping(float rate);
-
+	void set_angular_damping(float rate);
+ 
 	/// Returns linear velocity of the actor
 	/// @note
 	/// If actor is sleeping, linear velocity must be 0
-	Vector3				linear_velocity() const;
+	Vector3 linear_velocity() const;
 
 	/// Sets linear velocity of the actor
 	/// @note
 	/// If actor is sleeping, this will wake it up
-	void				set_linear_velocity(const Vector3& vel);
+	void set_linear_velocity(const Vector3& vel);
 
 	/// Returns angular velocity of the actor
 	/// @note
 	/// If actor is sleeping, angular velocity must be 0
-	Vector3				angular_velocity() const;
+	Vector3 angular_velocity() const;
 
 	/// Sets angular velocity of the actor
 	/// @note
 	/// If actor is sleeping, this will wake it up
-	void				set_angular_velocity(const Vector3& vel);
+	void set_angular_velocity(const Vector3& vel);
 
 	/// Applies a force (or impulse) defined in the global coordinate frame, acting at a particular point in global coordinates, to the actor.
 	/// @note
 	/// If the force does not act along the center of mass of the actor, this will also add the corresponding torque.
 	/// Because forces are reset at the end of every timestep, you can maintain a total external force on an object by calling this once every frame.
-	void				add_impulse(const Vector3& impulse);
+	void add_impulse(const Vector3& impulse);
 
 	/// Applies a force (or impulse) defined in the global coordinate frame, acting at a particular point in local coordinates, to the actor.
 	/// @note
 	/// If the force does not act along the center of mass of the actor, this will also add the corresponding torque.
 	/// Because forces are reset at the end of every timestep, you can maintain a total external force on an object by calling this once every frame. 
-	void				add_impulse_at(const Vector3& impulse, const Vector3& pos);
+	void add_impulse_at(const Vector3& impulse, const Vector3& pos);
 
 	/// Applies a force, evaluated by actor's @a mass and @a velocity that will be achieved, to the actor
-	void				push(const Vector3& vel, const float mass);
+	void push(const Vector3& vel, const float mass);
 
 	/// Returns true if tha actor is sleeping, false otherwise
-	bool				is_sleeping();
+	bool is_sleeping();
 
 	/// Forces the actor to wake up
-	void				wake_up();
+	void wake_up();
 
 	/// Returns actor's name
-	StringId32			name();
+	StringId32 name();
 
-	/// Returns the unit that owns this actor
-	Unit*				unit();
+	/// Returns the unit that owns the actor.
+	Unit* unit();
+
+	const PhysicsResource* resource() const { return m_resource; }
 
 private:
 
-	void				update(const Matrix4x4& pose);
-	void				create_shapes(const PhysicsResource* res, const PhysicsConfigResource* config, PxPhysics* physics, PxCooking* cooking);
-	Matrix4x4			get_kinematic_pose() const;
+	void create_objects();
+	void destroy_objects();
+
+	void update(const Matrix4x4& pose);
+	Matrix4x4 get_kinematic_pose() const;
 
 public:
 
-	const PhysicsResource*			m_resource;
-	const PhysicsConfigResource* 	m_config;
-	uint32_t						m_index;
+	PhysicsWorld& m_world;
+	const PhysicsResource* m_resource;
+	uint32_t m_index;
+	PxRigidActor* m_actor;
 
-	Unit*							m_unit;
+	SceneGraph& m_scene_graph;
+	int32_t m_node;
 
-	PxScene*						m_scene;
-	SceneGraph&						m_scene_graph;
-	int32_t							m_node;
-	PxRigidActor* 					m_actor;
-	uint32_t						m_group;
-	uint32_t						m_mask;
+	UnitId m_unit;
 
 private:
 
 	friend class PhysicsWorld;
 };
 
-} // namespace crown
+} // namespace crown

+ 4 - 1
engine/physics/PhysicsTypes.h

@@ -33,11 +33,14 @@ namespace crown
 
 typedef Id ActorId;
 typedef Id ControllerId;
-typedef Id TriggerId;
 typedef Id JointId;
 typedef Id RaycastId;
 
 struct Actor;
+struct Controller;
+struct Joint;
+struct Raycast;
+class PhysicsWorld;
 
 //-----------------------------------------------------------------------------
 struct ActorType

+ 12 - 5
engine/physics/PhysicsWorld.cpp

@@ -210,8 +210,9 @@ namespace physics_system
 } // namespace physics_system
 
 //-----------------------------------------------------------------------------
-PhysicsWorld::PhysicsWorld()
-	: m_scene(NULL)
+PhysicsWorld::PhysicsWorld(World& world)
+	: m_world(world)
+	, m_scene(NULL)
 	, m_buffer(m_hits, 64)
 	, m_actors_pool(default_allocator(), CE_MAX_ACTORS, sizeof(Actor), CE_ALIGNOF(Actor))
 	, m_controllers_pool(default_allocator(), CE_MAX_CONTROLLERS, sizeof(Controller), CE_ALIGNOF(Controller))
@@ -248,6 +249,8 @@ PhysicsWorld::PhysicsWorld()
 	// Create controller manager
 	m_controller_manager = PxCreateControllerManager(*m_scene);
 	CE_ASSERT(m_controller_manager != NULL, "Failed to create PhysX controller manager");
+
+	m_resource = (PhysicsConfigResource*) device()->resource_manager()->lookup("physics_config", "global");
 }
 
 //-----------------------------------------------------------------------------
@@ -259,10 +262,10 @@ PhysicsWorld::~PhysicsWorld()
 }
 
 //-----------------------------------------------------------------------------
-ActorId	PhysicsWorld::create_actor(const PhysicsResource* res, const uint32_t index, SceneGraph& sg, int32_t node, Unit* unit)
+ActorId	PhysicsWorld::create_actor(const PhysicsResource* res, const uint32_t index, SceneGraph& sg, int32_t node, UnitId unit_id)
 {
 	PhysicsConfigResource* config = (PhysicsConfigResource*) device()->resource_manager()->lookup("physics_config", "global");
-	Actor* actor = CE_NEW(m_actors_pool, Actor)(res, config, index, physics_system::s_physics, physics_system::s_cooking, m_scene, sg, node, unit, vector3::ZERO, quaternion::IDENTITY);
+	Actor* actor = CE_NEW(m_actors_pool, Actor)(*this, res, index, sg, node, unit_id);
 	return m_actors.create(actor);
 }
 
@@ -454,4 +457,8 @@ void PhysicsWorld::update(float dt)
 	}
 }
 
-} // namespace crown
+PxPhysics* PhysicsWorld::physx_physics() { return physics_system::s_physics; }
+PxCooking* PhysicsWorld::physx_cooking() { return physics_system::s_cooking; }
+PxScene* PhysicsWorld::physx_scene() { return m_scene; }
+
+} // namespace crown

+ 42 - 35
engine/physics/PhysicsWorld.h

@@ -31,8 +31,11 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "PhysicsTypes.h"
 #include "PhysicsCallback.h"
 #include "EventStream.h"
-
+#include "PhysicsTypes.h"
+#include "MathTypes.h"
+#include "WorldTypes.h"
 #include "PxScene.h"
+#include "PxCooking.h"
 #include "PxDefaultCpuDispatcher.h"
 #include "PxControllerManager.h"
 
@@ -44,6 +47,10 @@ using physx::PxDefaultCpuDispatcher;
 using physx::PxActor;
 using physx::PxOverlapHit;
 using physx::PxOverlapBuffer;
+using physx::PxMaterial;
+using physx::PxShape;
+using physx::PxPhysics;
+using physx::PxCooking;
 
 namespace crown
 {
@@ -63,17 +70,10 @@ namespace physics_system
 
 //-----------------------------------------------------------------------------
 class SceneGraph;
-struct Actor;
-struct Actor;
-struct Controller;
-struct Joint;
-struct Matrix4x4;
-struct PhysicsActor;
+class World;
 struct PhysicsResource;
-struct Quaternion;
-struct Raycast;
+struct PhysicsConfigResource;
 struct Unit;
-struct Vector3;
 
 /// Manages physics objects in a World.
 ///
@@ -82,42 +82,51 @@ class PhysicsWorld
 {
 public:
 
-	/// Constructor
-								PhysicsWorld();
-	/// Destroyer
-								~PhysicsWorld();
+	PhysicsWorld(World& world);
+	~PhysicsWorld();
 
-	ActorId						create_actor(const PhysicsResource* res, const uint32_t index, SceneGraph& sg, int32_t node, Unit* unit);
-	void						destroy_actor(ActorId id);
+	ActorId create_actor(const PhysicsResource* res, const uint32_t index, SceneGraph& sg, int32_t node, UnitId unit_id);
+	void destroy_actor(ActorId id);
 
-	ControllerId				create_controller(const PhysicsResource* pr, SceneGraph& sg, int32_t node);
-	void						destroy_controller(ControllerId id);
+	ControllerId create_controller(const PhysicsResource* pr, SceneGraph& sg, int32_t node);
+	void destroy_controller(ControllerId id);
 
-	JointId						create_joint(const PhysicsResource* pr, const uint32_t index, const Actor& actor_0, const Actor& actor_1);
-	void						destroy_joint(JointId id);
+	JointId create_joint(const PhysicsResource* pr, const uint32_t index, const Actor& actor_0, const Actor& actor_1);
+	void destroy_joint(JointId id);
 
-	RaycastId					create_raycast(const char* callback, CollisionMode::Enum mode, CollisionType::Enum filter);
-	void						destroy_raycast(RaycastId id);
+	RaycastId create_raycast(const char* callback, CollisionMode::Enum mode, CollisionType::Enum filter);
+	void destroy_raycast(RaycastId id);
 
-	Actor*						lookup_actor(StringId32 name);
-	Actor*						lookup_actor(ActorId id);
-	Controller*					lookup_controller(ControllerId id);
-	Raycast*					lookup_raycast(RaycastId id);
 
-	Vector3						gravity() const;
-	void						set_gravity(const Vector3& g);
+	Vector3 gravity() const;
+	void set_gravity(const Vector3& g);
 
-	void						set_kinematic(ActorId id);
-	void						clear_kinematic(ActorId id);
+	void set_kinematic(ActorId id);
+	void clear_kinematic(ActorId id);
 
 	/// Finds all actors in the physics world that are in a particular shape (supported: spheres, capsules and boxes)
-	void						overlap_test(const char* callback, CollisionType::Enum filter, ShapeType::Enum type,
+	void overlap_test(const char* callback, CollisionType::Enum filter, ShapeType::Enum type,
 											const Vector3& pos, const Quaternion& rot, const Vector3& size, Array<Actor*>& actors);
 
-	void						update(float dt);
+	void update(float dt);
+
+	Actor* lookup_actor(StringId32 name);
+	Actor* lookup_actor(ActorId id);
+	Controller* lookup_controller(ControllerId id);
+	Raycast* lookup_raycast(RaycastId id);
+
+	World& world() { return m_world; }
 
 public:
 
+	PxPhysics* physx_physics();
+	PxCooking* physx_cooking();
+	PxScene* physx_scene();
+	const PhysicsConfigResource* resource() { return m_resource; }
+
+private:
+
+	World&						m_world;
 	PxControllerManager*		m_controller_manager;
 	PxScene*					m_scene;
 	PxDefaultCpuDispatcher*		m_cpu_dispatcher;
@@ -139,9 +148,7 @@ public:
 	EventStream m_events;
 	PhysicsSimulationCallback m_callback;
 
-public:
-
-	friend class PhysicsSimulationCallback;
+	const PhysicsConfigResource* m_resource;
 };
 
 } // namespace crown

+ 3 - 2
engine/world/Unit.cpp

@@ -41,11 +41,12 @@ namespace crown
 {
 
 //-----------------------------------------------------------------------------
-Unit::Unit(World& w, const ResourceId id, const UnitResource* ur, const Matrix4x4& pose)
+Unit::Unit(World& w, UnitId unit_id, const ResourceId id, const UnitResource* ur, const Matrix4x4& pose)
 	: m_world(w)
 	, m_scene_graph(*w.scene_graph_manager()->create_scene_graph())
 	, m_resource_id(id)
 	, m_resource(ur)
+	, m_id(unit_id)
 	, m_num_cameras(0)
 	, m_num_meshes(0)
 	, m_num_sprites(0)
@@ -206,7 +207,7 @@ void Unit::create_physics_objects()
 		{
 			const PhysicsActor& actor = pr->actor(i);
 
-			ActorId id = m_world.physics_world()->create_actor(pr, i, m_scene_graph, m_scene_graph.node(actor.node), this);
+			ActorId id = m_world.physics_world()->create_actor(pr, i, m_scene_graph, m_scene_graph.node(actor.node), m_id);
 			add_actor(actor.name, id);
 		}
 

+ 1 - 1
engine/world/Unit.h

@@ -78,7 +78,7 @@ struct UnitResource;
 /// @ingroup World
 struct Unit
 {
-						Unit(World& w, const ResourceId id, const UnitResource* ur, const Matrix4x4& pose);
+						Unit(World& w, UnitId unit_id, const ResourceId id, const UnitResource* ur, const Matrix4x4& pose);
 						~Unit();
 
 	void				set_id(const UnitId id);

+ 4 - 6
engine/world/World.cpp

@@ -38,6 +38,7 @@ namespace crown
 World::World()
 	: m_unit_pool(default_allocator(), CE_MAX_UNITS, sizeof(Unit), CE_ALIGNOF(Unit))
 	, m_camera_pool(default_allocator(), CE_MAX_CAMERAS, sizeof(Camera), CE_ALIGNOF(Camera))
+	, m_physics_world(*this)
 	, m_events(default_allocator())
 {
 	m_id.id = INVALID_ID;
@@ -79,12 +80,9 @@ UnitId World::spawn_unit(const char* name, const Vector3& pos, const Quaternion&
 //-----------------------------------------------------------------------------
 UnitId World::spawn_unit(const ResourceId id, UnitResource* ur, const Vector3& pos, const Quaternion& rot)
 {
-	// Allocate memory for unit
-	Unit* unit = CE_NEW(m_unit_pool, Unit)(*this, id, ur, Matrix4x4(rot, pos));
-
-	// Create Id for the unit
-	const UnitId unit_id = m_units.create(unit);
-	unit->set_id(unit_id);
+	Unit* u = (Unit*) m_unit_pool.allocate(sizeof(Unit), CE_ALIGNOF(Unit));
+	const UnitId unit_id = m_units.create(u);
+	new (u) Unit(*this, unit_id, id, ur, Matrix4x4(rot, pos));
 
 	// SpawnUnitEvent ev;
 	// ev.unit = unit_id;