From 7c27e473379caf8c03f51b2b0bca942fa98b3137 Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Fri, 15 Mar 2019 12:58:30 +0100 Subject: [PATCH] Mesh: Added support for morph targets with BufferGeometry in raycast(). --- examples/webgl_morphtargets.html | 32 +++++++++++++++++++--- src/objects/Mesh.js | 46 ++++++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/examples/webgl_morphtargets.html b/examples/webgl_morphtargets.html index 94071a9cd4..8dc860e3d9 100644 --- a/examples/webgl_morphtargets.html +++ b/examples/webgl_morphtargets.html @@ -51,9 +51,9 @@ var container; - var camera, scene, renderer; + var camera, scene, renderer, raycaster; - var mesh; + var mesh, mouse = new THREE.Vector2(); init(); animate(); @@ -69,7 +69,8 @@ scene.background = new THREE.Color( 0x222222 ); scene.fog = new THREE.Fog( 0x000000, 1, 15000 ); - var light = new THREE.PointLight( 0xff2200 ); + var light = new THREE.PointLight( 0xffffff ); + light.position.z = 500; camera.add( light ); scene.add( camera ); @@ -77,7 +78,7 @@ scene.add( light ); var geometry = new THREE.BoxGeometry( 100, 100, 100 ); - var material = new THREE.MeshLambertMaterial( { color: 0xffffff, morphTargets: true } ); + var material = new THREE.MeshLambertMaterial( { color: 0xff0000, morphTargets: true } ); // construct 8 blend shapes @@ -169,6 +170,8 @@ // + raycaster = new THREE.Raycaster(); + renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); @@ -184,6 +187,27 @@ window.addEventListener( 'resize', onWindowResize, false ); + document.addEventListener( 'click', onClick, false ); + + } + + function onClick( event ) { + + event.preventDefault(); + + mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; + mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; + + raycaster.setFromCamera( mouse, camera ); + + var intersects = raycaster.intersectObject( mesh ); + + if ( intersects.length > 0 ) { + + mesh.material.color.set( Math.random() * 0xffffff ); + + } + } function onWindowResize() { diff --git a/src/objects/Mesh.js b/src/objects/Mesh.js index 0ba80b5bd4..8eac9af03e 100644 --- a/src/objects/Mesh.js +++ b/src/objects/Mesh.js @@ -126,6 +126,10 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { var tempB = new Vector3(); var tempC = new Vector3(); + var morphA = new Vector3(); + var morphB = new Vector3(); + var morphC = new Vector3(); + var uvA = new Vector2(); var uvB = new Vector2(); var uvC = new Vector2(); @@ -164,12 +168,43 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { } - function checkBufferGeometryIntersection( object, material, raycaster, ray, position, uv, a, b, c ) { + function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, a, b, c ) { vA.fromBufferAttribute( position, a ); vB.fromBufferAttribute( position, b ); vC.fromBufferAttribute( position, c ); + var morphInfluences = object.morphTargetInfluences; + + if ( material.morphTargets && morphPosition && morphInfluences ) { + + morphA.set( 0, 0, 0 ); + morphB.set( 0, 0, 0 ); + morphC.set( 0, 0, 0 ); + + for ( var i = 0, il = morphPosition.length; i < il; i ++ ) { + + var influence = morphInfluences[ i ]; + var morphAttribute = morphPosition[ i ]; + + if ( influence === 0 ) continue; + + tempA.fromBufferAttribute( morphAttribute, a ); + tempB.fromBufferAttribute( morphAttribute, b ); + tempC.fromBufferAttribute( morphAttribute, c ); + + morphA.addScaledVector( tempA.sub( vA ), influence ); + morphB.addScaledVector( tempB.sub( vB ), influence ); + morphC.addScaledVector( tempC.sub( vC ), influence ); + + } + + vA.add( morphA ); + vB.add( morphB ); + vC.add( morphC ); + + } + var intersection = checkIntersection( object, material, raycaster, ray, vA, vB, vC, intersectionPoint ); if ( intersection ) { @@ -232,6 +267,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { var a, b, c; var index = geometry.index; var position = geometry.attributes.position; + var morphPosition = geometry.morphAttributes.position; var uv = geometry.attributes.uv; var groups = geometry.groups; var drawRange = geometry.drawRange; @@ -259,7 +295,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { b = index.getX( j + 1 ); c = index.getX( j + 2 ); - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, uv, a, b, c ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c ); if ( intersection ) { @@ -284,7 +320,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { b = index.getX( i + 1 ); c = index.getX( i + 2 ); - intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, uv, a, b, c ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c ); if ( intersection ) { @@ -317,7 +353,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { b = j + 1; c = j + 2; - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, uv, a, b, c ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c ); if ( intersection ) { @@ -342,7 +378,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { b = i + 1; c = i + 2; - intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, uv, a, b, c ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c ); if ( intersection ) { -- GitLab