Răsfoiți Sursa

GLTF: Expose the inertia tensor instead of a vector

Aaron Franke 2 ani în urmă
părinte
comite
6dde6b4cdf

+ 3 - 3
modules/gltf/doc_classes/GLTFPhysicsBody.xml

@@ -44,9 +44,9 @@
 		<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".
 		</member>
-		<member name="inertia" type="Vector3" setter="set_inertia" getter="get_inertia" default="Vector3(0, 0, 0)">
-			The principle axes of 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".
-			This is written to and read from the GLTF file as a 3x3 matrix, but is exposed as a Vector3 since Godot only supports principal axis inertia values. When converted to a Godot [RigidBody3D] node, if this value is zero, then the inertia will be calculated automatically.
+		<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".
+			When converted to a Godot [RigidBody3D] node, if this value is zero, then the inertia will be calculated automatically.
 		</member>
 		<member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector3(0, 0, 0)">
 			The linear velocity of the physics body, in meters per second. This is only used when the body type is "rigid" or "vehicle".

+ 22 - 15
modules/gltf/extensions/physics/gltf_physics_body.cpp

@@ -48,14 +48,14 @@ 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_inertia"), &GLTFPhysicsBody::get_inertia);
-	ClassDB::bind_method(D_METHOD("set_inertia", "inertia"), &GLTFPhysicsBody::set_inertia);
+	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);
 
 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "body_type"), "set_body_type", "get_body_type");
 	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, "inertia"), "set_inertia", "get_inertia");
+	ADD_PROPERTY(PropertyInfo(Variant::BASIS, "inertia_tensor"), "set_inertia_tensor", "get_inertia_tensor");
 }
 
 String GLTFPhysicsBody::get_body_type() const {
@@ -90,12 +90,12 @@ void GLTFPhysicsBody::set_angular_velocity(Vector3 p_angular_velocity) {
 	angular_velocity = p_angular_velocity;
 }
 
-Vector3 GLTFPhysicsBody::get_inertia() const {
-	return inertia;
+Basis GLTFPhysicsBody::get_inertia_tensor() const {
+	return inertia_tensor;
 }
 
-void GLTFPhysicsBody::set_inertia(Vector3 p_inertia) {
-	inertia = p_inertia;
+void GLTFPhysicsBody::set_inertia_tensor(Basis p_inertia_tensor) {
+	inertia_tensor = p_inertia_tensor;
 }
 
 Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_node(const CollisionObject3D *p_body_node) {
@@ -111,7 +111,8 @@ 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->inertia = body->get_inertia();
+		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()) {
 			WARN_PRINT("GLTFPhysicsBody: This rigid body has a center of mass offset from the origin, which will be ignored when exporting to GLTF.");
 		}
@@ -142,7 +143,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const {
 		body->set_mass(mass);
 		body->set_linear_velocity(linear_velocity);
 		body->set_angular_velocity(angular_velocity);
-		body->set_inertia(inertia);
+		body->set_inertia(inertia_tensor.get_main_diagonal());
 		body->set_center_of_mass_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM);
 		return body;
 	}
@@ -151,7 +152,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const {
 		body->set_mass(mass);
 		body->set_linear_velocity(linear_velocity);
 		body->set_angular_velocity(angular_velocity);
-		body->set_inertia(inertia);
+		body->set_inertia(inertia_tensor.get_main_diagonal());
 		body->set_center_of_mass_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM);
 		return body;
 	}
@@ -196,7 +197,7 @@ Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_dictionary(const Dictionary p_diction
 		const Array &arr = p_dictionary["inertiaTensor"];
 		if (arr.size() == 9) {
 			// Only use the diagonal elements of the inertia tensor matrix (principal axes).
-			physics_body->set_inertia(Vector3(arr[0], arr[4], arr[8]));
+			physics_body->set_inertia_tensor(Basis(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8]));
 		} else {
 			ERR_PRINT("Error parsing GLTF physics body: The inertia tensor must be a 3x3 matrix (9 number array).");
 		}
@@ -229,13 +230,19 @@ Dictionary GLTFPhysicsBody::to_dictionary() const {
 		velocity_array[2] = angular_velocity.z;
 		d["angularVelocity"] = velocity_array;
 	}
-	if (inertia != Vector3()) {
+	if (inertia_tensor != Basis(0, 0, 0, 0, 0, 0, 0, 0, 0)) {
 		Array inertia_array;
 		inertia_array.resize(9);
 		inertia_array.fill(0.0);
-		inertia_array[0] = inertia.x;
-		inertia_array[4] = inertia.y;
-		inertia_array[8] = inertia.z;
+		inertia_array[0] = inertia_tensor[0][0];
+		inertia_array[1] = inertia_tensor[0][1];
+		inertia_array[2] = inertia_tensor[0][2];
+		inertia_array[3] = inertia_tensor[1][0];
+		inertia_array[4] = inertia_tensor[1][1];
+		inertia_array[5] = inertia_tensor[1][2];
+		inertia_array[6] = inertia_tensor[2][0];
+		inertia_array[7] = inertia_tensor[2][1];
+		inertia_array[8] = inertia_tensor[2][2];
 		d["inertiaTensor"] = inertia_array;
 	}
 	return d;

+ 3 - 3
modules/gltf/extensions/physics/gltf_physics_body.h

@@ -47,7 +47,7 @@ private:
 	real_t mass = 1.0;
 	Vector3 linear_velocity = Vector3();
 	Vector3 angular_velocity = Vector3();
-	Vector3 inertia = Vector3();
+	Basis inertia_tensor = Basis(0, 0, 0, 0, 0, 0, 0, 0, 0);
 
 public:
 	String get_body_type() const;
@@ -62,8 +62,8 @@ public:
 	Vector3 get_angular_velocity() const;
 	void set_angular_velocity(Vector3 p_angular_velocity);
 
-	Vector3 get_inertia() const;
-	void set_inertia(Vector3 p_inertia);
+	Basis get_inertia_tensor() const;
+	void set_inertia_tensor(Basis p_inertia_tensor);
 
 	static Ref<GLTFPhysicsBody> from_node(const CollisionObject3D *p_body_node);
 	CollisionObject3D *to_node() const;