Spaces:
Running
Running
| import { Vector3 } from '../math/Vector3.js'; | |
| import { Vector2 } from '../math/Vector2.js'; | |
| import { Sphere } from '../math/Sphere.js'; | |
| import { Ray } from '../math/Ray.js'; | |
| import { Matrix4 } from '../math/Matrix4.js'; | |
| import { Object3D } from '../core/Object3D.js'; | |
| import { Triangle } from '../math/Triangle.js'; | |
| import { DoubleSide, BackSide } from '../constants.js'; | |
| import { MeshBasicMaterial } from '../materials/MeshBasicMaterial.js'; | |
| import { BufferGeometry } from '../core/BufferGeometry.js'; | |
| const _inverseMatrix = /*@__PURE__*/ new Matrix4(); | |
| const _ray = /*@__PURE__*/ new Ray(); | |
| const _sphere = /*@__PURE__*/ new Sphere(); | |
| const _vA = /*@__PURE__*/ new Vector3(); | |
| const _vB = /*@__PURE__*/ new Vector3(); | |
| const _vC = /*@__PURE__*/ new Vector3(); | |
| const _tempA = /*@__PURE__*/ new Vector3(); | |
| const _tempB = /*@__PURE__*/ new Vector3(); | |
| const _tempC = /*@__PURE__*/ new Vector3(); | |
| const _morphA = /*@__PURE__*/ new Vector3(); | |
| const _morphB = /*@__PURE__*/ new Vector3(); | |
| const _morphC = /*@__PURE__*/ new Vector3(); | |
| const _uvA = /*@__PURE__*/ new Vector2(); | |
| const _uvB = /*@__PURE__*/ new Vector2(); | |
| const _uvC = /*@__PURE__*/ new Vector2(); | |
| const _intersectionPoint = /*@__PURE__*/ new Vector3(); | |
| const _intersectionPointWorld = /*@__PURE__*/ new Vector3(); | |
| class Mesh extends Object3D { | |
| constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) { | |
| super(); | |
| this.type = 'Mesh'; | |
| this.geometry = geometry; | |
| this.material = material; | |
| this.updateMorphTargets(); | |
| } | |
| copy(source) { | |
| super.copy(source); | |
| if (source.morphTargetInfluences !== undefined) { | |
| this.morphTargetInfluences = source.morphTargetInfluences.slice(); | |
| } | |
| if (source.morphTargetDictionary !== undefined) { | |
| this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); | |
| } | |
| this.material = source.material; | |
| this.geometry = source.geometry; | |
| return this; | |
| } | |
| updateMorphTargets() { | |
| const geometry = this.geometry; | |
| if (geometry.isBufferGeometry) { | |
| const morphAttributes = geometry.morphAttributes; | |
| const keys = Object.keys(morphAttributes); | |
| if (keys.length > 0) { | |
| const morphAttribute = morphAttributes[keys[0]]; | |
| if (morphAttribute !== undefined) { | |
| this.morphTargetInfluences = []; | |
| this.morphTargetDictionary = {}; | |
| for (let m = 0, ml = morphAttribute.length; m < ml; m++) { | |
| const name = morphAttribute[m].name || String(m); | |
| this.morphTargetInfluences.push(0); | |
| this.morphTargetDictionary[name] = m; | |
| } | |
| } | |
| } | |
| } else { | |
| const morphTargets = geometry.morphTargets; | |
| if (morphTargets !== undefined && morphTargets.length > 0) { | |
| console.error('THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); | |
| } | |
| } | |
| } | |
| raycast(raycaster, intersects) { | |
| const geometry = this.geometry; | |
| const material = this.material; | |
| const matrixWorld = this.matrixWorld; | |
| if (material === undefined) return; | |
| // Checking boundingSphere distance to ray | |
| if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); | |
| _sphere.copy(geometry.boundingSphere); | |
| _sphere.applyMatrix4(matrixWorld); | |
| if (raycaster.ray.intersectsSphere(_sphere) === false) return; | |
| // | |
| _inverseMatrix.copy(matrixWorld).invert(); | |
| _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix); | |
| // Check boundingBox before continuing | |
| if (geometry.boundingBox !== null) { | |
| if (_ray.intersectsBox(geometry.boundingBox) === false) return; | |
| } | |
| let intersection; | |
| if (geometry.isBufferGeometry) { | |
| const index = geometry.index; | |
| const position = geometry.attributes.position; | |
| const morphPosition = geometry.morphAttributes.position; | |
| const morphTargetsRelative = geometry.morphTargetsRelative; | |
| const uv = geometry.attributes.uv; | |
| const uv2 = geometry.attributes.uv2; | |
| const groups = geometry.groups; | |
| const drawRange = geometry.drawRange; | |
| if (index !== null) { | |
| // indexed buffer geometry | |
| if (Array.isArray(material)) { | |
| for (let i = 0, il = groups.length; i < il; i++) { | |
| const group = groups[i]; | |
| const groupMaterial = material[group.materialIndex]; | |
| const start = Math.max(group.start, drawRange.start); | |
| const end = Math.min(index.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); | |
| for (let j = start, jl = end; j < jl; j += 3) { | |
| const a = index.getX(j); | |
| const b = index.getX(j + 1); | |
| const c = index.getX(j + 2); | |
| intersection = checkBufferGeometryIntersection( | |
| this, | |
| groupMaterial, | |
| raycaster, | |
| _ray, | |
| position, | |
| morphPosition, | |
| morphTargetsRelative, | |
| uv, | |
| uv2, | |
| a, | |
| b, | |
| c | |
| ); | |
| if (intersection) { | |
| intersection.faceIndex = Math.floor(j / 3); // triangle number in indexed buffer semantics | |
| intersection.face.materialIndex = group.materialIndex; | |
| intersects.push(intersection); | |
| } | |
| } | |
| } | |
| } else { | |
| const start = Math.max(0, drawRange.start); | |
| const end = Math.min(index.count, drawRange.start + drawRange.count); | |
| for (let i = start, il = end; i < il; i += 3) { | |
| const a = index.getX(i); | |
| const b = index.getX(i + 1); | |
| const c = index.getX(i + 2); | |
| intersection = checkBufferGeometryIntersection( | |
| this, | |
| material, | |
| raycaster, | |
| _ray, | |
| position, | |
| morphPosition, | |
| morphTargetsRelative, | |
| uv, | |
| uv2, | |
| a, | |
| b, | |
| c | |
| ); | |
| if (intersection) { | |
| intersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics | |
| intersects.push(intersection); | |
| } | |
| } | |
| } | |
| } else if (position !== undefined) { | |
| // non-indexed buffer geometry | |
| if (Array.isArray(material)) { | |
| for (let i = 0, il = groups.length; i < il; i++) { | |
| const group = groups[i]; | |
| const groupMaterial = material[group.materialIndex]; | |
| const start = Math.max(group.start, drawRange.start); | |
| const end = Math.min(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); | |
| for (let j = start, jl = end; j < jl; j += 3) { | |
| const a = j; | |
| const b = j + 1; | |
| const c = j + 2; | |
| intersection = checkBufferGeometryIntersection( | |
| this, | |
| groupMaterial, | |
| raycaster, | |
| _ray, | |
| position, | |
| morphPosition, | |
| morphTargetsRelative, | |
| uv, | |
| uv2, | |
| a, | |
| b, | |
| c | |
| ); | |
| if (intersection) { | |
| intersection.faceIndex = Math.floor(j / 3); // triangle number in non-indexed buffer semantics | |
| intersection.face.materialIndex = group.materialIndex; | |
| intersects.push(intersection); | |
| } | |
| } | |
| } | |
| } else { | |
| const start = Math.max(0, drawRange.start); | |
| const end = Math.min(position.count, drawRange.start + drawRange.count); | |
| for (let i = start, il = end; i < il; i += 3) { | |
| const a = i; | |
| const b = i + 1; | |
| const c = i + 2; | |
| intersection = checkBufferGeometryIntersection( | |
| this, | |
| material, | |
| raycaster, | |
| _ray, | |
| position, | |
| morphPosition, | |
| morphTargetsRelative, | |
| uv, | |
| uv2, | |
| a, | |
| b, | |
| c | |
| ); | |
| if (intersection) { | |
| intersection.faceIndex = Math.floor(i / 3); // triangle number in non-indexed buffer semantics | |
| intersects.push(intersection); | |
| } | |
| } | |
| } | |
| } | |
| } else if (geometry.isGeometry) { | |
| console.error('THREE.Mesh.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); | |
| } | |
| } | |
| } | |
| Mesh.prototype.isMesh = true; | |
| function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) { | |
| let intersect; | |
| if (material.side === BackSide) { | |
| intersect = ray.intersectTriangle(pC, pB, pA, true, point); | |
| } else { | |
| intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point); | |
| } | |
| if (intersect === null) return null; | |
| _intersectionPointWorld.copy(point); | |
| _intersectionPointWorld.applyMatrix4(object.matrixWorld); | |
| const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld); | |
| if (distance < raycaster.near || distance > raycaster.far) return null; | |
| return { | |
| distance: distance, | |
| point: _intersectionPointWorld.clone(), | |
| object: object, | |
| }; | |
| } | |
| function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c) { | |
| _vA.fromBufferAttribute(position, a); | |
| _vB.fromBufferAttribute(position, b); | |
| _vC.fromBufferAttribute(position, c); | |
| const morphInfluences = object.morphTargetInfluences; | |
| if (morphPosition && morphInfluences) { | |
| _morphA.set(0, 0, 0); | |
| _morphB.set(0, 0, 0); | |
| _morphC.set(0, 0, 0); | |
| for (let i = 0, il = morphPosition.length; i < il; i++) { | |
| const influence = morphInfluences[i]; | |
| const morphAttribute = morphPosition[i]; | |
| if (influence === 0) continue; | |
| _tempA.fromBufferAttribute(morphAttribute, a); | |
| _tempB.fromBufferAttribute(morphAttribute, b); | |
| _tempC.fromBufferAttribute(morphAttribute, c); | |
| if (morphTargetsRelative) { | |
| _morphA.addScaledVector(_tempA, influence); | |
| _morphB.addScaledVector(_tempB, influence); | |
| _morphC.addScaledVector(_tempC, influence); | |
| } else { | |
| _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); | |
| } | |
| if (object.isSkinnedMesh) { | |
| object.boneTransform(a, _vA); | |
| object.boneTransform(b, _vB); | |
| object.boneTransform(c, _vC); | |
| } | |
| const intersection = checkIntersection(object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint); | |
| if (intersection) { | |
| if (uv) { | |
| _uvA.fromBufferAttribute(uv, a); | |
| _uvB.fromBufferAttribute(uv, b); | |
| _uvC.fromBufferAttribute(uv, c); | |
| intersection.uv = Triangle.getUV(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()); | |
| } | |
| if (uv2) { | |
| _uvA.fromBufferAttribute(uv2, a); | |
| _uvB.fromBufferAttribute(uv2, b); | |
| _uvC.fromBufferAttribute(uv2, c); | |
| intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()); | |
| } | |
| const face = { | |
| a: a, | |
| b: b, | |
| c: c, | |
| normal: new Vector3(), | |
| materialIndex: 0, | |
| }; | |
| Triangle.getNormal(_vA, _vB, _vC, face.normal); | |
| intersection.face = face; | |
| } | |
| return intersection; | |
| } | |
| export { Mesh }; | |