GLTF: Add center of mass property

This commit is contained in:
Aaron Franke 2023-08-09 17:10:29 -05:00
parent 4714e95896
commit d12b0787af
No known key found for this signature in database
GPG key ID: 40A1750B977E56BF
3 changed files with 40 additions and 3 deletions

View file

@ -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 angular velocity of the physics body, in radians per second. This is only used when the body type is "rigid" or "vehicle".
</member> </member>
<member name="body_type" type="String" setter="set_body_type" getter="get_body_type" default="&quot;static&quot;"> <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>
<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)"> <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". 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".

View file

@ -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("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("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("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("get_inertia_tensor"), &GLTFPhysicsBody::get_inertia_tensor);
ClassDB::bind_method(D_METHOD("set_inertia_tensor", "inertia_tensor"), &GLTFPhysicsBody::set_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::FLOAT, "mass"), "set_mass", "get_mass");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); 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, "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"); 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; 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 { Basis GLTFPhysicsBody::get_inertia_tensor() const {
return inertia_tensor; return inertia_tensor;
} }
@ -111,6 +122,7 @@ Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_node(const CollisionObject3D *p_body_
physics_body->mass = body->get_mass(); physics_body->mass = body->get_mass();
physics_body->linear_velocity = body->get_linear_velocity(); physics_body->linear_velocity = body->get_linear_velocity();
physics_body->angular_velocity = body->get_angular_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(); 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); 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()) { if (body->get_center_of_mass() != Vector3()) {
@ -145,6 +157,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const {
body->set_angular_velocity(angular_velocity); body->set_angular_velocity(angular_velocity);
body->set_inertia(inertia_tensor.get_main_diagonal()); 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_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM);
body->set_center_of_mass(center_of_mass);
return body; return body;
} }
if (body_type == "rigid") { if (body_type == "rigid") {
@ -154,6 +167,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const {
body->set_angular_velocity(angular_velocity); body->set_angular_velocity(angular_velocity);
body->set_inertia(inertia_tensor.get_main_diagonal()); 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_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM);
body->set_center_of_mass(center_of_mass);
return body; return body;
} }
if (body_type == "static") { 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."); 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")) { if (p_dictionary.has("inertiaTensor")) {
const Array &arr = p_dictionary["inertiaTensor"]; const Array &arr = p_dictionary["inertiaTensor"];
if (arr.size() == 9) { if (arr.size() == 9) {
@ -230,6 +252,14 @@ Dictionary GLTFPhysicsBody::to_dictionary() const {
velocity_array[2] = angular_velocity.z; velocity_array[2] = angular_velocity.z;
d["angularVelocity"] = velocity_array; 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)) { if (inertia_tensor != Basis(0, 0, 0, 0, 0, 0, 0, 0, 0)) {
Array inertia_array; Array inertia_array;
inertia_array.resize(9); inertia_array.resize(9);

View file

@ -45,8 +45,9 @@ protected:
private: private:
String body_type = "static"; String body_type = "static";
real_t mass = 1.0; real_t mass = 1.0;
Vector3 linear_velocity = Vector3(); Vector3 linear_velocity;
Vector3 angular_velocity = Vector3(); Vector3 angular_velocity;
Vector3 center_of_mass;
Basis inertia_tensor = Basis(0, 0, 0, 0, 0, 0, 0, 0, 0); Basis inertia_tensor = Basis(0, 0, 0, 0, 0, 0, 0, 0, 0);
public: public:
@ -62,6 +63,9 @@ public:
Vector3 get_angular_velocity() const; Vector3 get_angular_velocity() const;
void set_angular_velocity(Vector3 p_angular_velocity); 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; Basis get_inertia_tensor() const;
void set_inertia_tensor(Basis p_inertia_tensor); void set_inertia_tensor(Basis p_inertia_tensor);