Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 65 additions & 25 deletions addons/omi_extensions/vehicle/gltf_vehicle_hover_thruster.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,97 @@ class_name GLTFVehicleHoverThruster
extends Resource


## The ratio of the maximum hover energy the hover thruster is currently using for propulsion.
# Gimbal
## The maximum angle the hover thruster can gimbal or rotate in radians.
@export_custom(PROPERTY_HINT_NONE, "suffix:rad")
var max_gimbal_radians: float = 0.0
## Optionally, you may also want to allow the gimbal to be adjusted based on linear input.
## For example, if the user wants to go forward, and the thruster points downward,
## we can gimbal the thruster slightly backward to help thrust forward.
@export_range(0.0, 1.0, 0.01)
var current_hover_ratio: float = 0.0
## The ratio of the maximum gimbal angles the hover thruster is rotated to. The vector length may not be longer than 1.0.
@export var current_gimbal_ratio := Vector2(0.0, 0.0)
var linear_gimbal_adjust_ratio: float = 0.5
## The speed at which the gimbal angle changes, in radians per second. If negative, the angle changes instantly.
@export_custom(PROPERTY_HINT_NONE, "suffix:rad/s")
var gimbal_radians_per_second: float = 1.0
## The ratio of the maximum gimbal angles the hover thruster is targeting to be rotated to. The vector length may not be longer than 1.0.
@export var target_gimbal_ratio := Vector2(0.0, 0.0)

# Hover Thrust
## The maximum hover energy in Newton-meters (N⋅m or kg⋅m²/s²) that the hover thruster can provide.
@export_custom(PROPERTY_HINT_NONE, "suffix:kg\u22C5m\u00B2/s\u00B2 (N\u22C5m)")
var max_hover_energy: float = 0.0
## The maximum angle the hover thruster can gimbal or rotate in radians.
@export_custom(PROPERTY_HINT_NONE, "suffix:rad")
var max_gimbal: float = 0.0
## The speed at which the hover energy changes, in Newtons-meters per second. If negative, the force changes instantly.
@export_custom(PROPERTY_HINT_NONE, "suffix:N\u22C5m/s (kg\u22C5m\u00B2/s\u00B3)")
var hover_energy_change_per_second: float = -1.0
## The ratio of the maximum hover energy the hover thruster is targeting for propulsion.
@export_range(0.0, 1.0, 0.01)
var target_hover_ratio: float = 0.0


static func from_node(thruster_node: VehicleHoverThruster3D) -> GLTFVehicleHoverThruster:
var ret := GLTFVehicleHoverThruster.new()
ret.current_hover_ratio = thruster_node.current_hover_ratio
ret.current_gimbal_ratio = thruster_node.current_gimbal_ratio
# Gimbal
ret.max_gimbal_radians = thruster_node.max_gimbal_radians
ret.linear_gimbal_adjust_ratio = thruster_node.linear_gimbal_adjust_ratio
ret.gimbal_radians_per_second = thruster_node.gimbal_radians_per_second
ret.target_gimbal_ratio = thruster_node.target_gimbal_ratio
# Hover Thrust
ret.max_hover_energy = thruster_node.max_hover_energy
ret.max_gimbal = thruster_node.max_gimbal
ret.hover_energy_change_per_second = thruster_node.hover_energy_change_per_second
ret.target_hover_ratio = thruster_node.target_hover_ratio
return ret


func to_node() -> VehicleHoverThruster3D:
var thruster_node := VehicleHoverThruster3D.new()
thruster_node.current_hover_ratio = current_hover_ratio
thruster_node.current_gimbal_ratio = current_gimbal_ratio
# Gimbal
thruster_node.max_gimbal_radians = max_gimbal_radians
thruster_node.linear_gimbal_adjust_ratio = linear_gimbal_adjust_ratio
thruster_node.gimbal_radians_per_second = gimbal_radians_per_second
thruster_node.target_gimbal_ratio = target_gimbal_ratio
# Hover Thrust
thruster_node.max_hover_energy = max_hover_energy
thruster_node.max_gimbal = max_gimbal
thruster_node.hover_energy_change_per_second = hover_energy_change_per_second
thruster_node.target_hover_ratio = target_hover_ratio
return thruster_node


