Просмотр исходного кода

Add support for locking individual DOF

Daniele Bartolini 11 лет назад
Родитель
Сommit
0c7a1400dd

+ 14 - 48
engine/physics/actor.cpp

@@ -4,13 +4,9 @@
  */
 
 #include "actor.h"
-#include "device.h"
-#include "log.h"
 #include "matrix4x4.h"
-#include "mesh_resource.h"
 #include "physics_resource.h"
 #include "quaternion.h"
-#include "resource_manager.h"
 #include "scene_graph.h"
 #include "unit.h"
 #include "vector3.h"
@@ -18,47 +14,11 @@
 #include "physics_world.h"
 #include "quaternion.h"
 #include "string_utils.h"
-
 #include "PxPhysicsAPI.h"
 #include "PxCooking.h"
 #include "PxDefaultStreams.h"
 
-using physx::PxActorFlag;
-using physx::PxActorType;
-using physx::PxBoxGeometry;
-using physx::PxCapsuleGeometry;
-using physx::PxConvexFlag;
-using physx::PxConvexMesh;
-using physx::PxConvexMeshDesc;
-using physx::PxConvexMeshGeometry;
-using physx::PxD6Axis;
-using physx::PxD6Joint;
-using physx::PxD6JointCreate;
-using physx::PxD6Motion;
-using physx::PxDefaultMemoryInputData;
-using physx::PxDefaultMemoryOutputStream;
-using physx::PxFilterData;
-using physx::PxForceMode;
-using physx::PxMat44;
-using physx::PxPlaneGeometry;
-using physx::PxQuat;
-using physx::PxReal;
-using physx::PxRigidActor;
-using physx::PxRigidBody;
-using physx::PxRigidBodyExt;
-using physx::PxRigidBodyFlag;
-using physx::PxRigidDynamic;
-using physx::PxRigidDynamicFlag;
-using physx::PxRigidStatic;
-using physx::PxShape;
-using physx::PxShapeFlag;
-using physx::PxSphereGeometry;
-using physx::PxTransform;
-using physx::PxU16;
-using physx::PxU32;
-using physx::PxVec3;
-using physx::PxTransformFromPlaneEquation;
-using physx::PxPlane;
+using namespace physx;
 
 namespace crown
 {
@@ -98,10 +58,16 @@ void Actor::create_objects()
 			static_cast<PxRigidDynamic*>(m_actor)->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true);
 		}
 
-		// PxD6Joint* joint = PxD6JointCreate(*physics, m_actor, PxTransform(pose), NULL, PxTransform(pose));
-		// joint->setMotion(PxD6Axis::eX, PxD6Motion::eFREE);
-		// joint->setMotion(PxD6Axis::eY, PxD6Motion::eFREE);
-		// joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
+		if (actor->flags != 0)
+		{
+			PxD6Joint* d6 = PxD6JointCreate(*physics, m_actor, PxTransform::createIdentity(), NULL, PxTransform(pose));
+			d6->setMotion(PxD6Axis::eX, !(actor->flags & ActorFlags::LOCK_TRANSLATION_X) ? PxD6Motion::eFREE : PxD6Motion::eLOCKED);
+			d6->setMotion(PxD6Axis::eY, !(actor->flags & ActorFlags::LOCK_TRANSLATION_Y) ? PxD6Motion::eFREE : PxD6Motion::eLOCKED);
+			d6->setMotion(PxD6Axis::eZ, !(actor->flags & ActorFlags::LOCK_TRANSLATION_Z) ? PxD6Motion::eFREE : PxD6Motion::eLOCKED);
+			d6->setMotion(PxD6Axis::eTWIST, !(actor->flags & ActorFlags::LOCK_ROTATION_X) ? PxD6Motion::eFREE : PxD6Motion::eLOCKED);
+			d6->setMotion(PxD6Axis::eSWING1, !(actor->flags & ActorFlags::LOCK_ROTATION_Y) ? PxD6Motion::eFREE : PxD6Motion::eLOCKED);
+			d6->setMotion(PxD6Axis::eSWING2, !(actor->flags & ActorFlags::LOCK_ROTATION_Z) ? PxD6Motion::eFREE : PxD6Motion::eLOCKED);
+		}
 	}
 	else
 	{
@@ -456,9 +422,9 @@ void Actor::add_impulse_at(const Vector3& impulse, const Vector3& pos)
 		return;
 
 	PxRigidBodyExt::addForceAtPos(*static_cast<PxRigidDynamic*>(m_actor),
-									   PxVec3(impulse.x, impulse.y, impulse.z),
-									   PxVec3(pos.x, pos.y, pos.z),
-									   PxForceMode::eIMPULSE);
+		PxVec3(impulse.x, impulse.y, impulse.z),
+		PxVec3(pos.x, pos.y, pos.z),
+		PxForceMode::eIMPULSE);
 }
 
 void Actor::add_torque_impulse(const Vector3& i)

