I'm using your webvr-boilerplate and trying to map it to a human face mesh.
The way I do is is:
1) attach the camera to an eye bone
main js script:
//add camera to eye
mesh.skeleton.bones[ 22 ].add(camera);
//resets camera rotation
camera.rotation.set(0,0,0);
//looks at mesh up direction to face front
camera.lookAt( mesh.up );
//moves camera to middle of eyes
camera.position.set(10,10,0);
2) change the webvr-manager.js to update the neck bone ( passed as argument on initialization ) position and rotation and in index.php I swap the axis to match the HMD ones with the ones of the bone:
webvr-manager.js:
if ( state.orientation !== null ) {
object.quaternion.copy( state.orientation );
}
if ( state.position !== null ) {
object.position.copy( state.position ).multiplyScalar( scope.scale );
}
main js script:
/* INSIDE UPDATE CYCLE */
// mesh.rotation.y+=0.1;
controls.update();
//resets bone position to default
mesh.skeleton.bones[ neckVRControlBone ].position.set(neckInitPosition.x,neckInitPosition.y,neckInitPosition.z) ;
//ROTATION SWAP
mesh.skeleton.bones[ neckVRControlBone ].rotation.x = pivot.rotation.y;
mesh.skeleton.bones[ neckVRControlBone ].rotation.y = - pivot.rotation.z;
mesh.skeleton.bones[ neckVRControlBone ].rotation.z = - tempRotation;
to simplify and after some extra debug realised is not a clamp problem..
The restated problem is:
To map the VR controls to an object that has a different axis configuration of the HMD/Cardboard and keep the correct rotation rules. Example of object axis: * x - up * y - depth * z - side
Swapping the rotations by just
object .rotation.x = object .rotation.z
results that, after updating the controls, rotating to the side makes an undesired rotation after 45º.
The rotation rules for each axis are different :
Changed webvr-polyfill.js
and got it fixed for keyboard/mouse with this:
MouseKeyboardPositionSensorVRDevice.prototype.getState = function() {
// this.euler.set(this.phi, this.theta, 0, 'YXZ');
this.euler.set( this.theta , 0, - this.phi, 'YXZ');
But no way similar line to other controllers (HMD, cardboard, etc.). Maybe it would be nice the rotation order and mapping could be available to the user. Thanks
Example - try an set swappedAxis = true
in the js console and rotate the neck.
The main problem you are running into is gimbal lock because you are using Euler rotations. Use Quaternions to avoid this problem.
Additionally, the axes on your mesh appear to be flipped, so you have to account for that.
Instead of setting components of the rotation, just set the quaternion:
mesh.skeleton.bones[neckVRControlBone].quaternion.set(
pivot.quaternion.y,
-pivot.quaternion.z,
-pivot.quaternion.x,
pivot.quaternion.w
);