UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

583 lines (545 loc) 15.9 kB
import {Triangle, Mesh, Intersection, Color, Vector2, Vector3, Vector4, BufferAttribute, Face} from 'three'; import {NamedFunction2, NamedFunction3, NamedFunction4} from './_Base'; import {corePointClassFactory} from '../../core/geometry/CoreObjectFactory'; const positionA = new Vector3(); const positionB = new Vector3(); const positionC = new Vector3(); const _ca = new Color(); const _cb = new Color(); const _cc = new Color(); const _v2a = new Vector2(); const _v2b = new Vector2(); const _v2c = new Vector2(); const _v3a = new Vector3(); const _v3b = new Vector3(); const _v3c = new Vector3(); const _v4a = new Vector4(); const _v4b = new Vector4(); const _v4c = new Vector4(); const _v3 = new Vector3(); const _tmpColorA = new Color(); const _tmpColorB = new Color(); const _tmpColorC = new Color(); function triangleGetInterpolatedNumber( point: Vector3, p1: Vector3, p2: Vector3, p3: Vector3, va: number, vb: number, vc: number ) { Triangle.getBarycoord(point, p1, p2, p3, _v3); return va * _v3.x + vb * _v3.y + vc * _v3.z; } function triangleGetInterpolatedColor( point: Vector3, p1: Vector3, p2: Vector3, p3: Vector3, va: Color, vb: Color, vc: Color, target: Color ) { Triangle.getBarycoord(point, p1, p2, p3, _v3); target.r = 0; target.g = 0; target.b = 0; _tmpColorA.copy(va).multiplyScalar(_v3.x); _tmpColorB.copy(vb).multiplyScalar(_v3.y); _tmpColorC.copy(vc).multiplyScalar(_v3.z); target.add(_tmpColorA).add(_tmpColorB).add(_tmpColorC); return target; } function triangleGetInterpolatedVector2( point: Vector3, p1: Vector3, p2: Vector3, p3: Vector3, va: Vector2, vb: Vector2, vc: Vector2, target: Vector2 ) { Triangle.getBarycoord(point, p1, p2, p3, _v3); target.set(0, 0); target.addScaledVector(va, _v3.x); target.addScaledVector(vb, _v3.y); target.addScaledVector(vc, _v3.z); return target; } function triangleGetInterpolatedVector3( point: Vector3, p1: Vector3, p2: Vector3, p3: Vector3, va: Vector3, vb: Vector3, vc: Vector3, target: Vector3 ) { Triangle.getBarycoord(point, p1, p2, p3, _v3); target.set(0, 0, 0); target.addScaledVector(va, _v3.x); target.addScaledVector(vb, _v3.y); target.addScaledVector(vc, _v3.z); return target; } function triangleGetInterpolatedVector4( point: Vector3, p1: Vector3, p2: Vector3, p3: Vector3, va: Vector4, vb: Vector4, vc: Vector4, target: Vector4 ) { Triangle.getBarycoord(point, p1, p2, p3, _v3); target.set(0, 0, 0, 0); target.addScaledVector(va, _v3.x); target.addScaledVector(vb, _v3.y); target.addScaledVector(vc, _v3.z); return target; } function nearestFaceVertexIndex(intersection: Intersection, positionAttribute: BufferAttribute, face: Face): number { const intersectionPos = intersection.point; positionA.fromBufferAttribute(positionAttribute, face.a); positionB.fromBufferAttribute(positionAttribute, face.b); positionC.fromBufferAttribute(positionAttribute, face.c); const distanceA = positionA.distanceTo(intersectionPos); const distanceB = positionB.distanceTo(intersectionPos); const distanceC = positionC.distanceTo(intersectionPos); if (distanceA < distanceB && distanceA < distanceC) { return face.a; } if (distanceB < distanceA && distanceB < distanceC) { return face.b; } return face.c; } function nonInterpolatedVertexIndex(intersection: Intersection | undefined): number | void { if (!intersection) { return; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return; } const positionAttribute = geometry.getAttribute('position') as BufferAttribute; if (!positionAttribute) { return; } const face = intersection.face; if (!face) { return; } return nearestFaceVertexIndex(intersection, positionAttribute, face); } // // // number // // export class getIntersectionAttributeNumberNearest extends NamedFunction3<[Intersection | undefined, string, number]> { static override type() { return 'getIntersectionAttributeNumberNearest'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: number): number { if (!intersection) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } const value = attribute.array[vertexIndex]; return value; } } export class getIntersectionAttributeNumberInterpolated extends NamedFunction3< [Intersection | undefined, string, number] > { static override type() { return 'getIntersectionAttributeNumberInterpolated'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: number): number { if (!intersection) { return notFoundValue; } const face = intersection.face; if (!face) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } const positionAttribute = geometry.getAttribute('position') as BufferAttribute; if (!positionAttribute) { return notFoundValue; } const intersectionPos = intersection.point; positionA.fromBufferAttribute(positionAttribute, face.a); positionB.fromBufferAttribute(positionAttribute, face.b); positionC.fromBufferAttribute(positionAttribute, face.c); const va = attribute.array[face.a]; const vb = attribute.array[face.b]; const vc = attribute.array[face.c]; return triangleGetInterpolatedNumber(intersectionPos, positionA, positionB, positionC, va, vb, vc); } } // // // Color // // export class getIntersectionAttributeColorNearest extends NamedFunction4< [Intersection | undefined, string, Color, Color] > { static override type() { return 'getIntersectionAttributeColorNearest'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: Color, target: Color): Color { if (!intersection) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } return target.fromBufferAttribute(attribute, vertexIndex); } } export class getIntersectionAttributeColorInterpolated extends NamedFunction4< [Intersection | undefined, string, Color, Color] > { static override type() { return 'getIntersectionAttributeColorInterpolated'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: Color, target: Color): Color { if (!intersection) { return notFoundValue; } const face = intersection.face; if (!face) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } const positionAttribute = geometry.getAttribute('position') as BufferAttribute; if (!positionAttribute) { return notFoundValue; } const intersectionPos = intersection.point; positionA.fromBufferAttribute(positionAttribute, face.a); positionB.fromBufferAttribute(positionAttribute, face.b); positionC.fromBufferAttribute(positionAttribute, face.c); _ca.fromBufferAttribute(attribute, face.a); _cb.fromBufferAttribute(attribute, face.b); _cc.fromBufferAttribute(attribute, face.c); return triangleGetInterpolatedColor(intersectionPos, positionA, positionB, positionC, _ca, _cb, _cc, target); } } // // // Color // // const notFoundValueStr = ''; export class getIntersectionAttributeStringNearest extends NamedFunction2<[Intersection | undefined, string]> { static override type() { return 'getIntersectionAttributeStringNearest'; } func(intersection: Intersection | undefined, attribName: string): string { if (!intersection) { return notFoundValueStr; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValueStr; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValueStr; } const corePointClass = corePointClassFactory(intersection.object); const result = corePointClass.stringAttribValue(intersection.object, vertexIndex, attribName); if (result == null) { return notFoundValueStr; } return result; } } // // // Vector2 // // export class getIntersectionAttributeVector2Nearest extends NamedFunction4< [Intersection | undefined, string, Vector2, Vector2] > { static override type() { return 'getIntersectionAttributeVector2Nearest'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: Vector2, target: Vector2): Vector2 { if (!intersection) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } return target.fromBufferAttribute(attribute, vertexIndex); } } export class getIntersectionAttributeVector2Interpolated extends NamedFunction4< [Intersection | undefined, string, Vector2, Vector2] > { static override type() { return 'getIntersectionAttributeVector2Interpolated'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: Vector2, target: Vector2): Vector2 { if (!intersection) { return notFoundValue; } const face = intersection.face; if (!face) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } const positionAttribute = geometry.getAttribute('position') as BufferAttribute; if (!positionAttribute) { return notFoundValue; } const intersectionPos = intersection.point; positionA.fromBufferAttribute(positionAttribute, face.a); positionB.fromBufferAttribute(positionAttribute, face.b); positionC.fromBufferAttribute(positionAttribute, face.c); _v2a.fromBufferAttribute(attribute, face.a); _v2b.fromBufferAttribute(attribute, face.b); _v2c.fromBufferAttribute(attribute, face.c); return triangleGetInterpolatedVector2( intersectionPos, positionA, positionB, positionC, _v2a, _v2b, _v2c, target ); } } // // // Vector3 // // export class getIntersectionAttributeVector3Nearest extends NamedFunction4< [Intersection | undefined, string, Vector3, Vector3] > { static override type() { return 'getIntersectionAttributeVector3Nearest'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: Vector3, target: Vector3): Vector3 { if (!intersection) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } return target.fromBufferAttribute(attribute, vertexIndex); } } export class getIntersectionAttributeVector3Interpolated extends NamedFunction4< [Intersection | undefined, string, Vector3, Vector3] > { static override type() { return 'getIntersectionAttributeVector3Interpolated'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: Vector3, target: Vector3): Vector3 { if (!intersection) { return notFoundValue; } const face = intersection.face; if (!face) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } const positionAttribute = geometry.getAttribute('position') as BufferAttribute; if (!positionAttribute) { return notFoundValue; } const intersectionPos = intersection.point; positionA.fromBufferAttribute(positionAttribute, face.a); positionB.fromBufferAttribute(positionAttribute, face.b); positionC.fromBufferAttribute(positionAttribute, face.c); _v3a.fromBufferAttribute(attribute, face.a); _v3b.fromBufferAttribute(attribute, face.b); _v3c.fromBufferAttribute(attribute, face.c); return triangleGetInterpolatedVector3( intersectionPos, positionA, positionB, positionC, _v3a, _v3b, _v3c, target ); } } // // // Vector4 // // export class getIntersectionAttributeVector4Nearest extends NamedFunction4< [Intersection | undefined, string, Vector4, Vector4] > { static override type() { return 'getIntersectionAttributeVector4Nearest'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: Vector4, target: Vector4): Vector4 { if (!intersection) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } return target.fromBufferAttribute(attribute, vertexIndex); } } export class getIntersectionAttributeVector4Interpolated extends NamedFunction4< [Intersection | undefined, string, Vector4, Vector4] > { static override type() { return 'getIntersectionAttributeVector4Interpolated'; } func(intersection: Intersection | undefined, attribName: string, notFoundValue: Vector4, target: Vector4): Vector4 { if (!intersection) { return notFoundValue; } const face = intersection.face; if (!face) { return notFoundValue; } const geometry = (intersection.object as Mesh).geometry; if (!geometry) { return notFoundValue; } const vertexIndex = nonInterpolatedVertexIndex(intersection); if (vertexIndex == null) { return notFoundValue; } const attribute = geometry.getAttribute(attribName) as BufferAttribute; if (!attribute) { return notFoundValue; } const positionAttribute = geometry.getAttribute('position') as BufferAttribute; if (!positionAttribute) { return notFoundValue; } const intersectionPos = intersection.point; positionA.fromBufferAttribute(positionAttribute, face.a); positionB.fromBufferAttribute(positionAttribute, face.b); positionC.fromBufferAttribute(positionAttribute, face.c); _v4a.fromBufferAttribute(attribute, face.a); _v4b.fromBufferAttribute(attribute, face.b); _v4c.fromBufferAttribute(attribute, face.c); return triangleGetInterpolatedVector4( intersectionPos, positionA, positionB, positionC, _v4a, _v4b, _v4c, target ); } }