|
@@ -3,51 +3,56 @@ THREE.ClickResolver = function( camera, scene ) {
|
|
|
|
|
|
this.camera = camera;
|
|
this.camera = camera;
|
|
this.scene = scene;
|
|
this.scene = scene;
|
|
- this._debug = false;
|
|
|
|
|
|
+ this._debug = true;
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
THREE.ClickResolver.prototype = {
|
|
THREE.ClickResolver.prototype = {
|
|
-
|
|
|
|
|
|
+
|
|
findIntersectInScene : function ( xPercent, yPercent ) {
|
|
findIntersectInScene : function ( xPercent, yPercent ) {
|
|
-
|
|
|
|
|
|
+
|
|
var objects = this.scene.objects;
|
|
var objects = this.scene.objects;
|
|
var intersects = [];
|
|
var intersects = [];
|
|
-
|
|
|
|
|
|
+
|
|
var mouseRayStart = this.translateScreenCoordsToZIndex( xPercent, yPercent, 300 );
|
|
var mouseRayStart = this.translateScreenCoordsToZIndex( xPercent, yPercent, 300 );
|
|
var mouseRayEnd = this.translateScreenCoordsToZIndex( xPercent, yPercent, 800 );
|
|
var mouseRayEnd = this.translateScreenCoordsToZIndex( xPercent, yPercent, 800 );
|
|
-
|
|
|
|
|
|
+
|
|
var mouseRayDir = new THREE.Vector3().sub( mouseRayEnd, mouseRayStart );
|
|
var mouseRayDir = new THREE.Vector3().sub( mouseRayEnd, mouseRayStart );
|
|
-
|
|
|
|
|
|
+
|
|
var closestIntersect = null;
|
|
var closestIntersect = null;
|
|
-
|
|
|
|
- for ( var i = 0; i < objects.length; i++ ) {
|
|
|
|
-
|
|
|
|
- var o = objects[i];
|
|
|
|
- var intersect = this.getIntersectingFaces( this.scene, camera, o, mouseRayStart, mouseRayDir );
|
|
|
|
-
|
|
|
|
- if ( intersect.face != null &&
|
|
|
|
- (closestIntersect == null ||
|
|
|
|
- closestIntersect.distance > intersect.distance)
|
|
|
|
- ) {
|
|
|
|
-
|
|
|
|
- closestIntersect = intersect;
|
|
|
|
|
|
+
|
|
|
|
+ for ( var i = 0, l = objects.length; i < l; i++ ) {
|
|
|
|
+
|
|
|
|
+ var object = objects[i];
|
|
|
|
+
|
|
|
|
+ if ( object instanceof THREE.Mesh ) {
|
|
|
|
+
|
|
|
|
+ var intersect = this.getIntersectingFaces( this.scene, camera, object, mouseRayStart, mouseRayDir );
|
|
|
|
+
|
|
|
|
+ if ( intersect.face != null && (closestIntersect == null || closestIntersect.distance > intersect.distance) ) {
|
|
|
|
+
|
|
|
|
+ closestIntersect = intersect;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if ( closestIntersect != null && closestIntersect.face.onSelect ) {
|
|
if ( closestIntersect != null && closestIntersect.face.onSelect ) {
|
|
-
|
|
|
|
- closestIntersect.face.onSelect( scene, camera, o, closestIntersect.face, closestIntersect.point );
|
|
|
|
|
|
+
|
|
|
|
+ closestIntersect.face.onSelect( scene, camera, object, closestIntersect.face, closestIntersect.point );
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+
|
|
},
|
|
},
|
|
-
|
|
|
|
-
|
|
|
|
- translateScreenCoordsToZIndex : function ( xPercent, yPercent, targetZIndex ) {
|
|
|
|
|
|
+
|
|
|
|
+ translateScreenCoordsToZIndex: function ( xPercent, yPercent, targetZIndex ) {
|
|
|
|
|
|
var maxVisibleXatZIndex, maxVisibleYatZIndex;
|
|
var maxVisibleXatZIndex, maxVisibleYatZIndex;
|
|
- var rayToZIndex = new THREE.Vector3();
|
|
|
|
- var left = new THREE.Vector3();
|
|
|
|
- var up = new THREE.Vector3();
|
|
|
|
|
|
+ var rayToZIndex = new THREE.Vector3();
|
|
|
|
+ var left = new THREE.Vector3();
|
|
|
|
+ var up = new THREE.Vector3();
|
|
var coordAtZIndex = new THREE.Vector3();
|
|
var coordAtZIndex = new THREE.Vector3();
|
|
|
|
|
|
rayToZIndex.sub( this.camera.target.position, this.camera.position ).setLength( targetZIndex );
|
|
rayToZIndex.sub( this.camera.target.position, this.camera.position ).setLength( targetZIndex );
|
|
@@ -68,12 +73,11 @@ THREE.ClickResolver.prototype = {
|
|
|
|
|
|
if ( this._debug ) {
|
|
if ( this._debug ) {
|
|
|
|
|
|
- var vg = new THREE.Geometry();
|
|
|
|
|
|
+ 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;
|
|
|
|
|
|
- vg.vertices[ 0 ] = new THREE.Vertex( v );
|
|
|
|
- vg.vertices[ 1 ] = new THREE.Vertex( v );
|
|
|
|
-
|
|
|
|
- scene.addObject( new THREE.Line( vg, new THREE.LineColorMaterial( hex, 1, 10 )));
|
|
|
|
|
|
+ scene.addObject( p );
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
|
|
@@ -89,7 +93,7 @@ THREE.ClickResolver.prototype = {
|
|
lg.vertices[0] = new THREE.Vertex( s.clone() );
|
|
lg.vertices[0] = new THREE.Vertex( s.clone() );
|
|
lg.vertices[1] = new THREE.Vertex( e.clone() );
|
|
lg.vertices[1] = new THREE.Vertex( e.clone() );
|
|
|
|
|
|
- scene.addObject(new THREE.Line( lg, new THREE.LineColorMaterial( hex, 1, 4 ) ));
|
|
|
|
|
|
+ scene.addObject( new THREE.Line( lg, new THREE.LineColorMaterial( hex, 0.5 ) ) );
|
|
}
|
|
}
|
|
|
|
|
|
},
|
|
},
|
|
@@ -103,24 +107,19 @@ THREE.ClickResolver.prototype = {
|
|
distance : Number.MAX_VALUE
|
|
distance : Number.MAX_VALUE
|
|
};
|
|
};
|
|
|
|
|
|
- var geo = object3d.geometry;
|
|
|
|
|
|
+ var geometry = object3d.geometry;
|
|
var matrix = object3d.matrix;
|
|
var matrix = object3d.matrix;
|
|
|
|
|
|
- for ( f = 0; f < geo.faces.length; f++ ) {
|
|
|
|
-
|
|
|
|
- var face = geo.faces[ f ];
|
|
|
|
|
|
+ for ( f = 0; f < geometry.faces.length; f++ ) {
|
|
|
|
|
|
- if ( !face.selectable ) continue;
|
|
|
|
|
|
+ var face = geometry.faces[ f ];
|
|
|
|
|
|
- var a = matrix.transform( geo.vertices[ face.a ].position.clone() );
|
|
|
|
- var b = matrix.transform( geo.vertices[ face.b ].position.clone() );
|
|
|
|
- var c = matrix.transform( geo.vertices[ face.c ].position.clone() );
|
|
|
|
- var d = null;
|
|
|
|
|
|
+ // if ( !face.selectable ) continue;
|
|
|
|
|
|
- if ( face.d ) {
|
|
|
|
-
|
|
|
|
- d = matrix.transform( geo.vertices[ face.d ].position.clone() );
|
|
|
|
- }
|
|
|
|
|
|
+ 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 lineStart = linePoint.clone();
|
|
var lineStart = linePoint.clone();
|
|
var lineDirection = lineDir.clone();
|
|
var lineDirection = lineDir.clone();
|
|
@@ -128,73 +127,80 @@ THREE.ClickResolver.prototype = {
|
|
|
|
|
|
if ( this._debug ) {
|
|
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.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, a, 0xFF0000 ); // r
|
|
this.logPoint( scene, b, 0x00FF00 ); // g
|
|
this.logPoint( scene, b, 0x00FF00 ); // g
|
|
this.logPoint( scene, c, 0x0000FF ); // b
|
|
this.logPoint( scene, c, 0x0000FF ); // b
|
|
- this.logPoint( scene, d, 0xFFFF00 ); // y
|
|
|
|
|
|
+ if ( d ) this.logPoint( scene, d, 0xFFFF00 ); // y
|
|
|
|
+ */
|
|
}
|
|
}
|
|
-
|
|
|
|
- if ( Math.abs(dot) > .0001 ) {
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ if ( dot < 0 ) { // Math.abs( dot ) > 0.0001
|
|
|
|
+
|
|
var s = face.normal.dot( new THREE.Vector3().sub( a, lineStart ) ) / dot;
|
|
var s = face.normal.dot( new THREE.Vector3().sub( a, lineStart ) ) / dot;
|
|
var planeIntersect = lineStart.addSelf( lineDirection.multiplyScalar( s ) );
|
|
var planeIntersect = lineStart.addSelf( lineDirection.multiplyScalar( s ) );
|
|
-
|
|
|
|
- if ( this._debug ) this.logPoint( scene, planeIntersect, 0xFFCCAA );
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ // if ( this._debug ) this.logPoint( scene, planeIntersect, 0x808080 );
|
|
|
|
+
|
|
if ( d == null ) {
|
|
if ( d == null ) {
|
|
-
|
|
|
|
|
|
+
|
|
var ab = isInsideBoundary( planeIntersect, a, b, c );
|
|
var ab = isInsideBoundary( planeIntersect, a, b, c );
|
|
var bc = isInsideBoundary( planeIntersect, b, c, a );
|
|
var bc = isInsideBoundary( planeIntersect, b, c, a );
|
|
var ca = isInsideBoundary( planeIntersect, c, a, b );
|
|
var ca = isInsideBoundary( planeIntersect, c, a, b );
|
|
-
|
|
|
|
|
|
+
|
|
if ( ab && bc && ca ) {
|
|
if ( ab && bc && ca ) {
|
|
-
|
|
|
|
- if ( this._debug ) this.logPoint( scene, planeIntersect, 0xFF0000 );
|
|
|
|
|
|
+
|
|
|
|
+ if ( this._debug ) this.logPoint( scene, planeIntersect, 0x0000ff );
|
|
logIntersect( planeIntersect, face );
|
|
logIntersect( planeIntersect, face );
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+
|
|
} else {
|
|
} else {
|
|
-
|
|
|
|
|
|
+
|
|
var ab = isInsideBoundary( planeIntersect, a, b, c );
|
|
var ab = isInsideBoundary( planeIntersect, a, b, c );
|
|
var bc = isInsideBoundary( planeIntersect, b, c, d );
|
|
var bc = isInsideBoundary( planeIntersect, b, c, d );
|
|
var cd = isInsideBoundary( planeIntersect, c, d, a );
|
|
var cd = isInsideBoundary( planeIntersect, c, d, a );
|
|
var da = isInsideBoundary( planeIntersect, d, a, b );
|
|
var da = isInsideBoundary( planeIntersect, d, a, b );
|
|
-
|
|
|
|
|
|
+
|
|
if ( ab && bc && cd && da ) {
|
|
if ( ab && bc && cd && da ) {
|
|
-
|
|
|
|
- if ( this._debug ) this.logPoint( scene, planeIntersect, 0xFF0000 );
|
|
|
|
|
|
+
|
|
|
|
+ if ( this._debug ) this.logPoint( scene, planeIntersect, 0x000000 );
|
|
logIntersect( planeIntersect, face );
|
|
logIntersect( planeIntersect, face );
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
function logIntersect( planeIntersect, face ) {
|
|
function logIntersect( planeIntersect, face ) {
|
|
-
|
|
|
|
|
|
+
|
|
var distance = camera.position.distanceTo( planeIntersect );
|
|
var distance = camera.position.distanceTo( planeIntersect );
|
|
-
|
|
|
|
|
|
+
|
|
if ( distance < intersect.distance ) {
|
|
if ( distance < intersect.distance ) {
|
|
-
|
|
|
|
|
|
+
|
|
intersect.distance = distance;
|
|
intersect.distance = distance;
|
|
intersect.face = face;
|
|
intersect.face = face;
|
|
intersect.point = planeIntersect;
|
|
intersect.point = planeIntersect;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
function isInsideBoundary( pointOnPlaneToCheck, pointInside, boundaryPointA, boundaryPointB ) {
|
|
function isInsideBoundary( pointOnPlaneToCheck, pointInside, boundaryPointA, boundaryPointB ) {
|
|
-
|
|
|
|
|
|
+
|
|
var toB = boundaryPointB.clone().subSelf( boundaryPointA );
|
|
var toB = boundaryPointB.clone().subSelf( boundaryPointA );
|
|
var toI = pointInside.clone().subSelf( boundaryPointA );
|
|
var toI = pointInside.clone().subSelf( boundaryPointA );
|
|
var pointMid = toB.setLength( toI.dot( toB ) ).addSelf( boundaryPointA );
|
|
var pointMid = toB.setLength( toI.dot( toB ) ).addSelf( boundaryPointA );
|
|
var pointMirror = pointMid.subSelf( pointInside ).multiplyScalar( 2 ).addSelf( pointInside );
|
|
var pointMirror = pointMid.subSelf( pointInside ).multiplyScalar( 2 ).addSelf( pointInside );
|
|
-
|
|
|
|
- return pointOnPlaneToCheck.distanceToSquared( pointInside ) <
|
|
|
|
- pointOnPlaneToCheck.distanceToSquared( pointMirror );
|
|
|
|
|
|
+
|
|
|
|
+ return pointOnPlaneToCheck.distanceToSquared( pointInside ) < pointOnPlaneToCheck.distanceToSquared( pointMirror );
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
return intersect;
|
|
return intersect;
|
|
}
|
|
}
|
|
|
|
|