+ 2 - 3
engine/physics/joint.cpp

@@ -125,10 +125,9 @@ Joint::Joint(PxPhysics* physics, const JointResource* jr, const Actor& actor_0,
 
 			break;
 		}
-		case JointType::D6:
+		default:
 		{
-			// Must be implemented
-
+			CE_FATAL("Bad joint type");
 			break;
 		}
 	}

+ 0 - 1
engine/physics/physics_types.h

@@ -54,7 +54,6 @@ struct JointType
 		REVOLUTE,
 		PRISMATIC,
 		DISTANCE,
-		D6,
 
 		COUNT
 	};

+ 17 - 20
engine/resource/physics_resource.cpp

@@ -26,10 +26,11 @@ namespace physics_resource
 
 	static const Shape s_shape[ShapeType::COUNT] =
 	{
-		{ "sphere",  ShapeType::SPHERE  },
-		{ "capsule", ShapeType::CAPSULE },
-		{ "box",     ShapeType::BOX     },
-		{ "plane",   ShapeType::PLANE   }
+		{ "sphere",      ShapeType::SPHERE      },
+		{ "capsule",     ShapeType::CAPSULE     },
+		{ "box",         ShapeType::BOX         },
+		{ "plane",       ShapeType::PLANE       },
+		{ "convex_mesh", ShapeType::CONVEX_MESH }
 	};
 
 	struct Joint
@@ -44,8 +45,7 @@ namespace physics_resource
 		{ "spherical", JointType::SPHERICAL },
 		{ "revolute",  JointType::REVOLUTE  },
 		{ "prismatic", JointType::PRISMATIC },
-		{ "distance",  JointType::DISTANCE  },
-		{ "d6",        JointType::D6        }
+		{ "distance",  JointType::DISTANCE  }
 	};
 
 	static uint32_t shape_type_to_enum(const char* type)
@@ -130,11 +130,6 @@ namespace physics_resource
 					sr.data_3 = shape.key("distance").to_float();
 					break;
 				}
-				case ShapeType::CONVEX_MESH:
-				{
-					sr.resource = shape.key("mesh").to_resource_id("mesh");
-					break;
-				}
 			}
 			array::push_back(shapes, sr);
 		}
@@ -155,6 +150,13 @@ namespace physics_resource
 			pa.actor_class = actor.key("class").to_string_id();
 			pa.mass =        actor.key("mass").to_float();
 			pa.num_shapes =  actor.key("shapes").size();
+			pa.flags = 0;
+			pa.flags |= actor.key_or_nil("lock_translation_x").to_bool(false) ? ActorFlags::LOCK_TRANSLATION_X : 0;
+			pa.flags |= actor.key_or_nil("lock_translation_y").to_bool(false) ? ActorFlags::LOCK_TRANSLATION_Y : 0;
+			pa.flags |= actor.key_or_nil("lock_translation_z").to_bool(false) ? ActorFlags::LOCK_TRANSLATION_Z : 0;
+			pa.flags |= actor.key_or_nil("lock_rotation_x").to_bool(false) ? ActorFlags::LOCK_ROTATION_X : 0;
+			pa.flags |= actor.key_or_nil("lock_rotation_y").to_bool(false) ? ActorFlags::LOCK_ROTATION_Y : 0;
+			pa.flags |= actor.key_or_nil("lock_rotation_z").to_bool(false) ? ActorFlags::LOCK_ROTATION_Z : 0;
 
 			array::push_back(actors, pa);
 			array::push_back(shape_indices, array::size(shape_indices));
@@ -179,8 +181,8 @@ namespace physics_resource
 			pj.type         = joint_type_to_enum(jtype.c_str());
 			pj.actor_0      = joint.key("actor_0").to_string_id();
 			pj.actor_1      = joint.key("actor_1").to_string_id();
