Hi,
i bought the leapmotion 2 weeks ago with a simple goal in mind, use the hands and finger animation data for my 3D characters.
Yesterday i began digging in the samples to see how i could dump the captured data to Blender.
Using Visual Studio, i explored the objects and found some way to output hands, palm, fingers rotations.
In the documentation i found some diagram showing the base coordinate system used by the leapmotion.
But when i load these values in blender, in quaternion format (w,x,y,z), i spent the entire day trying to find what leap finger axis correspond to the fingers axis in blender, tried all possible combinations, and only got garbage.
Some rotation values are ranged from -1.0 to +1.0, making the fingers rotate in impossible ways backward, and making multiple turns on themselves forward.
I have absolutely no idea what these quaternion values from the LeapC sdk should be used for. Couldnt find a single picture showing the actual joint axis from Leap motion fingers model, to try and map them to my skeleton.
Is there anybody here that could save me ?
This is how i get the fingers value :
fprintf(file, "f_index.01.R ");
fprintf(file, "%f ", hand->index.proximal.rotation.w);
fprintf(file, "%f ", hand->index.proximal.rotation.x);
fprintf(file, "%f ", hand->index.proximal.rotation.y);
fprintf(file, "%f", hand->index.proximal.rotation.z);
fprintf(file, "\n");
fprintf(file, "f_index.02.R ");
fprintf(file, "%f ", hand->index.intermediate.rotation.w);
fprintf(file, "%f ", hand->index.intermediate.rotation.x);
fprintf(file, "%f ", hand->index.intermediate.rotation.y);
fprintf(file, "%f", hand->index.intermediate.rotation.z);
fprintf(file, "\n");
fprintf(file, "f_index.03.R ");
fprintf(file, "%f ", hand->index.distal.rotation.w);
fprintf(file, "%f ", hand->index.distal.rotation.x);
fprintf(file, "%f ", hand->index.distal.rotation.y);
fprintf(file, "%f", hand->index.distal.rotation.z);
fprintf(file, "\n");
//middle finger
fprintf(file, "f_middle.01.R ");
fprintf(file, "%f ", hand->middle.proximal.rotation.w);
fprintf(file, "%f ", hand->middle.proximal.rotation.x);
fprintf(file, "%f ", hand->middle.proximal.rotation.y);
fprintf(file, "%f", hand->middle.proximal.rotation.z);
fprintf(file, "\n");
fprintf(file, "f_middle.02.R ");
fprintf(file, "%f ", hand->middle.intermediate.rotation.w);
fprintf(file, "%f ", hand->middle.intermediate.rotation.x);
fprintf(file, "%f ", hand->middle.intermediate.rotation.y);
fprintf(file, "%f", hand->middle.intermediate.rotation.z);
fprintf(file, "\n");
fprintf(file, "f_middle.03.R ");
fprintf(file, "%f ", hand->middle.distal.rotation.w);
fprintf(file, "%f ", hand->middle.distal.rotation.x);
fprintf(file, "%f ", hand->middle.distal.rotation.y);
fprintf(file, "%f", hand->middle.distal.rotation.z);
fprintf(file, "\n");
//ring finger
fprintf(file, "f_ring.01.R ");
fprintf(file, "%f ", hand->ring.proximal.rotation.w);
fprintf(file, "%f ", hand->ring.proximal.rotation.x);
fprintf(file, "%f ", hand->ring.proximal.rotation.y);
fprintf(file, "%f", hand->ring.proximal.rotation.z);
fprintf(file, "\n");
fprintf(file, "f_ring.02.R ");
fprintf(file, "%f ", hand->ring.intermediate.rotation.w);
fprintf(file, "%f ", hand->ring.intermediate.rotation.x);
fprintf(file, "%f ", hand->ring.intermediate.rotation.y);
fprintf(file, "%f", hand->ring.intermediate.rotation.z);
fprintf(file, "\n");
fprintf(file, "f_ring.03.R ");
fprintf(file, "%f ", hand->ring.distal.rotation.w);
fprintf(file, "%f ", hand->ring.distal.rotation.x);
fprintf(file, "%f ", hand->ring.distal.rotation.y);
fprintf(file, "%f", hand->ring.distal.rotation.z);
fprintf(file, "\n");
//pinky finger
fprintf(file, "f_pinky.01.R ");
fprintf(file, "%f ", hand->pinky.proximal.rotation.w);
fprintf(file, "%f ", hand->pinky.proximal.rotation.x);
fprintf(file, "%f ", hand->pinky.proximal.rotation.y);
fprintf(file, "%f", hand->pinky.proximal.rotation.z);
fprintf(file, "\n");
fprintf(file, "f_pinky.02.R ");
fprintf(file, "%f ", hand->pinky.intermediate.rotation.w);
fprintf(file, "%f ", hand->pinky.intermediate.rotation.x);
fprintf(file, "%f ", hand->pinky.intermediate.rotation.y);
fprintf(file, "%f", hand->pinky.intermediate.rotation.z);
fprintf(file, "\n");
fprintf(file, "f_pinky.03.R ");
fprintf(file, "%f ", hand->pinky.distal.rotation.w);
fprintf(file, "%f ", hand->pinky.distal.rotation.x);
fprintf(file, "%f ", hand->pinky.distal.rotation.y);
fprintf(file, "%f", hand->pinky.distal.rotation.z);
fprintf(file, "\n");
And this is the code i use in Blender, to load the animated values in python
import math
import bpy
ob = bpy.data.objects['metarig']
bpy.context.scene.objects.active = ob
bpy.ops.object.mode_set(mode='POSE')
bpy.ops.pose.rot_clear()
bpy.ops.pose.loc_clear()
lines = []
with open('session_0.txt') as f: lines = [line.rstrip('\n') for line in f]
print("\n\n\n------ Parsing anim file ------")
idx = 0
for line in lines :
if line == "frame_end" :
idx += 1
else :
print(str(idx) + " Processing => " + line)
channel_name, w, x, y, z = line.split(" ")
pbone = ob.pose.bones[channel_name]
pbone.rotation_quaternion[0] = float(w)
pbone.rotation_quaternion[1] = -float(x)
pbone.rotation_quaternion[2] = float(z)
#pbone.rotation_quaternion[3] = float(y)
#insert a keyframe
pbone.keyframe_insert(data_path="rotation_quaternion" ,frame=idx)
print("------ END ------")
I tried all possible tricks for x, y, z axis, thinking that i would find the good match within a few minutes, but after wasting hours on this i lost all hope :
x y z
-x y z
-x -y -z
x -y -z
etc...
And the result is always weird looking with values too big and too low at the same time.
In blender the bones are configured to use quaternion rotation, so ithought it was just a matter of finding the correct axis, but it seems the values arent in the same range, or i didnt find the good axis combination yet.
The cpp project comes from the basic tracking samples that outputs text in the console for the palm.
You can download the blend file here : https://mega.nz/#!edJWCaqY!3m8mpsn4ENQWKyAPckgyUAoXi23JTk6tiAUkJKDZ-QQ
My original intent was to make a live link with blender, but outputing to file took me less time than messing with sockets between c and python.
I want to avoid having to purchase something like brekel pro hands just to animate the hands,
https://brekel.com/brekel-pro-hands/
It costs $79, and it outputs the animations to fbx/bvh, i tried the demo version and it works as expected.
Im not a mathematics expert, i can do a certain level of programming, but when it comes to hardcore math formulas with matrices etc, i'm lost.
Thanks for the help.