Attaching the Camera to an Armature

When viewing models I generally orbit the camera around the center of the object. The inputs were the distance of the camera from the object and the vertical and horizontal position of the camera, expressed at latitude and longitude.

Traditionally, I would use sine and cosine functions to compute the position of the camera. However, it struck me that I could avoid these computations by attaching the camera to an object that acts like an armature an rotates around the object of interest.The armature (camobj) would be the same distance from the object as the camera and would act like an armature. I could then position the camera correctly by simply rotating the camobj by the latitude and longitude.

When researching how to do this, I found many statements that “this has already been discussed”.
But when I went to find those discussions, they were so old that they had disappeared.

By trial and error, I was able to accomplish what I wanted to do. In addition, I found that I could easily attach the armature to difference objects. This proved very helpful when trying to view objects that rotate in different ways - as in a program showing the behavior of the earth, moon and sun.

Here are the snippets of code that I used:

// Math Predefined
var PieVal = Math.PI;		// PI (so I don't have to keep calling Math.PI function)
var DegRad = PieVal/180;	// Use this to convert Degrees to Radians
var RadDeg = 180/PieVal;	// Use this to convert Radians to Degrees

// Variables
var	camrad			// Camera distance from center
var	camlat, camlon		// Camera vertical and horizontal position

// Create Camera and Armature
var camera = new THREE.PerspectiveCamera(45, width/height, 1, 10000);
	camera.position.z = -camrad;		// Set camera distance from center
	camera.rotation.y = 180 * DegRad;	// Default = looking back toward center
var camobj = new THREE.Object3D();		// Use this to rotate camera
	camobj.rotation.order = "YXZ";
	camobj.add(camera);			// Link camera to object
var ctrobj = new THREE.Object3D();		// Default location = center
	scene.add(ctrobj);
	ctrobj.add(camobj);			// Link camobj to center (for now)

Standard Commands to Capture Mouse and Touch Movement 
document.addEventListener("mousemove", onDocumentMouseMove, false);
document.addEventListener("touchmove", onDocumentTouchMove, false);

// If using a mouse, you can use this to compute change in camera position

function onDocumentMouseMove(event) {
	if (isUserInteracting === true) {
		camlon = (onPointerDownPointerX - event.clientX) * 0.2 + onPointerDownLon;
		camlon = Mod360(camlon);
		camlat = (event.clientY - onPointerDownPointerY) * 0.2 + onPointerDownLat;
		camlat = Math.max(-85, Math.min(85, camlat));	// Sets max latitude at +/-85 degrees
	}
}

// If using a touch screen, you can use this to compute change in camera position

function onDocumentTouchMove(event) {
	// Single Touch
	if (event.touches.length == 1) {
		event.preventDefault();
		camlon = (onPointerDownPointerX - event.touches[0].clientX) * 0.2 + onPointerDownLon;
		camlon = Mod360(camlon);
		camlat = (event.touches[0].clientY - onPointerDownPointerY) * 0.2 + onPointerDownLat;
		camlat = Math.max(-85, Math.min(85, camlat));	// Sets max latitude at +/-85 degrees
	}
}

// Call the following aubroutine with every render
// Rotating camobj changes both the camera position and rotation for you (no math required)
// If you want to look outwards, camera.rotation.y = 0;

function moveCamera() {
	camera.position.z = -camrad;		// Use this if there is a change in camera distance
	camobj.rotation.x = camlat * DegRad;
	camobj.rotation.y = Mod360(camlon+180)*DegRad;
}

// If you want to attach the camera to a different object (target) which has already been added to the scene,
you can do this:
	ctrobj.remove(camobj);			// Remove default attachment
	target.add(camobj);			// Attach to new object

In my Program the camera is attached to one of the following locations:

  1. The center of the scene (ctrobj), looking inward.
  2. The center of the inclined axis of rotation for the earth (axeoobj), looking inward.
  3. Same as above, except looking outward, away from the sun.
    (Select these different views by pressing “V”)

I hope that other programmers find this useful and/or can point out how I could have done this better.