diff --git a/TODO b/TODO index 03678329a8a6fcbd6ac51b396eeca84bf4a4ef45..eb41c9a347740d70e8f2b2e8c4825b1139eb5480 100644 --- a/TODO +++ b/TODO @@ -5,6 +5,9 @@ Core Examples * DOMRenderer example +Examples/Geometry/Primitives +* Create more primitives. http://code.google.com/p/ogre-procedural/source/browse/#hg/library/src + Materials * MeshBitmapSphereMappingMaterial. http://en.wikipedia.org/wiki/Sphere_mapping * MeshBitmapCubeMappingMaterial. http://en.wikipedia.org/wiki/Cube_mapping diff --git a/examples/camera_orthographic.html b/examples/camera_orthographic.html index b79f89b90855d50d6b2d883cf68a39682dff5b98..fc16c6531ac3e38c69ae5462ac09eb317b032051 100644 --- a/examples/camera_orthographic.html +++ b/examples/camera_orthographic.html @@ -27,37 +27,11 @@ var SCREEN_WIDTH = window.innerWidth; var SCREEN_HEIGHT = window.innerHeight; - var container; - var stats; - - var camera; - var scene; - var renderer; - - var cube, plane; - - var mouseX = 0; - var mouseXOnMouseDown = 0; - - var windowHalfX = window.innerWidth / 2; - var windowHalfY = window.innerHeight / 2; - - var moveForward = false, - moveBackwards = false, - moveUp = false, - moveDown = false, - moveLeft = false, - moveRight = false, - - yawLeft = false, - yawRight = false, - pitchUp = false, - pitchDown = false, - rollLeft = false, - rollRight = false; + var container, stats; + var camera, scene, renderer; init(); - setInterval(loop, 1000/60); + setInterval( loop, 1000 / 60 ); function init() { @@ -67,22 +41,37 @@ camera = new THREE.Camera( 45, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 ); camera.projectionMatrix = THREE.Matrix4.makeOrtho( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -2000, 1000 ); camera.position.x = 200; - camera.position.y = 150; + camera.position.y = 100; camera.position.z = 200; scene = new THREE.Scene(); - // Plane + // Grid + + var geometry = new THREE.Geometry(); + geometry.vertices.push( new THREE.Vertex( new THREE.Vector3( - 500, 0, 0 ) ) ); + geometry.vertices.push( new THREE.Vertex( new THREE.Vector3( 500, 0, 0 ) ) ); - plane = new THREE.Mesh( new Plane( 1000, 1000, 20, 20 ), new THREE.MeshColorStrokeMaterial( 0x000000, 0.2 ) ); - plane.rotation.x = - 90 * ( Math.PI / 180 ); - scene.addObject( plane ); + for ( var i = 0; i <= 20; i ++ ) { - geometry = new Cube( 50, 50, 50 ); + var line = new THREE.Line( geometry, new THREE.LineColorMaterial( 0x000000, 0.2 ) ); + line.position.z = ( i * 50 ) - 500; + scene.addObject( line ); - for (var i = 0; i < 100; i ++ ) { + var line = new THREE.Line( geometry, new THREE.LineColorMaterial( 0x000000, 0.2 ) ); + line.position.x = ( i * 50 ) - 500; + line.rotation.y = 90 * Math.PI / 180; + scene.addObject( line ); - cube = new THREE.Mesh(geometry, new THREE.MeshColorFillMaterial( 0xffffff, Math.random() * 0.5 + 0.5 ) ); + } + + // Cubes + + var geometry = new Cube( 50, 50, 50 ); + + for ( var i = 0; i < 100; i ++ ) { + + var cube = new THREE.Mesh( geometry, new THREE.MeshColorFillMaterial( 0xffffff, Math.random() * 0.5 + 0.5 ) ); cube.overdraw = true; cube.scale.y = Math.floor( Math.random() * 2 + 1 ); @@ -126,8 +115,6 @@ } - // - function loop() { var timer = new Date().getTime() * 0.0001; diff --git a/examples/interactive_spheres.html b/examples/interactive_spheres.html index 8316d7a9c2c8f2d940cc927615519e503d26b35b..914fe0897fa08272133fed17b3c067c4df8fcfad 100644 --- a/examples/interactive_spheres.html +++ b/examples/interactive_spheres.html @@ -75,11 +75,7 @@ var cube, plane; - var targetRotation = 0; - var targetRotationOnMouseDown = 0; - - var mouseX = 0; - var mouseXOnMouseDown = 0; + var mouseX = 0, mouseY = 0, projector; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; @@ -130,7 +126,7 @@ cube.position.y = 150; scene.addObject(cube); - geometry2 = new Sphere( 100 ); + geometry2 = new Sphere( 100, 20, 20 ); for (var i = 0, l = geometry2.faces.length; i < l; i++) { @@ -148,12 +144,11 @@ cube2.position.z = 300; scene.addObject(cube2); - /* var geometry = new THREE.Geometry(); for (var i = 0; i < 100; i ++) { - var v = new THREE.Vector3( Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50 ); + var v = new THREE.Vector3( Math.random() * 1000 - 500, Math.random() * 1000 - 500, Math.random() * 1000 - 500 ); var v0 = new THREE.Vertex( new THREE.Vector3( Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50 ) ); var v1 = new THREE.Vertex( new THREE.Vector3( Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50 ) ); @@ -172,10 +167,11 @@ geometry.computeCentroids(); var mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() ); - mesh.doubleSided = true; - mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; + // mesh.doubleSided = true; + // mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; scene.addObject(mesh); - */ + + projector = new THREE.Projector(); renderer = new THREE.CanvasRenderer(); renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); @@ -188,30 +184,44 @@ container.appendChild(stats.domElement); document.addEventListener('mousedown', onDocumentMouseDown, false); + // document.addEventListener('mousemove', onDocumentMouseMove, false); } function onDocumentMouseDown( event ) { event.preventDefault(); - document.getElementById("msg").innerHTML = ""; + document.getElementById("msg").innerHTML = ""; + + clickResolver.findIntersectInScene( event.clientX / window.innerWidth, event.clientY / window.innerHeight ); + + var vector = projector.unprojectVector( new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.95 ), camera ); + + var particle = new THREE.Particle( new THREE.ParticleCircleMaterial( 0xff0000 ) ); + particle.position = vector; - clickResolver.findIntersectInScene( - event.clientX/window.innerWidth, - event.clientY/window.innerHeight); + scene.addObject( particle ); + } + + function onDocumentMouseMove( event ) { + + mouseX = event.clientX / window.innerWidth; + mouseY = event.clientY / window.innerHeight; } var radius = 600; var theta = 0; - + function loop() { - theta += 1; + theta += 0.2; camera.position.x = radius * Math.sin( theta * Math.PI / 360 ); // camera.position.y = radius * Math.sin( theta * Math.PI / 360 ); camera.position.z = radius * Math.cos( theta * Math.PI / 360 ); + // clickResolver.findIntersectInScene( mouseX, mouseY ); + renderer.render(scene, camera); stats.update(); } diff --git a/src/core/Ray.js b/src/core/Ray.js new file mode 100644 index 0000000000000000000000000000000000000000..9d4b10c1d5f4d70e251a5ee1c00bc4e1df5d4edc --- /dev/null +++ b/src/core/Ray.js @@ -0,0 +1,26 @@ +/** + * @author mr.doob / http://mrdoob.com/ + */ + +THREE.Ray = new function ( origin, direction ) { + + this.origin = origin || new THREE.Vector3(); + this.direction = direction || new THREE.Vector3(); + +} + +THREE.Ray.prototype = { + + intersectScene: function ( scene ) { + + + + }, + + intersectFace: function ( face ) { + + + + } + +}; diff --git a/src/hci/ClickResolver.js b/src/hci/ClickResolver.js index 2ce712530da04b810a7d9c957334a1032974744e..57aa1ae62cf21ee99515c396653e530ccdfc10fb 100644 --- a/src/hci/ClickResolver.js +++ b/src/hci/ClickResolver.js @@ -4,7 +4,7 @@ THREE.ClickResolver = function( camera, scene ) { this.camera = camera; this.scene = scene; this._debug = false; - + }; THREE.ClickResolver.prototype = { @@ -56,124 +56,62 @@ THREE.ClickResolver.prototype = { var coordAtZIndex = new THREE.Vector3(); rayToZIndex.sub( this.camera.target.position, this.camera.position ).setLength( targetZIndex ); - + maxVisibleYatZIndex = rayToZIndex.length() * Math.tan( this.camera.fov * Math.PI / 360 ); maxVisibleXatZIndex = maxVisibleYatZIndex * this.camera.aspect; - + left.cross( this.camera.up, rayToZIndex ); up .cross( rayToZIndex, left ); - + return coordAtZIndex.add( this.camera.position, rayToZIndex ). addSelf( left.setLength( maxVisibleXatZIndex * ( 1 - 2 * xPercent ))). addSelf( up .setLength( maxVisibleYatZIndex * ( 1 - 2 * yPercent ))); - }, - - - logPoint: function( scene, v, hex ) { - - if ( this._debug ) { - - var p = new THREE.Particle( new THREE.ParticleCircleMaterial( hex, 0.5 ) ); - p.position = v.clone(); - p.scale.x = p.scale.y = p.scale.z = 5; - - scene.addObject( p ); - } - }, - - - logLine: function( scene, s, e, hex ) { - - if ( this._debug ) { - - this.logPoint( scene, s.clone(), 0x000000 ); - - var lg = new THREE.Geometry(); - - lg.vertices[0] = new THREE.Vertex( s.clone() ); - lg.vertices[1] = new THREE.Vertex( e.clone() ); - - scene.addObject( new THREE.Line( lg, new THREE.LineColorMaterial( hex, 0.5 ) ) ); - } }, - - + getIntersectingFaces: function( scene, camera, object3d, linePoint, lineDir ) { - + var intersect = { face : null, point : null, distance : Number.MAX_VALUE }; - + var geometry = object3d.geometry; var matrix = object3d.matrix; - + for ( f = 0; f < geometry.faces.length; f++ ) { - + var face = geometry.faces[ f ]; - + // if ( !face.selectable ) continue; - + var a = matrix.transform( geometry.vertices[ face.a ].position.clone() ); var b = matrix.transform( geometry.vertices[ face.b ].position.clone() ); var c = matrix.transform( geometry.vertices[ face.c ].position.clone() ); - var d = face.d ? matrix.transform( geometry.vertices[ face.d ].position.clone() ) : null; - + var d = face instanceof THREE.Face4 ? matrix.transform( geometry.vertices[ face.d ].position.clone() ) : null; + var lineStart = linePoint.clone(); var lineDirection = lineDir.clone(); var dot = face.normal.dot( lineDirection ); - - if ( this._debug ) { - - this.logLine( scene, a, new THREE.Vector3().add( a, new THREE.Vector3().addSelf( face.normal ).multiplyScalar( 100 ) ), 0x0000FF ); - this.logLine( scene, lineStart, lineStart.clone().addSelf( lineDirection ), 0x55FF88 ); - this.logPoint( scene, a, 0xFF0000 ); // r - this.logPoint( scene, b, 0x00FF00 ); // g - this.logPoint( scene, c, 0x0000FF ); // b - if ( d ) this.logPoint( scene, d, 0xFFFF00 ); // y - } if ( dot < 0 ) { // Math.abs( dot ) > 0.0001 var s = face.normal.dot( new THREE.Vector3().sub( a, lineStart ) ) / dot; var planeIntersect = lineStart.addSelf( lineDirection.multiplyScalar( s ) ); - // if ( this._debug ) this.logPoint( scene, planeIntersect, 0x808080 ); - - if ( d == null ) { - - /* - var ab = isInsideBoundary( planeIntersect, a, b, c ); - var bc = isInsideBoundary( planeIntersect, b, c, a ); - var ca = isInsideBoundary( planeIntersect, c, a, b ); - - if ( ab && bc && ca ) { - */ + if ( face instanceof THREE.Face3 ) { - // console.log( f, ab, bc, ca ); + if ( pointInFace3( planeIntersect, a, b, c ) ) { - if ( pointInFace3Fast( planeIntersect, a, b, c ) ) { - - if ( this._debug ) this.logPoint( scene, planeIntersect, 0x0000ff ); logIntersect( planeIntersect, face ); } - } else { - - /* - var ab = isInsideBoundary( planeIntersect, a, b, c ); - var bc = isInsideBoundary( planeIntersect, b, c, d ); - var cd = isInsideBoundary( planeIntersect, c, d, a ); - var da = isInsideBoundary( planeIntersect, d, a, b ); + } else if ( face instanceof THREE.Face4 ) { - if ( ab && bc && cd && da ) { - */ - if ( pointInFace4( planeIntersect, a, b, c, d ) ) { + if ( pointInFace3( planeIntersect, a, b, d ) || pointInFace3( planeIntersect, b, c, d ) ) { - if ( this._debug ) this.logPoint( scene, planeIntersect, 0x000000 ); logIntersect( planeIntersect, face ); } @@ -198,28 +136,10 @@ THREE.ClickResolver.prototype = { } - /* - function isInsideBoundary( pointOnPlaneToCheck, pointInside, boundaryPointA, boundaryPointB ) { - - var toB = boundaryPointB.clone().subSelf( boundaryPointA ); - var toI = pointInside.clone().subSelf( boundaryPointA ); - var pointMid = toB.setLength( toI.dot( toB ) ).addSelf( boundaryPointA ); - var pointMirror = pointMid.subSelf( pointInside ).multiplyScalar( 2 ).addSelf( pointInside ); - - return pointOnPlaneToCheck.distanceToSquared( pointInside ) < pointOnPlaneToCheck.distanceToSquared( pointMirror ); - } - */ - // http://www.blackpawn.com/texts/pointinpoly/default.html function pointInFace3( p, a, b, c ) { - return sameSide( p, a, b, c ) && sameSide( p, b, a, c ) && sameSide( p, c, a, b ); - - } - - function pointInFace3Fast( p, a, b, c ) { - var v0 = c.clone().subSelf( a ), v1 = b.clone().subSelf( a ), v2 = p.clone().subSelf( a ), dot00 = v0.dot( v0 ), dot01 = v0.dot( v1 ), dot02 = v0.dot( v2 ), dot11 = v1.dot( v1 ), dot12 = v1.dot( v2 ), @@ -231,22 +151,7 @@ THREE.ClickResolver.prototype = { } - function pointInFace4( p, a, b, c, d ) { - - return sameSide( p, a, b, c ) && sameSide( p, b, c, d ) && sameSide( p, c, d, a ) && sameSide( p, c, a, b ); - - } - - function sameSide( p1, p2, a, b ) { - - var cp1 = new THREE.Vector3().cross( b.clone().subSelf( a ), p1.clone().subSelf( a ) ); - var cp2 = new THREE.Vector3().cross( b.clone().subSelf( a ), p2.clone().subSelf( a ) ); - return cp1.dot( cp2 ) >= 0; - - } - return intersect; } - }; diff --git a/src/renderers/Projector.js b/src/renderers/Projector.js index 075de6a68969d25e0fa57ed16f2d99df2ab7b045..e19555671e8f9c67bb9883da986451a82b08aacf 100644 --- a/src/renderers/Projector.js +++ b/src/renderers/Projector.js @@ -238,4 +238,16 @@ THREE.Projector = function() { }; + this.unprojectVector = function ( vector, camera ) { + + var vector2 = vector.clone(), + matrix = new THREE.Matrix4(); + + matrix.multiply( THREE.Matrix4.makeInvert( camera.matrix ), THREE.Matrix4.makeInvert( camera.projectionMatrix ) ); + matrix.transform( vector2 ); + + return vector2; + + }; + };