Quellcode durchsuchen

remake InstanceMesh.raycast

webglzhang vor 5 Jahren
Ursprung
Commit
57fbfb770b
3 geänderte Dateien mit 53 neuen und 202 gelöschten Zeilen
  1. 0 1
      examples/files.js
  2. 0 195
      examples/webgl_instancing_morphtargets_raycast.html
  3. 53 6
      src/objects/InstancedMesh.js

+ 0 - 1
examples/files.js

@@ -49,7 +49,6 @@ var files = {
 		"webgl_helpers",
 		"webgl_instancing_suzanne",
 		"webgl_instancing_raycast",
-		"webgl_instancing_morphtargets_raycast",
 		"webgl_interactive_buffergeometry",
 		"webgl_interactive_cubes",
 		"webgl_interactive_cubes_gpu",

+ 0 - 195
examples/webgl_instancing_morphtargets_raycast.html

@@ -1,195 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-	<title>three.js webgl - instancing - morph targets - raycast </title>
-	<meta charset="utf-8">
-	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-	<link type="text/css" rel="stylesheet" href="main.css">
-</head>
-<body>
-<div id="container"></div>
-<div id="info">
-	<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - WebGL instancing morphTarget raycast
-	example
-</div>
-
-<script type="module">
-
-	import * as THREE from '../build/three.module.js';
-
-	import Stats from './jsm/libs/stats.module.js';
-	import {OrbitControls} from './jsm/controls/OrbitControls.js';
-
-	var container;
-
-	var camera, scene, renderer, raycaster, controls, stats;
-
-	var mesh, mouse = new THREE.Vector2();
-
-	var object = new THREE.Object3D();
-
-	var amount = parseInt( window.location.search.substr( 1 ) ) || 10;
-
-	var count = Math.pow( amount, 3 );
-
-	var rotationTheta = 0.1;
-	var rotationMatrix = new THREE.Matrix4().makeRotationY( rotationTheta );
-	var instanceMatrix = new THREE.Matrix4();
-	var matrix = new THREE.Matrix4();
-
-	init();
-	animate();
-
-	function init() {
-
-		container = document.getElementById( 'container' );
-
-		scene = new THREE.Scene();
-		scene.background = new THREE.Color( 0x000000 );
-
-		camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
-		camera.position.set( 25, 25, 25 );
-		camera.lookAt( new THREE.Vector3( 0, 0, 0 ) );
-		scene.add( camera );
-
-		var light = new THREE.AmbientLight( 0xffffff );
-		scene.add( light );
-
-		var geometry = new THREE.BoxGeometry( 0.5, 0.5, 0.5 );
-		var material = new THREE.MeshNormalMaterial( { morphTargets: true } );
-
-		// construct 8 blend shapes
-
-		for ( var i = 0; i < 8; i ++ ) {
-
-			var vertices = [];
-
-			for ( var v = 0; v < geometry.vertices.length; v ++ ) {
-
-				vertices.push( geometry.vertices[ v ].clone() );
-
-				if ( v === i ) {
-
-					vertices[ vertices.length - 1 ].x *= 2;
-					vertices[ vertices.length - 1 ].y *= 2;
-					vertices[ vertices.length - 1 ].z *= 2;
-
-				}
-
-			}
-
-			geometry.morphTargets.push( { name: "target" + i, vertices: vertices } );
-
-		}
-
-		geometry = new THREE.BufferGeometry().fromGeometry( geometry );
-
-		mesh = new THREE.InstancedMesh( geometry, material, count );
-
-		mesh.position.set( 0, 0, 0 );
-
-		var i = 0;
-		var offset = amount / 2;
-
-		for ( var x = 0; x < amount; x ++ ) {
-
-			for ( var y = 0; y < amount; y ++ ) {
-
-				for ( var z = 0; z < amount; z ++ ) {
-
-					object.position.set( ( offset - x ) * 2, ( offset - y ) * 2, ( offset - z ) * 2 );
-
-					object.updateMatrix();
-
-					mesh.setMatrixAt( i ++, object.matrix );
-
-				}
-
-			}
-
-		}
-
-		scene.add( mesh );
-
-		raycaster = new THREE.Raycaster();
-
-		renderer = new THREE.WebGLRenderer( { antialias: true } );
-		renderer.setPixelRatio( window.devicePixelRatio );
-		renderer.setSize( window.innerWidth, window.innerHeight );
-		container.appendChild( renderer.domElement );
-
-		controls = new OrbitControls( camera, renderer.domElement );
-
-		stats = new Stats();
-		document.body.appendChild( stats.dom );
-
-		window.addEventListener( 'resize', onWindowResize, false );
-
-		document.addEventListener( 'mousemove', onMouseMove, false );
-
-	}
-
-	function onMouseMove( event ) {
-
-		event.preventDefault();
-
-		mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
-		mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
-
-	}
-
-	function onWindowResize() {
-
-		camera.aspect = window.innerWidth / window.innerHeight;
-		camera.updateProjectionMatrix();
-
-		renderer.setSize( window.innerWidth, window.innerHeight );
-
-	}
-
-	function animate() {
-
-		requestAnimationFrame( animate );
-		render();
-
-	}
-
-	function updateMorphTargetInfluences() {
-
-		for ( var i = 0; i < mesh.morphTargetInfluences.length; i ++ ) {
-
-			mesh.morphTargetInfluences[ i ] = Math.sin( Date.now() * 0.001 ) + 0.5;
-
-		}
-
-	}
-
-	function render() {
-
-		updateMorphTargetInfluences();
-
-		raycaster.setFromCamera( mouse, camera );
-
-		var intersects = raycaster.intersectObject( mesh );
-
-		if ( intersects.length > 0 ) {
-
-			mesh.getMatrixAt( intersects[ 0 ].instanceId, instanceMatrix );
-			matrix.multiplyMatrices( instanceMatrix, rotationMatrix );
-
-			mesh.setMatrixAt( intersects[ 0 ].instanceId, matrix );
-			mesh.instanceMatrix.needsUpdate = true;
-
-		}
-
-		renderer.render( scene, camera );
-
-		stats.update();
-
-	}
-
-
-</script>
-
-</body>
-</html>

+ 53 - 6
src/objects/InstancedMesh.js

@@ -5,6 +5,13 @@ import { BufferAttribute } from '../core/BufferAttribute.js';
 import { Mesh } from './Mesh.js';
 import { Matrix4 } from '../math/Matrix4.js';
 
+var _instanceLocalMatrix = new Matrix4();
+var _instanceWorldMatrix = new Matrix4();
+
+var _instanceIntersects = [];
+
+var _agentMesh = new Mesh();
+
 function InstancedMesh( geometry, material, count ) {
 
 	Mesh.call( this, geometry, material );
@@ -23,11 +30,51 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	getMatrixAt: function ( index, matrix ) {
 
-		var matrix = matrix || new Matrix4();
-
 		matrix.fromArray( this.instanceMatrix.array, index * 16 );
 
-		return matrix;
+	},
+
+	raycast: function ( raycaster, intersects ) {
+
+		var matrixWorld = this.matrixWorld;
+		var raycastTimes = this.count;
+
+		_agentMesh.geometry = this.geometry;
+		_agentMesh.material = this.material;
+
+		if ( _agentMesh.material === undefined ) return;
+
+		for ( var instanceId = 0; instanceId < raycastTimes; instanceId ++ ) {
+
+			//Calculate the world matrix for each instance
+
+			this.getMatrixAt( instanceId, _instanceLocalMatrix );
+
+			_instanceWorldMatrix.multiplyMatrices( matrixWorld, _instanceLocalMatrix );
+
+
+			//The agent mesh represents this single instance
+
+			_agentMesh.matrix = _instanceWorldMatrix;
+
+			_agentMesh.matrixWorld.copy( _instanceWorldMatrix );
+
+			_agentMesh.raycast( raycaster, _instanceIntersects );
+
+			//Process the result of raycast
+
+			if ( _instanceIntersects.length > 0 ) {
+
+				_instanceIntersects[ 0 ].instanceId = instanceId;
+				_instanceIntersects[ 0 ].object = this;
+
+				intersects.push( _instanceIntersects[ 0 ] );
+
+				_instanceIntersects = [];
+
+			}
+
+		}
 
 	},
 
@@ -37,9 +84,9 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	},
 
-	// updateMorphTargets: function () {
-	//
-	// }
+	updateMorphTargets: function () {
+
+	}
 
 } );