How to position camera according to model location

736 views
Skip to first unread message

andre....@inovmapping.com

unread,
Sep 4, 2014, 9:57:19 AM9/4/14
to cesiu...@googlegroups.com
Hi, I started playing around with Cesium yesterday in order to see if I could move youbeQ ( https://youbeq.com ) from the Google Earth Plugin to your platform, and I encountered some issues with dealing with the Camera.

I'm trying to position the Camera according to a 3D model, which I can control with the keyboard. What I wanted was to position the camera with the heading, tilt and roll of the model, but with a fixed trail distance. I explored the examples and documentation and arrived at a point where the camera follows the 3D model as I move it around but there is always an offset between the vehicle and camera heading, and it changes depending on the start location.
Maybe I'm going the wrong about it, here is the code for manipulating the camera:

// code snippet ----->
var startLocation = {lng: 169.8046875, lat: -45.33670190996812};
var height = 0.0;

function getEulerAngles(matrix3) {
var deltaX = Math.atan2(matrix3[7], matrix3[8]);
var deltaY = -Math.asin(matrix3[6]);
var deltaZ = Math.atan2(matrix3[3], matrix3[0]);

return {x: deltaX, y: deltaY, z: deltaZ};
};

var modelMatrix = Cesium.Transforms.northEastDownToFixedFrame(
Cesium.Cartesian3.fromDegrees(
startLocation.lng,
startLocation.lat,
height
)
);

// load the model ---->
// ...
// <---- load the model

// when the model is loaded
viewer.clock.onTick.addEventListener(function(clock) {
// move 3D model according to key pressed ---->
// ....
// <---- move 3D model

var center = Cesium.Matrix4.multiplyByPoint(
model.modelMatrix,
model.boundingSphere.center,
new Cesium.Cartesian3()
);

var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);
camera.transform = transform;
var controller = scene.screenSpaceCameraController;
var r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
controller.minimumZoomDistance = r * 0.5;

// Get the rotation matrix of the 3D model
var rotation = new Cesium.Matrix3();
Cesium.Matrix4.getRotation(model.modelMatrix, rotation);

// Get the euler angles
var eulerAngles = getEulerAngles(rotation);

// Get the camera position
var eye = Cesium.Matrix3.multiplyByVector(
Cesium.Matrix3.fromRotationZ(eulerAngles.z),
new Cesium.Cartesian3(r, r, 0.5),
new Cesium.Cartesian3()
);

var target = new Cesium.Cartesian3(0.0, 0.0, 0.0);
var up = Cesium.Cartesian3.UNIT_Z;

camera.lookAt(
eye,
target,
up
);
});

//<----- code snippet

Any help is greatly appreciated.

Daniel Bagnell

unread,
Sep 8, 2014, 2:09:30 PM9/8/14
to cesiu...@googlegroups.com, andre....@inovmapping.com
You can transform the direction the model is pointing in model coordinates to the coordinates of the camera like this:

// move 3D model

// set camera transform

var xDir = Cesium.Matrix4.multiplyByPointAsVector(model.modelMatrix, Cesium.Cartesian3.UNIT_X, new Cesium.Cartesian3());
Cesium.Matrix4.multiplyByPointAsVector(camera.inverseTransform, xDir, xDir);
Cesium.Cartesian3.negate(xDir, xDir);

var offset = 50.0;
var eyePos = Cesium.Cartesian3.multiplyByScalar(xDir, offset, new Cesium.Cartesian3());
camera.lookAt(eyePos, Cesium.Cartesian3.ZERO, Cesium.Cartesian3.UNIT_Z);

Here, I'm assuming that the model is moving in the x direction in the models coordinate system. You can set the UNIT_X vector above to whatever direction your model is moving and set offset to the fixed distance you want the camera to follow.

andre....@inovmapping.com

unread,
Sep 8, 2014, 2:23:27 PM9/8/14
to cesiu...@googlegroups.com, andre....@inovmapping.com
That did it. Thanks for the help!
Reply all
Reply to author
Forward
0 new messages