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

Merge pull request #80463 from aaronfranke/gltf-center-of-mass

GLTF: Add center of mass property
Rémi Verschelde 2 лет назад
Родитель
Сommit
08d599d89b

+ 4 - 1
modules/gltf/doc_classes/GLTFPhysicsBody.xml

@@ -42,7 +42,10 @@
 			The angular velocity of the physics body, in radians per second. This is only used when the body type is "rigid" or "vehicle".
 		</member>
 		<member name="body_type" type="String" setter="set_body_type" getter="get_body_type" default="&quot;static&quot;">
-			The type of the body. Valid values are "static", "kinematic", "character", "rigid", "vehicle", and "trigger".
+			The type of the body. When importing, this controls what type of [CollisionObject3D] node Godot should generate. Valid values are "static", "kinematic", "character", "rigid", "vehicle", and "trigger".
+		</member>
+		<member name="center_of_mass" type="Vector3" setter="set_center_of_mass" getter="get_center_of_mass" default="Vector3(0, 0, 0)">
+			The center of mass of the body, in meters. This is in local space relative to the body. By default, the center of the mass is the body's origin.
 		</member>
 		<member name="inertia_tensor" type="Basis" setter="set_inertia_tensor" getter="get_inertia_tensor" default="Basis(0, 0, 0, 0, 0, 0, 0, 0, 0)">
 			The inertia tensor of the physics body, in kilogram meter squared (kg⋅m²). This is only used when the body type is "rigid" or "vehicle".

+ 30 - 0
modules/gltf/extensions/physics/gltf_physics_body.cpp

@@ -48,6 +48,8 @@ void GLTFPhysicsBody::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &GLTFPhysicsBody::set_linear_velocity);
 	ClassDB::bind_method(D_METHOD("get_angular_velocity"), &GLTFPhysicsBody::get_angular_velocity);
 	ClassDB::bind_method(D_METHOD("set_angular_velocity", "angular_velocity"), &GLTFPhysicsBody::set_angular_velocity);
+	ClassDB::bind_method(D_METHOD("get_center_of_mass"), &GLTFPhysicsBody::get_center_of_mass);
+	ClassDB::bind_method(D_METHOD("set_center_of_mass", "center_of_mass"), &GLTFPhysicsBody::set_center_of_mass);
 	ClassDB::bind_method(D_METHOD("get_inertia_tensor"), &GLTFPhysicsBody::get_inertia_tensor);
 	ClassDB::bind_method(D_METHOD("set_inertia_tensor", "inertia_tensor"), &GLTFPhysicsBody::set_inertia_tensor);
 
@@ -55,6 +57,7 @@ void GLTFPhysicsBody::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass"), "set_mass", "get_mass");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
+	ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_of_mass"), "set_center_of_mass", "get_center_of_mass");
 	ADD_PROPERTY(PropertyInfo(Variant::BASIS, "inertia_tensor"), "set_inertia_tensor", "get_inertia_tensor");
 }
 
@@ -90,6 +93,14 @@ void GLTFPhysicsBody::set_angular_velocity(Vector3 p_angular_velocity) {
 	angular_velocity = p_angular_velocity;
 }
 
+Vector3 GLTFPhysicsBody::get_center_of_mass() const {
+	return center_of_mass;
+}
+
+void GLTFPhysicsBody::set_center_of_mass(const Vector3 &p_center_of_mass) {
+	center_of_mass = p_center_of_mass;
+}
+
 Basis GLTFPhysicsBody::get_inertia_tensor() const {
 	return inertia_tensor;
 }
@@ -111,6 +122,7 @@ Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_node(const CollisionObject3D *p_body_
 		physics_body->mass = body->get_mass();
 		physics_body->linear_velocity = body->get_linear_velocity();
 		physics_body->angular_velocity = body->get_angular_velocity();
+		physics_body->center_of_mass = body->get_center_of_mass();
 		Vector3 inertia_diagonal = body->get_inertia();
 		physics_body->inertia_tensor = Basis(inertia_diagonal.x, 0, 0, 0, inertia_diagonal.y, 0, 0, 0, inertia_diagonal.z);
 		if (body->get_center_of_mass() != Vector3()) {
@@ -145,6 +157,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const {
 		body->set_angular_velocity(angular_velocity);
 		body->set_inertia(inertia_tensor.get_main_diagonal());
 		body->set_center_of_mass_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM);
+		body->set_center_of_mass(center_of_mass);
 		return body;
 	}
 	if (body_type == "rigid") {
@@ -154,6 +167,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const {
 		body->set_angular_velocity(angular_velocity);
 		body->set_inertia(inertia_tensor.get_main_diagonal());
 		body->set_center_of_mass_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM);
+		body->set_center_of_mass(center_of_mass);
 		return body;
 	}
 	if (body_type == "static") {
@@ -193,6 +207,14 @@ Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_dictionary(const Dictionary p_diction
 			ERR_PRINT("Error parsing GLTF physics body: The angular velocity vector must have exactly 3 numbers.");
 		}
 	}
+	if (p_dictionary.has("centerOfMass")) {
+		const Array &arr = p_dictionary["centerOfMass"];
+		if (arr.size() == 3) {
+			physics_body->set_center_of_mass(Vector3(arr[0], arr[1], arr[2]));
+		} else {
+			ERR_PRINT("Error parsing GLTF physics body: The center of mass vector must have exactly 3 numbers.");
+		}
+	}
 	if (p_dictionary.has("inertiaTensor")) {
 		const Array &arr = p_dictionary["inertiaTensor"];
 		if (arr.size() == 9) {
@@ -230,6 +252,14 @@ Dictionary GLTFPhysicsBody::to_dictionary() const {
 		velocity_array[2] = angular_velocity.z;
 		d["angularVelocity"] = velocity_array;
 	}
+	if (center_of_mass != Vector3()) {
+		Array center_of_mass_array;
+		center_of_mass_array.resize(3);
+		center_of_mass_array[0] = center_of_mass.x;
+		center_of_mass_array[1] = center_of_mass.y;
+		center_of_mass_array[2] = center_of_mass.z;
+		d["centerOfMass"] = center_of_mass_array;
+	}
 	if (inertia_tensor != Basis(0, 0, 0, 0, 0, 0, 0, 0, 0)) {
 		Array inertia_array;
 		inertia_array.resize(9);

+ 6 - 2
modules/gltf/extensions/physics/gltf_physics_body.h

@@ -45,8 +45,9 @@ protected:
 private:
 	String body_type = "static";
 	real_t mass = 1.0;
-	Vector3 linear_velocity = Vector3();
-	Vector3 angular_velocity = Vector3();
+	Vector3 linear_velocity;
+	Vector3 angular_velocity;
+	Vector3 center_of_mass;
 	Basis inertia_tensor = Basis(0, 0, 0, 0, 0, 0, 0, 0, 0);
 
 public:
@@ -62,6 +63,9 @@ public:
 	Vector3 get_angular_velocity() const;
 	void set_angular_velocity(Vector3 p_angular_velocity);
 
+	Vector3 get_center_of_mass() const;
+	void set_center_of_mass(const Vector3 &p_center_of_mass);
+
 	Basis get_inertia_tensor() const;
 	void set_inertia_tensor(Basis p_inertia_tensor);