Needs a lot of cleanup. Data has been de-duplicated, and where identical copies existed, one of them has been replaced with a symlink. Some files have been excluded, such as binaries, installers and debug dumps. Some of that may still be present.
260 lines
9.4 KiB
JavaScript
260 lines
9.4 KiB
JavaScript
//
|
|
// leapOfFaith.js
|
|
// examples
|
|
//
|
|
// Created by Sam Cake on 6/22/14.
|
|
// Copyright 2014 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
|
|
var jointList = MyAvatar.getJointNames();
|
|
var jointMappings = "\n# Joint list start";
|
|
for (var i = 0; i < jointList.length; i++) {
|
|
jointMappings = jointMappings + "\njointIndex = " + jointList[i] + " = " + i;
|
|
}
|
|
print(jointMappings + "\n# Joint list end");
|
|
|
|
function vec3ToString( v ) {
|
|
return ("(" + v.x +", " + v.y + ", " + v.z + ")" );
|
|
}
|
|
function quatToString( q ) {
|
|
return ("(" + q.x +", " + q.y + ", " + q.z + ", " + q.w + ")" );
|
|
}
|
|
|
|
function printSpatialEvent( label, spatialEvent ) {
|
|
if ( false ){//label == "RightHandIndex1" ) {
|
|
var dataString = label + " " +
|
|
/*vec3ToString( spatialEvent.locTranslation ) + " " +
|
|
quatToString( spatialEvent.locRotation ) + " " +*/
|
|
vec3ToString( spatialEvent.absTranslation ) + " " +
|
|
quatToString( spatialEvent.absRotation );
|
|
print( dataString );
|
|
}
|
|
}
|
|
|
|
function avatarToWorldPos( apos ) {
|
|
|
|
// apply offset ?
|
|
var offset = { x: 0, y: 0.5, z: -0.5 };
|
|
var lpos = Vec3.sum(apos, offset);
|
|
|
|
var wpos = Vec3.sum( MyAvatar.position , Vec3.multiplyQbyV(MyAvatar.orientation, lpos) );
|
|
|
|
return wpos;
|
|
}
|
|
|
|
function avatarToWorldQuat( aori) {
|
|
|
|
var wori = Quat.multiply(MyAvatar.orientation, aori);
|
|
return wori;
|
|
}
|
|
|
|
function controlerToSkeletonOri( jointName, isRightSide, event ) {
|
|
|
|
var qAvatarRootOffset = Quat.angleAxis( -180, {x:0, y:1, z:0});
|
|
var qAxisOffset = Quat.angleAxis( -( 2 * isRightSide - 1) * 90, {x:0, y:1, z:0});
|
|
var qAbsJoint = event.absRotation;
|
|
|
|
|
|
return Quat.multiply( qAvatarRootOffset, Quat.multiply( qAbsJoint, qAxisOffset ) );
|
|
}
|
|
|
|
|
|
var jointShperes = [];
|
|
function updateJointShpere( joint, pos, ori, look ) {
|
|
/* print( "debug 1" );
|
|
var jointID = jointShperes[ joint ];
|
|
if ( jointID == null ) {
|
|
print( "debug create " + joint );
|
|
*/
|
|
var radius = 0.005* look.r;
|
|
var ballProperties = {
|
|
type: "Sphere",
|
|
position: pos,
|
|
velocity: { x: 0, y: 0, z: 0},
|
|
gravity: { x: 0, y: 0, z: 0 },
|
|
damping: 0,
|
|
dimensions: { x: radius, y: radius, z: radius },
|
|
color: look.c,
|
|
lifetime: 0.05
|
|
};
|
|
var atomPos = Entities.addEntity(ballProperties);
|
|
|
|
/* // Zaxis
|
|
var Zaxis = Vec3.multiply( Quat.getFront( ori ), - 1.5 * radius ) ;
|
|
ballProperties.position = Vec3.sum(pos, Zaxis );
|
|
ballProperties.radius = 0.35* radius;
|
|
ballProperties.color= { red: 255, green: 255, blue: 255 };
|
|
|
|
var atomZ = Entities.addEntity(ballProperties);
|
|
|
|
var up = Vec3.multiply( Quat.getUp( ori ), 1.5 * radius ) ;
|
|
ballProperties.position = Vec3.sum(pos, up) ;
|
|
ballProperties.dimensions = { x: 0.35* radius, y: 0.35* radius, z: 0.35* radius };
|
|
ballProperties.color= { red: 0, green: 255, blue: 0 };
|
|
|
|
var atomY = Entities.addEntity(ballProperties);
|
|
|
|
var right = Vec3.multiply( Quat.getRight( ori ), 1.5 * radius ) ;
|
|
ballProperties.position = Vec3.sum(pos, right) ;
|
|
ballProperties.dimensions = { x: 0.35* radius, y: 0.35* radius, z: 0.35* radius };
|
|
ballProperties.color= { red: 255, green: 0, blue: 225 };
|
|
|
|
var atomX = Entities.addEntity(ballProperties);
|
|
*/
|
|
// jointShperes[ joint ] = { p: atomPos, x: atomX, y: atomY, z: atomZ };
|
|
/*
|
|
} else {
|
|
//print( "debug update " + joint );
|
|
|
|
var p = Entities.getEntityProperties( jointID.p );
|
|
p.position = pos;
|
|
// p.lifetime = 1.0;
|
|
Entities.editEntity( jointID.p, p );
|
|
|
|
|
|
}*/
|
|
}
|
|
|
|
function evalArmBoneLook( isRightSide, bone ) {
|
|
return { c: { red: (255 * ( 1 - isRightSide )),
|
|
green: 255 * ( ((bone)) / 2 ),
|
|
blue: (255 * isRightSide) },
|
|
r: 3 ,
|
|
side: isRightSide };
|
|
}
|
|
|
|
function evalFingerBoneLook( isRightSide, finger, bone ) {
|
|
return { c: { red: (255 * ( 1 - isRightSide )),
|
|
green: 255 * ( ((bone - 1)) / 3 ),
|
|
blue: (255 * isRightSide) },
|
|
r: (5 + (5 - (finger-1))) / 10.0,
|
|
side: isRightSide };
|
|
}
|
|
|
|
var leapJoints = [
|
|
|
|
{ n: "joint_L_elbow", l: evalArmBoneLook( 0, 2) },
|
|
{ n: "joint_L_hand", l: evalArmBoneLook( 0, 1) },
|
|
{ n: "joint_L_wrist", l: evalArmBoneLook( 0, 0) },
|
|
|
|
{ n: "joint_L_thumb2", l: evalFingerBoneLook( 0, 1, 2) },
|
|
{ n: "joint_L_thumb3", l: evalFingerBoneLook( 0, 1, 3) },
|
|
{ n: "joint_L_thumb4", l: evalFingerBoneLook( 0, 1, 4) },
|
|
|
|
{ n: "joint_L_index1", l: evalFingerBoneLook( 0, 2, 1) },
|
|
{ n: "joint_L_index2", l: evalFingerBoneLook( 0, 2, 2) },
|
|
{ n: "joint_L_index3", l: evalFingerBoneLook( 0, 2, 3) },
|
|
{ n: "joint_L_index4", l: evalFingerBoneLook( 0, 2, 4) },
|
|
|
|
{ n: "joint_L_middle1", l: evalFingerBoneLook( 0, 3, 1) },
|
|
{ n: "joint_L_middle2", l: evalFingerBoneLook( 0, 3, 2) },
|
|
{ n: "joint_L_middle3", l: evalFingerBoneLook( 0, 3, 3) },
|
|
{ n: "joint_L_middle4", l: evalFingerBoneLook( 0, 3, 4) },
|
|
|
|
{ n: "joint_L_ring1", l: evalFingerBoneLook( 0, 4, 1) },
|
|
{ n: "joint_L_ring2", l: evalFingerBoneLook( 0, 4, 2) },
|
|
{ n: "joint_L_ring3", l: evalFingerBoneLook( 0, 4, 3) },
|
|
{ n: "joint_L_ring4", l: evalFingerBoneLook( 0, 4, 4) },
|
|
|
|
{ n: "joint_L_pinky1", l: evalFingerBoneLook( 0, 5, 1) },
|
|
{ n: "joint_L_pinky2", l: evalFingerBoneLook( 0, 5, 2) },
|
|
{ n: "joint_L_pinky3", l: evalFingerBoneLook( 0, 5, 3) },
|
|
{ n: "joint_L_pinky4", l: evalFingerBoneLook( 0, 5, 4) },
|
|
|
|
{ n: "joint_R_elbow", l: evalArmBoneLook( 1, 2) },
|
|
{ n: "joint_R_hand", l: evalArmBoneLook( 1, 1) },
|
|
{ n: "joint_R_wrist", l: evalArmBoneLook( 1, 0) },
|
|
|
|
{ n: "joint_R_thumb2", l: evalFingerBoneLook( 1, 1, 2) },
|
|
{ n: "joint_R_thumb3", l: evalFingerBoneLook( 1, 1, 3) },
|
|
{ n: "joint_R_thumb4", l: evalFingerBoneLook( 1, 1, 4) },
|
|
|
|
{ n: "joint_R_index1", l: evalFingerBoneLook( 1, 2, 1) },
|
|
{ n: "joint_R_index2", l: evalFingerBoneLook( 1, 2, 2) },
|
|
{ n: "joint_R_index3", l: evalFingerBoneLook( 1, 2, 3) },
|
|
{ n: "joint_R_index4", l: evalFingerBoneLook( 1, 2, 4) },
|
|
|
|
{ n: "joint_R_middle1", l: evalFingerBoneLook( 1, 3, 1) },
|
|
{ n: "joint_R_middle2", l: evalFingerBoneLook( 1, 3, 2) },
|
|
{ n: "joint_R_middle3", l: evalFingerBoneLook( 1, 3, 3) },
|
|
{ n: "joint_R_middle4", l: evalFingerBoneLook( 1, 3, 4) },
|
|
|
|
{ n: "joint_R_ring1", l: evalFingerBoneLook( 1, 4, 1) },
|
|
{ n: "joint_R_ring2", l: evalFingerBoneLook( 1, 4, 2) },
|
|
{ n: "joint_R_ring3", l: evalFingerBoneLook( 1, 4, 3) },
|
|
{ n: "joint_R_ring4", l: evalFingerBoneLook( 1, 4, 4) },
|
|
|
|
{ n: "joint_R_pinky1", l: evalFingerBoneLook( 1, 5, 1) },
|
|
{ n: "joint_R_pinky2", l: evalFingerBoneLook( 1, 5, 2) },
|
|
{ n: "joint_R_pinky3", l: evalFingerBoneLook( 1, 5, 3) },
|
|
{ n: "joint_R_pinky4", l: evalFingerBoneLook( 1, 5, 4) },
|
|
|
|
];
|
|
|
|
function onSpatialEventHandler( jointName, look ) {
|
|
var _jointName = jointName;
|
|
var _look = look;
|
|
var _side = look.side;
|
|
return (function( spatialEvent ) {
|
|
|
|
// THis should be the call to update the skeleton joint from
|
|
// the absolute joint transform coming from the Leap controller
|
|
// WE need a new method on MyAvatar which will ultimately call
|
|
// state.setRotationFromBindFrame(rotation, priority) in
|
|
// Avatar::simulate=>void Model::setJointState(int index, bool valid, const glm::quat& rotation, float priority)
|
|
|
|
// MyAvatar.setJointRotationFromBindSpace(_jointName, controlerToSkeletonOri( _jointName, _side, spatialEvent ));
|
|
|
|
|
|
updateJointShpere(_jointName,
|
|
avatarToWorldPos( spatialEvent.absTranslation ),
|
|
avatarToWorldQuat( spatialEvent.absRotation ),
|
|
_look );
|
|
printSpatialEvent(_jointName, spatialEvent );
|
|
});
|
|
}
|
|
|
|
var isPullingSpatialData = true;
|
|
|
|
var jointControllers = [];
|
|
for ( i in leapJoints ) {
|
|
|
|
print( leapJoints[i].n );
|
|
// In the current implementation, the LEapmotion is the only "Spatial" device
|
|
// Each jointTracker is retreived from the joint name following the rigging convention
|
|
var controller = Controller.createInputController( "Spatial", leapJoints[i].n );
|
|
var handler = onSpatialEventHandler( leapJoints[i].n, leapJoints[i].l );
|
|
jointControllers.push( { c: controller, h: handler } );
|
|
|
|
if ( ! isPullingSpatialData ) {
|
|
controller.spatialEvent.connect( handler );
|
|
}
|
|
}
|
|
|
|
|
|
Script.update.connect(function(deltaTime) {
|
|
|
|
if ( isPullingSpatialData )
|
|
{
|
|
for ( i in jointControllers ) {
|
|
if ( jointControllers[i].c.isActive() ) {
|
|
var spatialEvent = { absTranslation: jointControllers[i].c.getAbsTranslation(),
|
|
absRotation: jointControllers[i].c.getAbsRotation(),
|
|
locTranslation: jointControllers[i].c.getLocTranslation(),
|
|
locRotation: jointControllers[i].c.getLocRotation() };
|
|
jointControllers[i].h( spatialEvent );
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
Script.scriptEnding.connect(function() {
|
|
var i;
|
|
for (i = 0; i < jointControllers.length; i += 1) {
|
|
Controller.releaseInputController(jointControllers[i].c);
|
|
}
|
|
});
|