/** * @author alteredq / http://alteredqualia.com/ * * - shows frustum, line of sight and up of the camera * - suitable for fast updates * - based on frustum visualization in lightgl.js shadowmap example * http://evanw.github.com/lightgl.js/tests/shadowmap.html */ THREE.CameraHelper = function ( camera ) { THREE.Line.call( this ); var scope = this; this.geometry = new THREE.Geometry(); this.material = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors } ); this.type = THREE.LinePieces; this.matrixWorld = camera.matrixWorld; this.matrixAutoUpdate = false; this.pointMap = {}; // colors var hexFrustum = 0xffaa00; var hexCone = 0xff0000; var hexUp = 0x00aaff; var hexTarget = 0xffffff; var hexCross = 0x333333; // near addLine( "n1", "n2", hexFrustum ); addLine( "n2", "n4", hexFrustum ); addLine( "n4", "n3", hexFrustum ); addLine( "n3", "n1", hexFrustum ); // far addLine( "f1", "f2", hexFrustum ); addLine( "f2", "f4", hexFrustum ); addLine( "f4", "f3", hexFrustum ); addLine( "f3", "f1", hexFrustum ); // sides addLine( "n1", "f1", hexFrustum ); addLine( "n2", "f2", hexFrustum ); addLine( "n3", "f3", hexFrustum ); addLine( "n4", "f4", hexFrustum ); // cone addLine( "p", "n1", hexCone ); addLine( "p", "n2", hexCone ); addLine( "p", "n3", hexCone ); addLine( "p", "n4", hexCone ); // up addLine( "u1", "u2", hexUp ); addLine( "u2", "u3", hexUp ); addLine( "u3", "u1", hexUp ); // target addLine( "c", "t", hexTarget ); addLine( "p", "c", hexCross ); // cross addLine( "cn1", "cn2", hexCross ); addLine( "cn3", "cn4", hexCross ); addLine( "cf1", "cf2", hexCross ); addLine( "cf3", "cf4", hexCross ); this.camera = camera; function addLine( a, b, hex ) { addPoint( a, hex ); addPoint( b, hex ); } function addPoint( id, hex ) { scope.geometry.vertices.push( new THREE.Vector3() ); scope.geometry.colors.push( new THREE.Color( hex ) ); if ( scope.pointMap[ id ] === undefined ) scope.pointMap[ id ] = []; scope.pointMap[ id ].push( scope.geometry.vertices.length - 1 ); } this.update( camera ); }; THREE.CameraHelper.prototype = Object.create( THREE.Line.prototype ); THREE.CameraHelper.prototype.update = function () { var scope = this; var w = 1, h = 1; // we need just camera projection matrix // world matrix must be identity THREE.CameraHelper.__c.projectionMatrix.copy( this.camera.projectionMatrix ); // center / target setPoint( "c", 0, 0, -1 ); setPoint( "t", 0, 0, 1 ); // near setPoint( "n1", -w, -h, -1 ); setPoint( "n2", w, -h, -1 ); setPoint( "n3", -w, h, -1 ); setPoint( "n4", w, h, -1 ); // far setPoint( "f1", -w, -h, 1 ); setPoint( "f2", w, -h, 1 ); setPoint( "f3", -w, h, 1 ); setPoint( "f4", w, h, 1 ); // up setPoint( "u1", w * 0.7, h * 1.1, -1 ); setPoint( "u2", -w * 0.7, h * 1.1, -1 ); setPoint( "u3", 0, h * 2, -1 ); // cross setPoint( "cf1", -w, 0, 1 ); setPoint( "cf2", w, 0, 1 ); setPoint( "cf3", 0, -h, 1 ); setPoint( "cf4", 0, h, 1 ); setPoint( "cn1", -w, 0, -1 ); setPoint( "cn2", w, 0, -1 ); setPoint( "cn3", 0, -h, -1 ); setPoint( "cn4", 0, h, -1 ); function setPoint( point, x, y, z ) { THREE.CameraHelper.__v.set( x, y, z ); THREE.CameraHelper.__projector.unprojectVector( THREE.CameraHelper.__v, THREE.CameraHelper.__c ); var points = scope.pointMap[ point ]; if ( points !== undefined ) { for ( var i = 0, il = points.length; i < il; i ++ ) { scope.geometry.vertices[ points[ i ] ].copy( THREE.CameraHelper.__v ); } } } this.geometry.verticesNeedUpdate = true; }; THREE.CameraHelper.__projector = new THREE.Projector(); THREE.CameraHelper.__v = new THREE.Vector3(); THREE.CameraHelper.__c = new THREE.Camera();