UNPKG

lathe

Version:

A discrete solid modeller using BSPs

122 lines (100 loc) 4 kB
define([] , function() { var Trackball = function(viewports) { var minDistance = 3; var maxDistance = 10000; var position = { azimuth: Math.PI/4, elevation: Math.PI*3/8, distance: 20 }; var target = { azimuth: Math.PI/4, elevation: Math.PI*3/8, distance: 20, scenePosition: new THREE.Vector3()}; var lastMousePosition, mouseDownPosition, targetOnDown, state; var damping = 0.25; this.mousedown = function(event) { mouseDownPosition = eventToPosition(event); targetOnDown = { azimuth: target.azimuth, elevation: target.elevation, }; }; this.mouseup = function(event) { state = undefined; mouseDownPosition = undefined; }; this.mousemove = function(event) { if (mouseDownPosition && lastMousePosition) { var eventPosition = eventToPosition(event); var dMouseFromDown = { x: eventPosition.x - mouseDownPosition.x, y: eventPosition.y - mouseDownPosition.y, } var dMouseFromLast = { x: eventPosition.x - lastMousePosition.x, y: eventPosition.y - lastMousePosition.y, } if (state === undefined) { state = 'rotating'; } if (state === 'rotating') { var zoomDamp = 0.001 * Math.sqrt(position.distance); target.azimuth = targetOnDown.azimuth - dMouseFromDown.x * zoomDamp; target.elevation = targetOnDown.elevation - dMouseFromDown.y * zoomDamp; target.elevation = target.elevation > Math.PI ? Math.PI : target.elevation; target.elevation = target.elevation < 0 ? 0 : target.elevation; that.updateCamera(); } } lastMousePosition = eventToPosition(event); }; this.mousewheel = function(event) { var factor = 0.005; event.preventDefault(); event.stopPropagation(); if (event.wheelDelta) { target.distance -= event.wheelDelta * Math.sqrt(position.distance)*factor; } // For Firefox if (event.detail) { target.distance -= -event.detail*60 * Math.sqrt(position.distance)*factor; } }; function animate() { requestAnimationFrame(animate); that.updateCamera(); } this.updateCamera = function() { position.azimuth += (target.azimuth - position.azimuth) * damping; position.elevation += (target.elevation - position.elevation) * damping; var dDistance = (target.distance - position.distance) * damping; var newDistance = position.distance + dDistance; if (newDistance > maxDistance) { target.distance = maxDistance; position.distance = maxDistance; } else if (newDistance < minDistance) { target.distance = minDistance; position.distance = minDistance; } else { position.distance = newDistance; } viewports.forEach(function(viewport) { viewport.camera.position.x = position.distance * Math.sin(position.elevation) * Math.cos(position.azimuth); viewport.camera.position.y = position.distance * Math.sin(position.elevation) * Math.sin(position.azimuth); viewport.camera.position.z = position.distance * Math.cos(position.elevation); viewport.camera.up = new THREE.Vector3(0,0,1); viewport.camera.lookAt(new THREE.Vector3(0,0,0)); }); } var that = this; viewports.forEach(function(viewport) { viewport.container.addEventListener('mousemove', that.mousemove, false); viewport.container.addEventListener('mousedown', that.mousedown, false); viewport.container.addEventListener('mouseup', that.mouseup, false); viewport.container.addEventListener('mouseout', that.mouseup, false); viewport.container.addEventListener('mousewheel', that.mousewheel, false); }); animate(); } var eventToPosition = function(event) { return { x: event.offsetX, y: event.offsetY, }; } return Trackball; });