I've been pulling my hair out finding why some code I have for a physics based approach to moving and rotating held objects based on the location and orientation of the player's hand in VR.
I believe the problem stems from something to do with the way Godot XR Tools handles hand rotation.
In the video below, the only important code is lines 37 and 38:
print("vector check")
print(HandMesh.global_rotation_degrees)
All I'm doing is getting the rotation of the handmesh (I also tried getting the rotation directly from the controller node itself) and printing it out.
In the video, you can see me rotating me hand to first test the z axis, then the y axis, and finally the x axis. The z and y axes work perfectly fine, ranging from -180 to 180 degrees. But then, when I print the x axis, we only see it printing from -90 to 90 degrees. When I rotate my controller past the point where the fingers are pointing straight up, the x rotation vector starts decreasing.
I believe this may be because, once the hand crosses this point of my fingers pointing straight up, Godot XR Tools represents that as the hand facing forwards but pointed slightly upwards, then rotated around the y and z axes 180 degrees, so the x axis will never actually surpass -90 to 90 degrees.
This normally wouldn't be a problem, except that I'm trying to add rotational force so that the grabbed object rotates with the hand, using the following code:
if(held_object_body):
held_object_body.linear_velocity = (global_position - held_object_point.global_position) * translational_strength * delta
held_object_body.angular_velocity = vector_angle_difference(global_rotation_degrees, held_object_body.global_rotation_degrees) * rotational_strength * delta
func vector_angle_difference(vector1: Vector3, vector2: Vector3) -> Vector3: # input 2 Vector3s of angles
var diff_x = rad_to_deg(angle_difference(deg_to_rad(vector2.x), deg_to_rad(vector1.x)))
var diff_y = rad_to_deg(angle_difference(deg_to_rad(vector2.y), deg_to_rad(vector1.y)))
var diff_z = rad_to_deg(angle_difference(deg_to_rad(vector2.z), deg_to_rad(vector1.z)))
return Vector3(diff_x, diff_y, diff_z)
So, because of this, once my hand faces in the opposite direction so that my fingertips cross that 90 degree threshold, the object I'm holding starts spinning in random directions VIOLENTLY. I believe that's due the the fact that we suddenly apply 180 degree velocities to 2 axes, but even if I slowed this down, it wouldn't fix the fact that the object shouldn't have to spin around in the first place, just because the hand crosses the x threshold I mentioned earlier.
Does anyone have any ideas to fix this? I really don't want to give up the physics based movement since I like the way it feels over simply locking objects to the player's hands, and I also have some cool ideas I want to implement with this later, something similar to Boneworks style interactions. I am open to ideas though.
video: