2

In my app, I am trying to rotate an Object Group via Rotations I get from Device Orientation API.

At some point, I want to calibrate the rotation of my object so that it looks in the same direction as my camera. (having rotation values (0,0,0)! )

But since I am setting the objects rotation via

var euler = new THREE.Euler(x, y, z, 'ZXY'); // angles come from Device Orientation
this.object.setRotationFromEuler(euler);

my object always takes the absolute rotation of my device. For calibrating this, I want to set a rotation on my group and then 'apply' the rotation matrix to the group. Effectively setting it's rotation values x,y,z to 0 so I can set them again with absolute values but the group should rotate relative to the calibrated rotation.

I tried sth like this before, but as I my group doesn't have a geometry, it won't work. Do I have to traverse through every sub-object and apply the rotation to every geometry or is there any way to set a rotation state as 'base' for a group?

The only other solution I can think of is to save the current rotation values on calibrate request and always rotate relative to those, but It would be nice if there was such a method.

Community
  • 1
  • 1
Manuel Graf
  • 462
  • 5
  • 20

1 Answers1

2

There are three ways that come to mind.

One - as you already said - you could apply the calibrated rotation to all geometries in the group, but that doesn't sound right in this case as you are not calibrating the models themselves.

You also mentioned the next one, which is to adjust the device-orientation-values with some calibration-offsets before applying them to the model. This could be the simplest of the options and would allow you to add other things like attenuation and sensor-fusion (think predicting motion from acceleration) and things like that before feeding the values into the model.

The last way I can think of is to use another group that will act as calibration-reference and update it's rotation when the calibration is performed. This could look something like this:

var reference = new THREE.Group();
var model = new THREE.Group();

// your model goes here
model.add(new THREE.Mesh(
  new THREE.BoxGeometry(1,1,1), 
  new THREE.MeshStandardMaterial()
));

reference.add(model);
scene.add(reference);

// (not shown) model-rotation will always be updated with 
// unmodified device-orientation data.

// for calibration, set rotation of the reference-group to the 
// inverse of the current global rotation of the model. 
// That way the overall rotation of the model should be zero for the 
// current value from device-orientation (using the world/global rotation 
// makes this repeatable regardless of previous calibration-values)
function onCalibration() {
  reference.quaternion
      .copy(model.getWorldQuaternion())
      .inverse();
}
Martin Schuhfuß
  • 6,814
  • 1
  • 36
  • 44