diff --git a/modules/gltf/doc_classes/GLTFPhysicsBody.xml b/modules/gltf/doc_classes/GLTFPhysicsBody.xml index 3aab1c51831..d364069193d 100644 --- a/modules/gltf/doc_classes/GLTFPhysicsBody.xml +++ b/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". - 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". + + + 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. 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". diff --git a/modules/gltf/extensions/physics/gltf_physics_body.cpp b/modules/gltf/extensions/physics/gltf_physics_body.cpp index 3b0fad064a7..49a6edd2e32 100644 --- a/modules/gltf/extensions/physics/gltf_physics_body.cpp +++ b/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::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::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); diff --git a/modules/gltf/extensions/physics/gltf_physics_body.h b/modules/gltf/extensions/physics/gltf_physics_body.h index 5fedb4f1111..391b4b873f6 100644 --- a/modules/gltf/extensions/physics/gltf_physics_body.h +++ b/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);