@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
143 lines (133 loc) • 4.6 kB
text/typescript
import {Material, Matrix4, Box3, Sphere, Object3D, Vector3, Quaternion, Euler} from 'three';
import {SDFGeometry, SDFObjectType, SDFTesselationParams} from './SDFCommon';
import {ObjectContent, CoreObjectType, ObjectGeometryMap, objectContentCopyProperties} from '../../ObjectContent';
import {SDFGeometryToObject3D} from './toObject3D/SDFToObject3D';
import {isArray} from '../../../Type';
import {Number3} from '../../../../types/GlobalTypes';
import {SDFLoaderSync} from './SDFLoaderSync';
const _box = new Box3();
const _size = new Vector3();
const _t = new Vector3();
const _q = new Quaternion();
const _s = new Vector3();
const _euler = new Euler();
const _tN3: Number3 = [0, 0, 0];
const _rN3: Number3 = [0, 0, 0];
const _sN3: Number3 = [1, 1, 1];
// function cloneFloat32Array(src: Float32Array) {
// const clone = new Float32Array(src.length);
// let i = 0;
// for (let elem of src) {
// clone[i] = elem;
// i++;
// }
// console.log(src, clone);
// return clone;
// }
// function cloneUint32Array(src: Uint32Array) {
// const clone = new Uint32Array(src.length);
// let i = 0;
// for (let elem of src) {
// clone[i] = elem;
// i++;
// }
// console.log(src, clone);
// return clone;
// }
// function cloneSDFMesh(mesh:Mesh){
// const manifold = SDFLoaderSync.manifold();
// const clonedMesh = new manifold.Mesh({
// numProp: mesh.numProp,
// vertProperties: cloneFloat32Array(mesh.vertProperties),
// triVerts: cloneUint32Array(mesh.triVerts),
// mergeFromVert: mesh.mergeFromVert ? cloneUint32Array(mesh.mergeFromVert) : undefined,
// mergeToVert: mesh.mergeToVert ? cloneUint32Array(mesh.mergeToVert) : undefined,
// runIndex: mesh.runIndex ? cloneUint32Array(mesh.runIndex) : undefined,
// runOriginalID: mesh.runOriginalID ? cloneUint32Array(mesh.runOriginalID) : undefined,
// runTransform: mesh.runTransform ? cloneFloat32Array(mesh.runTransform) : undefined,
// faceID: mesh.faceID ? cloneUint32Array(mesh.faceID) : undefined,
// halfedgeTangent: mesh.halfedgeTangent ? cloneFloat32Array(mesh.halfedgeTangent) : undefined,
// });
// return clonedMesh
// }
export class SDFObject implements ObjectContent<CoreObjectType.SDF> {
public visible = true;
get geometry() {
return this._geometry as ObjectGeometryMap[CoreObjectType.SDF];
}
get type() {
return this._type;
}
userData = {};
name = '';
castShadow = true;
receiveShadow = true;
renderOrder = 0;
frustumCulled = true;
matrixAutoUpdate = false;
material: Material | undefined;
children: ObjectContent<CoreObjectType.SDF>[] = [];
parent: ObjectContent<CoreObjectType.SDF> | null = null;
private _type: SDFObjectType;
constructor(private _geometry: SDFGeometry) {
this._type = SDFObjectType.DEFAULT;
}
SDFGeometry() {
return this.geometry! as SDFGeometry;
}
dispose() {}
applyMatrix4(matrix: Matrix4) {
// matrix is decomposed so that we can use .translate.rotate.scale,
// as .transform isn't yet available
matrix.decompose(_t, _q, _s);
_euler.setFromQuaternion(_q);
_t.toArray(_tN3);
_s.toArray(_sN3);
// euler.toArray makes the array becomes Number4
_rN3[0] = _euler.x;
_rN3[1] = _euler.y;
_rN3[2] = _euler.z;
const geometry = this.geometry.translate(_tN3).rotate(_rN3).scale(_sN3);
this._geometry = geometry;
}
add(...object: ObjectContent<CoreObjectType>[]) {}
remove(...object: ObjectContent<CoreObjectType>[]) {}
dispatchEvent(event: {type: string}) {}
traverse(callback: (object: SDFObject) => any) {
callback(this);
}
clone(): SDFObject {
const manifold = SDFLoaderSync.manifold();
const mesh = this.geometry.getMesh();
const clonedGeometry = new manifold.Manifold(mesh);
// const clonedGeometry = this.geometry.asOriginal();
const clone = new SDFObject(clonedGeometry);
objectContentCopyProperties(this, clone);
return clone;
}
toObject3D(tesselationParams: SDFTesselationParams): Object3D | Object3D[] | undefined {
const object = SDFGeometryToObject3D(this.geometry, tesselationParams);
if (object) {
if (isArray(object)) {
for (const element of object) {
objectContentCopyProperties(this, element);
}
} else {
objectContentCopyProperties(this, object);
}
}
return object;
}
boundingBox(target: Box3): void {
const bbox = this.geometry.boundingBox();
target.min.fromArray(bbox.min);
target.max.fromArray(bbox.max);
}
boundingSphere(target: Sphere): void {
this.boundingBox(_box);
_box.getCenter(target.center);
_box.getSize(_size);
const diameter = Math.max(_size.x, _size.y, _size.z);
target.radius = diameter * 0.5;
}
}