Last active
August 29, 2015 14:13
-
-
Save abarax/5ca1f9e0f95002c82571 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//----------------------------------------------------------------------------- | |
//----------------------------------------------------------------------------- | |
// Camera Rotate | |
// | |
// Give the camera rotate tool some mass so that | |
// camera motion is smoothed out | |
// | |
// Directions: | |
// Adjust the properties of the camera rotation by calling the various | |
// set____() methods of the cameraController object at the end of the script. | |
// The script attempts to calculate some defaults values based on the size | |
// of your model so it might work right out of the box. | |
// | |
// Daniel Beardsley, Adobe Systems, Inc. | |
// March, 2006 | |
// | |
// Updated: 07/14/06 | |
// | |
//----------------------------------------------------------------------------- | |
//----------------------------------------------------------------------------- | |
console.println( "* The Javascript 'CameraRotate.js' is now being read..." ); | |
//---------------------------------------------------------------- | |
// Camera Position Class | |
//---------------------------------------------------------------- | |
function CameraPosition(inTargetPosition, inPitch, inYaw, inDistance) | |
{ | |
this.TargetPosition = inTargetPosition; | |
this.CamVector = new Vector3(inPitch, inYaw, inDistance); | |
this.getPitch = function(){return this.CamVector.x;} | |
this.getYaw = function(){return this.CamVector.y;} | |
this.getDistance = function(){return this.CamVector.z;} | |
this.setPitch = function(val){this.CamVector.x = val;} | |
this.setYaw = function(val){this.CamVector.y = val;} | |
this.setDistance = function(val){this.CamVector.z = val;} | |
}//---------------------------------------------------------------- | |
function SetDefaultCameraPosition(myCameraRotate) | |
{ | |
var scenebounds = scene.computeBoundingBox(); | |
var scenesize = scenebounds.max.subtract(scenebounds.min).length; | |
cameraDistance = scenesize * 2; | |
trueCameraPos = scenebounds.center; | |
myCameraRotate.setMaxZoom(scenesize*4); | |
myCameraRotate.setMinZoom(scenesize/2); | |
myCameraRotate.setCameraPos(new CameraPosition(scenebounds.center, 0, 0, cameraDistance)); | |
} | |
//--------------------------------------------- | |
//--------------------------------------------- | |
// CameraRotate Class | |
//--------------------------------------------- | |
//--------------------------------------------- | |
function CameraRotate(inCamera) | |
{ | |
cameraRotate = this; | |
//---------------------------------------------------------------- | |
// constants | |
//---------------------------------------------------------------- | |
var GLOBAL_UP_DIRECTION = new Vector3( 0.0, 0.0, 1.0 ); | |
var DEFAULT_FRICTION = 8.0; | |
var DEFAULT_MOUSE_FORCE = 0.025; | |
var DEFAULT_MAX_PITCH = Math.PI * 0.4999; // just a bit less than rotated 90 degrees | |
var MAX_MOUSE_FORCE = 0.3; | |
var MAX_YAW_SPEED = 16; | |
var MIN_SPEED = 0.005; | |
var PI_2 = Math.PI / 2; | |
//---------------------------------- | |
// private members | |
//---------------------------------- | |
var camera = inCamera; | |
var generalMouseEventHandler = new MouseEventHandler(); | |
//Camera Orientation Variables | |
var cameraDirection = new Vector3(); | |
var trueCameraPos = new Vector3(); | |
var yaw = 0.0; | |
var pitch = 0.3; | |
var targetPosition = new Vector3(); | |
var yawDelta = 0.0; | |
var pitchDelta = 0.0; | |
var cameraDistance = 80; | |
var mouse_XPrevious = 0; | |
var mouse_YPrevious = 0; | |
var originalCameraDistance = 0; | |
//Control parameters | |
var friction = DEFAULT_FRICTION; | |
var mouseForce = DEFAULT_MOUSE_FORCE; | |
var maxPitch = DEFAULT_MAX_PITCH; | |
var minPitch = 0; | |
var maxZoom = 0; | |
var minZoom = 0; | |
var GlobalZoomScale = 1; | |
//Effect Flags | |
var yawCoast = false; | |
var allowZoom = true; | |
//Internal State variables | |
this.ShouldUpdate = true; | |
var mouseButtonDown = false; | |
var FOV = inCamera.fov; | |
var clockwise = true; | |
//------------------------------------------------------ | |
// General Mouse Event Handler for whole 3D Annotation | |
//------------------------------------------------------ | |
generalMouseEventHandler.onMouseDown = true; | |
generalMouseEventHandler.onMouseMove = true; | |
generalMouseEventHandler.onMouseUp = true; | |
generalMouseEventHandler.reportAllTargets = false; | |
generalMouseEventHandler.onEvent = function( event ) | |
{ | |
//----------------------------------------------- | |
// mouse is dragging left button | |
//----------------------------------------------- | |
if ( event.isMouseMove && mouseButtonDown && event.leftButtonDown ) | |
{ | |
yawDelta += ( event.mouseX - mouse_XPrevious ) * mouseForce; | |
pitchDelta += ( event.mouseY - mouse_YPrevious ) * mouseForce * 0.8; | |
if (yawDelta > MAX_YAW_SPEED) yawDelta = MAX_YAW_SPEED; | |
else if (yawDelta < -MAX_YAW_SPEED) yawDelta = -MAX_YAW_SPEED; | |
mouse_XPrevious = event.mouseX; | |
mouse_YPrevious = event.mouseY; | |
cameraRotate.ShouldUpdate = true; | |
} | |
//----------------------------------------------- | |
// mouse is dragging right button - Zoom In/Out | |
//----------------------------------------------- | |
if (allowZoom && event.isMouseMove && mouseButtonDown && event.rightButtonDown ) | |
{ | |
var scale = Math.abs(mouse_YPrevious - event.mouseY) / 300 + 1; | |
if(mouse_YPrevious > event.mouseY) | |
scale = 1 / scale; | |
cameraDistance = (scale * scale) * originalCameraDistance; | |
if(maxZoom > 0) | |
cameraDistance = Math.min(maxZoom, cameraDistance); | |
cameraDistance = Math.max(minZoom, cameraDistance); | |
cameraRotate.ShouldUpdate = true; | |
} | |
//----------------------------------------------- | |
// mouse button is down | |
//----------------------------------------------- | |
if ( event.isMouseDown ) | |
{ | |
mouseButtonDown = true; | |
cameraRotate.saveCameraDistance(); | |
originalCameraDistance = cameraDistance; | |
mouse_XPrevious = event.mouseX; | |
mouse_YPrevious = event.mouseY; | |
} | |
//----------------------------------------------- | |
// mouse button is released | |
//----------------------------------------------- | |
if ( event.isMouseUp ) | |
{ | |
mouseButtonDown = false; | |
cameraRotate.saveCameraDistance(); | |
} | |
}//-------------------------------------------------------- | |
runtime.addEventHandler( generalMouseEventHandler ); | |
//--------------------------------------------- | |
// Grabs the current Camera distance from the target | |
//--------------------------------------------- | |
this.saveCameraDistance = function() | |
{ | |
var cameraVector = new Vector3( camera.position ); | |
cameraVector.subtractInPlace( camera.targetPosition ); | |
cameraDistance = cameraVector.length / GlobalZoomScale; | |
} | |
//--------------------------------------------- | |
this.registerOwnEventHandler = function() | |
{ | |
var mytimer = new TimeEventHandler(); | |
mytimer.onEvent = function (event) | |
{ | |
// if(cameraRotate.ShouldUpdate) | |
cameraRotate.Update(event.deltaTime); | |
}; | |
runtime.addEventHandler(mytimer); | |
}//--------------------------------------------- | |
//--------------------------------------------- | |
this.Update = function( deltaTime ) | |
{ | |
cameraRotate.applyPitchFriction( deltaTime ); | |
if(!yawCoast || mouseButtonDown) | |
cameraRotate.applyYawFriction( deltaTime ); | |
if(Math.abs(yawDelta) < MIN_SPEED && | |
Math.abs(pitchDelta) < MIN_SPEED) | |
this.ShouldUpdate = false; | |
//--------------------------------------------- | |
// Update by delta | |
//--------------------------------------------- | |
if (yaw + (0.5 * deltaTime) < 0.5 && !clockwise){ | |
yaw += 0.5 * deltaTime; | |
} | |
else { | |
clockwise = true; | |
} | |
if (yaw - (0.5 * deltaTime) > -0.5 && clockwise) { | |
yaw -= 0.5 * deltaTime; | |
} else { | |
clockwise = false; | |
} | |
pitch += pitchDelta * deltaTime; | |
//--------------------------------------------- | |
// max pitch | |
//--------------------------------------------- | |
if ( pitch > maxPitch ) { pitch = maxPitch; } | |
if ( pitch < minPitch ) { pitch = minPitch; } | |
if(yaw > Math.PI) yaw = yaw - Math.PI*2; | |
else if(yaw < -Math.PI) yaw = yaw + Math.PI*2; | |
cameraRotate.updateCameraPosition(); | |
}//---- Update function----------------------------------------- | |
//-------------------------------------------------- | |
this.updateCameraPosition = function() | |
{ | |
//----------------------------------------------- | |
// Update camera direction | |
//----------------------------------------------- | |
var x = Math.sin( yaw ) * Math.cos( pitch ); | |
var y = Math.cos( yaw ) * Math.cos( pitch ); | |
var z = Math.sin( pitch ); | |
cameraDirection.set( x, y, z ); | |
//----------------------------------------------- | |
// Update camera position | |
//----------------------------------------------- | |
trueCameraPos.set(targetPosition); | |
trueCameraPos.addScaledInPlace(cameraDirection, cameraDistance * GlobalZoomScale); | |
camera.up.set(targetPosition.x, targetPosition.y, targetPosition.z + cameraDistance); | |
camera.position.set(trueCameraPos); | |
camera.targetPosition.set(targetPosition); | |
}//-------------------------------------------------- | |
//-------------------------------------------------- | |
this.setCameraPos = function(CamPos) | |
{ | |
yaw = CamPos.getYaw(); | |
cameraDistance = CamPos.getDistance(); | |
pitch = CamPos.getPitch(); | |
if (CamPos.TargetPosition != null) | |
targetPosition = CamPos.TargetPosition; | |
cameraRotate.updateCameraPosition(); | |
}//-------------------------------------------------- | |
//-------------------------------------------------- | |
this.getCameraPos = function(CamPos) | |
{ | |
return new CameraPosition(targetPosition, pitch, yaw, cameraDistance); | |
}//-------------------------------------------------- | |
//-------------------------------------------------- | |
this.applyYawFriction = function( deltaTime ) | |
{ | |
yawDelta *= Math.max(0, 1.0 - ( friction * deltaTime )); | |
}//------------------------------------------------- | |
//--------------------------------------------------- | |
this.applyPitchFriction = function( deltaTime ) | |
{ | |
pitchDelta *= Math.max(0, 1.0 - ( friction * deltaTime )); | |
}//-------------------------------------------------- | |
//---------------------------------------------------- | |
// FOV = Camera Field of View | |
// Expressed in Radians from 0 to PI | |
// When this is altered, the Camera distance is adjusted | |
// so that the target remains the same visual size. | |
//---------------------------------------------------- | |
this.setFOV = function(fov) | |
{ | |
var oldFOV = FOV; | |
FOV = fov; | |
camera.fov = fov; | |
GlobalZoomScale *= Math.tan(oldFOV/2) / Math.tan(fov/2); | |
this.Update(0.0001); | |
scene.update(); | |
}//-------------------------------------------------- | |
//---------------------------------------------------- | |
// Max Pitch = Maximum angle between the horizon and | |
// the camera. Expressed in Radians from -PI/2 to PI/2 | |
// PI/2 = 90 degrees up from horizontal (looking down the -z axis) | |
// -PI/2 = 90 degrees down from horizontal (looking up the +z axis) | |
//---------------------------------------------------- | |
this.setMaxPitch = function( p ) | |
{ | |
p = Math.max(-DEFAULT_MAX_PITCH, p); | |
p = Math.min(DEFAULT_MAX_PITCH, p); | |
maxPitch = p; | |
}//-------------------------------------------------- | |
//---------------------------------------------------- | |
// Min Pitch = Minimum angle between the horizon and | |
// the camera. Expressed in Radians from -PI/2 to PI/2 | |
// PI/2 = 90 degrees up from horizontal (looking down the -z axis) | |
// -PI/2 = 90 degrees down from horizontal (looking up the +z axis) | |
//---------------------------------------------------- | |
this.setMinPitch = function( p ) | |
{ | |
p = Math.max(-DEFAULT_MAX_PITCH, p); | |
p = Math.min(DEFAULT_MAX_PITCH, p); | |
minPitch = p; | |
}//-------------------------------------------------- | |
//---------------------------------------------------- | |
// MouseForce = amount of effect the mouse dragging has on Camera movement. | |
// 0 - 30 (Default = 2.5) | |
//---------------------------------------------------- | |
this.setMouseForce = function( f ) | |
{ | |
mouseForce = f/100; | |
if ( mouseForce < 0.0 ) | |
mouseForce = 0.0; | |
else if ( mouseForce > MAX_MOUSE_FORCE ) | |
mouseForce = MAX_MOUSE_FORCE; | |
}//--------------------------------------------------- | |
//---------------------------------------------------- | |
// Friction = How quickly the camera slows to a stop after mouse dragging | |
// 0 - infinity (Default = 8.0) | |
//---------------------------------------------------- | |
this.setFriction = function( f ) | |
{ | |
friction = f; | |
if (friction < 0.0 ) | |
friction = 0.0; | |
}//---------------------------------------------------- | |
//---------------------------------------------------- | |
// setYawCoast(bool) (Default = false) | |
// If set to true, the camera will ignore friction in the | |
// horizontal direction and will continue to orbit it's target | |
//----------------------------------------------------- | |
this.setYawCoast = function( b ) | |
{ | |
yawCoast = (b == true); | |
}//---------------------------------------------------- | |
//---------------------------------------------------- | |
// setAllowZoom(bool) (Default = true) | |
// Sets wether or not to allow the Camera to zoom in/out | |
// (i.e. get closer or further from the target) | |
// When set to true, you can zoom in/out by clicking and | |
// dragging with the right mouse button held down. | |
//---------------------------------------------------- | |
this.setAllowZoom = function( allow ) | |
{ | |
allowZoom = (allow == true); | |
}//---------------------------------------------------- | |
//---------------------------------------------------- | |
// setMinZoom(float) (Default = 0) | |
// Sets how close the Camera is allowed to get to the | |
// target in the same units as the scene. | |
//---------------------------------------------------- | |
this.setMinZoom = function( z ) | |
{ | |
minZoom = Math.max(0, z); | |
}//-------------------------------------------------- | |
//---------------------------------------------------- | |
// setMaxZoom(float) (Default = 0) | |
// Sets how far the Camera is allowed to get from the | |
// target in the same units as the scene. | |
// Setting this to 0 = No Maximum Zoom | |
//---------------------------------------------------- | |
this.setMaxZoom = function( z ) | |
{ | |
maxZoom = Math.max(0, z); | |
}//-------------------------------------------------- | |
//--------------------------------------------------- | |
// This will be used in a future release | |
//--------------------------------------------------- | |
/* | |
this.printCameraView = function() | |
{ | |
console.println("viewManager.AddView('View"+ Math.round(Math.random()*1000) +"', TargetPos, "+pitch+", "+yaw+", "+cameraDistance+");"); | |
} | |
*/ | |
}//-------------------------------------------------------------- | |
cameraController = new CameraRotate(scene.cameras.getByIndex(0)); | |
SetDefaultCameraPosition(cameraController); | |
cameraController.registerOwnEventHandler(); | |
console.println( "* The Javascript 'CameraRotate.js' has been read to the end." ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment