Browse Source

SkinnedMesh: Add raycast() method back. (#25957)

Michael Herzog 2 years ago
parent
commit
00a427c48e
2 changed files with 46 additions and 17 deletions
  1. 13 9
      src/objects/Mesh.js
  2. 33 8
      src/objects/SkinnedMesh.js

+ 13 - 9
src/objects/Mesh.js

@@ -155,13 +155,15 @@ class Mesh extends Object3D {
 
 		if ( material === undefined ) return;
 
-		// Checking boundingSphere distance to ray
+		// test with bounding sphere in world space
 
 		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
 
 		_sphere.copy( geometry.boundingSphere );
 		_sphere.applyMatrix4( matrixWorld );
 
+		// check distance from ray origin to bounding sphere
+
 		_ray.copy( raycaster.ray ).recast( raycaster.near );
 
 		if ( _sphere.containsPoint( _ray.origin ) === false ) {
@@ -172,12 +174,12 @@ class Mesh extends Object3D {
 
 		}
 
-		//
+		// convert ray to local space of mesh
 
 		_inverseMatrix.copy( matrixWorld ).invert();
 		_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
 
-		// Check boundingBox before continuing
+		// test with bounding box in local space
 
 		if ( geometry.boundingBox !== null ) {
 
@@ -185,11 +187,13 @@ class Mesh extends Object3D {
 
 		}
 
-		this._computeIntersections( raycaster, intersects );
+		// test for intersections with geometry
+
+		this._computeIntersections( raycaster, intersects, _ray );
 
 	}
 
-	_computeIntersections( raycaster, intersects ) {
+	_computeIntersections( raycaster, intersects, rayLocalSpace ) {
 
 		let intersection;
 
@@ -224,7 +228,7 @@ class Mesh extends Object3D {
 						const b = index.getX( j + 1 );
 						const c = index.getX( j + 2 );
 
-						intersection = checkGeometryIntersection( this, groupMaterial, raycaster, _ray, uv, uv1, normal, a, b, c );
+						intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c );
 
 						if ( intersection ) {
 
@@ -249,7 +253,7 @@ class Mesh extends Object3D {
 					const b = index.getX( i + 1 );
 					const c = index.getX( i + 2 );
 
-					intersection = checkGeometryIntersection( this, material, raycaster, _ray, uv, uv1, normal, a, b, c );
+					intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c );
 
 					if ( intersection ) {
 
@@ -282,7 +286,7 @@ class Mesh extends Object3D {
 						const b = j + 1;
 						const c = j + 2;
 
-						intersection = checkGeometryIntersection( this, groupMaterial, raycaster, _ray, uv, uv1, normal, a, b, c );
+						intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c );
 
 						if ( intersection ) {
 
@@ -307,7 +311,7 @@ class Mesh extends Object3D {
 					const b = i + 1;
 					const c = i + 2;
 
-					intersection = checkGeometryIntersection( this, material, raycaster, _ray, uv, uv1, normal, a, b, c );
+					intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c );
 
 					if ( intersection ) {
 

+ 33 - 8
src/objects/SkinnedMesh.js

@@ -4,6 +4,7 @@ import { Matrix4 } from '../math/Matrix4.js';
 import { Sphere } from '../math/Sphere.js';
 import { Vector3 } from '../math/Vector3.js';
 import { Vector4 } from '../math/Vector4.js';
+import { Ray } from '../math/Ray.js';
 
 const _basePosition = /*@__PURE__*/ new Vector3();
 
@@ -14,7 +15,9 @@ const _vector3 = /*@__PURE__*/ new Vector3();
 const _matrix4 = /*@__PURE__*/ new Matrix4();
 const _vertex = /*@__PURE__*/ new Vector3();
 
-//const _sphere = /*@__PURE__*/ new Sphere();
+const _sphere = /*@__PURE__*/ new Sphere();
+const _inverseMatrix = /*@__PURE__*/ new Matrix4();
+const _ray = /*@__PURE__*/ new Ray();
 
 class SkinnedMesh extends Mesh {
 
@@ -97,18 +100,40 @@ class SkinnedMesh extends Mesh {
 
 	}
 
-	// raycast( raycaster, intersects ) {
+	raycast( raycaster, intersects ) {
 
-	// 	if ( this.boundingSphere === null ) this.computeBoundingSphere();
+		const material = this.material;
+		const matrixWorld = this.matrixWorld;
 
-	// 	_sphere.copy( this.boundingSphere );
-	// 	_sphere.applyMatrix4( this.matrixWorld );
+		if ( material === undefined ) return;
 
-	// 	if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return;
+		// test with bounding sphere in world space
 
-	// 	this._computeIntersections( raycaster, intersects );
+		if ( this.boundingSphere === null ) this.computeBoundingSphere();
 
-	// }
+		_sphere.copy( this.boundingSphere );
+		_sphere.applyMatrix4( matrixWorld );
+
+		if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return;
+
+		// convert ray to local space of skinned mesh
+
+		_inverseMatrix.copy( matrixWorld ).invert();
+		_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
+
+		// test with bounding box in local space
+
+		if ( this.boundingBox !== null ) {
+
+			if ( _ray.intersectsBox( this.boundingBox ) === false ) return;
+
+		}
+
+		// test for intersections with geometry
+
+		this._computeIntersections( raycaster, intersects, _ray );
+
+	}
 
 	getVertexPosition( index, target ) {