提交 b57169bc 编写于 作者: M Mr.doob

Projector.unprojectVector() apparently working

Work in progress refactoring ClickResolver.js to Ray.js
上级 f30216ff
......@@ -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
......
......@@ -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;
......
......@@ -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();
}
......
/**
* @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 ) {
}
};
......@@ -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;
}
};
......@@ -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;
};
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册