-			pj.anchor_0     = joint.key("anchor_0").to_vector3();
-			pj.anchor_1     = joint.key("anchor_1").to_vector3();
+			pj.anchor_0     = joint.key_or_nil("anchor_0").to_vector3(vector3::ZERO);
+			pj.anchor_1     = joint.key_or_nil("anchor_1").to_vector3(vector3::ZERO);
 			pj.restitution  = joint.key_or_nil("restitution").to_float(0.5f);
 			pj.spring       = joint.key_or_nil("spring").to_float(100.0f);
 			pj.damping      = joint.key_or_nil("damping").to_float(0.0f);
@@ -215,11 +217,6 @@ namespace physics_resource
 					pj.max_distance = joint.key_or_nil("max_distance").to_float(0.0f);
 					break;
 				}
-				case JointType::D6:
-				{
-					CE_FATAL("Not implemented");
-					break;
-				}
 			}
 
 			array::push_back(joints, pj);
@@ -265,7 +262,7 @@ namespace physics_resource
 
 		uint32_t offt = sizeof(PhysicsResource);
 		pr.controller_offset = offt; offt += sizeof(ControllerResource) * pr.num_controllers;
-		pr.actors_offset = offt; offt += sizeof(ActorResource) * pr.num_actors;
+		pr.actors_offset = offt; offt += sizeof(ActorResource) * pr.num_actors + sizeof(ShapeResource) * array::size(m_shapes);
 		pr.joints_offset = offt;
 
 		// Write all
@@ -294,6 +291,7 @@ namespace physics_resource
 			opts.write(m_actors[i].node);
 			opts.write(m_actors[i].actor_class);
 			opts.write(m_actors[i].mass);
+			opts.write(m_actors[i].flags);
 			opts.write(m_actors[i].num_shapes);
 
 			for (uint32_t ss = 0; ss < m_actors[i].num_shapes; ++ss)
@@ -304,7 +302,6 @@ namespace physics_resource
 				opts.write(m_shapes[base + ss].shape_class);
 				opts.write(m_shapes[base + ss].type);
 				opts.write(m_shapes[base + ss].material);
-				opts.write(m_shapes[base + ss].resource);
 				opts.write(m_shapes[base + ss].position);
 				opts.write(m_shapes[base + ss].rotation);
 				opts.write(m_shapes[base + ss].data_0);

+ 14 - 1
engine/resource/physics_resource.h

@@ -37,12 +37,26 @@ struct ControllerResource
 	StringId32 collision_filter;// Collision filter from global.physics_config
 };
 
+struct ActorFlags
+{
+	enum Enum
+	{
+		LOCK_TRANSLATION_X = (1 << 0),
+		LOCK_TRANSLATION_Y = (1 << 1),
+		LOCK_TRANSLATION_Z = (1 << 2),
+		LOCK_ROTATION_X = (1 << 3),
+		LOCK_ROTATION_Y = (1 << 4),
+		LOCK_ROTATION_Z = (1 << 5)
+	};
+};
+
 struct ActorResource
 {
 	StringId32 name;			// Name of the actor
 	StringId32 node;			// Node from .unit file
 	StringId32 actor_class;		// Actor from global.physics
 	float mass;					// Mass of the actor
+	uint32_t flags;
 	uint32_t num_shapes;		// Number of shapes
 };
 
@@ -52,7 +66,6 @@ struct ShapeResource
 	StringId32 shape_class;		// Shape class from global.physics_config
 	StringId32 type;			// Type of the shape
 	StringId32 material;		// Material from global.physics_config
-	ResourceId resource;		// Resource such as .mesh or .heightmap
 	Vector3 position;			// In actor space
 	Quaternion rotation;		// In actor space
 	float data_0;

+ 1 - 5
engine/world/unit.cpp

@@ -199,11 +199,7 @@ void Unit::create_physics_objects()
 		for (uint32_t i = 0; i < num_joints(pr); i++)
 		{
 			const JointResource* jr = physics_resource::joint(pr, i);
-
-			Actor* a1 = jr->actor_0 ? actor_by_index(jr->actor_0) : NULL;
-			Actor* a2 = jr->actor_1 ? actor_by_index(jr->actor_1) : NULL;
-
-			m_world.physics_world()->create_joint(jr, a1, a2);
+			m_world.physics_world()->create_joint(jr, *actor_by_index(jr->actor_0), *actor_by_index(jr->actor_1));
 		}
 	}
 }