static func from_dictionary(dict: Dictionary) -> GLTFVehicleHoverThruster:
var ret := GLTFVehicleHoverThruster.new()
if dict.has("currentHoverRatio"):
ret.current_force_ratio = dict["currentHoverRatio"]
if dict.has("currentGimbalRatio"):
ret.current_gimbal_ratio = dict["currentGimbalRatio"]
# Gimbal
if dict.has("maxGimbal"):
ret.max_gimbal_radians = dict["maxGimbal"]
if dict.has("linearGimbalAdjustRatio"):
ret.linear_gimbal_adjust_ratio = dict["linearGimbalAdjustRatio"]
if dict.has("gimbalChangeRate"):
ret.gimbal_radians_per_second = dict["gimbalChangeRate"]
if dict.has("targetGimbalRatio"):
ret.target_gimbal_ratio = dict["targetGimbalRatio"]
# Hover Thrust
if dict.has("maxHoverEnergy"):
ret.max_hover_energy = dict["maxHoverEnergy"]
if dict.has("maxGimbal"):
ret.max_gimbal = dict["maxGimbal"]
if dict.has("hoverEnergyChangeRate"):
ret.hover_energy_change_per_second = dict["hoverEnergyChangeRate"]
if dict.has("targetHoverRatio"):
ret.target_hover_ratio = dict["targetHoverRatio"]
return ret


func to_dictionary() -> Dictionary:
var ret: Dictionary = {}
# Alphabetical order when converting to Dictionary.
if gimbal_radians_per_second != 1.0:
ret["gimbalChangeRate"] = gimbal_radians_per_second
if hover_energy_change_per_second != -1.0:
ret["hoverEnergyChangeRate"] = hover_energy_change_per_second
if linear_gimbal_adjust_ratio != 0.5:
ret["linearGimbalAdjustRatio"] = linear_gimbal_adjust_ratio
if max_gimbal_radians != 0.0:
ret["maxGimbal"] = max_gimbal_radians
# Always include maxHoverEnergy since it is a required property for hover thrusters.
ret["maxHoverEnergy"] = max_hover_energy
if current_hover_ratio != 0.0:
ret["currentHoverRatio"] = current_hover_ratio
if current_gimbal_ratio != Vector2.ZERO:
ret["currentGimbalRatio"] = current_gimbal_ratio
if max_gimbal != 0.0:
ret["maxGimbal"] = max_gimbal
if target_gimbal_ratio != Vector2.ZERO:
ret["targetGimbalRatio"] = target_gimbal_ratio
if target_hover_ratio != 0.0:
ret["targetHoverRatio"] = target_hover_ratio
return ret
90 changes: 65 additions & 25 deletions addons/omi_extensions/vehicle/gltf_vehicle_thruster.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,97 @@ class_name GLTFVehicleThruster
extends Resource


## The ratio of the maximum thrust force the thruster is currently using for propulsion.
# Gimbal
## The maximum angle the thruster can gimbal or rotate in radians.
@export_custom(PROPERTY_HINT_NONE, "suffix:rad")
var max_gimbal_radians: float = 0.0
## Optionally, you may also want to allow the gimbal to be adjusted based on linear input.
## For example, if the user wants to go forward, and the thruster points downward,
## we can gimbal the thruster slightly backward to help thrust forward.
@export_range(0.0, 1.0, 0.01)
var current_force_ratio: float = 0.0
## The ratio of the maximum gimbal angles the thruster is rotated to. The vector length may not be longer than 1.0.
@export var current_gimbal_ratio := Vector2(0.0, 0.0)
var linear_gimbal_adjust_ratio: float = 0.0
## The speed at which the gimbal angle changes, in radians per second. If negative, the angle changes instantly.
@export_custom(PROPERTY_HINT_NONE, "suffix:rad/s")
var gimbal_radians_per_second: float = 1.0
## The ratio of the maximum gimbal angles the thruster is targeting to be rotated to. The vector length may not be longer than 1.0.
@export var target_gimbal_ratio := Vector2(0.0, 0.0)

# Thrust Force
## The maximum thrust force in Newtons (kg⋅m/s²) that the thruster can provide.
@export_custom(PROPERTY_HINT_NONE, "suffix:kg\u22C5m/s\u00B2 (N)")
var max_force: float = 0.0
## The maximum angle the thruster can gimbal or rotate in radians.
@export_custom(PROPERTY_HINT_NONE, "suffix:rad")
var max_gimbal: float = 0.0
## The speed at which the thruster force changes, in Newtons per second. If negative, the force changes instantly.
@export_custom(PROPERTY_HINT_NONE, "suffix:N/s (kg\u22C5m/s\u00B3)")
var force_change_per_second: float = -1.0
## The ratio of the maximum thrust force the thruster is targeting for propulsion.
@export_range(0.0, 1.0, 0.01)
var target_force_ratio: float = 0.0


