Still haven't managed to make any head way on this. I've reduced the geometry of the new track mesh down to something similar to the track mesh in the example, I even imported the example's mesh into Blender to compare the normals and everything seems the same.
Example's:
My Mesh:
With the reduced geometry the erroneous behavior is even more apparent:
And again, when disabling the barycentric function so we're only using the face normals, the traveling object correctly orientates with the track.
Because everything works with the example's mesh, I'm not inclined to believe that the issue with the code itself. Never the less here's what it looks like:
Traveling Object:
extends CharacterBody3D
var target_velocity = Vector3.ZERO;
var speed = 4;
@export_category("Settings")
@export var use_bary_coords = false;
@onready var ray_cast: RayCast3D = $RayCast3D;
func _ready():
print("READY");
func _physics_process(_delta: float) -> void:
if ray_cast.is_colliding():
var other: CollisionObject3D = ray_cast.get_collider()
position.y = ray_cast.get_collision_point().y + .1
align_up_direction(ray_cast.get_collision_normal())
if ray_cast.get_collider().is_in_group("mesh_colliders") and use_bary_coords:
var vertices: Array[Vector3] = other.get_vertex_positions_at_face_index(ray_cast.get_collision_face_index())
var vertex_normals: Array[Vector3] = other.get_vertex_normals_at_face_index(ray_cast.get_collision_face_index())
var bary_coords: Vector3 = Geometry3D.get_triangle_barycentric_coords(ray_cast.get_collision_point(), vertices[0], vertices[1], vertices[2])
var up_normal: Vector3 = (vertex_normals[0] * bary_coords.x) + (vertex_normals[1] * bary_coords.y) + (vertex_normals[2] * bary_coords.z)
up_normal = up_normal.normalized()
align_up_direction(up_normal)
print(up_normal)
target_velocity.z = int(Input.is_action_pressed("ui_left")) + -int(Input.is_action_pressed("ui_right"));
velocity = target_velocity*speed;
move_and_slide();
func align_up_direction(up_normal: Vector3) -> void:
var new_basis: Basis = transform.basis
new_basis.y = up_normal
new_basis.x = -basis.z.cross(basis.y)
new_basis = new_basis.orthonormalized()
basis = new_basis
Track Object:
extends StaticBody3D
class_name TRACKOBJ_testoval
@onready var mesh: Mesh = $basic_Flat_003.mesh
var mesh_data: MeshDataTool
func _ready() -> void:
mesh_data = MeshDataTool.new()
mesh_data.create_from_surface(mesh, 0)
func get_vertex_normals_at_face_index(index: int) -> Array[Vector3]:
var normals: Array[Vector3] = []
for i in range(0, 3):
normals.append(mesh_data.get_vertex_normal(mesh_data.get_face_vertex(index, i)))
return normals
func get_vertex_positions_at_face_index(index: int) -> Array[Vector3]:
var vertices: Array[Vector3] = []
for i in range(0, 3):
vertices.append(mesh_data.get_vertex(mesh_data.get_face_vertex(index, i)))
return vertices
Maybe it's possible that the vertices are incorrectly ordered in the new track mesh? Not sure how to check that other then drawing debug geometry based on the normals and vertices arrays. Honestly I'm kinda spitballing at this point, if anyone else wants to take a crack at it here's the project file: