mirror of
https://github.com/godotengine/godot-tests.git
synced 2025-12-31 13:48:10 +03:00
Add godot cubic interpolation tests.
Update the license to the standard template.
This commit is contained in:
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Normalize EOL for all files that Git considers text files.
|
||||
* text=auto eol=lf
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
# Godot 4+ specific ignores
|
||||
.godot
|
||||
.import
|
||||
|
||||
tests/blend_export/**/*.import
|
||||
3
LICENSE
3
LICENSE
@@ -1,6 +1,7 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Godot Engine
|
||||
Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.
|
||||
Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
23
tests/cubic_slerp/Crosshair.gd
Normal file
23
tests/cubic_slerp/Crosshair.gd
Normal file
@@ -0,0 +1,23 @@
|
||||
extends Sprite2D
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
var camera = get_node("../Head/FirstPersonCamera")
|
||||
var firstPerson = get_node("..")
|
||||
if (camera.current and firstPerson.mouse_captured):
|
||||
var center = get_viewport_rect().size
|
||||
self.position = center / 2
|
||||
self.visible = true
|
||||
else:
|
||||
self.visible = false
|
||||
BIN
tests/cubic_slerp/Crosshair.png
Normal file
BIN
tests/cubic_slerp/Crosshair.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 732 B |
33
tests/cubic_slerp/Crosshair.png.import
Normal file
33
tests/cubic_slerp/Crosshair.png.import
Normal file
@@ -0,0 +1,33 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bshkbofr21m3w"
|
||||
path="res://.godot/imported/Crosshair.png-1956ffc22614618aaaacdf35a0cc4cd2.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://Crosshair.png"
|
||||
dest_files=["res://.godot/imported/Crosshair.png-1956ffc22614618aaaacdf35a0cc4cd2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
63
tests/cubic_slerp/DebugLines.gd
Normal file
63
tests/cubic_slerp/DebugLines.gd
Normal file
@@ -0,0 +1,63 @@
|
||||
extends MeshInstance3D
|
||||
|
||||
@export var lineMaterial:Material
|
||||
@export var debugIndicatorPath = ""
|
||||
|
||||
var immediate:ImmediateMesh
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
immediate = ImmediateMesh.new()
|
||||
mesh = immediate
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
immediate.clear_surfaces()
|
||||
|
||||
var preATipX = get_node(debugIndicatorPath + "/LOSolver_PreA/DebugIndicator/XAxis/TipEnd")
|
||||
var preATipY = get_node(debugIndicatorPath + "/LOSolver_PreA/DebugIndicator/YAxis/TipEnd")
|
||||
var preATipZ = get_node(debugIndicatorPath + "/LOSolver_PreA/DebugIndicator/ZAxis/TipEnd")
|
||||
|
||||
var aTipX = get_node(debugIndicatorPath + "/LOSolver_A/DebugIndicator/XAxis/TipEnd")
|
||||
var aTipY = get_node(debugIndicatorPath + "/LOSolver_A/DebugIndicator/YAxis/TipEnd")
|
||||
var aTipZ = get_node(debugIndicatorPath + "/LOSolver_A/DebugIndicator/ZAxis/TipEnd")
|
||||
|
||||
var bTipX = get_node(debugIndicatorPath + "/LOSolver_B/DebugIndicator/XAxis/TipEnd")
|
||||
var bTipY = get_node(debugIndicatorPath + "/LOSolver_B/DebugIndicator/YAxis/TipEnd")
|
||||
var bTipZ = get_node(debugIndicatorPath + "/LOSolver_B/DebugIndicator/ZAxis/TipEnd")
|
||||
|
||||
var postBTipX = get_node(debugIndicatorPath + "/LOSolver_PostB/DebugIndicator/XAxis/TipEnd")
|
||||
var postBTipY = get_node(debugIndicatorPath + "/LOSolver_PostB/DebugIndicator/YAxis/TipEnd")
|
||||
var postBTipZ = get_node(debugIndicatorPath + "/LOSolver_PostB/DebugIndicator/ZAxis/TipEnd")
|
||||
|
||||
if not preATipX:
|
||||
return
|
||||
if not aTipX:
|
||||
return
|
||||
if not bTipX:
|
||||
return
|
||||
if not postBTipX:
|
||||
return
|
||||
immediate.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, lineMaterial)
|
||||
# immediate.surface_set_color(Color(0, 0, 0))
|
||||
immediate.surface_add_vertex(preATipX.global_transform.origin)
|
||||
immediate.surface_add_vertex(aTipX.global_transform.origin)
|
||||
immediate.surface_add_vertex(bTipX.global_transform.origin)
|
||||
immediate.surface_add_vertex(postBTipX.global_transform.origin)
|
||||
immediate.surface_end()
|
||||
|
||||
immediate.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, lineMaterial)
|
||||
# immediate.surface_set_color(Color(0, 0, 0))
|
||||
immediate.surface_add_vertex(preATipY.global_transform.origin)
|
||||
immediate.surface_add_vertex(aTipY.global_transform.origin)
|
||||
immediate.surface_add_vertex(bTipY.global_transform.origin)
|
||||
immediate.surface_add_vertex(postBTipY.global_transform.origin)
|
||||
immediate.surface_end()
|
||||
|
||||
immediate.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, lineMaterial)
|
||||
# immediate.surface_set_color(Color(0, 0, 0))
|
||||
immediate.surface_add_vertex(preATipZ.global_transform.origin)
|
||||
immediate.surface_add_vertex(aTipZ.global_transform.origin)
|
||||
immediate.surface_add_vertex(bTipZ.global_transform.origin)
|
||||
immediate.surface_add_vertex(postBTipZ.global_transform.origin)
|
||||
immediate.surface_end()
|
||||
71
tests/cubic_slerp/DebugTraces.gd
Normal file
71
tests/cubic_slerp/DebugTraces.gd
Normal file
@@ -0,0 +1,71 @@
|
||||
extends MeshInstance3D
|
||||
|
||||
@export var pointMaterial:Material
|
||||
@export var tipHistoryLength:int = 240
|
||||
@export var debugIndicatorPath = ""
|
||||
@export var minDistanceBetweenPoints:float = 0.01
|
||||
|
||||
var immediate:ImmediateMesh
|
||||
|
||||
var tipXHistory = []
|
||||
var tipYHistory = []
|
||||
var tipZHistory = []
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
immediate = ImmediateMesh.new()
|
||||
mesh = immediate
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
var interpolatedTipX = get_node(debugIndicatorPath + "/XAxis/TipEnd")
|
||||
var interpolatedTipY = get_node(debugIndicatorPath + "/YAxis/TipEnd")
|
||||
var interpolatedTipZ = get_node(debugIndicatorPath + "/ZAxis/TipEnd")
|
||||
|
||||
if not interpolatedTipX:
|
||||
return
|
||||
if not interpolatedTipY:
|
||||
return
|
||||
if not interpolatedTipZ:
|
||||
return
|
||||
if (tipXHistory.size() == 0 or
|
||||
interpolatedTipX.global_transform.origin.distance_to(tipXHistory[tipXHistory.size()-1]) >= minDistanceBetweenPoints or
|
||||
interpolatedTipY.global_transform.origin.distance_to(tipYHistory[tipYHistory.size()-1]) >= minDistanceBetweenPoints or
|
||||
interpolatedTipZ.global_transform.origin.distance_to(tipZHistory[tipZHistory.size()-1]) >= minDistanceBetweenPoints
|
||||
):
|
||||
tipXHistory.push_back(interpolatedTipX.global_transform.origin)
|
||||
tipYHistory.push_back(interpolatedTipY.global_transform.origin)
|
||||
tipZHistory.push_back(interpolatedTipZ.global_transform.origin)
|
||||
|
||||
while tipXHistory.size() > tipHistoryLength:
|
||||
tipXHistory.pop_front()
|
||||
while tipYHistory.size() > tipHistoryLength:
|
||||
tipYHistory.pop_front()
|
||||
while tipZHistory.size() > tipHistoryLength:
|
||||
tipZHistory.pop_front()
|
||||
|
||||
immediate.clear_surfaces()
|
||||
|
||||
immediate.surface_begin(Mesh.PRIMITIVE_POINTS, pointMaterial)
|
||||
immediate.surface_set_color(Color(0.5, 0, 0))
|
||||
for coords in tipXHistory:
|
||||
immediate.surface_add_vertex(coords)
|
||||
immediate.surface_end()
|
||||
|
||||
immediate.surface_begin(Mesh.PRIMITIVE_POINTS, pointMaterial)
|
||||
immediate.surface_set_color(Color(0, 0.5, 0))
|
||||
for coords in tipYHistory:
|
||||
immediate.surface_add_vertex(coords)
|
||||
immediate.surface_end()
|
||||
|
||||
immediate.surface_begin(Mesh.PRIMITIVE_POINTS, pointMaterial)
|
||||
immediate.surface_set_color(Color(0, 0, 0.5))
|
||||
for coords in tipZHistory:
|
||||
immediate.surface_add_vertex(coords)
|
||||
immediate.surface_end()
|
||||
|
||||
func clear():
|
||||
tipXHistory.clear()
|
||||
tipYHistory.clear()
|
||||
tipZHistory.clear()
|
||||
|
||||
287
tests/cubic_slerp/FirstPersonFlyer.gd
Normal file
287
tests/cubic_slerp/FirstPersonFlyer.gd
Normal file
@@ -0,0 +1,287 @@
|
||||
extends CharacterBody3D
|
||||
|
||||
var camera_angle_y_unfiltered:float = 0
|
||||
var camera_angle_x_unfiltered:float = 0
|
||||
var camera_angle_y_filtered:float = 0
|
||||
var camera_angle_x_filtered:float = 0
|
||||
|
||||
# Use values like 0.1 for the next to smoothen camera angle changes more.
|
||||
# This makes turning less responsive, but maybe easier to follow
|
||||
# when creating videos etc.
|
||||
const camera_angle_filter_coeff:float = 0.1
|
||||
#const camera_angle_filter_coeff:float = 0.001 #0.01
|
||||
|
||||
enum NavigationMode {
|
||||
NAVMODE_FPS,
|
||||
NAVMODE_6DOF }
|
||||
|
||||
const mouse_sensitivity = 0.15
|
||||
var camera_change = Vector2()
|
||||
const ZAxisMax6DOFTurningSpeed:float = 90
|
||||
const ZAxis6DOFTurningSpeedAcceleration = 0.9 # 0 = Don't turn, 1 = immediately full speed
|
||||
var ZAxis6DOFTurningSpeed:float = 0
|
||||
var last_camera_angle_x_filtered:float
|
||||
var last_camera_angle_y_filtered:float
|
||||
var navMode:NavigationMode = NavigationMode.NAVMODE_FPS
|
||||
|
||||
# Movement:
|
||||
var direction:Vector3 = Vector3()
|
||||
var velocityMultiplier:float = 5
|
||||
const minVelocityMultiplier:float = 0.01
|
||||
const maxVelocityMultiplier:float = 20
|
||||
const flyAcceleration:float = 0.9 # 0 = don't move, 1 = immediately full speed
|
||||
|
||||
|
||||
# Due to physics-process being run only 60 Hz and refresh rate
|
||||
# may differ from that, head is moved "in advance" before
|
||||
# the other parts. This is for the translation in world-coordinates for it
|
||||
var headDetachment:Vector3 = Vector3()
|
||||
|
||||
var mouse_captured = false
|
||||
|
||||
func _ready():
|
||||
var manipulator = get_node("ManipulatorCollisionShape")
|
||||
var capsule = get_node("Capsule")
|
||||
var manipulatorMeshes = get_node("ManipulatorMeshes")
|
||||
|
||||
manipulator.disabled = true
|
||||
manipulator.visible = true
|
||||
capsule.disabled = true
|
||||
manipulatorMeshes.visible = false
|
||||
|
||||
var rmbManipulator = get_node("RMBManipulatorCollisionShape")
|
||||
var rmbManipulatorMeshes = get_node("RMBManipulatorMeshes")
|
||||
rmbManipulator.disabled = true
|
||||
rmbManipulator.visible = true
|
||||
rmbManipulatorMeshes.visible = false
|
||||
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
|
||||
func _physics_process(delta):
|
||||
# var head:Node3D = get_node("Head")
|
||||
|
||||
# Due to physics-process being run only 60 Hz and refresh rate
|
||||
# may differ from that, head is moved "in advance" before
|
||||
# the other parts.
|
||||
# The movement accumulated during _process-calls
|
||||
# is relayed to the physics-engine here
|
||||
velocity = headDetachment / delta # motion_velocity is in m/s, therefore /delta
|
||||
headDetachment = Vector3() # Start accumulating from zero again
|
||||
var _discard = move_and_slide()
|
||||
|
||||
# Tried to prevent strange jitter with this. Didn't help
|
||||
var lastUptime_us:int = -1
|
||||
|
||||
func _process(delta):
|
||||
# Tried to prevent strange jitter with this. Didn't help
|
||||
# var upTime_us = Time.get_ticks_usec()
|
||||
# var deltaOverride = float(upTime_us - lastUptime_us) / 1e6
|
||||
# if (deltaOverride < 0.1):
|
||||
# delta = deltaOverride
|
||||
# lastUptime_us = upTime_us
|
||||
|
||||
var manipulator = get_node("ManipulatorCollisionShape")
|
||||
var capsule = get_node("Capsule")
|
||||
var manipulatorMeshes = get_node("ManipulatorMeshes")
|
||||
var rmbManipulator = get_node("RMBManipulatorCollisionShape")
|
||||
var rmbManipulatorMeshes = get_node("RMBManipulatorMeshes")
|
||||
|
||||
if Input.is_action_just_pressed('toggle_mouse'):
|
||||
if mouse_captured:
|
||||
mouse_captured = false
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
else:
|
||||
mouse_captured = true
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
# This is outside the mouse_captured-branch below to keep flying speed
|
||||
# identical between all first persons (there may be many instances)
|
||||
handleFlyingSpeed(delta)
|
||||
|
||||
if !mouse_captured or !(get_node("Head/FirstPersonCamera").current):
|
||||
# Do not react if camera is not in use
|
||||
# (There can be many instances of this class)
|
||||
manipulator.disabled = true
|
||||
capsule.disabled = true
|
||||
manipulatorMeshes.visible = false
|
||||
rmbManipulator.disabled = true
|
||||
rmbManipulatorMeshes.visible = false
|
||||
|
||||
# Prevent annoying movements when changing to this camera due to remembering some old values
|
||||
camera_angle_y_unfiltered = camera_angle_y_filtered
|
||||
camera_angle_x_unfiltered = camera_angle_x_filtered
|
||||
direction = Vector3()
|
||||
velocity = Vector3()
|
||||
velocity = Vector3()
|
||||
# accumulatedVelocity = Vector3()
|
||||
camera_change = Vector2()
|
||||
|
||||
return
|
||||
|
||||
if mouse_captured:
|
||||
aim(delta)
|
||||
fly(delta)
|
||||
|
||||
if Input.is_action_just_pressed("mouse_left"):
|
||||
manipulator.disabled = false
|
||||
capsule.disabled = false
|
||||
manipulatorMeshes.visible = true
|
||||
if Input.is_action_just_released("mouse_left"):
|
||||
manipulator.disabled = true
|
||||
capsule.disabled = true
|
||||
manipulatorMeshes.visible = false
|
||||
|
||||
if Input.is_action_just_pressed("mouse_right"):
|
||||
rmbManipulator.disabled = false
|
||||
rmbManipulatorMeshes.visible = true
|
||||
if Input.is_action_just_released("mouse_right"):
|
||||
rmbManipulator.disabled = true
|
||||
rmbManipulatorMeshes.visible = false
|
||||
|
||||
func _input(event):
|
||||
if mouse_captured and (event is InputEventMouseMotion):
|
||||
camera_change += event.relative
|
||||
|
||||
func fly(delta):
|
||||
# reset the direction of the player
|
||||
direction = Vector3()
|
||||
|
||||
# get the rotation of the camera
|
||||
var lookingAt = $Head/FirstPersonCamera.get_global_transform().basis
|
||||
|
||||
# check input and change direction
|
||||
if Input.is_action_pressed("move_forward"):
|
||||
direction -= lookingAt.z
|
||||
if Input.is_action_pressed("move_backward"):
|
||||
direction += lookingAt.z
|
||||
if Input.is_action_pressed("move_left"):
|
||||
direction -= lookingAt.x
|
||||
if Input.is_action_pressed("move_right"):
|
||||
direction += lookingAt.x
|
||||
if (Input.is_action_pressed("move_up") ||
|
||||
(Input.is_action_pressed("6dof_rotate_z_right") && (navMode == NavigationMode.NAVMODE_FPS))):
|
||||
direction += lookingAt.y
|
||||
if (Input.is_action_pressed("move_down") ||
|
||||
(Input.is_action_pressed("6dof_rotate_z_left") && (navMode == NavigationMode.NAVMODE_FPS))):
|
||||
direction -= lookingAt.y
|
||||
|
||||
# where would the player go at max speed (m/s)
|
||||
var target = direction * velocityMultiplier
|
||||
|
||||
var correctedCoeff = pow(1 - flyAcceleration, delta)
|
||||
velocity = correctedCoeff * velocity + target * (1 - correctedCoeff)
|
||||
# print(velocity)
|
||||
|
||||
var translation = velocity * delta
|
||||
headDetachment += translation
|
||||
|
||||
var head:Node3D = get_node("Head")
|
||||
head.set_transform(Transform3D(head.get_transform().basis, head.to_local(head.get_global_transform().origin + headDetachment)))
|
||||
|
||||
func handleFlyingSpeed(delta):
|
||||
if Input.is_action_pressed("movement_speed_down"):
|
||||
velocityMultiplier /= (1 + delta)
|
||||
if Input.is_action_just_released("movement_speed_down_mousewheel"):
|
||||
velocityMultiplier /= (1 + (delta * 20))
|
||||
|
||||
if Input.is_action_pressed("movement_speed_up"):
|
||||
velocityMultiplier *= (1 + delta)
|
||||
if Input.is_action_just_released("movement_speed_up_mousewheel"):
|
||||
velocityMultiplier *= (1 + (delta * 20))
|
||||
|
||||
velocityMultiplier = clamp(velocityMultiplier, minVelocityMultiplier, maxVelocityMultiplier)
|
||||
|
||||
func aim(delta):
|
||||
if Input.is_action_just_pressed("switch_navigation_mode"):
|
||||
if (navMode == NavigationMode.NAVMODE_FPS):
|
||||
navMode = NavigationMode.NAVMODE_6DOF
|
||||
else:
|
||||
navMode = NavigationMode.NAVMODE_FPS
|
||||
camera_angle_x_filtered = -rad2deg(asin(transform.basis.z.y))
|
||||
camera_angle_y_filtered = rad2deg(atan2(transform.basis.z.x, transform.basis.z.z))
|
||||
camera_angle_x_unfiltered = camera_angle_x_filtered
|
||||
camera_angle_y_unfiltered = camera_angle_y_filtered
|
||||
|
||||
if (navMode == NavigationMode.NAVMODE_FPS):
|
||||
aimFPS(delta)
|
||||
else:
|
||||
aim6DOF(delta)
|
||||
|
||||
|
||||
func aimFPS(delta):
|
||||
if camera_change.length() > 0:
|
||||
# $Head.rotate_y(deg2rad(-camera_change.x * mouse_sensitivity))
|
||||
camera_angle_y_unfiltered -= camera_change.x * mouse_sensitivity
|
||||
camera_angle_x_unfiltered -= camera_change.y * mouse_sensitivity
|
||||
|
||||
if camera_angle_x_unfiltered < -90:
|
||||
camera_angle_x_unfiltered = -90
|
||||
if camera_angle_x_unfiltered > 90:
|
||||
camera_angle_x_unfiltered = 90
|
||||
|
||||
camera_change = Vector2()
|
||||
|
||||
transform.basis = Basis()
|
||||
|
||||
var correctedCoeff = pow(camera_angle_filter_coeff, delta)
|
||||
|
||||
camera_angle_x_filtered = camera_angle_x_filtered * correctedCoeff + camera_angle_x_unfiltered * (1 - correctedCoeff)
|
||||
camera_angle_y_filtered = camera_angle_y_filtered * correctedCoeff + camera_angle_y_unfiltered * (1 - correctedCoeff)
|
||||
|
||||
last_camera_angle_x_filtered = camera_angle_x_filtered
|
||||
last_camera_angle_y_filtered = camera_angle_y_filtered
|
||||
|
||||
rotate_x(deg2rad(camera_angle_x_filtered))
|
||||
rotate_y(deg2rad(camera_angle_y_filtered))
|
||||
|
||||
func aim6DOF(delta):
|
||||
if camera_change.length() > 0:
|
||||
# $Head.rotate_y(deg2rad(-camera_change.x * mouse_sensitivity))
|
||||
camera_angle_y_unfiltered -= camera_change.x * mouse_sensitivity
|
||||
camera_angle_x_unfiltered -= camera_change.y * mouse_sensitivity
|
||||
|
||||
camera_change = Vector2()
|
||||
|
||||
var correctedCoeff = pow(camera_angle_filter_coeff, delta)
|
||||
|
||||
camera_angle_x_filtered = camera_angle_x_filtered * correctedCoeff + camera_angle_x_unfiltered * (1 - correctedCoeff)
|
||||
camera_angle_y_filtered = camera_angle_y_filtered * correctedCoeff + camera_angle_y_unfiltered * (1 - correctedCoeff)
|
||||
|
||||
var camera_angle_x_filtered_change = camera_angle_x_filtered - last_camera_angle_x_filtered
|
||||
var camera_angle_y_filtered_change = camera_angle_y_filtered - last_camera_angle_y_filtered
|
||||
|
||||
last_camera_angle_x_filtered = camera_angle_x_filtered
|
||||
last_camera_angle_y_filtered = camera_angle_y_filtered
|
||||
|
||||
var unFilteredZAxisTurningSpeed = 0
|
||||
|
||||
if Input.is_action_pressed("6dof_rotate_z_left"):
|
||||
unFilteredZAxisTurningSpeed += ZAxisMax6DOFTurningSpeed
|
||||
if Input.is_action_pressed("6dof_rotate_z_right"):
|
||||
unFilteredZAxisTurningSpeed -= ZAxisMax6DOFTurningSpeed
|
||||
|
||||
correctedCoeff = pow(1 - ZAxis6DOFTurningSpeedAcceleration, delta)
|
||||
|
||||
ZAxis6DOFTurningSpeed = ZAxis6DOFTurningSpeed * correctedCoeff + unFilteredZAxisTurningSpeed * (1 - correctedCoeff)
|
||||
|
||||
var tempBasis = transform.basis
|
||||
tempBasis = tempBasis.rotated(tempBasis.x, deg2rad(camera_angle_x_filtered_change))
|
||||
tempBasis = tempBasis.rotated(tempBasis.y, deg2rad(camera_angle_y_filtered_change))
|
||||
tempBasis = tempBasis.rotated(tempBasis.z, deg2rad(ZAxis6DOFTurningSpeed * delta))
|
||||
transform.basis = tempBasis.orthonormalized()
|
||||
|
||||
func set_LocationOrientation(newTransform: Transform3D):
|
||||
# TODO: should relay this to _physics_process instead
|
||||
# TODO: 6DOF?
|
||||
transform = newTransform
|
||||
transform.basis = Basis()
|
||||
var newBasis = newTransform.basis
|
||||
camera_angle_x_unfiltered = - rad2deg(asin(newBasis.z.y))
|
||||
camera_angle_x_filtered = camera_angle_x_unfiltered
|
||||
camera_angle_y_unfiltered = rad2deg(atan2(newBasis.z.x, newBasis.z.z))
|
||||
camera_angle_y_filtered = camera_angle_y_unfiltered
|
||||
rotate_x(deg2rad(camera_angle_x_filtered))
|
||||
rotate_y(deg2rad(camera_angle_y_filtered))
|
||||
# firstPerson.camera_change = Vector2(0,0)
|
||||
|
||||
|
||||
105
tests/cubic_slerp/FirstPersonFlyer.tscn
Normal file
105
tests/cubic_slerp/FirstPersonFlyer.tscn
Normal file
@@ -0,0 +1,105 @@
|
||||
[gd_scene load_steps=14 format=3 uid="uid://b3ywvgurbetiy"]
|
||||
|
||||
[ext_resource type="Script" path="res://FirstPersonFlyer.gd" id="1_0cyb0"]
|
||||
[ext_resource type="Texture2D" uid="uid://bshkbofr21m3w" path="res://Crosshair.png" id="2_252at"]
|
||||
[ext_resource type="Script" path="res://Crosshair.gd" id="3_dckbd"]
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="1"]
|
||||
radius = 0.6
|
||||
|
||||
[sub_resource type="ConvexPolygonShape3D" id="2"]
|
||||
points = PackedVector3Array(0, 2, 0.05, 0.0353553, 2, 0.0353553, 0.05, 2, 3.06162e-18, 0.0353553, 2, -0.0353553, 6.12323e-18, 2, -0.05, -0.0353553, 2, -0.0353553, -0.05, 2, -9.18485e-18, -0.0353553, 2, 0.0353553, -1.22465e-17, 2, 0.05, 0, 0, 0.05, 0.0353553, 0, 0.0353553, 0.05, 0, 3.06162e-18, 0.0353553, 0, -0.0353553, 6.12323e-18, 0, -0.05, -0.0353553, 0, -0.0353553, -0.05, 0, -9.18485e-18, -0.0353553, 0, 0.0353553, -1.22465e-17, 0, 0.05, 0, -2, 0.05, 0.0353553, -2, 0.0353553, 0.05, -2, 3.06162e-18, 0.0353553, -2, -0.0353553, 6.12323e-18, -2, -0.05, -0.0353553, -2, -0.0353553, -0.05, -2, -9.18485e-18, -0.0353553, -2, 0.0353553, -1.22465e-17, -2, 0.05, 0, 2, 0, 0, 2, 0.05, 0.0353553, 2, 0.0353553, 0.05, 2, 3.06162e-18, 0.0353553, 2, -0.0353553, 6.12323e-18, 2, -0.05, -0.0353553, 2, -0.0353553, -0.05, 2, -9.18485e-18, -0.0353553, 2, 0.0353553, -1.22465e-17, 2, 0.05, 0, -2, 0, 0, -2, 0.05, 0.0353553, -2, 0.0353553, 0.05, -2, 3.06162e-18, 0.0353553, -2, -0.0353553, 6.12323e-18, -2, -0.05, -0.0353553, -2, -0.0353553, -0.05, -2, -9.18485e-18, -0.0353553, -2, 0.0353553, -1.22465e-17, -2, 0.05)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="3"]
|
||||
albedo_color = Color(1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="4"]
|
||||
material = SubResource("3")
|
||||
top_radius = 0.05
|
||||
bottom_radius = 0.05
|
||||
height = 4.0
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="SphereMesh" id="5"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="7"]
|
||||
render_priority = 1
|
||||
transparency = 1
|
||||
albedo_color = Color(0.0627451, 0.894118, 0.0666667, 0.505882)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="8"]
|
||||
material = SubResource("7")
|
||||
top_radius = 0.05
|
||||
bottom_radius = 0.05
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="9"]
|
||||
albedo_color = Color(1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="10"]
|
||||
material = SubResource("9")
|
||||
size = Vector3(5, 0.2, 5)
|
||||
|
||||
[sub_resource type="ConvexPolygonShape3D" id="11"]
|
||||
points = PackedVector3Array(-2.5, 0.1, 2.5, 2.5, 0.1, -2.5, 2.5, 0.1, 2.5, -2.5, 0.1, -2.5, -2.5, -0.1, 2.5, 2.5, -0.1, -2.5, 2.5, -0.1, 2.5, -2.5, -0.1, -2.5, 2.5, 0.1, 2.5, -2.5, 0.1, -2.5, 2.5, 0.1, -2.5, -2.5, 0.1, 2.5, 2.5, -0.1, 2.5, -2.5, -0.1, -2.5, 2.5, -0.1, -2.5, -2.5, -0.1, 2.5, 2.5, 0.1, 2.5, -2.5, -0.1, 2.5, -2.5, 0.1, 2.5, 2.5, -0.1, 2.5, 2.5, 0.1, -2.5, -2.5, -0.1, -2.5, -2.5, 0.1, -2.5, 2.5, -0.1, -2.5)
|
||||
|
||||
[node name="FirstPersonFlyer" type="CharacterBody3D"]
|
||||
script = ExtResource("1_0cyb0")
|
||||
|
||||
[node name="Capsule" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0)
|
||||
shape = SubResource("1")
|
||||
|
||||
[node name="Head" type="Node3D" parent="."]
|
||||
|
||||
[node name="FirstPersonCamera" type="Camera3D" parent="Head"]
|
||||
current = true
|
||||
fov = 42.0
|
||||
near = 0.01
|
||||
far = 5000.0
|
||||
|
||||
[node name="OmniLight" type="OmniLight3D" parent="."]
|
||||
visible = false
|
||||
light_energy = 1.67
|
||||
omni_range = 25.0
|
||||
|
||||
[node name="ManipulatorCollisionShape" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, -1.62921e-07, -1, 0, 1, -1.62921e-07, 0, -1.5, -3.5)
|
||||
visible = false
|
||||
shape = SubResource("2")
|
||||
|
||||
[node name="ManipulatorMeshes" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, 0)
|
||||
visible = false
|
||||
|
||||
[node name="ManipulatorMesh" type="MeshInstance3D" parent="ManipulatorMeshes"]
|
||||
transform = Transform3D(1, -2.98023e-08, 0, 0, -1.62921e-07, -1, 2.98023e-08, 1, -1.62921e-07, 1.19209e-06, 0, -3.5)
|
||||
mesh = SubResource("4")
|
||||
|
||||
[node name="ManipulatorTip" type="MeshInstance3D" parent="ManipulatorMeshes"]
|
||||
transform = Transform3D(1, 0, -2.98023e-08, 0, 1, 0, 2.98023e-08, 0, 1, 9.53674e-07, 0, -5.5)
|
||||
mesh = SubResource("5")
|
||||
|
||||
[node name="ManipulatorExtension" type="MeshInstance3D" parent="ManipulatorMeshes"]
|
||||
transform = Transform3D(1, -2.98023e-08, 0, 0, -1.62921e-07, -1, 2.98023e-08, 1, -1.62921e-07, 0, 0, -6.5)
|
||||
mesh = SubResource("8")
|
||||
|
||||
[node name="RMBManipulatorMeshes" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, 0)
|
||||
visible = false
|
||||
|
||||
[node name="Plate" type="MeshInstance3D" parent="RMBManipulatorMeshes"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -3.37924, -10.7638)
|
||||
mesh = SubResource("10")
|
||||
|
||||
[node name="RMBManipulatorCollisionShape" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -4.9, -10.764)
|
||||
visible = false
|
||||
shape = SubResource("11")
|
||||
|
||||
[node name="Crosshair" type="Sprite2D" parent="."]
|
||||
position = Vector2(500, 300)
|
||||
texture = ExtResource("2_252at")
|
||||
script = ExtResource("3_dckbd")
|
||||
BIN
tests/cubic_slerp/GreenCheckerboard.png
Normal file
BIN
tests/cubic_slerp/GreenCheckerboard.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 930 B |
35
tests/cubic_slerp/GreenCheckerboard.png.import
Normal file
35
tests/cubic_slerp/GreenCheckerboard.png.import
Normal file
@@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ckmlr2jsohlh1"
|
||||
path.s3tc="res://.godot/imported/GreenCheckerboard.png-d0c9342e56f02658d0ef8f3f4aa435d6.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/GreenCheckerboard.png-d0c9342e56f02658d0ef8f3f4aa435d6.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc", "etc2"],
|
||||
"vram_texture": true
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://GreenCheckerboard.png"
|
||||
dest_files=["res://.godot/imported/GreenCheckerboard.png-d0c9342e56f02658d0ef8f3f4aa435d6.s3tc.ctex", "res://.godot/imported/GreenCheckerboard.png-d0c9342e56f02658d0ef8f3f4aa435d6.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=true
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
||||
24
tests/cubic_slerp/LICENSE
Normal file
24
tests/cubic_slerp/LICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.
|
||||
Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).
|
||||
Copyright (c) 2022 K. S. Ernest (iFire) Lee
|
||||
Copyright (c) 2018 Roujel Williams
|
||||
Copyright (c) 2019 Jon Ring
|
||||
Copyright (c) 2020-2022 Pasi Nuutinmaki
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
223
tests/cubic_slerp/LOScriptReplayer_Node3D.gd
Normal file
223
tests/cubic_slerp/LOScriptReplayer_Node3D.gd
Normal file
@@ -0,0 +1,223 @@
|
||||
extends Node3D
|
||||
|
||||
enum QUAT_INTERPOLATION_METHOD { lastLastValue, lastValue, nextValue, nextNextValue, nearestValue, slerp, slerpni, cubic_slerp }
|
||||
enum ORIGIN_INTERPOLATION_METHOD { lastValue, nextValue, nearestValue, linear, cubic }
|
||||
|
||||
@export var loFilename:String = ""
|
||||
@export var readTimeShift:int = 124140000
|
||||
|
||||
@export var originInterpolationMethod:ORIGIN_INTERPOLATION_METHOD = ORIGIN_INTERPOLATION_METHOD.cubic
|
||||
@export var quatInterpolationMethod:QUAT_INTERPOLATION_METHOD = QUAT_INTERPOLATION_METHOD.slerp
|
||||
|
||||
# To get sparser data for quaternion interpolation tests:
|
||||
# 0 -> Does not skip any lines, 1 -> Skips every other line etc.
|
||||
@export var readLineSkip = 3
|
||||
|
||||
class LOItem:
|
||||
var origin:Vector3
|
||||
var quat:Quaternion
|
||||
func _init(origin_p:Vector3, quat_p:Quaternion):
|
||||
self.origin = origin_p
|
||||
self.quat = quat_p
|
||||
|
||||
var loData = {}
|
||||
var loDataKeys
|
||||
|
||||
var nextReplayTimeIndex:int = 0
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
if loFilename.length() > 0:
|
||||
# Try to load file at this phase only if defined.
|
||||
loadFile(loFilename)
|
||||
|
||||
func loadFile(fileName):
|
||||
loData.clear()
|
||||
loDataKeys = []
|
||||
|
||||
var file = File.new()
|
||||
#var metadata = {}
|
||||
if file.open(fileName, File.READ) != OK:
|
||||
print("Can't open file " + fileName)
|
||||
return
|
||||
var line
|
||||
while not file.eof_reached():
|
||||
line = file.get_line()
|
||||
var subStrings = line.split("\t")
|
||||
if subStrings.size() < 2:
|
||||
continue
|
||||
|
||||
if subStrings[0] == "META":
|
||||
if subStrings[1] == "END":
|
||||
break
|
||||
# TODO: Add some sanity checks here.
|
||||
# (now just skipping all checks...)
|
||||
|
||||
line = file.get_line()
|
||||
if line != "iTOW\tOrigin_X\tOrigin_Y\tOrigin_Z\tBasis_XX\tBasis_XY\tBasis_XZ\tBasis_YX\tBasis_YY\tBasis_YZ\tBasis_ZX\tBasis_ZY\tBasis_ZZ" and line != "Uptime\tOrigin_X\tOrigin_Y\tOrigin_Z\tBasis_XX\tBasis_XY\tBasis_XZ\tBasis_YX\tBasis_YY\tBasis_YZ\tBasis_ZX\tBasis_ZY\tBasis_ZZ":
|
||||
printt("Invalid header line in " + loFilename)
|
||||
return
|
||||
|
||||
while not file.eof_reached():
|
||||
# TODO: Maybe add some error checking here...
|
||||
line = file.get_line()
|
||||
var subStrings = line.split("\t")
|
||||
if (subStrings.size() >= (1 + (4 * 3))):
|
||||
var replayTime = subStrings[0].to_int() - readTimeShift
|
||||
|
||||
#Coordinates in Godot's native "EUS"-convention:
|
||||
var origin = Vector3(0,0, 0)
|
||||
# var origin = Vector3(subStrings[1].to_float(), subStrings[2].to_float(), subStrings[3].to_float())
|
||||
var unitVecX = Vector3(subStrings[4].to_float(), subStrings[5].to_float(), subStrings[6].to_float())
|
||||
var unitVecY = Vector3(subStrings[7].to_float(), subStrings[8].to_float(), subStrings[9].to_float())
|
||||
var unitVecZ = Vector3(subStrings[10].to_float(), subStrings[11].to_float(), subStrings[12].to_float())
|
||||
|
||||
# These convert NED-coordinates to godot's "EUS" on the fly
|
||||
# var origin = Vector3(subStrings[2].to_float(), -subStrings[3].to_float(), -subStrings[1].to_float())
|
||||
# var unitVecX = Vector3(subStrings[5].to_float(), -subStrings[6].to_float(), -subStrings[4].to_float())
|
||||
# var unitVecY = Vector3(subStrings[8].to_float(), -subStrings[9].to_float(), -subStrings[7].to_float())
|
||||
# var unitVecZ = Vector3(subStrings[11].to_float(), -subStrings[12].to_float(), -subStrings[10].to_float())
|
||||
|
||||
var basisTemp = Basis(unitVecX, unitVecY, unitVecZ).orthonormalized()
|
||||
# var tr = Transform(unitVecX, unitVecY, unitVecZ, origin)
|
||||
# print(basisTemp)
|
||||
var quat = Quaternion(basisTemp)
|
||||
|
||||
loData[replayTime] = LOItem.new(origin, quat)
|
||||
for _i in range(readLineSkip):
|
||||
# To get sparser data for quaternion interpolation tests
|
||||
file.get_line()
|
||||
|
||||
loDataKeys = loData.keys()
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
# pass
|
||||
|
||||
#func _physics_process(delta):
|
||||
if loData.is_empty():
|
||||
return
|
||||
|
||||
var currentReplayTime:float = get_node("/root/Main").replayTime
|
||||
|
||||
if nextReplayTimeIndex < loDataKeys.size():
|
||||
for _i in range(10):
|
||||
# Maybe this faster than using bsearch every time(?)
|
||||
# Run this some rounds to allow some hickups in screen update etc.
|
||||
if nextReplayTimeIndex < loDataKeys.size() and currentReplayTime >= loDataKeys[nextReplayTimeIndex]:
|
||||
# Typical case: monotonically increasing ReplayTime
|
||||
nextReplayTimeIndex += 1
|
||||
continue
|
||||
elif nextReplayTimeIndex > 0 and currentReplayTime < loDataKeys[nextReplayTimeIndex - 1]:
|
||||
# Another typical(ish?) case: monotonically decreasing ReplayTime
|
||||
nextReplayTimeIndex -= 1
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
if (nextReplayTimeIndex > 0 and nextReplayTimeIndex < loDataKeys.size() and
|
||||
(currentReplayTime < loDataKeys[nextReplayTimeIndex - 1] or
|
||||
currentReplayTime >= loDataKeys[nextReplayTimeIndex])):
|
||||
# ReplayTime changed too fast
|
||||
# -> Use bsearch to find the correct index
|
||||
nextReplayTimeIndex = loDataKeys.bsearch(currentReplayTime)
|
||||
elif currentReplayTime < loDataKeys[loDataKeys.size() - 1]:
|
||||
# "Rewind" while in the last item
|
||||
nextReplayTimeIndex = loDataKeys.bsearch(currentReplayTime)
|
||||
|
||||
var nextReplayTimeValue:int
|
||||
|
||||
if nextReplayTimeIndex < loDataKeys.size():
|
||||
nextReplayTimeValue = loDataKeys[nextReplayTimeIndex]
|
||||
else:
|
||||
nextReplayTimeValue = loDataKeys[loDataKeys.size() - 1]
|
||||
|
||||
var origin:Vector3
|
||||
var quat:Quaternion
|
||||
|
||||
if nextReplayTimeIndex <= 0:
|
||||
origin = loData[nextReplayTimeValue].origin
|
||||
quat = loData[nextReplayTimeValue].quat
|
||||
elif nextReplayTimeValue == currentReplayTime:
|
||||
origin = loData[nextReplayTimeValue].origin
|
||||
quat = loData[nextReplayTimeValue].quat
|
||||
elif nextReplayTimeIndex >= loDataKeys.size() - 1:
|
||||
origin = loData[loDataKeys[loDataKeys.size() -1]].origin
|
||||
quat = loData[loDataKeys[loDataKeys.size() -1]].quat
|
||||
else:
|
||||
var lastReplayTimeIndex:int = nextReplayTimeIndex - 1
|
||||
var lastReplayTimeValue:int = loDataKeys[lastReplayTimeIndex]
|
||||
var fraction:float = float(currentReplayTime - lastReplayTimeValue) / (nextReplayTimeValue - lastReplayTimeValue)
|
||||
var origin_a:Vector3 = loData[lastReplayTimeValue].origin
|
||||
var origin_b:Vector3 = loData[nextReplayTimeValue].origin
|
||||
var quat_a:Quaternion = loData[lastReplayTimeValue].quat
|
||||
var quat_b:Quaternion = loData[nextReplayTimeValue].quat
|
||||
|
||||
if nextReplayTimeIndex == 1 or nextReplayTimeIndex == loDataKeys.size() - 1:
|
||||
# linear interpolation when cubic not possible
|
||||
origin = origin_a.lerp(origin_b, fraction)
|
||||
quat = quat_a.slerp(quat_b, fraction)
|
||||
else:
|
||||
|
||||
match originInterpolationMethod:
|
||||
ORIGIN_INTERPOLATION_METHOD.lastValue:
|
||||
origin = origin_a
|
||||
ORIGIN_INTERPOLATION_METHOD.nextValue:
|
||||
origin = origin_b
|
||||
ORIGIN_INTERPOLATION_METHOD.nearestValue:
|
||||
origin = origin_a if fraction < 0.5 else origin_b
|
||||
ORIGIN_INTERPOLATION_METHOD.linear:
|
||||
origin = origin_a.lerp(origin_b, fraction)
|
||||
ORIGIN_INTERPOLATION_METHOD.cubic:
|
||||
var origin_pre_a:Vector3 = loData[loDataKeys[lastReplayTimeIndex - 1]].origin
|
||||
var origin_post_b:Vector3 = loData[loDataKeys[nextReplayTimeIndex + 1]].origin
|
||||
origin = origin_a.cubic_interpolate(origin_b, origin_pre_a, origin_post_b, fraction)
|
||||
_:
|
||||
origin = origin_a
|
||||
|
||||
var quat_pre_a:Quaternion = loData[loDataKeys[lastReplayTimeIndex - 1]].quat
|
||||
var quat_post_b:Quaternion = loData[loDataKeys[nextReplayTimeIndex + 1]].quat
|
||||
|
||||
match quatInterpolationMethod:
|
||||
QUAT_INTERPOLATION_METHOD.lastLastValue:
|
||||
quat = quat_pre_a
|
||||
QUAT_INTERPOLATION_METHOD.lastValue:
|
||||
quat = quat_a
|
||||
QUAT_INTERPOLATION_METHOD.nextValue:
|
||||
quat = quat_b
|
||||
QUAT_INTERPOLATION_METHOD.nextNextValue:
|
||||
quat = quat_post_b
|
||||
QUAT_INTERPOLATION_METHOD.nearestValue:
|
||||
quat = quat_a if fraction < 0.5 else quat_b
|
||||
QUAT_INTERPOLATION_METHOD.slerp:
|
||||
quat = quat_a.slerp(quat_b, fraction)
|
||||
QUAT_INTERPOLATION_METHOD.slerpni:
|
||||
# Causes some strange jitter
|
||||
quat = quat_a.slerpni(quat_b, fraction)
|
||||
QUAT_INTERPOLATION_METHOD.cubic_slerp:
|
||||
# If you want to test the interpolation method in PR
|
||||
# https://github.com/godotengine/godot/pull/63287
|
||||
# use cubic_interpolate-version below:
|
||||
# quat = quat_a.cubic_interpolate(quat_b, quat_pre_a, quat_post_b, fraction)
|
||||
|
||||
# "Traditional" version:
|
||||
quat = quat_a.cubic_slerp(quat_b, quat_pre_a, quat_post_b, fraction)
|
||||
_:
|
||||
quat = quat_a
|
||||
|
||||
var basisTemp:Basis = Basis(quat)
|
||||
|
||||
# print("Original basis: ", basis)
|
||||
|
||||
# print("Original basis inverse: ", basis.inverse())
|
||||
|
||||
# Why is .transposed() needed for basis here?
|
||||
# In Godot 3.x (from where this code was copied from) it was not needed.
|
||||
# Addition: Dug a bit deeper with this. It seems that this may be related
|
||||
# to a change how Godot stores Basis (transposed or not). Some info:
|
||||
# https://github.com/godotengine/godot-proposals/issues/2738
|
||||
# Quick test: When printing identically rotated Basis in 3.x and 4.0 dev they
|
||||
# really seem to output differently ordered values.
|
||||
# Can live with this, so...
|
||||
|
||||
transform = Transform3D(basisTemp.transposed(), origin)
|
||||
33
tests/cubic_slerp/Main_only_match.gd
Normal file
33
tests/cubic_slerp/Main_only_match.gd
Normal file
@@ -0,0 +1,33 @@
|
||||
extends Node3D
|
||||
|
||||
@export var replaySpeed:float = 1
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
|
||||
if Input.is_action_just_pressed("reset_playback"):
|
||||
$AnimationPlayer.seek(0, true)
|
||||
$DebugTraces_slerp.clear()
|
||||
$DebugTraces_cubic_slerp.clear()
|
||||
|
||||
$Label_PlaybackPos.text = " %1.2f s (%1.1f %%)" % [$AnimationPlayer.current_animation_position, 100.0 * ($AnimationPlayer.current_animation_position / $AnimationPlayer.current_animation_length)]
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey and event.pressed:
|
||||
var keyEvent:InputEventKey = event
|
||||
if (keyEvent.keycode == KEY_0):
|
||||
replaySpeed = 0
|
||||
$AnimationPlayer.playback_speed = 0
|
||||
elif ((keyEvent.keycode >= KEY_1) && (keyEvent.keycode <= KEY_9)):
|
||||
var tempSpeed:float = pow(2, keyEvent.keycode - KEY_7)
|
||||
|
||||
if (Input.is_action_pressed("replay_backward")):
|
||||
tempSpeed *= -1
|
||||
|
||||
replaySpeed = tempSpeed;
|
||||
|
||||
$AnimationPlayer.playback_speed = replaySpeed
|
||||
195
tests/cubic_slerp/Main_only_match.tscn
Normal file
195
tests/cubic_slerp/Main_only_match.tscn
Normal file
@@ -0,0 +1,195 @@
|
||||
[gd_scene load_steps=21 format=3 uid="uid://boxar1mx1sjn6"]
|
||||
|
||||
[ext_resource type="Script" path="res://Main_only_match.gd" id="1_0w34i"]
|
||||
[ext_resource type="PackedScene" uid="uid://bsiv04ubiyxjr" path="res://debug_indicator.tscn" id="1_fe687"]
|
||||
[ext_resource type="PackedScene" uid="uid://b3ywvgurbetiy" path="res://FirstPersonFlyer.tscn" id="2_c50us"]
|
||||
[ext_resource type="Script" path="res://DebugTraces.gd" id="3_q672x"]
|
||||
[ext_resource type="Texture2D" uid="uid://ckmlr2jsohlh1" path="res://GreenCheckerboard.png" id="4_cq5uj"]
|
||||
|
||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_eko38"]
|
||||
sky_top_color = Color(1, 1, 1, 1)
|
||||
sky_horizon_color = Color(0.780392, 0.780392, 0.782353, 1)
|
||||
ground_bottom_color = Color(0.121569, 0.121569, 0.129412, 1)
|
||||
ground_horizon_color = Color(0.780392, 0.780392, 0.782353, 1)
|
||||
|
||||
[sub_resource type="Sky" id="Sky_00uh5"]
|
||||
sky_material = SubResource("ProceduralSkyMaterial_eko38")
|
||||
|
||||
[sub_resource type="Environment" id="Environment_5bc8l"]
|
||||
background_mode = 2
|
||||
background_energy = 0.5
|
||||
sky = SubResource("Sky_00uh5")
|
||||
tonemap_mode = 2
|
||||
sdfgi_enabled = true
|
||||
sdfgi_use_occlusion = true
|
||||
sdfgi_cascades = 1
|
||||
sdfgi_min_cell_size = 31.25
|
||||
sdfgi_cascade0_distance = 2000.0
|
||||
sdfgi_max_distance = 4000.0
|
||||
sdfgi_y_scale = 2
|
||||
glow_enabled = true
|
||||
|
||||
[sub_resource type="Animation" id="Animation_x6cxi"]
|
||||
resource_name = "Test"
|
||||
length = 54.0
|
||||
loop_mode = 1
|
||||
step = 0.5
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("slerp:quaternion")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22.1, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0, 0, 0, 1), Quaternion(0, 0, -0.707, 0.707), Quaternion(0.509045, 0.505648, -0.49089, 0.494187), Quaternion(0.707105, 0.00212132, 0.707105, 0), Quaternion(0.458449, 0.538813, 0.458986, 0.537436), Quaternion(-0.000707107, 0.707107, 0, 0.707107), Quaternion(0.707107, 0, 0, 0.707107), Quaternion(0.5, 0.5, 0.5, 0.5), Quaternion(0.790594, -0.205453, -0.449878, 0.361053), Quaternion(-0.0370055, -0.196145, 0.881975, 0.426939), Quaternion(0, 0, 0, 1), Quaternion(0, 0, 0, 1), Quaternion(0, 0, 0, 1), Quaternion(0, 0, 0, 1), Quaternion(0.707, 0, 0.707, 0), Quaternion(1, 0, 0, 0), Quaternion(-1, 0, 0, 0), Quaternion(0, 0, 0, 1), Quaternion(0, 0, -0.707, 0.707), Quaternion(0.509045, 0.505648, -0.49089, 0.494187), Quaternion(0.707, 0, 0.707, 0), Quaternion(0, 1, 0, 0), Quaternion(0, 0, 0, 1), Quaternion(1, 0, 0, 0), Quaternion(0, -0.707, 0.707, 0), Quaternion(0.707, 0, 0, 0.707), Quaternion(0, 1, 0, 0)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("cubic_slerp:quaternion")
|
||||
tracks/1/interp = 2
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22.1, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0, 0, 0, 1), Quaternion(0, 0, -0.707, 0.707), Quaternion(0.509045, 0.505648, -0.49089, 0.494187), Quaternion(0.707105, 0.00212132, 0.707105, 0), Quaternion(0.458449, 0.538813, 0.458986, 0.537436), Quaternion(-0.000707107, 0.707107, 0, 0.707107), Quaternion(0.707107, 0, 0, 0.707107), Quaternion(0.5, 0.5, 0.5, 0.5), Quaternion(0.790594, -0.205453, -0.449878, 0.361053), Quaternion(-0.0370055, -0.196145, 0.881975, 0.426939), Quaternion(0, 0, 0, 1), Quaternion(0, 0, 0, 1), Quaternion(0, 0, 0, 1), Quaternion(0, 0, 0, 1), Quaternion(0.707, 0, 0.707, 0), Quaternion(1, 0, 0, 0), Quaternion(-1, 0, 0, 0), Quaternion(0, 0, 0, 1), Quaternion(0, 0, -0.707, 0.707), Quaternion(0.509045, 0.505648, -0.49089, 0.494187), Quaternion(0.707, 0, 0.707, 0), Quaternion(0, 1, 0, 0), Quaternion(0, 0, 0, 1), Quaternion(1, 0, 0, 0), Quaternion(0, -0.707, 0.707, 0), Quaternion(0.707, 0, 0, 0.707), Quaternion(0, 1, 0, 0)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("lastKey:quaternion")
|
||||
tracks/2/interp = 0
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20.1, 22, 24, 26, 28.0035, 29.9957, 32, 34, 36, 38, 40, 42, 44, 45.9624, 48, 50, 52),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0, 0, -0.707, 0.707), Quaternion(0.509045, 0.505648, -0.49089, 0.494187), Quaternion(0.707105, 0.00212132, 0.707105, 0), Quaternion(0.458449, 0.538813, 0.458986, 0.537436), Quaternion(-0.000707107, 0.707107, 0, 0.707107), Quaternion(0.707107, 0, 0, 0.707107), Quaternion(0.5, 0.5, 0.5, 0.5), Quaternion(0.790594, -0.205453, -0.449878, 0.361053), Quaternion(-0.0370055, -0.196145, 0.881975, 0.426939), Quaternion(0, 0, 0, 1), Quaternion(0, 0, 0, 1), Quaternion(0, 0, 0, 1), Quaternion(0, 0, 0, 1), Quaternion(0.707, 0, 0.707, 0), Quaternion(1, 0, 0, 0), Quaternion(-1, 0, 0, 0), Quaternion(0, 0, 0, 1), Quaternion(0, 0, -0.707, 0.707), Quaternion(0.509045, 0.505648, -0.49089, 0.494187), Quaternion(0.707105, 0.00212132, 0.707105, 0), Quaternion(0, 1, 0, 0), Quaternion(0, 0, 0, 1), Quaternion(1, 0, 0, 0), Quaternion(0, -0.707, 0.707, 0), Quaternion(0.707, 0, 0, 0.707), Quaternion(0, 1, 0, 0), Quaternion(0, 0, 0, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_igpm5"]
|
||||
_data = {
|
||||
"Test": SubResource("Animation_x6cxi")
|
||||
}
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_erogr"]
|
||||
shading_mode = 0
|
||||
vertex_color_use_as_albedo = true
|
||||
use_point_size = true
|
||||
point_size = 5.0
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_86kc0"]
|
||||
albedo_color = Color(1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_jr4ad"]
|
||||
material = SubResource("StandardMaterial3D_86kc0")
|
||||
size = Vector3(0.4, 0.4, 0.4)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_r0uvn"]
|
||||
shading_mode = 0
|
||||
albedo_color = Color(1, 1, 0, 1)
|
||||
use_point_size = true
|
||||
point_size = 5.0
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fhh1v"]
|
||||
albedo_color = Color(0, 1, 0, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_4dbh4"]
|
||||
material = SubResource("StandardMaterial3D_fhh1v")
|
||||
size = Vector3(0.4, 0.4, 0.4)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_u5htn"]
|
||||
albedo_color = Color(0, 0, 1, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_j2fwk"]
|
||||
material = SubResource("StandardMaterial3D_u5htn")
|
||||
size = Vector3(0.4, 0.4, 0.4)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bdqjc"]
|
||||
transparency = 1
|
||||
albedo_color = Color(1, 1, 1, 0.0313726)
|
||||
albedo_texture = ExtResource("4_cq5uj")
|
||||
uv1_scale = Vector3(32, 32, 32)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_kiq8u"]
|
||||
material = SubResource("StandardMaterial3D_bdqjc")
|
||||
size = Vector3(100, 1, 100)
|
||||
|
||||
[node name="Main" type="Node3D"]
|
||||
script = ExtResource("1_0w34i")
|
||||
replaySpeed = 1.0
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0)
|
||||
shadow_enabled = true
|
||||
directional_shadow_max_distance = 250.0
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource("Environment_5bc8l")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
autoplay = "Test"
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_igpm5")
|
||||
}
|
||||
|
||||
[node name="DebugTraces_slerp" type="MeshInstance3D" parent="."]
|
||||
visible = false
|
||||
skeleton = NodePath("../slerp")
|
||||
script = ExtResource("3_q672x")
|
||||
pointMaterial = SubResource("StandardMaterial3D_erogr")
|
||||
tipHistoryLength = 120
|
||||
debugIndicatorPath = "../slerp/DebugIndicator"
|
||||
|
||||
[node name="slerp" type="Node3D" parent="."]
|
||||
transform = Transform3D(0.50142, 0, 0.865203, 0, -0.999999, 0, 0.865204, 0, -0.501419, 0, 0, 0)
|
||||
rotation_edit_mode = 1
|
||||
visible = false
|
||||
|
||||
[node name="DebugIndicator" parent="slerp" instance=ExtResource("1_fe687")]
|
||||
|
||||
[node name="Box" type="MeshInstance3D" parent="slerp"]
|
||||
mesh = SubResource("BoxMesh_jr4ad")
|
||||
|
||||
[node name="DebugTraces_cubic_slerp" type="MeshInstance3D" parent="."]
|
||||
skeleton = NodePath("../slerp")
|
||||
script = ExtResource("3_q672x")
|
||||
pointMaterial = SubResource("StandardMaterial3D_r0uvn")
|
||||
tipHistoryLength = 120
|
||||
debugIndicatorPath = "../cubic_slerp/DebugIndicator"
|
||||
|
||||
[node name="cubic_slerp" type="Node3D" parent="."]
|
||||
transform = Transform3D(0.410949, 0.0794689, 0.908187, -0.0794688, -0.989279, 0.122524, 0.908187, -0.122524, -0.400228, 0, 0, 0)
|
||||
rotation_edit_mode = 1
|
||||
|
||||
[node name="DebugIndicator" parent="cubic_slerp" instance=ExtResource("1_fe687")]
|
||||
|
||||
[node name="Box" type="MeshInstance3D" parent="cubic_slerp"]
|
||||
mesh = SubResource("BoxMesh_4dbh4")
|
||||
|
||||
[node name="lastKey" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 2.1, 0)
|
||||
rotation_edit_mode = 1
|
||||
|
||||
[node name="DebugIndicator" parent="lastKey" instance=ExtResource("1_fe687")]
|
||||
|
||||
[node name="Box" type="MeshInstance3D" parent="lastKey"]
|
||||
mesh = SubResource("BoxMesh_j2fwk")
|
||||
|
||||
[node name="FirstPersonFlyer" parent="." instance=ExtResource("2_c50us")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 6)
|
||||
|
||||
[node name="Ground" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.69822, 0)
|
||||
mesh = SubResource("BoxMesh_kiq8u")
|
||||
|
||||
[node name="Label_PlaybackPos" type="Label" parent="."]
|
||||
anchor_top = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = -23.0
|
||||
offset_right = 137.0
|
||||
grow_vertical = 0
|
||||
39
tests/cubic_slerp/Main_only_script.gd
Normal file
39
tests/cubic_slerp/Main_only_script.gd
Normal file
@@ -0,0 +1,39 @@
|
||||
extends Node3D
|
||||
|
||||
@export var replayTime:float = 0
|
||||
@export var replaySpeed:float = 1
|
||||
@export var replayTimeLoopStart = 0
|
||||
@export var replayTimeLoopEnd = 100 * 1000
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
replayTime += delta * 1000 * replaySpeed
|
||||
if (replayTime > replayTimeLoopEnd):
|
||||
replayTime = replayTimeLoopStart
|
||||
if (replayTime < replayTimeLoopStart):
|
||||
replayTime = replayTimeLoopEnd
|
||||
|
||||
if Input.is_action_just_pressed("reset_playback"):
|
||||
replayTime = replayTimeLoopStart
|
||||
$DebugTraces_LOScript_slerp.clear()
|
||||
$DebugTraces_LOScript_cubic_slerp.clear()
|
||||
|
||||
$Label_PlaybackPos.text = " %1.2f s (%1.1f %%)" % [((replayTime - replayTimeLoopStart) / 1000), 100.0 * ((replayTime - replayTimeLoopStart) / (replayTimeLoopEnd - replayTimeLoopStart))]
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey and event.pressed:
|
||||
var keyEvent:InputEventKey = event
|
||||
if (keyEvent.keycode == KEY_0):
|
||||
replaySpeed = 0
|
||||
elif ((keyEvent.keycode >= KEY_1) && (keyEvent.keycode <= KEY_9)):
|
||||
var tempSpeed:float = pow(2, keyEvent.keycode - KEY_7)
|
||||
|
||||
if (Input.is_action_pressed("replay_backward")):
|
||||
tempSpeed *= -1
|
||||
|
||||
replaySpeed = tempSpeed;
|
||||
|
||||
209
tests/cubic_slerp/Main_only_script.tscn
Normal file
209
tests/cubic_slerp/Main_only_script.tscn
Normal file
@@ -0,0 +1,209 @@
|
||||
[gd_scene load_steps=21 format=3 uid="uid://h0niudrbg7j3"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bsiv04ubiyxjr" path="res://debug_indicator.tscn" id="1_fe687"]
|
||||
[ext_resource type="Script" path="res://Main_only_script.gd" id="1_rnfxm"]
|
||||
[ext_resource type="PackedScene" uid="uid://b3ywvgurbetiy" path="res://FirstPersonFlyer.tscn" id="2_c50us"]
|
||||
[ext_resource type="Script" path="res://DebugTraces.gd" id="3_q672x"]
|
||||
[ext_resource type="Texture2D" uid="uid://ckmlr2jsohlh1" path="res://GreenCheckerboard.png" id="4_cq5uj"]
|
||||
[ext_resource type="Script" path="res://LOScriptReplayer_Node3D.gd" id="5_bviin"]
|
||||
[ext_resource type="Script" path="res://DebugLines.gd" id="6_nec70"]
|
||||
[ext_resource type="PackedScene" uid="uid://dgfq0cgjlpn7x" path="res://debug_indicator_TipsOnly.tscn" id="6_tilwc"]
|
||||
|
||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_eko38"]
|
||||
sky_top_color = Color(1, 1, 1, 1)
|
||||
sky_horizon_color = Color(0.780392, 0.780392, 0.782353, 1)
|
||||
ground_bottom_color = Color(0.121569, 0.121569, 0.129412, 1)
|
||||
ground_horizon_color = Color(0.780392, 0.780392, 0.782353, 1)
|
||||
|
||||
[sub_resource type="Sky" id="Sky_00uh5"]
|
||||
sky_material = SubResource("ProceduralSkyMaterial_eko38")
|
||||
|
||||
[sub_resource type="Environment" id="Environment_5bc8l"]
|
||||
background_mode = 2
|
||||
background_energy = 0.5
|
||||
sky = SubResource("Sky_00uh5")
|
||||
tonemap_mode = 2
|
||||
sdfgi_enabled = true
|
||||
sdfgi_use_occlusion = true
|
||||
sdfgi_cascades = 1
|
||||
sdfgi_min_cell_size = 31.25
|
||||
sdfgi_cascade0_distance = 2000.0
|
||||
sdfgi_max_distance = 4000.0
|
||||
sdfgi_y_scale = 2
|
||||
glow_enabled = true
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bdqjc"]
|
||||
transparency = 1
|
||||
albedo_color = Color(1, 1, 1, 0.0313726)
|
||||
albedo_texture = ExtResource("4_cq5uj")
|
||||
uv1_scale = Vector3(32, 32, 32)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_kiq8u"]
|
||||
material = SubResource("StandardMaterial3D_bdqjc")
|
||||
size = Vector3(100, 1, 100)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_dcyws"]
|
||||
shading_mode = 0
|
||||
vertex_color_use_as_albedo = true
|
||||
use_point_size = true
|
||||
point_size = 5.0
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1uw0r"]
|
||||
shading_mode = 0
|
||||
albedo_color = Color(1, 1, 0, 1)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_86kc0"]
|
||||
albedo_color = Color(1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_jr4ad"]
|
||||
material = SubResource("StandardMaterial3D_86kc0")
|
||||
size = Vector3(0.4, 0.4, 0.4)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cui2m"]
|
||||
shading_mode = 0
|
||||
albedo_color = Color(1, 1, 0, 1)
|
||||
use_point_size = true
|
||||
point_size = 5.0
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fhh1v"]
|
||||
albedo_color = Color(0, 1, 0, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_4dbh4"]
|
||||
material = SubResource("StandardMaterial3D_fhh1v")
|
||||
size = Vector3(0.4, 0.4, 0.4)
|
||||
|
||||
[node name="Main" type="Node3D"]
|
||||
script = ExtResource("1_rnfxm")
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0)
|
||||
shadow_enabled = true
|
||||
directional_shadow_max_distance = 250.0
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource("Environment_5bc8l")
|
||||
|
||||
[node name="FirstPersonFlyer" parent="." instance=ExtResource("2_c50us")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0229836, 3.18882)
|
||||
|
||||
[node name="Ground" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.69822, 0)
|
||||
mesh = SubResource("BoxMesh_kiq8u")
|
||||
|
||||
[node name="DebugTraces_LOScript_slerp" type="MeshInstance3D" parent="."]
|
||||
visible = false
|
||||
skeleton = NodePath("")
|
||||
script = ExtResource("3_q672x")
|
||||
pointMaterial = SubResource("StandardMaterial3D_dcyws")
|
||||
tipHistoryLength = 120
|
||||
debugIndicatorPath = "../LOScriptReplayerGroup_slerp/LOSolver_Interpolated/DebugIndicator"
|
||||
|
||||
[node name="DebugLines_LOScript_slerp" type="MeshInstance3D" parent="."]
|
||||
visible = false
|
||||
skeleton = NodePath("")
|
||||
script = ExtResource("6_nec70")
|
||||
lineMaterial = SubResource("StandardMaterial3D_1uw0r")
|
||||
debugIndicatorPath = "../LOScriptReplayerGroup_slerp"
|
||||
|
||||
[node name="LOScriptReplayerGroup_slerp" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.707107, -0.707107, 0, 0.707107, 0.707107, 0, 0, 0)
|
||||
|
||||
[node name="LOSolver_Interpolated" type="Node3D" parent="LOScriptReplayerGroup_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_slerp/LOSolver_Interpolated" instance=ExtResource("1_fe687")]
|
||||
|
||||
[node name="Box" type="MeshInstance3D" parent="LOScriptReplayerGroup_slerp/LOSolver_Interpolated"]
|
||||
mesh = SubResource("BoxMesh_jr4ad")
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="LOSolver_PreA" type="Node3D" parent="LOScriptReplayerGroup_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
quatInterpolationMethod = 0
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_slerp/LOSolver_PreA" instance=ExtResource("6_tilwc")]
|
||||
|
||||
[node name="LOSolver_A" type="Node3D" parent="LOScriptReplayerGroup_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
quatInterpolationMethod = 1
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_slerp/LOSolver_A" instance=ExtResource("6_tilwc")]
|
||||
|
||||
[node name="LOSolver_B" type="Node3D" parent="LOScriptReplayerGroup_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
quatInterpolationMethod = 2
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_slerp/LOSolver_B" instance=ExtResource("6_tilwc")]
|
||||
|
||||
[node name="LOSolver_PostB" type="Node3D" parent="LOScriptReplayerGroup_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
quatInterpolationMethod = 3
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_slerp/LOSolver_PostB" instance=ExtResource("6_tilwc")]
|
||||
|
||||
[node name="DebugTraces_LOScript_cubic_slerp" type="MeshInstance3D" parent="."]
|
||||
skeleton = NodePath("")
|
||||
script = ExtResource("3_q672x")
|
||||
pointMaterial = SubResource("StandardMaterial3D_cui2m")
|
||||
tipHistoryLength = 120
|
||||
debugIndicatorPath = "../LOScriptReplayerGroup_cubic_slerp/LOSolver_Interpolated/DebugIndicator"
|
||||
|
||||
[node name="DebugLines_LOScript_cubic_slerp" type="MeshInstance3D" parent="."]
|
||||
skeleton = NodePath("")
|
||||
script = ExtResource("6_nec70")
|
||||
lineMaterial = SubResource("StandardMaterial3D_1uw0r")
|
||||
debugIndicatorPath = "../LOScriptReplayerGroup_cubic_slerp"
|
||||
|
||||
[node name="LOScriptReplayerGroup_cubic_slerp" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.707107, -0.707107, 0, 0.707107, 0.707107, 0, 0, 0)
|
||||
|
||||
[node name="LOSolver_Interpolated" type="Node3D" parent="LOScriptReplayerGroup_cubic_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
quatInterpolationMethod = 7
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_cubic_slerp/LOSolver_Interpolated" instance=ExtResource("1_fe687")]
|
||||
|
||||
[node name="Box" type="MeshInstance3D" parent="LOScriptReplayerGroup_cubic_slerp/LOSolver_Interpolated"]
|
||||
mesh = SubResource("BoxMesh_4dbh4")
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="LOSolver_PreA" type="Node3D" parent="LOScriptReplayerGroup_cubic_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
quatInterpolationMethod = 0
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_cubic_slerp/LOSolver_PreA" instance=ExtResource("6_tilwc")]
|
||||
|
||||
[node name="LOSolver_A" type="Node3D" parent="LOScriptReplayerGroup_cubic_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
quatInterpolationMethod = 1
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_cubic_slerp/LOSolver_A" instance=ExtResource("6_tilwc")]
|
||||
|
||||
[node name="LOSolver_B" type="Node3D" parent="LOScriptReplayerGroup_cubic_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
quatInterpolationMethod = 2
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_cubic_slerp/LOSolver_B" instance=ExtResource("6_tilwc")]
|
||||
|
||||
[node name="LOSolver_PostB" type="Node3D" parent="LOScriptReplayerGroup_cubic_slerp"]
|
||||
script = ExtResource("5_bviin")
|
||||
loFilename = "res://ObjectWiggle_Object.LOScript"
|
||||
quatInterpolationMethod = 3
|
||||
|
||||
[node name="DebugIndicator" parent="LOScriptReplayerGroup_cubic_slerp/LOSolver_PostB" instance=ExtResource("6_tilwc")]
|
||||
|
||||
[node name="Label_PlaybackPos" type="Label" parent="."]
|
||||
anchor_top = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = -23.0
|
||||
offset_right = 40.0
|
||||
grow_vertical = 0
|
||||
1462
tests/cubic_slerp/ObjectWiggle_Object.LOScript
Normal file
1462
tests/cubic_slerp/ObjectWiggle_Object.LOScript
Normal file
File diff suppressed because it is too large
Load Diff
7
tests/cubic_slerp/README.md
Normal file
7
tests/cubic_slerp/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# godot-40592
|
||||
|
||||
Test project from https://github.com/godotengine/godot/issues/40592
|
||||
|
||||
## Bindings
|
||||
|
||||
Press control to fly.
|
||||
116
tests/cubic_slerp/debug_indicator.tscn
Normal file
116
tests/cubic_slerp/debug_indicator.tscn
Normal file
@@ -0,0 +1,116 @@
|
||||
[gd_scene load_steps=13 format=3 uid="uid://bsiv04ubiyxjr"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_os3na"]
|
||||
albedo_color = Color(1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_4kib1"]
|
||||
material = SubResource("StandardMaterial3D_os3na")
|
||||
top_radius = 0.05
|
||||
bottom_radius = 0.05
|
||||
height = 0.8
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_hcck1"]
|
||||
albedo_color = Color(1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_bn27b"]
|
||||
material = SubResource("StandardMaterial3D_hcck1")
|
||||
top_radius = 0.001
|
||||
bottom_radius = 0.1
|
||||
height = 0.2
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_b3p13"]
|
||||
albedo_color = Color(0, 1, 0, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_4wg8y"]
|
||||
material = SubResource("StandardMaterial3D_b3p13")
|
||||
top_radius = 0.05
|
||||
bottom_radius = 0.05
|
||||
height = 0.8
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ke7xm"]
|
||||
albedo_color = Color(0, 1, 0, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_nnl2u"]
|
||||
material = SubResource("StandardMaterial3D_ke7xm")
|
||||
top_radius = 0.001
|
||||
bottom_radius = 0.1
|
||||
height = 0.2
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0kox7"]
|
||||
albedo_color = Color(0, 0, 1, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_xbf7f"]
|
||||
material = SubResource("StandardMaterial3D_0kox7")
|
||||
top_radius = 0.05
|
||||
bottom_radius = 0.05
|
||||
height = 0.8
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ekuhs"]
|
||||
albedo_color = Color(0, 0, 1, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_bbh0s"]
|
||||
material = SubResource("StandardMaterial3D_ekuhs")
|
||||
top_radius = 0.001
|
||||
bottom_radius = 0.1
|
||||
height = 0.2
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[node name="DebugIndicator" type="Node3D"]
|
||||
|
||||
[node name="XAxis" type="Node3D" parent="."]
|
||||
transform = Transform3D(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0)
|
||||
|
||||
[node name="Cone" type="MeshInstance3D" parent="XAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0)
|
||||
mesh = SubResource("CylinderMesh_4kib1")
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipCone" type="MeshInstance3D" parent="XAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
|
||||
mesh = SubResource("CylinderMesh_bn27b")
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipEnd" type="Node3D" parent="XAxis"]
|
||||
transform = Transform3D(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
|
||||
|
||||
[node name="YAxis" type="Node3D" parent="."]
|
||||
|
||||
[node name="Cone" type="MeshInstance3D" parent="YAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0)
|
||||
mesh = SubResource("CylinderMesh_4wg8y")
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipCone" type="MeshInstance3D" parent="YAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
|
||||
mesh = SubResource("CylinderMesh_nnl2u")
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipEnd" type="Node3D" parent="YAxis"]
|
||||
transform = Transform3D(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
|
||||
|
||||
[node name="ZAxis" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0)
|
||||
|
||||
[node name="Cone" type="MeshInstance3D" parent="ZAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0)
|
||||
mesh = SubResource("CylinderMesh_xbf7f")
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipCone" type="MeshInstance3D" parent="ZAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
|
||||
mesh = SubResource("CylinderMesh_bbh0s")
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipEnd" type="Node3D" parent="ZAxis"]
|
||||
transform = Transform3D(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
|
||||
176
tests/cubic_slerp/debug_indicator_TipsOnly.tscn
Normal file
176
tests/cubic_slerp/debug_indicator_TipsOnly.tscn
Normal file
@@ -0,0 +1,176 @@
|
||||
[gd_scene load_steps=19 format=3 uid="uid://dgfq0cgjlpn7x"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_os3na"]
|
||||
albedo_color = Color(1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_4kib1"]
|
||||
material = SubResource( "StandardMaterial3D_os3na" )
|
||||
top_radius = 0.05
|
||||
bottom_radius = 0.05
|
||||
height = 0.8
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_hcck1"]
|
||||
transparency = 1
|
||||
albedo_color = Color(1, 0, 0, 0.501961)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_bn27b"]
|
||||
material = SubResource( "StandardMaterial3D_hcck1" )
|
||||
top_radius = 0.001
|
||||
bottom_radius = 0.1
|
||||
height = 0.2
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gujtq"]
|
||||
transparency = 1
|
||||
shading_mode = 0
|
||||
albedo_color = Color(1, 0, 0, 0.501961)
|
||||
|
||||
[sub_resource type="SphereMesh" id="SphereMesh_pq4sr"]
|
||||
material = SubResource( "StandardMaterial3D_gujtq" )
|
||||
radius = 0.025
|
||||
height = 0.05
|
||||
radial_segments = 8
|
||||
rings = 4
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_b3p13"]
|
||||
albedo_color = Color(0, 1, 0, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_4wg8y"]
|
||||
material = SubResource( "StandardMaterial3D_b3p13" )
|
||||
top_radius = 0.05
|
||||
bottom_radius = 0.05
|
||||
height = 0.8
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ke7xm"]
|
||||
transparency = 1
|
||||
albedo_color = Color(0, 1, 0, 0.501961)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_nnl2u"]
|
||||
material = SubResource( "StandardMaterial3D_ke7xm" )
|
||||
top_radius = 0.001
|
||||
bottom_radius = 0.1
|
||||
height = 0.2
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_caeuv"]
|
||||
transparency = 1
|
||||
shading_mode = 0
|
||||
albedo_color = Color(0, 1, 0, 0.501961)
|
||||
|
||||
[sub_resource type="SphereMesh" id="SphereMesh_bxc3p"]
|
||||
material = SubResource( "StandardMaterial3D_caeuv" )
|
||||
radius = 0.025
|
||||
height = 0.05
|
||||
radial_segments = 8
|
||||
rings = 4
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0kox7"]
|
||||
albedo_color = Color(0, 0, 1, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_xbf7f"]
|
||||
material = SubResource( "StandardMaterial3D_0kox7" )
|
||||
top_radius = 0.05
|
||||
bottom_radius = 0.05
|
||||
height = 0.8
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ekuhs"]
|
||||
transparency = 1
|
||||
albedo_color = Color(0, 0, 1, 0.501961)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_bbh0s"]
|
||||
material = SubResource( "StandardMaterial3D_ekuhs" )
|
||||
top_radius = 0.001
|
||||
bottom_radius = 0.1
|
||||
height = 0.2
|
||||
radial_segments = 8
|
||||
rings = 1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_rm88u"]
|
||||
transparency = 1
|
||||
shading_mode = 0
|
||||
albedo_color = Color(0, 0, 1, 0.501961)
|
||||
|
||||
[sub_resource type="SphereMesh" id="SphereMesh_b1oof"]
|
||||
material = SubResource( "StandardMaterial3D_rm88u" )
|
||||
radius = 0.025
|
||||
height = 0.05
|
||||
radial_segments = 8
|
||||
rings = 4
|
||||
|
||||
[node name="DebugIndicator" type="Node3D"]
|
||||
|
||||
[node name="XAxis" type="Node3D" parent="."]
|
||||
transform = Transform3D(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0)
|
||||
|
||||
[node name="Cone" type="MeshInstance3D" parent="XAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0)
|
||||
visible = false
|
||||
mesh = SubResource( "CylinderMesh_4kib1" )
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipCone" type="MeshInstance3D" parent="XAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
|
||||
visible = false
|
||||
mesh = SubResource( "CylinderMesh_bn27b" )
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipEnd" type="Node3D" parent="XAxis"]
|
||||
transform = Transform3D(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
|
||||
|
||||
[node name="TipPoint" type="MeshInstance3D" parent="XAxis/TipEnd"]
|
||||
transform = Transform3D(0, -1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0)
|
||||
mesh = SubResource( "SphereMesh_pq4sr" )
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="YAxis" type="Node3D" parent="."]
|
||||
|
||||
[node name="Cone" type="MeshInstance3D" parent="YAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0)
|
||||
visible = false
|
||||
mesh = SubResource( "CylinderMesh_4wg8y" )
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipCone" type="MeshInstance3D" parent="YAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
|
||||
visible = false
|
||||
mesh = SubResource( "CylinderMesh_nnl2u" )
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipEnd" type="Node3D" parent="YAxis"]
|
||||
transform = Transform3D(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
|
||||
|
||||
[node name="TipPoint" type="MeshInstance3D" parent="YAxis/TipEnd"]
|
||||
transform = Transform3D(0, -1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0)
|
||||
mesh = SubResource( "SphereMesh_bxc3p" )
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="ZAxis" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0)
|
||||
|
||||
[node name="Cone" type="MeshInstance3D" parent="ZAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0)
|
||||
visible = false
|
||||
mesh = SubResource( "CylinderMesh_xbf7f" )
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipCone" type="MeshInstance3D" parent="ZAxis"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
|
||||
visible = false
|
||||
mesh = SubResource( "CylinderMesh_bbh0s" )
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="TipEnd" type="Node3D" parent="ZAxis"]
|
||||
transform = Transform3D(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
|
||||
|
||||
[node name="TipPoint" type="MeshInstance3D" parent="ZAxis/TipEnd"]
|
||||
transform = Transform3D(0, -1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0)
|
||||
mesh = SubResource( "SphereMesh_b1oof" )
|
||||
skeleton = NodePath("../..")
|
||||
BIN
tests/cubic_slerp/icon.png
Normal file
BIN
tests/cubic_slerp/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
33
tests/cubic_slerp/icon.png.import
Normal file
33
tests/cubic_slerp/icon.png.import
Normal file
@@ -0,0 +1,33 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c1gxgrweyd7jr"
|
||||
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
117
tests/cubic_slerp/project.godot
Normal file
117
tests/cubic_slerp/project.godot
Normal file
@@ -0,0 +1,117 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Quat Cubic Slerp Issue"
|
||||
run/main_scene="res://Main_only_script.tscn"
|
||||
config/features=PackedStringArray("4.0", "Vulkan Clustered")
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=600
|
||||
|
||||
[input]
|
||||
|
||||
toggle_mouse={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":16777238,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
mouse_left={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
mouse_right={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_forward={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_backward={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_left={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_up={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_down={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
6dof_rotate_z_right={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
6dof_rotate_z_left={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
movement_speed_down={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":71,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
movement_speed_down_mousewheel={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":5,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
movement_speed_up={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":84,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
movement_speed_up_mousewheel={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":4,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
switch_navigation_mode={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":16777218,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
replay_backward={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":16777237,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
reset_playback={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"store_command":true,"alt_pressed":false,"shift_pressed":false,"meta_pressed":false,"command_pressed":false,"pressed":false,"keycode":0,"physical_keycode":16777220,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[rendering]
|
||||
|
||||
anti_aliasing/quality/msaa=3
|
||||
2
tests/cubic_slerp_small/.gitattributes
vendored
Normal file
2
tests/cubic_slerp_small/.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Normalize EOL for all files that Git considers text files.
|
||||
* text=auto eol=lf
|
||||
2
tests/cubic_slerp_small/.gitignore
vendored
Normal file
2
tests/cubic_slerp_small/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
BIN
tests/cubic_slerp_small/icon.png
Normal file
BIN
tests/cubic_slerp_small/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
34
tests/cubic_slerp_small/icon.png.import
Normal file
34
tests/cubic_slerp_small/icon.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture2D"
|
||||
uid="uid://dglx7oykmbhse"
|
||||
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
compress/streamed=false
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
127
tests/cubic_slerp_small/node_3d.tscn
Normal file
127
tests/cubic_slerp_small/node_3d.tscn
Normal file
@@ -0,0 +1,127 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://do0yfibxleg14"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4eswk"]
|
||||
albedo_color = Color(0, 1, 0, 1)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ffia4"]
|
||||
albedo_color = Color(1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_dhgvt"]
|
||||
albedo_color = Color(0, 0, 1, 1)
|
||||
|
||||
[sub_resource type="Animation" id="Animation_l45ir"]
|
||||
resource_name = "New Anim"
|
||||
length = 3.0
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("gizmo:quaternion")
|
||||
tracks/0/interp = 2
|
||||
tracks/0/loop_wrap = false
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0.5, 1.2, 2.1, 2.8),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0.991445, 0, 0, 0.130526), Quaternion(-0.41709, 0, 0, 0.908865), Quaternion(0, 0, 0, 1), Quaternion(0.991445, 0, 0, -0.130526)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("gizmo2:quaternion")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = false
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0.5, 1.2, 2.1, 2.8),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0.991, 0, 0, 0.131), Quaternion(-0.417, 0, 0, 0.909), Quaternion(0, 0, 0, 1), Quaternion(0.991, 0, 0, -0.131)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_7v8ca"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("gizmo:rotation")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector3(3.14159, 0, 0)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("gizmo:quaternion")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0, 0, 0, 1)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("gizmo2:quaternion")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0, 0, 0, 1)]
|
||||
}
|
||||
|
||||
[node name="Node3D" type="Node3D"]
|
||||
|
||||
[node name="gizmo" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, -1, -2.53518e-06, 0, 2.53518e-06, -1, 0, 0, 1)
|
||||
rotation_edit_mode = 1
|
||||
|
||||
[node name="CSGBox3D" type="CSGBox3D" parent="gizmo"]
|
||||
size = Vector3(0.2, 0.2, 0.2)
|
||||
|
||||
[node name="CSGBox3D2" type="CSGBox3D" parent="gizmo"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
||||
size = Vector3(0.05, 1, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_4eswk" )
|
||||
|
||||
[node name="CSGBox3D3" type="CSGBox3D" parent="gizmo"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 0)
|
||||
size = Vector3(1, 0.05, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_ffia4" )
|
||||
|
||||
[node name="CSGBox3D4" type="CSGBox3D" parent="gizmo"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5)
|
||||
size = Vector3(0.05, 0.05, 1)
|
||||
material = SubResource( "StandardMaterial3D_dhgvt" )
|
||||
|
||||
[node name="gizmo2" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1)
|
||||
rotation_edit_mode = 1
|
||||
|
||||
[node name="CSGBox3D" type="CSGBox3D" parent="gizmo2"]
|
||||
size = Vector3(0.2, 0.2, 0.2)
|
||||
|
||||
[node name="CSGBox3D2" type="CSGBox3D" parent="gizmo2"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
||||
size = Vector3(0.05, 1, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_4eswk" )
|
||||
|
||||
[node name="CSGBox3D3" type="CSGBox3D" parent="gizmo2"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 0)
|
||||
size = Vector3(1, 0.05, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_ffia4" )
|
||||
|
||||
[node name="CSGBox3D4" type="CSGBox3D" parent="gizmo2"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5)
|
||||
size = Vector3(0.05, 0.05, 1)
|
||||
material = SubResource( "StandardMaterial3D_dhgvt" )
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
"anims/New Anim" = SubResource( "Animation_l45ir" )
|
||||
anims/RESET = SubResource( "Animation_7v8ca" )
|
||||
160
tests/cubic_slerp_small/node_3d2.tscn
Normal file
160
tests/cubic_slerp_small/node_3d2.tscn
Normal file
@@ -0,0 +1,160 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://bj1ofxj4r0q4y"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4eswk"]
|
||||
albedo_color = Color(0, 1, 0, 1)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ffia4"]
|
||||
albedo_color = Color(1, 0, 0, 1)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_dhgvt"]
|
||||
albedo_color = Color(0, 0, 1, 1)
|
||||
|
||||
[sub_resource type="Animation" id="Animation_l45ir"]
|
||||
resource_name = "New Anim"
|
||||
length = 3.0
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("gizmo:quaternion")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 3),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0, 0, 0, 1), Quaternion(0.707107, 0, 0, 0.707107)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("gizmo2:quaternion")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0.258819, 0, 0, 0.965926)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("gizmo3:quaternion")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0.5, 0, 0, 0.866025)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_7v8ca"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("gizmo:quaternion")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0, 0, 0, 1)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("gizmo2:quaternion")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0.258819, 0, 0, 0.965926)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("gizmo3:quaternion")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Quaternion(0.5, 0, 0, 0.866025)]
|
||||
}
|
||||
|
||||
[node name="Node3D" type="Node3D"]
|
||||
|
||||
[node name="gizmo" type="Node3D" parent="."]
|
||||
rotation_edit_mode = 1
|
||||
|
||||
[node name="CSGBox3D" type="CSGBox3D" parent="gizmo"]
|
||||
size = Vector3(0.2, 0.2, 0.2)
|
||||
|
||||
[node name="CSGBox3D2" type="CSGBox3D" parent="gizmo"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
||||
size = Vector3(0.05, 1, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_4eswk" )
|
||||
|
||||
[node name="CSGBox3D3" type="CSGBox3D" parent="gizmo"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 0)
|
||||
size = Vector3(1, 0.05, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_ffia4" )
|
||||
|
||||
[node name="CSGBox3D4" type="CSGBox3D" parent="gizmo"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5)
|
||||
size = Vector3(0.05, 0.05, 1)
|
||||
material = SubResource( "StandardMaterial3D_dhgvt" )
|
||||
|
||||
[node name="gizmo2" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.866025, -0.5, 0, 0.5, 0.866025, 0, 0, 0)
|
||||
rotation_edit_mode = 1
|
||||
|
||||
[node name="CSGBox3D" type="CSGBox3D" parent="gizmo2"]
|
||||
size = Vector3(0.2, 0.2, 0.2)
|
||||
|
||||
[node name="CSGBox3D2" type="CSGBox3D" parent="gizmo2"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
||||
size = Vector3(0.05, 1, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_4eswk" )
|
||||
|
||||
[node name="CSGBox3D3" type="CSGBox3D" parent="gizmo2"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 0)
|
||||
size = Vector3(1, 0.05, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_ffia4" )
|
||||
|
||||
[node name="CSGBox3D4" type="CSGBox3D" parent="gizmo2"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5)
|
||||
size = Vector3(0.05, 0.05, 1)
|
||||
material = SubResource( "StandardMaterial3D_dhgvt" )
|
||||
|
||||
[node name="gizmo3" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.5, -0.866025, 0, 0.866025, 0.5, 0, 0, 0)
|
||||
rotation_edit_mode = 1
|
||||
|
||||
[node name="CSGBox3D" type="CSGBox3D" parent="gizmo3"]
|
||||
size = Vector3(0.2, 0.2, 0.2)
|
||||
|
||||
[node name="CSGBox3D2" type="CSGBox3D" parent="gizmo3"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
||||
size = Vector3(0.05, 1, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_4eswk" )
|
||||
|
||||
[node name="CSGBox3D3" type="CSGBox3D" parent="gizmo3"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 0)
|
||||
size = Vector3(1, 0.05, 0.05)
|
||||
material = SubResource( "StandardMaterial3D_ffia4" )
|
||||
|
||||
[node name="CSGBox3D4" type="CSGBox3D" parent="gizmo3"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5)
|
||||
size = Vector3(0.05, 0.05, 1)
|
||||
material = SubResource( "StandardMaterial3D_dhgvt" )
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
"anims/New Anim" = SubResource( "Animation_l45ir" )
|
||||
anims/RESET = SubResource( "Animation_7v8ca" )
|
||||
15
tests/cubic_slerp_small/project.godot
Normal file
15
tests/cubic_slerp_small/project.godot
Normal file
@@ -0,0 +1,15 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="cubic_slerp_test"
|
||||
config/icon="res://icon.png"
|
||||
config/features=PackedStringArray("4.0", "Vulkan Clustered")
|
||||
Reference in New Issue
Block a user