@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
180 lines (171 loc) • 6.05 kB
text/typescript
import {Object3D, Color} from 'three';
import {PolyEngine} from '../../../../engine/Poly';
import {isArray} from '../../../Type';
import {
registerFactoryFunctions,
CoreFactoryFunctions,
CorePointClassFactoryCheckFunction,
CorePointInstanceFactoryCheckFunction,
CoreVertexClassFactoryCheckFunction,
CoreVertexInstanceFactoryCheckFunction,
CorePrimitiveClassFactoryCheckFunction,
CorePrimitiveInstanceFactoryCheckFunction,
CoreObjectClassFactoryCheckFunction,
CoreObjectInstanceFactoryCheckFunction,
} from '../../CoreObjectFactory';
import {BaseSopNodeType} from '../../../../engine/nodes/sop/_Base';
import {SpecializedChildrenHook} from '../../../../engine/poly/PolySpecializedChildrenController';
import {CoreGroup} from '../../Group';
import {CoreObjectType, ObjectContent} from '../../ObjectContent';
import {CSG_GEOMETRY_TYPES_SET, CsgGeometryType, CSGTesselationParams, CSGOBJTesselationParams} from './CsgCommon';
import {CsgCoreObject} from './CsgCoreObject';
import {CsgPoint} from './CsgPoint';
import {CsgVertex} from './CsgVertex';
import {CsgObject} from './CsgObject';
import {TypeAssert} from '../../../../engine/poly/Assert';
import {CsgPrimitivePath2} from './CsgPrimitivePath2';
import {CsgPrimitiveGeom2} from './CsgPrimitiveGeom2';
import {CsgPrimitiveGeom3} from './CsgPrimitiveGeom3';
const CSG_TESSELATION_PARAMS: CSGTesselationParams = {
facetAngle: 0,
wireframe: false,
meshesColor: new Color(),
linesColor: new Color(),
};
function updateCSGTesselationParams(params: CSGOBJTesselationParams) {
CSG_TESSELATION_PARAMS.facetAngle = params.CSGFacetAngle;
CSG_TESSELATION_PARAMS.wireframe = params.CSGWireframe;
CSG_TESSELATION_PARAMS.meshesColor.copy(params.CSGMeshesColor);
CSG_TESSELATION_PARAMS.linesColor.copy(params.CSGLinesColor);
}
const onAddSpecializedChildren: SpecializedChildrenHook = (
displayNode: BaseSopNodeType,
coreGroup: CoreGroup,
newObjects: Object3D[],
params: CSGOBJTesselationParams
) => {
let newObjectsAreDifferent = false;
const newCsgObjects = coreGroup.csgObjects();
if (newCsgObjects && newCsgObjects.length != 0) {
updateCSGTesselationParams(params);
for (const csgObject of newCsgObjects) {
const newObject3D = csgObject.toObject3D(CSG_TESSELATION_PARAMS);
if (newObject3D) {
newObjectsAreDifferent = true;
if (isArray(newObject3D)) {
newObjects.push(...newObject3D);
} else {
newObjects.push(newObject3D);
}
}
}
}
return newObjectsAreDifferent;
};
export const primitiveClassFactoryNonAbstract = (object: ObjectContent<CoreObjectType>) => {
if (CSG_GEOMETRY_TYPES_SET.has(object.type as CsgGeometryType)) {
// return CsgPrimitive;
const type = object.type as CsgGeometryType;
switch (type) {
case CsgGeometryType.PATH2: {
return CsgPrimitivePath2;
}
case CsgGeometryType.GEOM2: {
return CsgPrimitiveGeom2;
}
case CsgGeometryType.GEOM3: {
return CsgPrimitiveGeom3;
}
}
TypeAssert.unreachable(type);
}
};
export function onCsgModuleRegister(poly: PolyEngine) {
//
//
// CORE OBJECT CHECKS
//
//
// point methods
const pointClassFactory: CorePointClassFactoryCheckFunction = (object: ObjectContent<CoreObjectType>) => {
if (CSG_GEOMETRY_TYPES_SET.has(object.type as CsgGeometryType)) {
return CsgPoint;
}
};
const pointInstanceFactory: CorePointInstanceFactoryCheckFunction = (
object: ObjectContent<CoreObjectType>,
index: number = 0
) => {
if (CSG_GEOMETRY_TYPES_SET.has(object.type as CsgGeometryType)) {
return new CsgPoint(object as CsgObject<CsgGeometryType>, index);
}
};
// vertex methods
const vertexClassFactory: CoreVertexClassFactoryCheckFunction = (object: ObjectContent<CoreObjectType>) => {
if (CSG_GEOMETRY_TYPES_SET.has(object.type as CsgGeometryType)) {
return CsgVertex;
}
};
const vertexInstanceFactory: CoreVertexInstanceFactoryCheckFunction = (
object: ObjectContent<CoreObjectType>,
index: number = 0
) => {
if (CSG_GEOMETRY_TYPES_SET.has(object.type as CsgGeometryType)) {
return new CsgVertex(object as CsgObject<CsgGeometryType>, index);
}
};
// primitive methods
const primitiveClassFactory: CorePrimitiveClassFactoryCheckFunction = primitiveClassFactoryNonAbstract;
const primitiveInstanceFactory: CorePrimitiveInstanceFactoryCheckFunction = (
object: ObjectContent<CoreObjectType>,
index: number = 0
) => {
if (CSG_GEOMETRY_TYPES_SET.has(object.type as CsgGeometryType)) {
// return new CsgPrimitive(object as CsgObject<CsgGeometryType>, index);
const type = object.type as CsgGeometryType;
switch (type) {
case CsgGeometryType.PATH2: {
return new CsgPrimitivePath2(object as CsgObject<CsgGeometryType.PATH2>, index);
}
case CsgGeometryType.GEOM2: {
return new CsgPrimitiveGeom2(object as CsgObject<CsgGeometryType.GEOM2>, index);
}
case CsgGeometryType.GEOM3: {
return new CsgPrimitiveGeom3(object as CsgObject<CsgGeometryType.GEOM3>, index);
}
}
TypeAssert.unreachable(type);
}
};
// object methods
const objectClassFactory: CoreObjectClassFactoryCheckFunction = (object: ObjectContent<CoreObjectType>) => {
if (CSG_GEOMETRY_TYPES_SET.has(object.type as CsgGeometryType)) {
return CsgCoreObject;
}
};
const objectInstanceFactory: CoreObjectInstanceFactoryCheckFunction = (
object: ObjectContent<CoreObjectType>,
index: number = 0
) => {
if (CSG_GEOMETRY_TYPES_SET.has(object.type as CsgGeometryType)) {
return new CsgCoreObject(object as CsgObject<CsgGeometryType>, index);
}
};
const factoryFunctions: CoreFactoryFunctions = {
pointClass: pointClassFactory,
pointInstance: pointInstanceFactory,
vertexClass: vertexClassFactory,
vertexInstance: vertexInstanceFactory,
primitiveClass: primitiveClassFactory,
primitiveInstance: primitiveInstanceFactory,
objectClass: objectClassFactory,
objectInstance: objectInstanceFactory,
};
registerFactoryFunctions(factoryFunctions);
//
//
// SPECIALIZED CHILDREN
//
//
poly.specializedChildren.registerHook('CSG', onAddSpecializedChildren);
}