diff --git a/README.md b/README.md index d5b38e2..91587b5 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,15 @@ This repository is used by the [Open Metaverse Interoperability Group](https://o Extensions implemented in this repository: -| Extension name | Import | Export | Godot version | Link | -| ------------------- | ------ | ------ | ------------- | ---------------------------------------------------------------------------------------------------------------------- | -| **OMI_seat** | Yes | Yes | 4.0+ | [OMI_seat extension spec](https://github.com/omigroup/gltf-extensions/tree/main/extensions/2.0/OMI_seat) | -| **OMI_spawn_point** | Yes | No | 4.0+ | [OMI_spawn_point extension spec](https://github.com/omigroup/gltf-extensions/tree/main/extensions/2.0/OMI_spawn_point) | +| Extension name | Import | Export | Godot version | Link | +| --------------------- | ------ | ------ | ------------- | -------------------------------------------------------------------------------------------------------------------------- | +| **OMI_seat** | Yes | Yes | 4.0+ | [OMI_seat extension spec](https://github.com/omigroup/gltf-extensions/tree/main/extensions/2.0/OMI_seat) | +| **OMI_spawn_point** | Yes | No | 4.0+ | [OMI_spawn_point extension spec](https://github.com/omigroup/gltf-extensions/tree/main/extensions/2.0/OMI_spawn_point) | +| **OMI_physics_joint** | Yes | Yes | 4.1+ | [OMI_physics_joint extension spec](https://github.com/omigroup/gltf-extensions/tree/main/extensions/2.0/OMI_physics_joint) | Extensions implemented upstream in Godot Engine: | Extension name | Import | Export | Godot version | Link | | -------------------- | ------ | ------ | ------------- | ------------------------------------------------------------------------------------------------------------------------ | -| **OMI_collider** | Yes | Yes | 4.1+ | [OMI_collider extension spec](https://github.com/omigroup/gltf-extensions/tree/main/extensions/2.0/OMI_collider) | -| **OMI_physics_body** | Yes | Yes | 4.1+ | [OMI_physics_body extension spec](https://github.com/omigroup/gltf-extensions/tree/main/extensions/2.0/OMI_physics_body) | +| **OMI_collider** | Yes | Yes | 4.1+ or 3.6+ | [OMI_collider extension spec](https://github.com/omigroup/gltf-extensions/tree/main/extensions/2.0/OMI_collider) | +| **OMI_physics_body** | Yes | Yes | 4.1+ or 3.6+ | [OMI_physics_body extension spec](https://github.com/omigroup/gltf-extensions/tree/main/extensions/2.0/OMI_physics_body) | diff --git a/addons/omi_extensions/omi_extensions_plugin.gd b/addons/omi_extensions/omi_extensions_plugin.gd index 58fb15a..878d13a 100644 --- a/addons/omi_extensions/omi_extensions_plugin.gd +++ b/addons/omi_extensions/omi_extensions_plugin.gd @@ -9,3 +9,5 @@ func _enter_tree() -> void: GLTFDocument.register_gltf_document_extension(ext) ext = GLTFDocumentExtensionOMISpawnPoint.new() GLTFDocument.register_gltf_document_extension(ext) + ext = GLTFDocumentExtensionOMIPhysicsJoint.new() + GLTFDocument.register_gltf_document_extension(ext) diff --git a/addons/omi_extensions/physics_joint/gltf_physics_joint.gd b/addons/omi_extensions/physics_joint/gltf_physics_joint.gd new file mode 100644 index 0000000..2fb52af --- /dev/null +++ b/addons/omi_extensions/physics_joint/gltf_physics_joint.gd @@ -0,0 +1,358 @@ +@tool +class_name GLTFPhysicsJoint +extends Resource + + +var node_a: PhysicsBody3D +var node_b: PhysicsBody3D + +var linear_x: GLTFPhysicsJointConstraint = null +var linear_y: GLTFPhysicsJointConstraint = null +var linear_z: GLTFPhysicsJointConstraint = null +var angular_x: GLTFPhysicsJointConstraint = null +var angular_y: GLTFPhysicsJointConstraint = null +var angular_z: GLTFPhysicsJointConstraint = null + + +static func from_node(joint_node: Joint3D) -> GLTFPhysicsJoint: + var ret := GLTFPhysicsJoint.new() + if not joint_node.node_a.is_empty(): + ret.node_a = joint_node.get_node(joint_node.node_a) + if not joint_node.node_b.is_empty(): + ret.node_b = joint_node.get_node(joint_node.node_b) + # We need different code for each type of Godot joint we want to convert. + if joint_node is Generic6DOFJoint3D: + _convert_generic_joint_constraints(joint_node, ret) + elif joint_node is HingeJoint3D: + var linear_constraint := GLTFPhysicsJointConstraint.new() + linear_constraint.linear_axes = [0, 1, 2] + linear_constraint.stiffness = joint_node.get_param(HingeJoint3D.PARAM_BIAS) + ret.linear_x = linear_constraint + ret.linear_y = linear_constraint + ret.linear_z = linear_constraint + var fixed_angular_constraint := GLTFPhysicsJointConstraint.new() + fixed_angular_constraint.angular_axes = [0, 1] + fixed_angular_constraint.stiffness = joint_node.get_param(HingeJoint3D.PARAM_LIMIT_BIAS) + fixed_angular_constraint.damping = 1.0 / joint_node.get_param(HingeJoint3D.PARAM_LIMIT_RELAXATION) + ret.angular_x = fixed_angular_constraint + ret.angular_y = fixed_angular_constraint + # Godot's Hinge joint rotates around the local Z axis (in the XY plane). + if joint_node.get_flag(HingeJoint3D.FLAG_USE_LIMIT): + var loose_angular_constraint := GLTFPhysicsJointConstraint.new() + loose_angular_constraint.angular_axes = [2] + loose_angular_constraint.lower_limit = joint_node.get_param(HingeJoint3D.PARAM_LIMIT_LOWER) + loose_angular_constraint.upper_limit = joint_node.get_param(HingeJoint3D.PARAM_LIMIT_UPPER) + loose_angular_constraint.stiffness = joint_node.get_param(HingeJoint3D.PARAM_LIMIT_SOFTNESS) + loose_angular_constraint.damping = 1.0 / joint_node.get_param(HingeJoint3D.PARAM_LIMIT_RELAXATION) + ret.angular_z = loose_angular_constraint + elif joint_node is PinJoint3D: + var constraint := GLTFPhysicsJointConstraint.new() + constraint.linear_axes = [0, 1, 2] + constraint.stiffness = joint_node.get_param(PinJoint3D.PARAM_BIAS) + constraint.damping = joint_node.get_param(PinJoint3D.PARAM_DAMPING) + ret.linear_x = constraint + ret.linear_y = constraint + ret.linear_z = constraint + elif joint_node is SliderJoint3D: + # Godot's Slider joint slides on the local X axis. + var loose_linear_constraint := GLTFPhysicsJointConstraint.new() + loose_linear_constraint.linear_axes = [0] + loose_linear_constraint.lower_limit = joint_node.get_param(SliderJoint3D.PARAM_LINEAR_LIMIT_LOWER) + loose_linear_constraint.upper_limit = joint_node.get_param(SliderJoint3D.PARAM_LINEAR_LIMIT_UPPER) + loose_linear_constraint.stiffness = joint_node.get_param(SliderJoint3D.PARAM_LINEAR_LIMIT_SOFTNESS) + loose_linear_constraint.damping = joint_node.get_param(SliderJoint3D.PARAM_LINEAR_LIMIT_DAMPING) + if loose_linear_constraint.lower_limit <= loose_linear_constraint.upper_limit: + # In Godot's Slider joint, the lower limit being higher than the upper limit means unconstrained. + ret.linear_x = loose_linear_constraint + var fixed_linear_constraint := GLTFPhysicsJointConstraint.new() + fixed_linear_constraint.linear_axes = [1, 2] + fixed_linear_constraint.stiffness = joint_node.get_param(SliderJoint3D.PARAM_LINEAR_ORTHOGONAL_SOFTNESS) + fixed_linear_constraint.damping = joint_node.get_param(SliderJoint3D.PARAM_LINEAR_ORTHOGONAL_DAMPING) + ret.linear_y = fixed_linear_constraint + ret.linear_z = fixed_linear_constraint + # Godot's Slider joint rotates around the local X axis (in the YZ plane). + var loose_angular_constraint := GLTFPhysicsJointConstraint.new() + loose_angular_constraint.angular_axes = [0] + loose_angular_constraint.lower_limit = joint_node.get_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_LOWER) + loose_angular_constraint.upper_limit = joint_node.get_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_UPPER) + loose_angular_constraint.stiffness = joint_node.get_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_SOFTNESS) + loose_angular_constraint.damping = joint_node.get_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_DAMPING) + if loose_angular_constraint.lower_limit <= loose_angular_constraint.upper_limit: + # In Godot's Slider joint, the lower limit being higher than the upper limit means unconstrained. + ret.angular_x = loose_angular_constraint + var fixed_angular_constraint := GLTFPhysicsJointConstraint.new() + fixed_angular_constraint.angular_axes = [1, 2] + fixed_angular_constraint.stiffness = joint_node.get_param(SliderJoint3D.PARAM_ANGULAR_ORTHOGONAL_SOFTNESS) + fixed_angular_constraint.damping = joint_node.get_param(SliderJoint3D.PARAM_ANGULAR_ORTHOGONAL_DAMPING) + ret.angular_y = fixed_angular_constraint + ret.angular_z = fixed_angular_constraint + elif joint_node is ConeTwistJoint3D: + # It doesn't seem possible to fully represent ConeTwistJoint3D, so use an approximation. + push_warning("GLTF Physics Joint: Converting a ConeTwistJoint3D which cannot be properly represented as a GLTF joint, so it will only be approximated.") + var linear_constraint := GLTFPhysicsJointConstraint.new() + linear_constraint.linear_axes = [0, 1, 2] + ret.linear_x = linear_constraint + ret.linear_y = linear_constraint + ret.linear_z = linear_constraint + var angular_constraint := GLTFPhysicsJointConstraint.new() + angular_constraint.angular_axes = [0, 1, 2] + angular_constraint.lower_limit = -joint_node.get_param(ConeTwistJoint3D.PARAM_SWING_SPAN) + angular_constraint.upper_limit = joint_node.get_param(ConeTwistJoint3D.PARAM_SWING_SPAN) + angular_constraint.stiffness = joint_node.get_param(ConeTwistJoint3D.PARAM_SOFTNESS) + angular_constraint.damping = 1.0 / joint_node.get_param(ConeTwistJoint3D.PARAM_RELAXATION) + ret.angular_x = angular_constraint + ret.angular_y = angular_constraint + ret.angular_z = angular_constraint + else: + printerr("GLTF Physics Joint: Unable to convert '" + str(joint_node) + "'. Returning a default pin joint as fallback.") + var constraint := GLTFPhysicsJointConstraint.new() + constraint.linear_axes = [0, 1, 2] + ret.linear_x = constraint + ret.linear_y = constraint + ret.linear_z = constraint + return ret + + +func to_node() -> Joint3D: + if linear_x != null and linear_x.is_fixed_at_zero() \ + and linear_y != null and linear_y.is_fixed_at_zero() \ + and linear_z != null and linear_z.is_fixed_at_zero(): + # Linearly fixed at zero, so it could be a pin or hinge. + if angular_x == null and angular_y == null and angular_z == null: + # No angular constraint, so this is a pin joint. + var pin = PinJoint3D.new() + # Calculate values that will not cause Godot's physics engine to explode. + var bias = (linear_x.stiffness + linear_y.stiffness + linear_z.stiffness) / 6.0 + pin.set_param(PinJoint3D.PARAM_BIAS, clamp(bias, 0.01, 0.99)) + var damping: float = (linear_x.damping + linear_y.damping + linear_z.damping) / 3.0 + pin.set_param(PinJoint3D.PARAM_BIAS, clamp(damping, bias * 0.51, 2.0)) + return pin + if angular_x != null and angular_x.is_fixed_at_zero() \ + and angular_y != null and angular_y.is_fixed_at_zero() \ + and angular_x.limits_equal_to(angular_y) \ + and (angular_z == null or not angular_z.is_fixed_at_zero()): + # Angular X and Y are equally fixed at zero, Z is not, so this is a hinge joint. + var hinge = HingeJoint3D.new() + if angular_z != null: + hinge.set_flag(HingeJoint3D.FLAG_USE_LIMIT, true) + hinge.set_param(HingeJoint3D.PARAM_LIMIT_LOWER, angular_z.lower_limit) + hinge.set_param(HingeJoint3D.PARAM_LIMIT_UPPER, angular_z.upper_limit) + hinge.set_param(HingeJoint3D.PARAM_LIMIT_SOFTNESS, angular_z.stiffness) + hinge.set_param(HingeJoint3D.PARAM_LIMIT_RELAXATION, 1.0 / angular_z.damping) + return hinge + if linear_y != null and linear_y.is_fixed_at_zero() \ + and linear_z != null and linear_z.is_fixed_at_zero() \ + and linear_y.limits_equal_to(linear_z) \ + and angular_y != null and angular_y.is_fixed_at_zero() \ + and angular_z != null and angular_z.is_fixed_at_zero() \ + and angular_y.limits_equal_to(angular_z) \ + and (angular_x == null or not angular_x.is_fixed_at_zero() \ + or linear_x == null or not linear_x.is_fixed_at_zero()): + # The only free axes are the linear and/or angular X, so this looks like a Slider. + var slider = SliderJoint3D.new() + if linear_x == null: + # In Godot's Slider joint, the lower limit being higher than the upper limit means unconstrained. + slider.set_param(SliderJoint3D.PARAM_LINEAR_LIMIT_LOWER, 1.0) + slider.set_param(SliderJoint3D.PARAM_LINEAR_LIMIT_UPPER, -1.0) + else: + slider.set_param(SliderJoint3D.PARAM_LINEAR_LIMIT_LOWER, linear_x.lower_limit) + slider.set_param(SliderJoint3D.PARAM_LINEAR_LIMIT_UPPER, linear_x.upper_limit) + slider.set_param(SliderJoint3D.PARAM_LINEAR_LIMIT_SOFTNESS, linear_x.stiffness) + slider.set_param(SliderJoint3D.PARAM_LINEAR_LIMIT_DAMPING, linear_x.damping) + slider.set_param(SliderJoint3D.PARAM_LINEAR_ORTHOGONAL_SOFTNESS, linear_y.stiffness) + slider.set_param(SliderJoint3D.PARAM_LINEAR_ORTHOGONAL_DAMPING, linear_y.damping) + if angular_x == null: + # In Godot's Slider joint, the lower limit being higher than the upper limit means unconstrained. + slider.set_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_LOWER, 1.0) + slider.set_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_UPPER, -1.0) + else: + slider.set_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_LOWER, angular_x.lower_limit) + slider.set_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_UPPER, angular_x.upper_limit) + slider.set_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_SOFTNESS, angular_x.stiffness) + slider.set_param(SliderJoint3D.PARAM_ANGULAR_LIMIT_DAMPING, angular_x.damping) + slider.set_param(SliderJoint3D.PARAM_ANGULAR_ORTHOGONAL_SOFTNESS, angular_y.stiffness) + slider.set_param(SliderJoint3D.PARAM_ANGULAR_ORTHOGONAL_DAMPING, angular_y.damping) + return slider + # If none of the special-purpose joints apply, use the generic one. + return _create_generic_joint_with_constraints() + + +func get_constraints() -> Array: + var ret: Array = [] + if linear_x != null: + ret.append(linear_x) + if linear_y != null and not linear_y in ret: + ret.append(linear_y) + if linear_z != null and not linear_z in ret: + ret.append(linear_z) + if angular_x != null and not angular_x in ret: + ret.append(angular_x) + if angular_y != null and not angular_y in ret: + ret.append(angular_y) + if angular_z != null and not angular_z in ret: + ret.append(angular_z) + return ret + + +func apply_constraint(joint_constraint: GLTFPhysicsJointConstraint) -> void: + for linear_axis in joint_constraint.linear_axes: + match linear_axis: + 0: + linear_x = joint_constraint + 1: + linear_y = joint_constraint + 2: + linear_z = joint_constraint + for angular_axis in joint_constraint.angular_axes: + match angular_axis: + 0: + angular_x = joint_constraint + 1: + angular_y = joint_constraint + 2: + angular_z = joint_constraint + + +func _create_generic_joint_with_constraints() -> Generic6DOFJoint3D: + var ret := Generic6DOFJoint3D.new() + if linear_x == null: + ret.set_flag_x(Generic6DOFJoint3D.FLAG_ENABLE_LINEAR_LIMIT, false) + else: + ret.set_param_x(Generic6DOFJoint3D.PARAM_LINEAR_LOWER_LIMIT, linear_x.lower_limit) + ret.set_param_x(Generic6DOFJoint3D.PARAM_LINEAR_UPPER_LIMIT, linear_x.upper_limit) + # Calculate values that will not cause Godot's physics engine to explode. + var stiffness: float = clampf(linear_x.stiffness, 0.01, 2.0) + var minimum_damping: float = 0.01 + if stiffness > 0.5: + minimum_damping = 0.25 * sqrt(stiffness - 0.498) + ret.set_param_x(Generic6DOFJoint3D.PARAM_LINEAR_LIMIT_SOFTNESS, stiffness) + ret.set_param_x(Generic6DOFJoint3D.PARAM_LINEAR_DAMPING, clampf(linear_x.damping, minimum_damping, 16.0)) + if linear_y == null: + ret.set_flag_y(Generic6DOFJoint3D.FLAG_ENABLE_LINEAR_LIMIT, false) + else: + ret.set_param_y(Generic6DOFJoint3D.PARAM_LINEAR_LOWER_LIMIT, linear_y.lower_limit) + ret.set_param_y(Generic6DOFJoint3D.PARAM_LINEAR_UPPER_LIMIT, linear_y.upper_limit) + var stiffness: float = clampf(linear_y.stiffness, 0.01, 2.0) + var minimum_damping: float = 0.01 + if stiffness > 0.5: + minimum_damping = 0.25 * sqrt(stiffness - 0.498) + ret.set_param_y(Generic6DOFJoint3D.PARAM_LINEAR_LIMIT_SOFTNESS, stiffness) + ret.set_param_y(Generic6DOFJoint3D.PARAM_LINEAR_DAMPING, clampf(linear_y.damping, minimum_damping, 16.0)) + if linear_z == null: + ret.set_flag_z(Generic6DOFJoint3D.FLAG_ENABLE_LINEAR_LIMIT, false) + else: + ret.set_param_z(Generic6DOFJoint3D.PARAM_LINEAR_LOWER_LIMIT, linear_z.lower_limit) + ret.set_param_z(Generic6DOFJoint3D.PARAM_LINEAR_UPPER_LIMIT, linear_z.upper_limit) + var stiffness: float = clampf(linear_z.stiffness, 0.01, 2.0) + var minimum_damping: float = 0.01 + if stiffness > 0.5: + minimum_damping = 0.25 * sqrt(stiffness - 0.498) + ret.set_param_z(Generic6DOFJoint3D.PARAM_LINEAR_LIMIT_SOFTNESS, stiffness) + ret.set_param_z(Generic6DOFJoint3D.PARAM_LINEAR_DAMPING, clampf(linear_z.damping, minimum_damping, 16.0)) + if angular_x == null: + ret.set_flag_x(Generic6DOFJoint3D.FLAG_ENABLE_ANGULAR_LIMIT, false) + else: + ret.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_LOWER_LIMIT, angular_x.lower_limit) + ret.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_UPPER_LIMIT, angular_x.upper_limit) + var stiffness: float = clampf(angular_x.stiffness, 0.01, 2.0) + var minimum_damping: float = 0.01 + if stiffness > 0.5: + minimum_damping = 0.25 * sqrt(stiffness - 0.498) + ret.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_LIMIT_SOFTNESS, stiffness) + ret.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_DAMPING, clampf(angular_x.damping, minimum_damping, 16.0)) + if angular_y == null: + ret.set_flag_y(Generic6DOFJoint3D.FLAG_ENABLE_ANGULAR_LIMIT, false) + else: + ret.set_param_y(Generic6DOFJoint3D.PARAM_ANGULAR_LOWER_LIMIT, angular_y.lower_limit) + ret.set_param_y(Generic6DOFJoint3D.PARAM_ANGULAR_UPPER_LIMIT, angular_y.upper_limit) + var stiffness: float = clampf(angular_y.stiffness, 0.01, 2.0) + var minimum_damping: float = 0.01 + if stiffness > 0.5: + minimum_damping = 0.25 * sqrt(stiffness - 0.498) + ret.set_param_y(Generic6DOFJoint3D.PARAM_ANGULAR_LIMIT_SOFTNESS, stiffness) + ret.set_param_y(Generic6DOFJoint3D.PARAM_ANGULAR_DAMPING, clampf(angular_y.damping, minimum_damping, 16.0)) + if angular_z == null: + ret.set_flag_z(Generic6DOFJoint3D.FLAG_ENABLE_ANGULAR_LIMIT, false) + else: + ret.set_param_z(Generic6DOFJoint3D.PARAM_ANGULAR_LOWER_LIMIT, angular_z.lower_limit) + ret.set_param_z(Generic6DOFJoint3D.PARAM_ANGULAR_UPPER_LIMIT, angular_z.upper_limit) + var stiffness: float = clampf(angular_z.stiffness, 0.01, 2.0) + var minimum_damping: float = 0.01 + if stiffness > 0.5: + minimum_damping = 0.25 * sqrt(stiffness - 0.498) + ret.set_param_z(Generic6DOFJoint3D.PARAM_ANGULAR_LIMIT_SOFTNESS, stiffness) + ret.set_param_z(Generic6DOFJoint3D.PARAM_ANGULAR_DAMPING, clampf(angular_z.damping, minimum_damping, 16.0)) + return ret + + +static func _convert_generic_joint_constraints(joint_node: Generic6DOFJoint3D, gltf_joint: GLTFPhysicsJoint) -> void: + if joint_node.get_flag_x(Generic6DOFJoint3D.FLAG_ENABLE_LINEAR_LIMIT): + var constraint := GLTFPhysicsJointConstraint.new() + constraint.lower_limit = joint_node.get_param_x(Generic6DOFJoint3D.PARAM_LINEAR_LOWER_LIMIT) + constraint.upper_limit = joint_node.get_param_x(Generic6DOFJoint3D.PARAM_LINEAR_UPPER_LIMIT) + constraint.stiffness = joint_node.get_param_x(Generic6DOFJoint3D.PARAM_LINEAR_LIMIT_SOFTNESS) + constraint.damping = joint_node.get_param_x(Generic6DOFJoint3D.PARAM_LINEAR_DAMPING) + constraint.linear_axes = [0] + gltf_joint.linear_x = constraint + if joint_node.get_flag_y(Generic6DOFJoint3D.FLAG_ENABLE_LINEAR_LIMIT): + var constraint := GLTFPhysicsJointConstraint.new() + constraint.lower_limit = joint_node.get_param_y(Generic6DOFJoint3D.PARAM_LINEAR_LOWER_LIMIT) + constraint.upper_limit = joint_node.get_param_y(Generic6DOFJoint3D.PARAM_LINEAR_UPPER_LIMIT) + constraint.stiffness = joint_node.get_param_y(Generic6DOFJoint3D.PARAM_LINEAR_LIMIT_SOFTNESS) + constraint.damping = joint_node.get_param_y(Generic6DOFJoint3D.PARAM_LINEAR_DAMPING) + if gltf_joint.linear_x != null and constraint.limits_equal_to(gltf_joint.linear_x): + gltf_joint.linear_x.linear_axes.append(1) + gltf_joint.linear_y = gltf_joint.linear_x + else: + constraint.linear_axes = [1] + gltf_joint.linear_y = constraint + if joint_node.get_flag_z(Generic6DOFJoint3D.FLAG_ENABLE_LINEAR_LIMIT): + var constraint := GLTFPhysicsJointConstraint.new() + constraint.lower_limit = joint_node.get_param_z(Generic6DOFJoint3D.PARAM_LINEAR_LOWER_LIMIT) + constraint.upper_limit = joint_node.get_param_z(Generic6DOFJoint3D.PARAM_LINEAR_UPPER_LIMIT) + constraint.stiffness = joint_node.get_param_z(Generic6DOFJoint3D.PARAM_LINEAR_LIMIT_SOFTNESS) + constraint.damping = joint_node.get_param_z(Generic6DOFJoint3D.PARAM_LINEAR_DAMPING) + if gltf_joint.linear_x != null and constraint.limits_equal_to(gltf_joint.linear_x): + gltf_joint.linear_x.linear_axes.append(2) + gltf_joint.linear_z = gltf_joint.linear_x + elif gltf_joint.linear_y != null and constraint.limits_equal_to(gltf_joint.linear_y): + gltf_joint.linear_y.linear_axes.append(2) + gltf_joint.linear_z = gltf_joint.linear_y + else: + constraint.linear_axes = [2] + gltf_joint.linear_z = constraint + if joint_node.get_flag_x(Generic6DOFJoint3D.FLAG_ENABLE_ANGULAR_LIMIT): + var constraint := GLTFPhysicsJointConstraint.new() + constraint.lower_limit = joint_node.get_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_LOWER_LIMIT) + constraint.upper_limit = joint_node.get_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_UPPER_LIMIT) + constraint.stiffness = joint_node.get_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_LIMIT_SOFTNESS) + constraint.damping = joint_node.get_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_DAMPING) + constraint.angular_axes = [0] + gltf_joint.angular_x = constraint + if joint_node.get_flag_y(Generic6DOFJoint3D.FLAG_ENABLE_ANGULAR_LIMIT): + var constraint := GLTFPhysicsJointConstraint.new() + constraint.lower_limit = joint_node.get_param_y(Generic6DOFJoint3D.PARAM_ANGULAR_LOWER_LIMIT) + constraint.upper_limit = joint_node.get_param_y(Generic6DOFJoint3D.PARAM_ANGULAR_UPPER_LIMIT) + constraint.stiffness = joint_node.get_param_y(Generic6DOFJoint3D.PARAM_ANGULAR_LIMIT_SOFTNESS) + constraint.damping = joint_node.get_param_y(Generic6DOFJoint3D.PARAM_ANGULAR_DAMPING) + if gltf_joint.angular_x != null and constraint.limits_equal_to(gltf_joint.angular_x): + gltf_joint.angular_x.angular_axes.append(1) + gltf_joint.angular_y = gltf_joint.angular_x + else: + constraint.angular_axes = [1] + gltf_joint.angular_y = constraint + if joint_node.get_flag_z(Generic6DOFJoint3D.FLAG_ENABLE_ANGULAR_LIMIT): + var constraint := GLTFPhysicsJointConstraint.new() + constraint.lower_limit = joint_node.get_param_z(Generic6DOFJoint3D.PARAM_ANGULAR_LOWER_LIMIT) + constraint.upper_limit = joint_node.get_param_z(Generic6DOFJoint3D.PARAM_ANGULAR_UPPER_LIMIT) + constraint.stiffness = joint_node.get_param_z(Generic6DOFJoint3D.PARAM_ANGULAR_LIMIT_SOFTNESS) + constraint.damping = joint_node.get_param_z(Generic6DOFJoint3D.PARAM_ANGULAR_DAMPING) + if gltf_joint.angular_x != null and constraint.limits_equal_to(gltf_joint.angular_x): + gltf_joint.angular_x.angular_axes.append(2) + gltf_joint.angular_z = gltf_joint.angular_x + elif gltf_joint.angular_y != null and constraint.limits_equal_to(gltf_joint.angular_y): + gltf_joint.angular_y.angular_axes.append(2) + gltf_joint.angular_z = gltf_joint.angular_y + else: + constraint.angular_axes = [2] + gltf_joint.angular_z = constraint diff --git a/addons/omi_extensions/physics_joint/gltf_physics_joint_constraint.gd b/addons/omi_extensions/physics_joint/gltf_physics_joint_constraint.gd new file mode 100644 index 0000000..c149540 --- /dev/null +++ b/addons/omi_extensions/physics_joint/gltf_physics_joint_constraint.gd @@ -0,0 +1,66 @@ +@tool +class_name GLTFPhysicsJointConstraint +extends Resource + + +var linear_axes: Array = [] +var angular_axes: Array = [] +var lower_limit: float = 0.0 +var upper_limit: float = 0.0 +var stiffness: float = INF +var damping: float = 1.0 + + +func to_dictionary() -> Dictionary: + var ret: Dictionary = {} + if not linear_axes.is_empty(): + ret["linearAxes"] = linear_axes + if not angular_axes.is_empty(): + ret["angularAxes"] = angular_axes + if lower_limit != 0.0: + ret["lowerLimit"] = lower_limit + if upper_limit != 0.0: + ret["upperLimit"] = upper_limit + if stiffness != INF: + ret["stiffness"] = stiffness + if damping != 1.0: + ret["damping"] = damping + return ret + + +static func from_dictionary(joint_dict: Dictionary) -> GLTFPhysicsJointConstraint: + var ret = GLTFPhysicsJointConstraint.new() + if joint_dict.has("linearAxes"): + var dict_axes: Array = joint_dict["linearAxes"] + for dict_axis in dict_axes: + ret.linear_axes.append(int(dict_axis)) + if joint_dict.has("angularAxes"): + var dict_axes: Array = joint_dict["angularAxes"] + for dict_axis in dict_axes: + ret.angular_axes.append(int(dict_axis)) + if joint_dict.has("lowerLimit"): + ret.lower_limit = joint_dict["lowerLimit"] + if joint_dict.has("upperLimit"): + ret.upper_limit = joint_dict["upperLimit"] + if joint_dict.has("stiffness"): + ret.stiffness = joint_dict["stiffness"] + if joint_dict.has("damping"): + ret.damping = joint_dict["damping"] + return ret + + +func is_fixed_at_zero() -> bool: + return is_zero_approx(lower_limit) and is_zero_approx(upper_limit) + + +func is_equal_to(other: GLTFPhysicsJointConstraint) -> bool: + return limits_equal_to(other) \ + and linear_axes.hash() == other.linear_axes.hash() \ + and angular_axes.hash() == other.angular_axes.hash() + + +func limits_equal_to(other: GLTFPhysicsJointConstraint) -> bool: + return is_equal_approx(lower_limit, other.lower_limit) \ + and is_equal_approx(upper_limit, other.upper_limit) \ + and is_equal_approx(stiffness, other.stiffness) \ + and is_equal_approx(damping, other.damping) diff --git a/addons/omi_extensions/physics_joint/omi_physics_joint_doc_ext.gd b/addons/omi_extensions/physics_joint/omi_physics_joint_doc_ext.gd new file mode 100644 index 0000000..8f23ef6 --- /dev/null +++ b/addons/omi_extensions/physics_joint/omi_physics_joint_doc_ext.gd @@ -0,0 +1,172 @@ +@tool +class_name GLTFDocumentExtensionOMIPhysicsJoint +extends GLTFDocumentExtension + + +# Import process. +func _import_preflight(state: GLTFState, extensions: PackedStringArray) -> Error: + if not extensions.has("OMI_physics_joint"): + return ERR_SKIP + var state_json = state.get_json() + if not state_json.has("extensions"): + return ERR_FILE_CORRUPT + var state_extensions: Dictionary = state_json["extensions"] + if not state_extensions.has("OMI_physics_joint"): + return ERR_FILE_CORRUPT + var omi_physics_joint_doc_ext: Dictionary = state_extensions["OMI_physics_joint"] + if not omi_physics_joint_doc_ext.has("constraints"): + return ERR_FILE_CORRUPT + var state_constraint_dicts: Array = omi_physics_joint_doc_ext["constraints"] + var state_constraints: Array = [] + for constraint_dict in state_constraint_dicts: + state_constraints.append(GLTFPhysicsJointConstraint.from_dictionary(constraint_dict)) + state.set_additional_data("GLTFPhysicsJointConstraints", state_constraints) + return OK + + +func _get_supported_extensions() -> PackedStringArray: + return PackedStringArray(["OMI_physics_joint"]) + + +func _parse_node_extensions(state: GLTFState, gltf_node: GLTFNode, extensions: Dictionary) -> Error: + if not extensions.has("OMI_physics_joint"): + return OK + var joint_dict = extensions.get("OMI_physics_joint") + if not joint_dict is Dictionary: + printerr("Error: OMI_physics_joint extension should be a Dictionary.") + return ERR_FILE_CORRUPT + var constraints = joint_dict.get("constraints") + if not constraints is Array or constraints.is_empty(): + printerr("Error: OMI_physics_joint extension should have at least one constraint.") + return ERR_FILE_CORRUPT + var state_constraints: Array = state.get_additional_data("GLTFPhysicsJointConstraints") + var joint := GLTFPhysicsJoint.new() + for constraint in constraints: + var joint_constraint: GLTFPhysicsJointConstraint + if constraint is float: # Remember, JSON only stores "number". + joint_constraint = state_constraints[int(constraint)] + else: + joint_constraint = GLTFPhysicsJointConstraint.from_dictionary(constraint) + joint.apply_constraint(joint_constraint) + gltf_node.set_additional_data("GLTFPhysicsJoint", joint) + return OK + + +func _generate_scene_node(state: GLTFState, gltf_node: GLTFNode, scene_parent: Node) -> Node3D: + var joint: GLTFPhysicsJoint = gltf_node.get_additional_data("GLTFPhysicsJoint") + if joint == null: + return null + return joint.to_node() + + +func _import_node(state: GLTFState, _gltf_node: GLTFNode, json: Dictionary, node: Node) -> Error: + if not json.has("extensions"): + return OK + var extensions = json.get("extensions") + if not extensions.has("OMI_physics_joint"): + return OK + var joint_dict = extensions.get("OMI_physics_joint") + if not joint_dict is Dictionary: + printerr("Error: OMI_physics_joint extension should be a Dictionary.") + return ERR_FILE_CORRUPT + if not joint_dict.has("nodeA") or not joint_dict.has("nodeB"): + printerr("Error: OMI_physics_joint extension should have nodeA and nodeB.") + return ERR_FILE_CORRUPT + var joint_node: Joint3D = node as Joint3D + var node_a_index: int = int(joint_dict["nodeA"]) + if node_a_index != -1: + var node_a: Node = state.get_scene_node(node_a_index) + if not node_a is PhysicsBody3D: + printerr("Error: OMI_physics_joint nodeA should be a physics body (non-trigger).") + return ERR_FILE_CORRUPT + joint_node.node_a = joint_node.get_path_to(node_a) + var node_b_index: int = int(joint_dict["nodeB"]) + if node_b_index != -1: + var node_b: Node = state.get_scene_node(node_b_index) + if not node_b is PhysicsBody3D: + printerr("Error: OMI_physics_joint nodeB should be a physics body (non-trigger).") + return ERR_FILE_CORRUPT + joint_node.node_b = joint_node.get_path_to(node_b) + return OK + + +# Export process. +func _convert_scene_node(state: GLTFState, gltf_node: GLTFNode, scene_node: Node) -> void: + if not scene_node is Joint3D: + return + var joint := GLTFPhysicsJoint.from_node(scene_node) + gltf_node.set_additional_data("GLTFPhysicsJoint", joint) + + +func _get_or_create_state_constraints_in_state(state: GLTFState) -> Array: + var state_json = state.get_json() + var state_extensions: Dictionary + if state_json.has("extensions"): + state_extensions = state_json["extensions"] + else: + state_extensions = {} + state_json["extensions"] = state_extensions + var omi_physics_joint_doc_ext: Dictionary + if state_extensions.has("OMI_physics_joint"): + omi_physics_joint_doc_ext = state_extensions["OMI_physics_joint"] + else: + omi_physics_joint_doc_ext = {} + state_extensions["OMI_physics_joint"] = omi_physics_joint_doc_ext + state.add_used_extension("OMI_physics_joint", false) + var state_constraints: Array + if omi_physics_joint_doc_ext.has("constraints"): + state_constraints = omi_physics_joint_doc_ext["constraints"] + else: + state_constraints = [] + omi_physics_joint_doc_ext["constraints"] = state_constraints + return state_constraints + + +func _get_or_insert_constraint_in_state(state: GLTFState, constraint: GLTFPhysicsJointConstraint) -> int: + var state_constraints: Array = _get_or_create_state_constraints_in_state(state) + var size: int = state_constraints.size() + var constraint_dict: Dictionary = constraint.to_dictionary() + for i in range(size): + var other: Dictionary = state_constraints[i] + if other == constraint_dict: + # De-duplication: If we already have an identical constraint, + # return the index of the existing constraint. + return i + # If we don't have an identical constraint, add it to the array. + state_constraints.push_back(constraint_dict) + return size + + +func _node_index_from_scene_node(state: GLTFState, scene_node: Node) -> int: + var index: int = 0 + var node: Node = state.get_scene_node(index) + while node != null: + if node == scene_node: + return index + index = index + 1 + node = state.get_scene_node(index) + return -1 + + +func _export_node(state: GLTFState, gltf_node: GLTFNode, json: Dictionary, _node: Node) -> Error: + var gltf_physics_joint: GLTFPhysicsJoint = gltf_node.get_additional_data("GLTFPhysicsJoint") + if gltf_physics_joint == null: + return OK + var node_extensions = json["extensions"] + if not node_extensions is Dictionary: + node_extensions = {} + json["extensions"] = node_extensions + var omi_physics_joint_node_ext: Dictionary = {} + # Populate the constraints. + var constraints: Array = gltf_physics_joint.get_constraints() + var constraint_indices: Array[int] = [] + for constraint in constraints: + var index: int = _get_or_insert_constraint_in_state(state, constraint) + if not index in constraint_indices: + constraint_indices.append(index) + omi_physics_joint_node_ext["constraints"] = constraint_indices + # Populate the node references. + omi_physics_joint_node_ext["nodeA"] = _node_index_from_scene_node(state, gltf_physics_joint.node_a) + omi_physics_joint_node_ext["nodeB"] = _node_index_from_scene_node(state, gltf_physics_joint.node_b) + node_extensions["OMI_physics_joint"] = omi_physics_joint_node_ext + return OK diff --git a/examples/omi_physics_joint/gltf/hanging_rope.gltf b/examples/omi_physics_joint/gltf/hanging_rope.gltf new file mode 100644 index 0000000..f8d444b --- /dev/null +++ b/examples/omi_physics_joint/gltf/hanging_rope.gltf @@ -0,0 +1,877 @@ +{ + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 0.25, + 0.25, + 0.25 + ], + "min": [ + -0.25, + -0.25, + -0.25 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000015, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 4, + "byteOffset": 0, + "componentType": 5125, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 5, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 6, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 7, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 8, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 9, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 10, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 11, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 12, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 13, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 14, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 15, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 16, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 17, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 18, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 19, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + } + ], + "asset": { + "generator": "Godot Engine v4.1.dev.custom_build@9f12e7b52d944281a39b7d3a33de6700c76cc23a", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 0 + }, + { + "buffer": 0, + "byteLength": 384, + "byteOffset": 288 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 672 + }, + { + "buffer": 0, + "byteLength": 192, + "byteOffset": 960 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 1152 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 1296 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 24696 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 55896 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 79296 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 94896 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 136368 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 159768 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 190968 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 214368 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 229968 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 271440 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 294840 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 326040 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 349440 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 365040 + } + ], + "buffers": [ + { + "byteLength": 406512, + "uri": "hanging_rope0.bin" + } + ], + "cameras": [ + { + "perspective": { + "yfov": 1.30899691581726, + "zfar": 4000, + "znear": 0.0500000007450581 + }, + "type": "perspective" + } + ], + "extensions": { + "OMI_collider": { + "colliders": [ + { + "size": [ + 0.5, + 0.5, + 0.5 + ], + "type": "box" + }, + { + "height": 0.5, + "radius": 0.0500000007450581, + "type": "capsule" + } + ] + }, + "OMI_physics_joint": { + "constraints": [ + { + "linearAxes": [ + 0, + 1, + 2 + ], + "stiffness": 0.300000011920929 + } + ] + } + }, + "extensionsUsed": [ + "OMI_collider", + "OMI_physics_body", + "OMI_physics_joint" + ], + "materials": [ + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + } + ], + "meshes": [ + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 2, + "POSITION": 0, + "TANGENT": 1, + "TEXCOORD_0": 3 + }, + "indices": 4, + "material": 0, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 7, + "POSITION": 5, + "TANGENT": 6, + "TEXCOORD_0": 8 + }, + "indices": 9, + "material": 1, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 12, + "POSITION": 10, + "TANGENT": 11, + "TEXCOORD_0": 13 + }, + "indices": 14, + "material": 2, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 17, + "POSITION": 15, + "TANGENT": 16, + "TEXCOORD_0": 18 + }, + "indices": 19, + "material": 3, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1, + 4, + 5, + 8, + 9, + 12, + 13, + 16 + ], + "extensions": {}, + "name": "HangingRope" + }, + { + "children": [ + 2 + ], + "extensions": { + "OMI_physics_body": { + "type": "static" + } + }, + "name": "Ceiling", + "translation": [ + 0.00000000000208164995657567, + 1.5, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 3 + ], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "CeilingCollider" + }, + { + "extensions": {}, + "mesh": 0, + "name": "CeilingMesh" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0 + ], + "nodeA": 5, + "nodeB": 1 + } + }, + "name": "PinJoint1", + "translation": [ + -0.0000000279397, + 1.25, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 6 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "RopeSegmentTop", + "rotation": [ + 0.000000000000000213587655926077, + 0.000000000000000123314960753772, + 0.258819162845612, + 0.965925812721252 + ], + "translation": [ + -0.17000000178814, + 1.14999997615814, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 7 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "RopeColliderTop", + "rotation": [ + 0.000000000000000246629630339969, + 0.00000000000000000000000935848017, + 0.70710676908493, + 0.70710676908493 + ] + }, + { + "extensions": {}, + "mesh": 1, + "name": "RopeMeshTop" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0 + ], + "nodeA": 9, + "nodeB": 5 + } + }, + "name": "PinJoint2", + "translation": [ + -0.37000000476837, + 1.02999997138977, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 10 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "RopeSegmentMiddle", + "rotation": [ + 0.000000000000000202027284087501, + 0.000000000000000141460709354785, + 0.173648044466972, + 0.984807789325714 + ], + "translation": [ + -0.5799999833107, + 0.949999988079071, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 11 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "RopeColliderMiddle", + "rotation": [ + 0.000000000000000246629630339969, + 0.00000000000000000000000935848017, + 0.70710676908493, + 0.70710676908493 + ] + }, + { + "extensions": {}, + "mesh": 2, + "name": "RopeMeshMiddle" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0 + ], + "nodeA": 13, + "nodeB": 9 + } + }, + "name": "PinJoint3", + "translation": [ + -0.80000001192093, + 0.870000004768372, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 14 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "RopeSegmentBottom", + "translation": [ + -1.02999997138977, + 0.870000004768372, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 15 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "RopeColliderBottom", + "rotation": [ + 0.000000000000000246629630339969, + 0.00000000000000000000000935848017, + 0.70710676908493, + 0.70710676908493 + ] + }, + { + "extensions": {}, + "mesh": 3, + "name": "RopeMeshBottom" + }, + { + "camera": 0, + "extensions": {}, + "name": "Camera", + "translation": [ + 0.00000000000208164995657567, + 0.600000023841858, + 1.5 + ] + } + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ] +} diff --git a/examples/omi_physics_joint/gltf/hanging_rope.gltf.import b/examples/omi_physics_joint/gltf/hanging_rope.gltf.import new file mode 100644 index 0000000..828259e --- /dev/null +++ b/examples/omi_physics_joint/gltf/hanging_rope.gltf.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://ci6itm2taodm3" +path="res://.godot/imported/hanging_rope.gltf-116ef440a86e019930405332d54f98d3.scn" + +[deps] + +source_file="res://examples/omi_physics_joint/gltf/hanging_rope.gltf" +dest_files=["res://.godot/imported/hanging_rope.gltf-116ef440a86e019930405332d54f98d3.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/examples/omi_physics_joint/gltf/hanging_rope0.bin b/examples/omi_physics_joint/gltf/hanging_rope0.bin new file mode 100644 index 0000000..4c654f4 Binary files /dev/null and b/examples/omi_physics_joint/gltf/hanging_rope0.bin differ diff --git a/examples/omi_physics_joint/gltf/pendulum_balls.gltf b/examples/omi_physics_joint/gltf/pendulum_balls.gltf new file mode 100644 index 0000000..8e030e8 --- /dev/null +++ b/examples/omi_physics_joint/gltf/pendulum_balls.gltf @@ -0,0 +1,1333 @@ +{ + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0.1, + 0.1 + ], + "min": [ + -1, + -0.1, + -0.1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000015, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 4, + "byteOffset": 0, + "componentType": 5125, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 5, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.249717, + 0.25, + 0.249717 + ], + "min": [ + -0.249717, + -0.25, + -0.249717 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 6, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 7, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.998868, + 1, + 0.998868 + ], + "min": [ + -0.998869, + -1, + -0.998867 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 8, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 9, + "byteOffset": 0, + "componentType": 5125, + "count": 12672, + "max": [ + 2209 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 10, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.5, + 0.05 + ], + "min": [ + -0.05, + -0.5, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 11, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 12, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 13, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 14, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 15, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.249717, + 0.25, + 0.249717 + ], + "min": [ + -0.249717, + -0.25, + -0.249717 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 16, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 17, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.998868, + 1, + 0.998868 + ], + "min": [ + -0.998869, + -1, + -0.998867 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 18, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 19, + "byteOffset": 0, + "componentType": 5125, + "count": 12672, + "max": [ + 2209 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 20, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.5, + 0.05 + ], + "min": [ + -0.05, + -0.5, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 21, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 22, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 23, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 24, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 25, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.249717, + 0.25, + 0.249717 + ], + "min": [ + -0.249717, + -0.25, + -0.249717 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 26, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 27, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.998868, + 1, + 0.998868 + ], + "min": [ + -0.998869, + -1, + -0.998867 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 28, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 29, + "byteOffset": 0, + "componentType": 5125, + "count": 12672, + "max": [ + 2209 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 30, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.5, + 0.05 + ], + "min": [ + -0.05, + -0.5, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 31, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 32, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 33, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 34, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + } + ], + "asset": { + "generator": "Godot Engine v4.1.dev.custom_build@9f12e7b52d944281a39b7d3a33de6700c76cc23a", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 0 + }, + { + "buffer": 0, + "byteLength": 384, + "byteOffset": 288 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 672 + }, + { + "buffer": 0, + "byteLength": 192, + "byteOffset": 960 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 1152 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 1296 + }, + { + "buffer": 0, + "byteLength": 35360, + "byteOffset": 27816 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 63176 + }, + { + "buffer": 0, + "byteLength": 17680, + "byteOffset": 89696 + }, + { + "buffer": 0, + "byteLength": 50688, + "byteOffset": 107376 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 158064 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 181464 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 212664 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 236064 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 251664 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 293136 + }, + { + "buffer": 0, + "byteLength": 35360, + "byteOffset": 319656 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 355016 + }, + { + "buffer": 0, + "byteLength": 17680, + "byteOffset": 381536 + }, + { + "buffer": 0, + "byteLength": 50688, + "byteOffset": 399216 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 449904 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 473304 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 504504 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 527904 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 543504 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 584976 + }, + { + "buffer": 0, + "byteLength": 35360, + "byteOffset": 611496 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 646856 + }, + { + "buffer": 0, + "byteLength": 17680, + "byteOffset": 673376 + }, + { + "buffer": 0, + "byteLength": 50688, + "byteOffset": 691056 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 741744 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 765144 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 796344 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 819744 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 835344 + } + ], + "buffers": [ + { + "byteLength": 876816, + "uri": "pendulum_balls0.bin" + } + ], + "cameras": [ + { + "perspective": { + "yfov": 1.30899691581726, + "zfar": 4000, + "znear": 0.0500000007450581 + }, + "type": "perspective" + } + ], + "extensions": { + "OMI_collider": { + "colliders": [ + { + "size": [ + 2, + 0.200000002980232, + 0.200000002980232 + ], + "type": "box" + }, + { + "radius": 0.25, + "type": "sphere" + } + ] + }, + "OMI_physics_joint": { + "constraints": [ + { + "linearAxes": [ + 0, + 1, + 2 + ], + "stiffness": 0.300000011920929 + }, + { + "angularAxes": [ + 0, + 1 + ], + "stiffness": 0.300000011920929 + } + ] + } + }, + "extensionsUsed": [ + "OMI_collider", + "OMI_physics_body", + "OMI_physics_joint" + ], + "materials": [ + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + } + ], + "meshes": [ + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 2, + "POSITION": 0, + "TANGENT": 1, + "TEXCOORD_0": 3 + }, + "indices": 4, + "material": 0, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 7, + "POSITION": 5, + "TANGENT": 6, + "TEXCOORD_0": 8 + }, + "indices": 9, + "material": 1, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 12, + "POSITION": 10, + "TANGENT": 11, + "TEXCOORD_0": 13 + }, + "indices": 14, + "material": 2, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 17, + "POSITION": 15, + "TANGENT": 16, + "TEXCOORD_0": 18 + }, + "indices": 19, + "material": 3, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 22, + "POSITION": 20, + "TANGENT": 21, + "TEXCOORD_0": 23 + }, + "indices": 24, + "material": 4, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 27, + "POSITION": 25, + "TANGENT": 26, + "TEXCOORD_0": 28 + }, + "indices": 29, + "material": 5, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 32, + "POSITION": 30, + "TANGENT": 31, + "TEXCOORD_0": 33 + }, + "indices": 34, + "material": 6, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1, + 4, + 5, + 9, + 10, + 14, + 15, + 19 + ], + "extensions": {}, + "name": "PendulumBalls" + }, + { + "children": [ + 2 + ], + "extensions": { + "OMI_physics_body": { + "type": "static" + } + }, + "name": "TopBody", + "translation": [ + 0.00000000000208164995657567, + 1, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 3 + ], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "TopBodyShape" + }, + { + "extensions": {}, + "mesh": 0, + "name": "TopBodyMesh" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0, + 1 + ], + "nodeA": 1, + "nodeB": 5 + } + }, + "name": "HingeJoint1", + "translation": [ + 0.00000000000208164995657567, + 0.899999976158142, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 6, + 8 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "Ball1", + "translation": [ + 0.00000000000208164995657567, + -0.25, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 7 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "BallShape1" + }, + { + "extensions": {}, + "mesh": 1, + "name": "BallMesh1" + }, + { + "extensions": {}, + "mesh": 2, + "name": "BallStringMesh1", + "translation": [ + 0.00000000000208164995657567, + 0.699999988079071, + 0.00000000000208164995657567 + ] + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0, + 1 + ], + "nodeA": 1, + "nodeB": 10 + } + }, + "name": "HingeJoint2", + "translation": [ + -0.44999998807907, + 0.899999976158142, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 11, + 13 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "Ball2", + "rotation": [ + 0.000000000000000094381003489835, + 0.000000000000000227855912687686, + -0.38268345594406, + 0.923879563808441 + ], + "translation": [ + -1.26317000389099, + 0.0868272036314011, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 12 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "BallShape2" + }, + { + "extensions": {}, + "mesh": 3, + "name": "BallMesh2" + }, + { + "extensions": {}, + "mesh": 4, + "name": "BallStringMesh2", + "translation": [ + 0.00000000000208164995657567, + 0.699999988079071, + 0.00000000000208164995657567 + ] + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0, + 1 + ], + "nodeA": 1, + "nodeB": 15 + } + }, + "name": "HingeJoint3", + "rotation": [ + 0.000000000000000213587655926077, + 0.000000000000000123314960753772, + 0.258819162845612, + 0.965925812721252 + ], + "translation": [ + 0.449999988079071, + 0.899999976158142, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 16, + 18 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "Ball3", + "rotation": [ + 0.000000000000000440183937976967, + -0, + 0.991444885730743, + 0.130526155233383 + ], + "translation": [ + 0.747641980648041, + 2.01080989837646, + 0.00000000000208192989757661 + ] + }, + { + "children": [ + 17 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "BallShape22" + }, + { + "extensions": {}, + "mesh": 5, + "name": "BallMesh22" + }, + { + "extensions": {}, + "mesh": 6, + "name": "BallStringMesh22", + "translation": [ + 0.00000000000208164995657567, + 0.699999988079071, + 0.00000000000208164995657567 + ] + }, + { + "camera": 0, + "extensions": {}, + "name": "Camera", + "translation": [ + 0.00000000000208164995657567, + 0.00000000000208164995657567, + 1.5 + ] + } + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ] +} diff --git a/examples/omi_physics_joint/gltf/pendulum_balls.gltf.import b/examples/omi_physics_joint/gltf/pendulum_balls.gltf.import new file mode 100644 index 0000000..e29e938 --- /dev/null +++ b/examples/omi_physics_joint/gltf/pendulum_balls.gltf.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bfxsfq0gxuqqd" +path="res://.godot/imported/pendulum_balls.gltf-2daa923260ec45baa4e9fc7d76423694.scn" + +[deps] + +source_file="res://examples/omi_physics_joint/gltf/pendulum_balls.gltf" +dest_files=["res://.godot/imported/pendulum_balls.gltf-2daa923260ec45baa4e9fc7d76423694.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/examples/omi_physics_joint/gltf/pendulum_balls0.bin b/examples/omi_physics_joint/gltf/pendulum_balls0.bin new file mode 100644 index 0000000..fc06e65 Binary files /dev/null and b/examples/omi_physics_joint/gltf/pendulum_balls0.bin differ diff --git a/examples/omi_physics_joint/gltf/rope_railing.gltf b/examples/omi_physics_joint/gltf/rope_railing.gltf new file mode 100644 index 0000000..644cb65 --- /dev/null +++ b/examples/omi_physics_joint/gltf/rope_railing.gltf @@ -0,0 +1,1480 @@ +{ + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 0.075, + 0.55, + 0.075 + ], + "min": [ + -0.075, + -0.55, + -0.075 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000015, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 4, + "byteOffset": 0, + "componentType": 5125, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 5, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 6, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 7, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 8, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 9, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 10, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 11, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 12, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 13, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 14, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 15, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 16, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 17, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 18, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 19, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 20, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 21, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 22, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 23, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 24, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 25, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 26, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 27, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 28, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 29, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 30, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 0.075, + 0.55, + 0.075 + ], + "min": [ + -0.075, + -0.55, + -0.075 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 31, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000015, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 32, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 33, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 34, + "byteOffset": 0, + "componentType": 5125, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + } + ], + "asset": { + "generator": "Godot Engine v4.1.dev.custom_build@9f12e7b52d944281a39b7d3a33de6700c76cc23a", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 0 + }, + { + "buffer": 0, + "byteLength": 384, + "byteOffset": 288 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 672 + }, + { + "buffer": 0, + "byteLength": 192, + "byteOffset": 960 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 1152 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 1296 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 24696 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 55896 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 79296 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 94896 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 136368 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 159768 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 190968 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 214368 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 229968 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 271440 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 294840 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 326040 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 349440 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 365040 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 406512 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 429912 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 461112 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 484512 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 500112 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 541584 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 564984 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 596184 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 619584 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 635184 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 676656 + }, + { + "buffer": 0, + "byteLength": 384, + "byteOffset": 676944 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 677328 + }, + { + "buffer": 0, + "byteLength": 192, + "byteOffset": 677616 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 677808 + } + ], + "buffers": [ + { + "byteLength": 677952, + "uri": "rope_railing0.bin" + } + ], + "cameras": [ + { + "perspective": { + "yfov": 1.30899691581726, + "zfar": 4000, + "znear": 0.0500000007450581 + }, + "type": "perspective" + } + ], + "extensions": { + "OMI_collider": { + "colliders": [ + { + "size": [ + 0.150000005960464, + 1.10000002384186, + 0.150000005960464 + ], + "type": "box" + }, + { + "height": 0.5, + "radius": 0.0500000007450581, + "type": "capsule" + } + ] + }, + "OMI_physics_joint": { + "constraints": [ + { + "linearAxes": [ + 0, + 1, + 2 + ], + "stiffness": 0.300000011920929 + } + ] + } + }, + "extensionsUsed": [ + "OMI_collider", + "OMI_physics_body", + "OMI_physics_joint" + ], + "materials": [ + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + } + ], + "meshes": [ + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 2, + "POSITION": 0, + "TANGENT": 1, + "TEXCOORD_0": 3 + }, + "indices": 4, + "material": 0, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 7, + "POSITION": 5, + "TANGENT": 6, + "TEXCOORD_0": 8 + }, + "indices": 9, + "material": 1, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 12, + "POSITION": 10, + "TANGENT": 11, + "TEXCOORD_0": 13 + }, + "indices": 14, + "material": 2, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 17, + "POSITION": 15, + "TANGENT": 16, + "TEXCOORD_0": 18 + }, + "indices": 19, + "material": 3, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 22, + "POSITION": 20, + "TANGENT": 21, + "TEXCOORD_0": 23 + }, + "indices": 24, + "material": 4, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 27, + "POSITION": 25, + "TANGENT": 26, + "TEXCOORD_0": 28 + }, + "indices": 29, + "material": 5, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 32, + "POSITION": 30, + "TANGENT": 31, + "TEXCOORD_0": 33 + }, + "indices": 34, + "material": 6, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1, + 4, + 5, + 8, + 9, + 12, + 13, + 16, + 17, + 20, + 21, + 24, + 25, + 28 + ], + "extensions": {}, + "name": "RopeRailing" + }, + { + "children": [ + 2 + ], + "extensions": { + "OMI_physics_body": { + "type": "static" + } + }, + "name": "PoleLeft", + "translation": [ + -1.10000002384186, + 0.550000011920929, + 0.00000000000208164735449046 + ] + }, + { + "children": [ + 3 + ], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "PoleColliderLeft" + }, + { + "extensions": {}, + "mesh": 0, + "name": "PoleMeshLeft" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0 + ], + "nodeA": 1, + "nodeB": 5 + } + }, + "name": "PinJoint1", + "translation": [ + -1.02999997138977, + 0.980000019073486, + 0.00000000000208164735449046 + ] + }, + { + "children": [ + 6 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "RopeSegmentLeft", + "rotation": [ + 0.000000000000000123314947518882, + 0.000000000000000213587655926077, + -0.25881916284561, + 0.965925812721252 + ], + "translation": [ + -0.86000001430511, + 0.879999995231628, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 7 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "RopeColliderLeft", + "rotation": [ + 0.000000000000000246629630339969, + 0.00000000000000000000000935848017, + 0.70710676908493, + 0.70710676908493 + ] + }, + { + "extensions": {}, + "mesh": 1, + "name": "RopeMeshLeft" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0 + ], + "nodeA": 5, + "nodeB": 9 + } + }, + "name": "PinJoint2", + "translation": [ + -0.66000002622604, + 0.759999990463257, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 10 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "RopeSegmentLeftMiddle", + "rotation": [ + 0.000000000000000141460722589675, + 0.000000000000000202027284087501, + -0.17364804446697, + 0.984807789325714 + ], + "translation": [ + -0.44999998807907, + 0.680000007152557, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 11 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "RopeColliderLeftMiddle", + "rotation": [ + 0.000000000000000246629630339969, + 0.00000000000000000000000935848017, + 0.70710676908493, + 0.70710676908493 + ] + }, + { + "extensions": {}, + "mesh": 2, + "name": "RopeMeshLeftMiddle" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0 + ], + "nodeA": 9, + "nodeB": 13 + } + }, + "name": "PinJoint3", + "translation": [ + -0.23000000417233, + 0.600000023841858, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 14 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "RopeSegmentMiddle", + "translation": [ + 0.00000000000208164995657567, + 0.600000023841858, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 15 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "RopeColliderMiddle", + "rotation": [ + 0.000000000000000246629630339969, + 0.00000000000000000000000935848017, + 0.70710676908493, + 0.70710676908493 + ] + }, + { + "extensions": {}, + "mesh": 3, + "name": "RopeMeshMiddle" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0 + ], + "nodeA": 13, + "nodeB": 17 + } + }, + "name": "PinJoint4", + "translation": [ + 0.230000004172325, + 0.600000023841858, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 18 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "RopeSegmentRightMiddle", + "rotation": [ + 0.000000000000000202027284087501, + 0.000000000000000141460709354785, + 0.173648044466972, + 0.984807789325714 + ], + "translation": [ + 0.449999988079071, + 0.680000007152557, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 19 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "RopeColliderRightMiddle", + "rotation": [ + 0.000000000000000246629630339969, + 0.00000000000000000000000935848017, + 0.70710676908493, + 0.70710676908493 + ] + }, + { + "extensions": {}, + "mesh": 4, + "name": "RopeMeshRightMiddle" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0 + ], + "nodeA": 17, + "nodeB": 21 + } + }, + "name": "PinJoint5", + "translation": [ + 0.660000026226044, + 0.759999990463257, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 22 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "RopeSegmentRight", + "rotation": [ + 0.000000000000000213587655926077, + 0.000000000000000123314960753772, + 0.258819162845612, + 0.965925812721252 + ], + "translation": [ + 0.860000014305115, + 0.879999995231628, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 23 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "RopeColliderRight", + "rotation": [ + 0.000000000000000246629630339969, + 0.00000000000000000000000935848017, + 0.70710676908493, + 0.70710676908493 + ] + }, + { + "extensions": {}, + "mesh": 5, + "name": "RopeMeshRight" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0 + ], + "nodeA": 21, + "nodeB": 25 + } + }, + "name": "PinJoint6", + "translation": [ + 1.02999997138977, + 0.980000019073486, + 0.00000000000208164735449046 + ] + }, + { + "children": [ + 26 + ], + "extensions": { + "OMI_physics_body": { + "type": "static" + } + }, + "name": "PoleRight", + "translation": [ + 1.10000002384186, + 0.550000011920929, + 0.00000000000208164735449046 + ] + }, + { + "children": [ + 27 + ], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "PoleColliderRight" + }, + { + "extensions": {}, + "mesh": 6, + "name": "PoleMeshRight" + }, + { + "camera": 0, + "extensions": {}, + "name": "Camera", + "translation": [ + 0.00000000000208164995657567, + 0.600000023841858, + 1.5 + ] + } + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ] +} diff --git a/examples/omi_physics_joint/gltf/rope_railing.gltf.import b/examples/omi_physics_joint/gltf/rope_railing.gltf.import new file mode 100644 index 0000000..df00720 --- /dev/null +++ b/examples/omi_physics_joint/gltf/rope_railing.gltf.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://b510bj645xkt3" +path="res://.godot/imported/rope_railing.gltf-c9bb99e545cf01d46971f7ed25b8e292.scn" + +[deps] + +source_file="res://examples/omi_physics_joint/gltf/rope_railing.gltf" +dest_files=["res://.godot/imported/rope_railing.gltf-c9bb99e545cf01d46971f7ed25b8e292.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/examples/omi_physics_joint/gltf/rope_railing0.bin b/examples/omi_physics_joint/gltf/rope_railing0.bin new file mode 100644 index 0000000..bf45c6c Binary files /dev/null and b/examples/omi_physics_joint/gltf/rope_railing0.bin differ diff --git a/examples/omi_physics_joint/gltf/simple_joint.gltf b/examples/omi_physics_joint/gltf/simple_joint.gltf new file mode 100644 index 0000000..a230238 --- /dev/null +++ b/examples/omi_physics_joint/gltf/simple_joint.gltf @@ -0,0 +1,588 @@ +{ + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 4, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 5, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 6, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 7, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 8, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 9, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 10, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.125, + 0.5 + ], + "min": [ + -0.5, + -0.125, + -0.5 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 11, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000015, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 12, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 13, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 14, + "byteOffset": 0, + "componentType": 5125, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + } + ], + "asset": { + "generator": "Godot Engine v4.1.dev.custom_build@9f12e7b52d944281a39b7d3a33de6700c76cc23a", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 0 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 23400 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 54600 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 78000 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 93600 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 135072 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 158472 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 189672 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 213072 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 228672 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 270144 + }, + { + "buffer": 0, + "byteLength": 384, + "byteOffset": 270432 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 270816 + }, + { + "buffer": 0, + "byteLength": 192, + "byteOffset": 271104 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 271296 + } + ], + "buffers": [ + { + "byteLength": 271440, + "uri": "simple_joint0.bin" + } + ], + "cameras": [ + { + "perspective": { + "yfov": 1.30899691581726, + "zfar": 4000, + "znear": 0.0500000007450581 + }, + "type": "perspective" + } + ], + "extensions": { + "OMI_collider": { + "colliders": [ + { + "height": 0.5, + "radius": 0.0500000007450581, + "type": "capsule" + }, + { + "size": [1, 0.25, 1], + "type": "box" + } + ] + }, + "OMI_physics_joint": { + "constraints": [ + { + "linearAxes": [0, 1, 2] + } + ] + } + }, + "extensionsUsed": [ + "OMI_collider", + "OMI_physics_body", + "OMI_physics_joint" + ], + "materials": [ + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + } + ], + "meshes": [ + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 2, + "POSITION": 0, + "TANGENT": 1, + "TEXCOORD_0": 3 + }, + "indices": 4, + "material": 0, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 7, + "POSITION": 5, + "TANGENT": 6, + "TEXCOORD_0": 8 + }, + "indices": 9, + "material": 1, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 12, + "POSITION": 10, + "TANGENT": 11, + "TEXCOORD_0": 13 + }, + "indices": 14, + "material": 2, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "extensions": { + "OMI_physics_joint": { + "constraints": [0], + "nodeA": 1, + "nodeB": 2 + } + }, + "name": "PinJoint", + "translation": [-0.23, 0.6, 0.0] + }, + { + "children": [4], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "BodyA", + "rotation": [0.0, 0.0, -0.17364804446697, 0.984807789325714], + "translation": [-0.45, 0.68, 0.0] + }, + { + "children": [6], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "BodyB", + "translation": [0.0, 0.6, 0.0] + }, + { + "children": [0, 1, 2, 8, 11], + "extensions": {}, + "name": "SimpleJoint" + }, + { + "children": [5], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "ColliderA", + "rotation": [0.0, 0.0, 0.70710676908493, 0.70710676908493] + }, + { + "extensions": {}, + "mesh": 0, + "name": "MeshA" + }, + { + "children": [7], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "ColliderB", + "rotation": [0.0, 0.0, 0.70710676908493, 0.70710676908493] + }, + { + "extensions": {}, + "mesh": 1, + "name": "MeshB" + }, + { + "children": [9], + "extensions": { + "OMI_physics_body": { + "type": "static" + } + }, + "name": "FloorBody", + "translation": [0.1, 0.0, 0.0] + }, + { + "children": [10], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "FloorShape" + }, + { + "extensions": {}, + "mesh": 2, + "name": "FloorMesh" + }, + { + "camera": 0, + "extensions": {}, + "name": "Camera", + "translation": [0.0, 0.5, 1.5] + } + ], + "scene": 0, + "scenes": [ + { + "nodes": [3] + } + ] +} diff --git a/examples/omi_physics_joint/gltf/simple_joint.gltf.import b/examples/omi_physics_joint/gltf/simple_joint.gltf.import new file mode 100644 index 0000000..8346bff --- /dev/null +++ b/examples/omi_physics_joint/gltf/simple_joint.gltf.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://cbcl76ieoawm0" +path="res://.godot/imported/simple_joint.gltf-199cb5aef32bfadaa96b9d3d991c41ca.scn" + +[deps] + +source_file="res://examples/omi_physics_joint/gltf/simple_joint.gltf" +dest_files=["res://.godot/imported/simple_joint.gltf-199cb5aef32bfadaa96b9d3d991c41ca.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/examples/omi_physics_joint/gltf/simple_joint0.bin b/examples/omi_physics_joint/gltf/simple_joint0.bin new file mode 100644 index 0000000..e55afe0 Binary files /dev/null and b/examples/omi_physics_joint/gltf/simple_joint0.bin differ diff --git a/examples/omi_physics_joint/gltf/slider_ball.gltf b/examples/omi_physics_joint/gltf/slider_ball.gltf new file mode 100644 index 0000000..ddd65cb --- /dev/null +++ b/examples/omi_physics_joint/gltf/slider_ball.gltf @@ -0,0 +1,490 @@ +{ + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0.05, + 0.05 + ], + "min": [ + -1, + -0.05, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000015, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 4, + "byteOffset": 0, + "componentType": 5125, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 5, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.249717, + 0.25, + 0.249717 + ], + "min": [ + -0.249717, + -0.25, + -0.249717 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 6, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 7, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.998868, + 1, + 0.998868 + ], + "min": [ + -0.998869, + -1, + -0.998867 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 8, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 9, + "byteOffset": 0, + "componentType": 5125, + "count": 12672, + "max": [ + 2209 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + } + ], + "asset": { + "generator": "Godot Engine v4.1.dev.custom_build@9f12e7b52d944281a39b7d3a33de6700c76cc23a", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 0 + }, + { + "buffer": 0, + "byteLength": 384, + "byteOffset": 288 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 672 + }, + { + "buffer": 0, + "byteLength": 192, + "byteOffset": 960 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 1152 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 1296 + }, + { + "buffer": 0, + "byteLength": 35360, + "byteOffset": 27816 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 63176 + }, + { + "buffer": 0, + "byteLength": 17680, + "byteOffset": 89696 + }, + { + "buffer": 0, + "byteLength": 50688, + "byteOffset": 107376 + } + ], + "buffers": [ + { + "byteLength": 158064, + "uri": "slider_ball0.bin" + } + ], + "cameras": [ + { + "perspective": { + "yfov": 1.30899691581726, + "zfar": 4000, + "znear": 0.0500000007450581 + }, + "type": "perspective" + } + ], + "extensions": { + "OMI_collider": { + "colliders": [ + { + "size": [ + 2, + 0.100000001490116, + 0.100000001490116 + ], + "type": "box" + }, + { + "radius": 0.25, + "type": "sphere" + } + ] + }, + "OMI_physics_joint": { + "constraints": [ + { + "damping": 0.5, + "linearAxes": [ + 0 + ], + "lowerLimit": -1.75, + "stiffness": 1, + "upperLimit": 0.25 + }, + { + "linearAxes": [ + 1, + 2 + ], + "stiffness": 1 + }, + { + "angularAxes": [ + 0 + ], + "damping": 0, + "stiffness": 1 + }, + { + "angularAxes": [ + 1, + 2 + ], + "stiffness": 1 + } + ] + } + }, + "extensionsUsed": [ + "OMI_collider", + "OMI_physics_body", + "OMI_physics_joint" + ], + "materials": [ + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + } + ], + "meshes": [ + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 2, + "POSITION": 0, + "TANGENT": 1, + "TEXCOORD_0": 3 + }, + "indices": 4, + "material": 0, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 7, + "POSITION": 5, + "TANGENT": 6, + "TEXCOORD_0": 8 + }, + "indices": 9, + "material": 1, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1, + 4, + 5, + 8 + ], + "extensions": {}, + "name": "PendulumBalls" + }, + { + "children": [ + 2 + ], + "extensions": { + "OMI_physics_body": { + "type": "static" + } + }, + "name": "SliderLine" + }, + { + "children": [ + 3 + ], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "SliderLineShape" + }, + { + "extensions": {}, + "mesh": 0, + "name": "SliderLineMesh" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0, + 1, + 2, + 3 + ], + "nodeA": 5, + "nodeB": 1 + } + }, + "name": "SliderJoint", + "translation": [ + -0.75, + 0.00000000000208164995657567, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 6 + ], + "extensions": { + "OMI_physics_body": { + "angularVelocity": [ + 0.0174532998353243, + 0.0174532998353243, + 0.0174532998353243 + ], + "linearVelocity": [ + 1, + 0.00000000000208164995657567, + 0.00000000000208164995657567 + ], + "type": "rigid" + } + }, + "name": "Ball", + "translation": [ + -0.75, + 0.00000000000208164995657567, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 7 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "BallShape" + }, + { + "extensions": {}, + "mesh": 1, + "name": "BallMesh" + }, + { + "camera": 0, + "extensions": {}, + "name": "Camera", + "translation": [ + 0.00000000000208164995657567, + 0.00000000000208164995657567, + 1.5 + ] + } + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ] +} diff --git a/examples/omi_physics_joint/gltf/slider_ball.gltf.import b/examples/omi_physics_joint/gltf/slider_ball.gltf.import new file mode 100644 index 0000000..b9ae238 --- /dev/null +++ b/examples/omi_physics_joint/gltf/slider_ball.gltf.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bsru8jcku4pbm" +path="res://.godot/imported/slider_ball.gltf-22d65bf5cdc8cc03b0c9545fb3c54f94.scn" + +[deps] + +source_file="res://examples/omi_physics_joint/gltf/slider_ball.gltf" +dest_files=["res://.godot/imported/slider_ball.gltf-22d65bf5cdc8cc03b0c9545fb3c54f94.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/examples/omi_physics_joint/gltf/slider_ball0.bin b/examples/omi_physics_joint/gltf/slider_ball0.bin new file mode 100644 index 0000000..c75c0d7 Binary files /dev/null and b/examples/omi_physics_joint/gltf/slider_ball0.bin differ diff --git a/examples/omi_physics_joint/gltf/swing_and_slide.gltf b/examples/omi_physics_joint/gltf/swing_and_slide.gltf new file mode 100644 index 0000000..21e4b06 --- /dev/null +++ b/examples/omi_physics_joint/gltf/swing_and_slide.gltf @@ -0,0 +1,635 @@ +{ + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0.05, + 0.05 + ], + "min": [ + -1, + -0.05, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000015, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 4, + "byteOffset": 0, + "componentType": 5125, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 5, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.249717, + 0.25, + 0.249717 + ], + "min": [ + -0.249717, + -0.25, + -0.249717 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 6, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 7, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 0.998868, + 1, + 0.998868 + ], + "min": [ + -0.998869, + -1, + -0.998867 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 8, + "byteOffset": 0, + "componentType": 5126, + "count": 2210, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 9, + "byteOffset": 0, + "componentType": 5125, + "count": 12672, + "max": [ + 2209 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 10, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.5, + 0.05 + ], + "min": [ + -0.05, + -0.5, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 11, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 12, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 13, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 14, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + } + ], + "asset": { + "generator": "Godot Engine v4.1.dev.custom_build@9f12e7b52d944281a39b7d3a33de6700c76cc23a", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 0 + }, + { + "buffer": 0, + "byteLength": 384, + "byteOffset": 288 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 672 + }, + { + "buffer": 0, + "byteLength": 192, + "byteOffset": 960 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 1152 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 1296 + }, + { + "buffer": 0, + "byteLength": 35360, + "byteOffset": 27816 + }, + { + "buffer": 0, + "byteLength": 26520, + "byteOffset": 63176 + }, + { + "buffer": 0, + "byteLength": 17680, + "byteOffset": 89696 + }, + { + "buffer": 0, + "byteLength": 50688, + "byteOffset": 107376 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 158064 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 181464 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 212664 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 236064 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 251664 + } + ], + "buffers": [ + { + "byteLength": 293136, + "uri": "swing_and_slide0.bin" + } + ], + "cameras": [ + { + "perspective": { + "yfov": 1.30899691581726, + "zfar": 4000, + "znear": 0.0500000007450581 + }, + "type": "perspective" + } + ], + "extensions": { + "OMI_collider": { + "colliders": [ + { + "size": [ + 2, + 0.100000001490116, + 0.100000001490116 + ], + "type": "box" + }, + { + "radius": 0.25, + "type": "sphere" + } + ] + }, + "OMI_physics_joint": { + "constraints": [ + { + "linearAxes": [ + 0 + ], + "lowerLimit": -0.25, + "stiffness": 0.699999988079071, + "upperLimit": 1.75 + }, + { + "linearAxes": [ + 1, + 2 + ], + "stiffness": 0.699999988079071 + }, + { + "angularAxes": [ + 0, + 1 + ], + "stiffness": 0.5 + } + ] + } + }, + "extensionsUsed": [ + "OMI_collider", + "OMI_physics_body", + "OMI_physics_joint" + ], + "materials": [ + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + } + ], + "meshes": [ + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 2, + "POSITION": 0, + "TANGENT": 1, + "TEXCOORD_0": 3 + }, + "indices": 4, + "material": 0, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 7, + "POSITION": 5, + "TANGENT": 6, + "TEXCOORD_0": 8 + }, + "indices": 9, + "material": 1, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 12, + "POSITION": 10, + "TANGENT": 11, + "TEXCOORD_0": 13 + }, + "indices": 14, + "material": 2, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1, + 4, + 5, + 9 + ], + "extensions": {}, + "name": "SwingAndSlide" + }, + { + "children": [ + 2 + ], + "extensions": { + "OMI_physics_body": { + "type": "static" + } + }, + "name": "TopBody", + "translation": [ + 0.00000000000208164995657567, + 1, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 3 + ], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "TopBodyShape" + }, + { + "extensions": {}, + "mesh": 0, + "name": "TopBodyMesh" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [ + 0, + 1, + 2 + ], + "nodeA": 1, + "nodeB": 5 + } + }, + "name": "CustomJoint", + "translation": [ + -0.75, + 1, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 6, + 8 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "Ball", + "rotation": [ + 0.000000000000000094381003489835, + 0.000000000000000227855912687686, + -0.38268345594406, + 0.923879563808441 + ], + "translation": [ + -1.60000002384186, + 0.150000005960464, + 0.00000000000208164995657567 + ] + }, + { + "children": [ + 7 + ], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "BallShape" + }, + { + "extensions": {}, + "mesh": 1, + "name": "BallMesh" + }, + { + "extensions": {}, + "mesh": 2, + "name": "BallStringMesh", + "translation": [ + 0.00000000000208164995657567, + 0.699999988079071, + 0.00000000000208164995657567 + ] + }, + { + "camera": 0, + "extensions": {}, + "name": "Camera", + "translation": [ + 0.00000000000208164995657567, + 0.00000000000208164995657567, + 1.5 + ] + } + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ] +} diff --git a/examples/omi_physics_joint/gltf/swing_and_slide.gltf.import b/examples/omi_physics_joint/gltf/swing_and_slide.gltf.import new file mode 100644 index 0000000..28dd581 --- /dev/null +++ b/examples/omi_physics_joint/gltf/swing_and_slide.gltf.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bw0c7334lfcil" +path="res://.godot/imported/swing_and_slide.gltf-21422adc01d7471f98bd9f36c041ed62.scn" + +[deps] + +source_file="res://examples/omi_physics_joint/gltf/swing_and_slide.gltf" +dest_files=["res://.godot/imported/swing_and_slide.gltf-21422adc01d7471f98bd9f36c041ed62.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/examples/omi_physics_joint/gltf/swing_and_slide0.bin b/examples/omi_physics_joint/gltf/swing_and_slide0.bin new file mode 100644 index 0000000..807678c Binary files /dev/null and b/examples/omi_physics_joint/gltf/swing_and_slide0.bin differ diff --git a/examples/omi_physics_joint/gltf/weld_joint.gltf b/examples/omi_physics_joint/gltf/weld_joint.gltf new file mode 100644 index 0000000..f63e8ba --- /dev/null +++ b/examples/omi_physics_joint/gltf/weld_joint.gltf @@ -0,0 +1,595 @@ +{ + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 4, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 5, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 0.05, + 0.25, + 0.05 + ], + "min": [ + -0.05, + -0.25, + -0.05 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 6, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000022, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 7, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 8, + "byteOffset": 0, + "componentType": 5126, + "count": 1950, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 9, + "byteOffset": 0, + "componentType": 5125, + "count": 10368, + "max": [ + 1949 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 10, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.125, + 0.5 + ], + "min": [ + -0.5, + -0.125, + -0.5 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 11, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 0, + 1, + 1 + ], + "min": [ + -1, + -0.000015, + -1, + 1 + ], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 12, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 13, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 14, + "byteOffset": 0, + "componentType": 5125, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "normalized": false, + "type": "SCALAR" + } + ], + "asset": { + "generator": "Godot Engine v4.1.dev.custom_build@9f12e7b52d944281a39b7d3a33de6700c76cc23a", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 0 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 23400 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 54600 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 78000 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 93600 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 135072 + }, + { + "buffer": 0, + "byteLength": 31200, + "byteOffset": 158472 + }, + { + "buffer": 0, + "byteLength": 23400, + "byteOffset": 189672 + }, + { + "buffer": 0, + "byteLength": 15600, + "byteOffset": 213072 + }, + { + "buffer": 0, + "byteLength": 41472, + "byteOffset": 228672 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 270144 + }, + { + "buffer": 0, + "byteLength": 384, + "byteOffset": 270432 + }, + { + "buffer": 0, + "byteLength": 288, + "byteOffset": 270816 + }, + { + "buffer": 0, + "byteLength": 192, + "byteOffset": 271104 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 271296 + } + ], + "buffers": [ + { + "byteLength": 271440, + "uri": "weld_joint0.bin" + } + ], + "cameras": [ + { + "perspective": { + "yfov": 1.30899691581726, + "zfar": 4000, + "znear": 0.0500000007450581 + }, + "type": "perspective" + } + ], + "extensions": { + "OMI_collider": { + "colliders": [ + { + "height": 0.5, + "radius": 0.0500000007450581, + "type": "capsule" + }, + { + "size": [1, 0.25, 1], + "type": "box" + } + ] + }, + "OMI_physics_joint": { + "constraints": [ + { + "linearAxes": [0, 1, 2], + "angularAxes": [0, 1, 2] + } + ] + } + }, + "extensionsUsed": [ + "OMI_collider", + "OMI_physics_body", + "OMI_physics_joint" + ], + "materials": [ + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": {}, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.99999988079071, + 0.99999988079071, + 0.99999988079071, + 1 + ], + "metallicFactor": 0, + "roughnessFactor": 1 + } + } + ], + "meshes": [ + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 2, + "POSITION": 0, + "TANGENT": 1, + "TEXCOORD_0": 3 + }, + "indices": 4, + "material": 0, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 7, + "POSITION": 5, + "TANGENT": 6, + "TEXCOORD_0": 8 + }, + "indices": 9, + "material": 1, + "mode": 4 + } + ] + }, + { + "extras": { + "targetNames": [] + }, + "primitives": [ + { + "attributes": { + "NORMAL": 12, + "POSITION": 10, + "TANGENT": 11, + "TEXCOORD_0": 13 + }, + "indices": 14, + "material": 2, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [1, 4, 5, 8, 11], + "extensions": {}, + "name": "SimpleJoint" + }, + { + "children": [2], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "BodyA", + "rotation": [0.000859406718518585, 0.000151536631165072, -0.17364810407162, 0.984807372093201], + "translation": [-0.45, 0.68, 0.0] + }, + { + "children": [3], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "ColliderA", + "rotation": [0.0, 0.0, 0.70710676908493, 0.70710676908493] + }, + { + "extensions": {}, + "mesh": 0, + "name": "MeshA" + }, + { + "extensions": { + "OMI_physics_joint": { + "constraints": [0], + "nodeA": 1, + "nodeB": 5 + } + }, + "name": "WeldJoint", + "translation": [-0.23, 0.6, 0.0] + }, + { + "children": [ + 6 + ], + "extensions": { + "OMI_physics_body": { + "type": "rigid" + } + }, + "name": "BodyB", + "translation": [0.0, 0.6, 0.0] + }, + { + "children": [ + 7 + ], + "extensions": { + "OMI_collider": { + "collider": 0 + } + }, + "name": "ColliderB", + "rotation": [0.0, 0.0, 0.70710676908493, 0.70710676908493] + }, + { + "extensions": {}, + "mesh": 1, + "name": "MeshB" + }, + { + "children": [ + 9 + ], + "extensions": { + "OMI_physics_body": { + "type": "static" + } + }, + "name": "FloorBody", + "translation": [0.1, 0.0, 0.0] + }, + { + "children": [10], + "extensions": { + "OMI_collider": { + "collider": 1 + } + }, + "name": "FloorShape" + }, + { + "extensions": {}, + "mesh": 2, + "name": "FloorMesh" + }, + { + "camera": 0, + "extensions": {}, + "name": "Camera", + "translation": [0.0, 0.5, 1.5] + } + ], + "scene": 0, + "scenes": [ + { + "nodes": [0] + } + ] +} diff --git a/examples/omi_physics_joint/gltf/weld_joint.gltf.import b/examples/omi_physics_joint/gltf/weld_joint.gltf.import new file mode 100644 index 0000000..95f4ddd --- /dev/null +++ b/examples/omi_physics_joint/gltf/weld_joint.gltf.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://s8axa6fdgkc1" +path="res://.godot/imported/weld_joint.gltf-80ce40f4b1090d0d56bdbe65bd5cbcf2.scn" + +[deps] + +source_file="res://examples/omi_physics_joint/gltf/weld_joint.gltf" +dest_files=["res://.godot/imported/weld_joint.gltf-80ce40f4b1090d0d56bdbe65bd5cbcf2.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/examples/omi_physics_joint/gltf/weld_joint0.bin b/examples/omi_physics_joint/gltf/weld_joint0.bin new file mode 100644 index 0000000..e55afe0 Binary files /dev/null and b/examples/omi_physics_joint/gltf/weld_joint0.bin differ diff --git a/examples/omi_physics_joint/source/hanging_rope.tscn b/examples/omi_physics_joint/source/hanging_rope.tscn new file mode 100644 index 0000000..aa2ef6b --- /dev/null +++ b/examples/omi_physics_joint/source/hanging_rope.tscn @@ -0,0 +1,75 @@ +[gd_scene load_steps=5 format=3 uid="uid://c0xjnnw3nn2bj"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_5bdxa"] +size = Vector3(0.5, 0.5, 0.5) + +[sub_resource type="BoxMesh" id="BoxMesh_l2buq"] +size = Vector3(0.5, 0.5, 0.5) + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_8yjlq"] +radius = 0.05 +height = 0.5 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_eehis"] +radius = 0.05 +height = 0.5 + +[node name="HangingRope" type="Node3D"] + +[node name="Ceiling" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 1.5, 2.08165e-12) + +[node name="CeilingCollider" type="CollisionShape3D" parent="Ceiling"] +shape = SubResource("BoxShape3D_5bdxa") + +[node name="CeilingMesh" type="MeshInstance3D" parent="Ceiling/CeilingCollider"] +mesh = SubResource("BoxMesh_l2buq") +skeleton = NodePath("../..") + +[node name="PinJoint1" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.79397e-08, 1.25, 2.08165e-12) +node_a = NodePath("../RopeSegmentTop") +node_b = NodePath("../Ceiling") + +[node name="RopeSegmentTop" type="RigidBody3D" parent="."] +transform = Transform3D(0.866025, -0.5, 3.48787e-16, 0.5, 0.866025, -3.48787e-16, -1.27665e-16, 4.76452e-16, 1, -0.17, 1.15, 2.08165e-12) + +[node name="RopeColliderTop" type="CollisionShape3D" parent="RopeSegmentTop"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="RopeMeshTop" type="MeshInstance3D" parent="RopeSegmentTop/RopeColliderTop"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="PinJoint2" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.37, 1.03, 2.08165e-12) +node_a = NodePath("../RopeSegmentMiddle") +node_b = NodePath("../RopeSegmentTop") + +[node name="RopeSegmentMiddle" type="RigidBody3D" parent="."] +transform = Transform3D(0.939693, -0.34202, 3.48787e-16, 0.34202, 0.939693, -3.48787e-16, -2.0846e-16, 4.47045e-16, 1, -0.58, 0.95, 2.08165e-12) + +[node name="RopeColliderMiddle" type="CollisionShape3D" parent="RopeSegmentMiddle"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="RopeMeshMiddle" type="MeshInstance3D" parent="RopeSegmentMiddle/RopeColliderMiddle"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="PinJoint3" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.8, 0.87, 2.08165e-12) +node_a = NodePath("../RopeSegmentBottom") +node_b = NodePath("../RopeSegmentMiddle") + +[node name="RopeSegmentBottom" type="RigidBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.03, 0.87, 2.08165e-12) + +[node name="RopeColliderBottom" type="CollisionShape3D" parent="RopeSegmentBottom"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="RopeMeshBottom" type="MeshInstance3D" parent="RopeSegmentBottom/RopeColliderBottom"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.6, 1.5) diff --git a/examples/omi_physics_joint/source/pendulum_balls.tscn b/examples/omi_physics_joint/source/pendulum_balls.tscn new file mode 100644 index 0000000..9b963ac --- /dev/null +++ b/examples/omi_physics_joint/source/pendulum_balls.tscn @@ -0,0 +1,86 @@ +[gd_scene load_steps=6 format=3 uid="uid://qb7twdaj8cwf"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_wt0kw"] +size = Vector3(2, 0.2, 0.2) + +[sub_resource type="BoxMesh" id="BoxMesh_qqqod"] +size = Vector3(2, 0.2, 0.2) + +[sub_resource type="SphereShape3D" id="SphereShape3D_2n7rj"] +radius = 0.25 + +[sub_resource type="SphereMesh" id="SphereMesh_kjwoo"] +radius = 0.25 +height = 0.5 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_5jnur"] +radius = 0.05 +height = 1.0 + +[node name="PendulumBalls" type="Node3D"] + +[node name="TopBody" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 1, 2.08165e-12) + +[node name="TopBodyShape" type="CollisionShape3D" parent="TopBody"] +shape = SubResource("BoxShape3D_wt0kw") + +[node name="TopBodyMesh" type="MeshInstance3D" parent="TopBody/TopBodyShape"] +mesh = SubResource("BoxMesh_qqqod") + +[node name="HingeJoint1" type="HingeJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.9, 2.08165e-12) +node_a = NodePath("../TopBody") +node_b = NodePath("../Ball1") + +[node name="Ball1" type="RigidBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, -0.25, 2.08165e-12) + +[node name="BallShape1" type="CollisionShape3D" parent="Ball1"] +shape = SubResource("SphereShape3D_2n7rj") + +[node name="BallMesh1" type="MeshInstance3D" parent="Ball1/BallShape1"] +mesh = SubResource("SphereMesh_kjwoo") + +[node name="BallStringMesh1" type="MeshInstance3D" parent="Ball1"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.7, 2.08165e-12) +mesh = SubResource("CapsuleMesh_5jnur") + +[node name="HingeJoint2" type="HingeJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.45, 0.9, 2.08165e-12) +node_a = NodePath("../TopBody") +node_b = NodePath("../Ball2") + +[node name="Ball2" type="RigidBody3D" parent="."] +transform = Transform3D(0.707107, 0.707107, 3.48787e-16, -0.707107, 0.707107, -3.48787e-16, -4.93259e-16, 1.60554e-24, 1, -1.26317, 0.0868272, 2.08165e-12) + +[node name="BallShape2" type="CollisionShape3D" parent="Ball2"] +shape = SubResource("SphereShape3D_2n7rj") + +[node name="BallMesh2" type="MeshInstance3D" parent="Ball2/BallShape2"] +mesh = SubResource("SphereMesh_kjwoo") + +[node name="BallStringMesh2" type="MeshInstance3D" parent="Ball2"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.7, 2.08165e-12) +mesh = SubResource("CapsuleMesh_5jnur") + +[node name="HingeJoint3" type="HingeJoint3D" parent="."] +transform = Transform3D(0.866025, -0.5, 3.48787e-16, 0.5, 0.866025, -3.48787e-16, -1.27665e-16, 4.76452e-16, 1, 0.45, 0.9, 2.08165e-12) +node_a = NodePath("../TopBody") +node_b = NodePath("../Ball3") + +[node name="Ball3" type="RigidBody3D" parent="."] +transform = Transform3D(-0.965926, -0.258819, 8.25239e-16, 0.258819, -0.965926, -4.76452e-16, 9.20434e-16, -2.46629e-16, 1, 0.747642, 2.01081, 2.08193e-12) + +[node name="BallShape2" type="CollisionShape3D" parent="Ball3"] +shape = SubResource("SphereShape3D_2n7rj") + +[node name="BallMesh2" type="MeshInstance3D" parent="Ball3/BallShape2"] +mesh = SubResource("SphereMesh_kjwoo") + +[node name="BallStringMesh2" type="MeshInstance3D" parent="Ball3"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.7, 2.08165e-12) +mesh = SubResource("CapsuleMesh_5jnur") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 2.08165e-12, 1.5) diff --git a/examples/omi_physics_joint/source/rope_railing.tscn b/examples/omi_physics_joint/source/rope_railing.tscn new file mode 100644 index 0000000..47d1b0c --- /dev/null +++ b/examples/omi_physics_joint/source/rope_railing.tscn @@ -0,0 +1,120 @@ +[gd_scene load_steps=5 format=3 uid="uid://ctnut5kgrymkh"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_5bdxa"] +size = Vector3(0.15, 1.1, 0.15) + +[sub_resource type="BoxMesh" id="BoxMesh_l2buq"] +size = Vector3(0.15, 1.1, 0.15) + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_8yjlq"] +radius = 0.05 +height = 0.5 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_eehis"] +radius = 0.05 +height = 0.5 + +[node name="RopeRailing" type="Node3D"] + +[node name="PoleLeft" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.1, 0.55, 2.08165e-12) + +[node name="PoleColliderLeft" type="CollisionShape3D" parent="PoleLeft"] +shape = SubResource("BoxShape3D_5bdxa") + +[node name="PoleMeshLeft" type="MeshInstance3D" parent="PoleLeft/PoleColliderLeft"] +mesh = SubResource("BoxMesh_l2buq") +skeleton = NodePath("../..") + +[node name="PinJoint1" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.03, 0.98, 2.08165e-12) +node_a = NodePath("../PoleLeft") +node_b = NodePath("../RopeSegmentLeft") + +[node name="RopeSegmentLeft" type="RigidBody3D" parent="."] +transform = Transform3D(0.866025, 0.5, 3.48787e-16, -0.5, 0.866025, -3.48787e-16, -4.76452e-16, 1.27665e-16, 1, -0.86, 0.88, 2.08165e-12) + +[node name="RopeColliderLeft" type="CollisionShape3D" parent="RopeSegmentLeft"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="RopeMeshLeft" type="MeshInstance3D" parent="RopeSegmentLeft/RopeColliderLeft"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="PinJoint2" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.66, 0.76, 2.08165e-12) +node_a = NodePath("../RopeSegmentLeft") +node_b = NodePath("../RopeSegmentLeftMiddle") + +[node name="RopeSegmentLeftMiddle" type="RigidBody3D" parent="."] +transform = Transform3D(0.939693, 0.34202, 3.48787e-16, -0.34202, 0.939693, -3.48787e-16, -4.47045e-16, 2.0846e-16, 1, -0.45, 0.68, 2.08165e-12) + +[node name="RopeColliderLeftMiddle" type="CollisionShape3D" parent="RopeSegmentLeftMiddle"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="RopeMeshLeftMiddle" type="MeshInstance3D" parent="RopeSegmentLeftMiddle/RopeColliderLeftMiddle"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="PinJoint3" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.23, 0.6, 2.08165e-12) +node_a = NodePath("../RopeSegmentLeftMiddle") +node_b = NodePath("../RopeSegmentMiddle") + +[node name="RopeSegmentMiddle" type="RigidBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.6, 2.08165e-12) + +[node name="RopeColliderMiddle" type="CollisionShape3D" parent="RopeSegmentMiddle"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="RopeMeshMiddle" type="MeshInstance3D" parent="RopeSegmentMiddle/RopeColliderMiddle"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="PinJoint4" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.23, 0.6, 2.08165e-12) +node_a = NodePath("../RopeSegmentMiddle") +node_b = NodePath("../RopeSegmentRightMiddle") + +[node name="RopeSegmentRightMiddle" type="RigidBody3D" parent="."] +transform = Transform3D(0.939693, -0.34202, 3.48787e-16, 0.34202, 0.939693, -3.48787e-16, -2.0846e-16, 4.47045e-16, 1, 0.45, 0.68, 2.08165e-12) + +[node name="RopeColliderRightMiddle" type="CollisionShape3D" parent="RopeSegmentRightMiddle"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="RopeMeshRightMiddle" type="MeshInstance3D" parent="RopeSegmentRightMiddle/RopeColliderRightMiddle"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="PinJoint5" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.66, 0.76, 2.08165e-12) +node_a = NodePath("../RopeSegmentRightMiddle") +node_b = NodePath("../RopeSegmentRight") + +[node name="RopeSegmentRight" type="RigidBody3D" parent="."] +transform = Transform3D(0.866025, -0.5, 3.48787e-16, 0.5, 0.866025, -3.48787e-16, -1.27665e-16, 4.76452e-16, 1, 0.86, 0.88, 2.08165e-12) + +[node name="RopeColliderRight" type="CollisionShape3D" parent="RopeSegmentRight"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="RopeMeshRight" type="MeshInstance3D" parent="RopeSegmentRight/RopeColliderRight"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="PinJoint6" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.03, 0.98, 2.08165e-12) +node_a = NodePath("../RopeSegmentRight") +node_b = NodePath("../PoleRight") + +[node name="PoleRight" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.1, 0.55, 2.08165e-12) + +[node name="PoleColliderRight" type="CollisionShape3D" parent="PoleRight"] +shape = SubResource("BoxShape3D_5bdxa") + +[node name="PoleMeshRight" type="MeshInstance3D" parent="PoleRight/PoleColliderRight"] +mesh = SubResource("BoxMesh_l2buq") +skeleton = NodePath("../..") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.6, 1.5) diff --git a/examples/omi_physics_joint/source/simple_joint.tscn b/examples/omi_physics_joint/source/simple_joint.tscn new file mode 100644 index 0000000..c3fc112 --- /dev/null +++ b/examples/omi_physics_joint/source/simple_joint.tscn @@ -0,0 +1,55 @@ +[gd_scene load_steps=5 format=3 uid="uid://c4bn66lgb3dli"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_8yjlq"] +radius = 0.05 +height = 0.5 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_eehis"] +radius = 0.05 +height = 0.5 + +[sub_resource type="BoxShape3D" id="BoxShape3D_qw6jg"] +size = Vector3(1, 0.25, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_q2ukb"] +size = Vector3(1, 0.25, 1) + +[node name="SimpleJoint" type="Node3D"] + +[node name="BodyA" type="RigidBody3D" parent="."] +transform = Transform3D(0.939693, 0.34202, 3.48787e-16, -0.34202, 0.939693, -3.48787e-16, -4.47045e-16, 2.0846e-16, 1, -0.45, 0.68, 2.08165e-12) + +[node name="ColliderA" type="CollisionShape3D" parent="BodyA"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="MeshA" type="MeshInstance3D" parent="BodyA/ColliderA"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="PinJoint" type="PinJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.23, 0.6, 2.08165e-12) +node_a = NodePath("../BodyA") +node_b = NodePath("../BodyB") + +[node name="BodyB" type="RigidBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.6, 2.08165e-12) + +[node name="ColliderB" type="CollisionShape3D" parent="BodyB"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="MeshB" type="MeshInstance3D" parent="BodyB/ColliderB"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="FloorBody" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.1, 2.08165e-12, 2.08165e-12) + +[node name="FloorShape" type="CollisionShape3D" parent="FloorBody"] +shape = SubResource("BoxShape3D_qw6jg") + +[node name="FloorMesh" type="MeshInstance3D" parent="FloorBody/FloorShape"] +mesh = SubResource("BoxMesh_q2ukb") +skeleton = NodePath("../..") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.5, 1.5) diff --git a/examples/omi_physics_joint/source/slider_ball.tscn b/examples/omi_physics_joint/source/slider_ball.tscn new file mode 100644 index 0000000..4a23b7d --- /dev/null +++ b/examples/omi_physics_joint/source/slider_ball.tscn @@ -0,0 +1,46 @@ +[gd_scene load_steps=5 format=3 uid="uid://djjat4lcyycv"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_wt0kw"] +size = Vector3(2, 0.1, 0.1) + +[sub_resource type="BoxMesh" id="BoxMesh_qqqod"] +size = Vector3(2, 0.1, 0.1) + +[sub_resource type="SphereShape3D" id="SphereShape3D_2n7rj"] +radius = 0.25 + +[sub_resource type="SphereMesh" id="SphereMesh_kjwoo"] +radius = 0.25 +height = 0.5 + +[node name="PendulumBalls" type="Node3D"] + +[node name="SliderLine" type="StaticBody3D" parent="."] + +[node name="SliderLineShape" type="CollisionShape3D" parent="SliderLine"] +shape = SubResource("BoxShape3D_wt0kw") + +[node name="SliderLineMesh" type="MeshInstance3D" parent="SliderLine/SliderLineShape"] +mesh = SubResource("BoxMesh_qqqod") + +[node name="SliderJoint" type="SliderJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.75, 2.08165e-12, 2.08165e-12) +node_a = NodePath("../Ball") +node_b = NodePath("../SliderLine") +linear_limit/upper_distance = 0.25 +linear_limit/lower_distance = -1.75 +linear_limit/damping = 0.5 + +[node name="Ball" type="RigidBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.75, 2.08165e-12, 2.08165e-12) +linear_velocity = Vector3(1, 2.08165e-12, 2.08165e-12) +angular_velocity = Vector3(0.0174533, 0.0174533, 0.0174533) + +[node name="BallShape" type="CollisionShape3D" parent="Ball"] +shape = SubResource("SphereShape3D_2n7rj") + +[node name="BallMesh" type="MeshInstance3D" parent="Ball/BallShape"] +mesh = SubResource("SphereMesh_kjwoo") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 2.08165e-12, 1.5) diff --git a/examples/omi_physics_joint/source/swing_and_slide.tscn b/examples/omi_physics_joint/source/swing_and_slide.tscn new file mode 100644 index 0000000..23b0e06 --- /dev/null +++ b/examples/omi_physics_joint/source/swing_and_slide.tscn @@ -0,0 +1,53 @@ +[gd_scene load_steps=6 format=3 uid="uid://dbc53talxhou"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_wt0kw"] +size = Vector3(2, 0.1, 0.1) + +[sub_resource type="BoxMesh" id="BoxMesh_qqqod"] +size = Vector3(2, 0.1, 0.1) + +[sub_resource type="SphereShape3D" id="SphereShape3D_2n7rj"] +radius = 0.25 + +[sub_resource type="SphereMesh" id="SphereMesh_kjwoo"] +radius = 0.25 +height = 0.5 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_5jnur"] +radius = 0.05 +height = 1.0 + +[node name="SwingAndSlide" type="Node3D"] + +[node name="TopBody" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 1, 2.08165e-12) + +[node name="TopBodyShape" type="CollisionShape3D" parent="TopBody"] +shape = SubResource("BoxShape3D_wt0kw") + +[node name="TopBodyMesh" type="MeshInstance3D" parent="TopBody/TopBodyShape"] +mesh = SubResource("BoxMesh_qqqod") + +[node name="CustomJoint" type="Generic6DOFJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.75, 1, 2.08165e-12) +node_a = NodePath("../TopBody") +node_b = NodePath("../Ball") +linear_limit_x/upper_distance = 1.75 +linear_limit_x/lower_distance = -0.25 +angular_limit_z/enabled = false + +[node name="Ball" type="RigidBody3D" parent="."] +transform = Transform3D(0.707107, 0.707107, 3.48787e-16, -0.707107, 0.707107, -3.48787e-16, -4.93259e-16, 1.60554e-24, 1, -1.6, 0.15, 2.08165e-12) + +[node name="BallShape" type="CollisionShape3D" parent="Ball"] +shape = SubResource("SphereShape3D_2n7rj") + +[node name="BallMesh" type="MeshInstance3D" parent="Ball/BallShape"] +mesh = SubResource("SphereMesh_kjwoo") + +[node name="BallStringMesh" type="MeshInstance3D" parent="Ball"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.7, 2.08165e-12) +mesh = SubResource("CapsuleMesh_5jnur") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 2.08165e-12, 1.5) diff --git a/examples/omi_physics_joint/source/weld_joint.tscn b/examples/omi_physics_joint/source/weld_joint.tscn new file mode 100644 index 0000000..6d68ee9 --- /dev/null +++ b/examples/omi_physics_joint/source/weld_joint.tscn @@ -0,0 +1,55 @@ +[gd_scene load_steps=5 format=3 uid="uid://bqmw6nvxkn6tw"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_8yjlq"] +radius = 0.05 +height = 0.5 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_eehis"] +radius = 0.05 +height = 0.5 + +[sub_resource type="BoxShape3D" id="BoxShape3D_qw6jg"] +size = Vector3(1, 0.25, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_q2ukb"] +size = Vector3(1, 0.25, 1) + +[node name="SimpleJoint" type="Node3D"] + +[node name="BodyA" type="RigidBody3D" parent="."] +transform = Transform3D(0.939693, 0.34202, 3.48786e-16, -0.34202, 0.939691, -0.00174533, -0.000596938, 0.00164007, 0.999998, -0.45, 0.68, 2.08165e-12) + +[node name="ColliderA" type="CollisionShape3D" parent="BodyA"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="MeshA" type="MeshInstance3D" parent="BodyA/ColliderA"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="WeldJoint" type="Generic6DOFJoint3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.23, 0.6, 2.08165e-12) +node_a = NodePath("../BodyA") +node_b = NodePath("../BodyB") + +[node name="BodyB" type="RigidBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.6, 2.08165e-12) + +[node name="ColliderB" type="CollisionShape3D" parent="BodyB"] +transform = Transform3D(-4.37114e-08, -1, 3.48787e-16, 1, -4.37114e-08, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_8yjlq") + +[node name="MeshB" type="MeshInstance3D" parent="BodyB/ColliderB"] +mesh = SubResource("CapsuleMesh_eehis") + +[node name="FloorBody" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.1, 2.08165e-12, 2.08165e-12) + +[node name="FloorShape" type="CollisionShape3D" parent="FloorBody"] +shape = SubResource("BoxShape3D_qw6jg") + +[node name="FloorMesh" type="MeshInstance3D" parent="FloorBody/FloorShape"] +mesh = SubResource("BoxMesh_q2ukb") +skeleton = NodePath("../..") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 0.5, 1.5) diff --git a/examples/omi_physics_joint/test/hanging_rope_test.tscn b/examples/omi_physics_joint/test/hanging_rope_test.tscn new file mode 100644 index 0000000..207825d --- /dev/null +++ b/examples/omi_physics_joint/test/hanging_rope_test.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://523r5p5ifi78"] + +[ext_resource type="PackedScene" uid="uid://jtuy1pve36dv" path="res://examples/test_environment.tscn" id="1_actd1"] +[ext_resource type="PackedScene" uid="uid://ci6itm2taodm3" path="res://examples/omi_physics_joint/gltf/hanging_rope.gltf" id="2_leltm"] + +[node name="HangingRopeTest" type="Node3D"] + +[node name="TestEnvironment" parent="." instance=ExtResource("1_actd1")] + +[node name="hanging_rope" parent="." instance=ExtResource("2_leltm")] diff --git a/examples/omi_physics_joint/test/pendulum_balls_test.tscn b/examples/omi_physics_joint/test/pendulum_balls_test.tscn new file mode 100644 index 0000000..7856345 --- /dev/null +++ b/examples/omi_physics_joint/test/pendulum_balls_test.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://b04aep2udu4kk"] + +[ext_resource type="PackedScene" uid="uid://jtuy1pve36dv" path="res://examples/test_environment.tscn" id="1_bqy0h"] +[ext_resource type="PackedScene" uid="uid://bfxsfq0gxuqqd" path="res://examples/omi_physics_joint/gltf/pendulum_balls.gltf" id="1_pqjs7"] + +[node name="PendulumBallsTest" type="Node3D"] + +[node name="TestEnvironment" parent="." instance=ExtResource("1_bqy0h")] + +[node name="pendulum_balls" parent="." instance=ExtResource("1_pqjs7")] diff --git a/examples/omi_physics_joint/test/rope_railing_test.tscn b/examples/omi_physics_joint/test/rope_railing_test.tscn new file mode 100644 index 0000000..ac548af --- /dev/null +++ b/examples/omi_physics_joint/test/rope_railing_test.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://dmr8dv5lv6jox"] + +[ext_resource type="PackedScene" uid="uid://jtuy1pve36dv" path="res://examples/test_environment.tscn" id="1_0dddo"] +[ext_resource type="PackedScene" uid="uid://b510bj645xkt3" path="res://examples/omi_physics_joint/gltf/rope_railing.gltf" id="1_gib38"] + +[node name="RopeRailingTest" type="Node3D"] + +[node name="TestEnvironment" parent="." instance=ExtResource("1_0dddo")] + +[node name="rope_railing" parent="." instance=ExtResource("1_gib38")] diff --git a/examples/omi_physics_joint/test/simple_joint_test.tscn b/examples/omi_physics_joint/test/simple_joint_test.tscn new file mode 100644 index 0000000..e02a8af --- /dev/null +++ b/examples/omi_physics_joint/test/simple_joint_test.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://cipctumec3e7h"] + +[ext_resource type="PackedScene" uid="uid://cbcl76ieoawm0" path="res://examples/omi_physics_joint/gltf/simple_joint.gltf" id="1_efl7c"] +[ext_resource type="PackedScene" uid="uid://jtuy1pve36dv" path="res://examples/test_environment.tscn" id="1_kughc"] + +[node name="SimpleJointTest" type="Node3D"] + +[node name="TestEnvironment" parent="." instance=ExtResource("1_kughc")] + +[node name="simple_joint" parent="." instance=ExtResource("1_efl7c")] diff --git a/examples/omi_physics_joint/test/slider_ball_test.tscn b/examples/omi_physics_joint/test/slider_ball_test.tscn new file mode 100644 index 0000000..2b73c15 --- /dev/null +++ b/examples/omi_physics_joint/test/slider_ball_test.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://llt5ltyaojn8"] + +[ext_resource type="PackedScene" uid="uid://jtuy1pve36dv" path="res://examples/test_environment.tscn" id="1_4lldl"] +[ext_resource type="PackedScene" uid="uid://bsru8jcku4pbm" path="res://examples/omi_physics_joint/gltf/slider_ball.gltf" id="1_vbss6"] + +[node name="SliderBallTest" type="Node3D"] + +[node name="TestEnvironment" parent="." instance=ExtResource("1_4lldl")] + +[node name="slider_ball" parent="." instance=ExtResource("1_vbss6")] diff --git a/examples/omi_physics_joint/test/swing_and_slide_test.tscn b/examples/omi_physics_joint/test/swing_and_slide_test.tscn new file mode 100644 index 0000000..762d027 --- /dev/null +++ b/examples/omi_physics_joint/test/swing_and_slide_test.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://du2qdjcrr05v2"] + +[ext_resource type="PackedScene" uid="uid://jtuy1pve36dv" path="res://examples/test_environment.tscn" id="1_esshi"] +[ext_resource type="PackedScene" uid="uid://bw0c7334lfcil" path="res://examples/omi_physics_joint/gltf/swing_and_slide.gltf" id="1_hrmgk"] + +[node name="SwingAndSlideTest" type="Node3D"] + +[node name="TestEnvironment" parent="." instance=ExtResource("1_esshi")] + +[node name="swing_and_slide" parent="." instance=ExtResource("1_hrmgk")] diff --git a/examples/omi_physics_joint/test/weld_joint_test.tscn b/examples/omi_physics_joint/test/weld_joint_test.tscn new file mode 100644 index 0000000..803e8c3 --- /dev/null +++ b/examples/omi_physics_joint/test/weld_joint_test.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://bh87lj6jt4pup"] + +[ext_resource type="PackedScene" uid="uid://s8axa6fdgkc1" path="res://examples/omi_physics_joint/gltf/weld_joint.gltf" id="1_317my"] +[ext_resource type="PackedScene" uid="uid://jtuy1pve36dv" path="res://examples/test_environment.tscn" id="1_i3mh0"] + +[node name="WeldJointTest" type="Node3D"] + +[node name="TestEnvironment" parent="." instance=ExtResource("1_i3mh0")] + +[node name="weld_joint" parent="." instance=ExtResource("1_317my")] diff --git a/examples/test_environment.tscn b/examples/test_environment.tscn new file mode 100644 index 0000000..5eee343 --- /dev/null +++ b/examples/test_environment.tscn @@ -0,0 +1,19 @@ +[gd_scene load_steps=4 format=3 uid="uid://jtuy1pve36dv"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_yw5s5"] +sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) +ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) + +[sub_resource type="Sky" id="Sky_2voxo"] +sky_material = SubResource("ProceduralSkyMaterial_yw5s5") + +[sub_resource type="Environment" id="Environment_2xbq6"] +background_mode = 2 +sky = SubResource("Sky_2voxo") +tonemap_mode = 2 + +[node name="TestEnvironment" type="WorldEnvironment"] +environment = SubResource("Environment_2xbq6") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.866024, -0.433016, 0.250001, 0, 0.499998, 0.866026, -0.500003, 0.749999, -0.43301, 0, 0, 0)