@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
90 lines (86 loc) • 3.12 kB
text/typescript
import {Intersection, Vector2, Vector3, Mesh, BufferGeometry, BufferAttribute, Triangle, Points} from 'three';
import {TypeAssert} from '../../../engine/poly/Assert';
import {AttribType, objectTypeFromObject, ObjectType} from '../Constant';
import {corePointClassFactory} from '../CoreObjectFactory';
const _vA = new Vector3();
const _vB = new Vector3();
const _vC = new Vector3();
const _uvA = new Vector2();
const _uvB = new Vector2();
const _uvC = new Vector2();
const _hitUV = new Vector2();
export function resolveIntersectGeometryAttribute(
intersection: Intersection,
attribName: string,
attribType: AttribType
) {
const objectType = objectTypeFromObject(intersection.object);
switch (objectType) {
case ObjectType.MESH:
return resolveGeometryAttributeForMesh(intersection, attribName, attribType);
case ObjectType.POINTS:
return resolveGeometryAttributeForPoint(intersection, attribName, attribType);
}
// TODO: have the raycast cpu controller work with all object types
// TypeAssert.unreachable(object_type)
}
function resolveGeometryAttributeForMesh(intersection: Intersection, attribName: string, attribType: AttribType) {
const geometry = (intersection.object as Mesh).geometry as BufferGeometry;
if (geometry) {
const attribute = geometry.getAttribute(attribName) as BufferAttribute;
if (attribute) {
switch (attribType) {
case AttribType.NUMERIC: {
const position = geometry.getAttribute('position') as BufferAttribute;
if (intersection.face) {
_vA.fromBufferAttribute(position, intersection.face.a);
_vB.fromBufferAttribute(position, intersection.face.b);
_vC.fromBufferAttribute(position, intersection.face.c);
_uvA.fromBufferAttribute(attribute, intersection.face.a);
_uvB.fromBufferAttribute(attribute, intersection.face.b);
_uvC.fromBufferAttribute(attribute, intersection.face.c);
const uv = Triangle.getInterpolation(
intersection.point,
_vA,
_vB,
_vC,
_uvA,
_uvB,
_uvC,
_hitUV
);
if (uv) {
intersection.uv = uv;
}
return _hitUV.x;
}
return;
}
case AttribType.STRING: {
const corePointClass = corePointClassFactory(intersection.object);
return corePointClass.stringAttribValue(intersection.object, 0, attribName);
}
}
TypeAssert.unreachable(attribType);
}
}
}
function resolveGeometryAttributeForPoint(intersection: Intersection, attribName: string, attribType: AttribType) {
const geometry = (intersection.object as Points).geometry as BufferGeometry;
if (geometry && intersection.index != null) {
switch (attribType) {
case AttribType.NUMERIC: {
const attribute = geometry.getAttribute(attribName) as BufferAttribute | undefined;
if (attribute) {
return attribute.array[intersection.index];
}
return;
}
case AttribType.STRING: {
const corePointClass = corePointClassFactory(intersection.object);
return corePointClass.stringAttribValue(intersection.object, intersection.index, attribName);
}
}
TypeAssert.unreachable(attribType);
}
}