static func from_node(thruster_node: VehicleThruster3D) -> GLTFVehicleThruster:
var ret := GLTFVehicleThruster.new()
ret.current_force_ratio = thruster_node.current_force_ratio
ret.current_gimbal_ratio = thruster_node.current_gimbal_ratio
# Gimbal
ret.max_gimbal_radians = thruster_node.max_gimbal_radians
ret.linear_gimbal_adjust_ratio = thruster_node.linear_gimbal_adjust_ratio
ret.gimbal_radians_per_second = thruster_node.gimbal_radians_per_second
ret.target_gimbal_ratio = thruster_node.target_gimbal_ratio
# Thrust Force
ret.max_force = thruster_node.max_force
ret.max_gimbal = thruster_node.max_gimbal
ret.force_change_per_second = thruster_node.force_change_per_second
ret.target_force_ratio = thruster_node.target_force_ratio
return ret


func to_node() -> VehicleThruster3D:
var thruster_node := VehicleThruster3D.new()
thruster_node.current_force_ratio = current_force_ratio
thruster_node.current_gimbal_ratio = current_gimbal_ratio
# Gimbal
thruster_node.max_gimbal_radians = max_gimbal_radians
thruster_node.linear_gimbal_adjust_ratio = linear_gimbal_adjust_ratio
thruster_node.gimbal_radians_per_second = gimbal_radians_per_second
thruster_node.target_gimbal_ratio = target_gimbal_ratio
# Thrust Force
thruster_node.max_force = max_force
thruster_node.max_gimbal = max_gimbal
thruster_node.force_change_per_second = force_change_per_second
thruster_node.target_force_ratio = target_force_ratio
return thruster_node


static func from_dictionary(dict: Dictionary) -> GLTFVehicleThruster:
var ret := GLTFVehicleThruster.new()
if dict.has("currentForceRatio"):
ret.current_force_ratio = dict["currentForceRatio"]
if dict.has("currentGimbalRatio"):
ret.current_gimbal_ratio = dict["currentGimbalRatio"]
# Gimbal
if dict.has("maxGimbal"):
ret.max_gimbal_radians = dict["maxGimbal"]
if dict.has("linearGimbalAdjustRatio"):
ret.linear_gimbal_adjust_ratio = dict["linearGimbalAdjustRatio"]
if dict.has("gimbalChangeRate"):
ret.gimbal_radians_per_second = dict["gimbalChangeRate"]
if dict.has("targetGimbalRatio"):
ret.target_gimbal_ratio = dict["targetGimbalRatio"]
# Thrust Force
if dict.has("maxForce"):
ret.max_force = dict["maxForce"]
if dict.has("maxGimbal"):
ret.max_gimbal = dict["maxGimbal"]
if dict.has("forceChangeRate"):
ret.force_change_per_second = dict["forceChangeRate"]
if dict.has("targetForceRatio"):
ret.target_force_ratio = dict["targetForceRatio"]
return ret


func to_dictionary() -> Dictionary:
var ret: Dictionary = {}
# Alphabetical order when converting to Dictionary.
if force_change_per_second != -1.0:
ret["forceChangeRate"] = force_change_per_second
if gimbal_radians_per_second != 1.0:
ret["gimbalChangeRate"] = gimbal_radians_per_second
if linear_gimbal_adjust_ratio != 0.0:
ret["linearGimbalAdjustRatio"] = linear_gimbal_adjust_ratio
# Always include maxForce since it is a required property for thrusters.
ret["maxForce"] = max_force
if current_force_ratio != 0.0:
ret["currentForceRatio"] = current_force_ratio
if current_gimbal_ratio != Vector2.ZERO:
ret["currentGimbalRatio"] = current_gimbal_ratio
if max_gimbal != 0.0:
ret["maxGimbal"] = max_gimbal
if max_gimbal_radians != 0.0:
ret["maxGimbal"] = max_gimbal_radians
if target_force_ratio != 0.0:
ret["targetForceRatio"] = target_force_ratio
if target_gimbal_ratio != Vector2.ZERO:
ret["targetGimbalRatio"] = target_gimbal_ratio
return ret
Loading