@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
108 lines (102 loc) • 4.34 kB
text/typescript
/**
* Updates points with JS nodes
*
*
*/
import {Vector3, BufferAttribute} from 'three';
import {SopType} from '../../poly/registers/nodes/types/Sop';
import {PointBuilderPersistedConfig} from '../js/code/assemblers/pointBuilder/PointBuilderPersistedConfig';
import {AssemblerName} from '../../poly/registers/assemblers/_BaseRegister';
import {BasePointBuilderSopNode, BasePointBuilderSopParamsConfig} from './_BasePointBuilder';
import {PointBuilderEvaluator} from '../js/code/assemblers/pointBuilder/PointBuilderEvaluator';
import {PointContainer} from '../js/code/assemblers/pointBuilder/PointBuilderAssemblerCommon';
import {Attribute} from '../../../core/geometry/Attribute';
import {ParamConfig} from '../utils/params/ParamsConfig';
import {isBooleanTrue} from '../../../core/Type';
import {pointsCountFromObject} from '../../../core/geometry/entities/point/CorePointUtils';
import {CoreObjectType, ObjectContent} from '../../../core/geometry/ObjectContent';
import {corePointClassFactory} from '../../../core/geometry/CoreObjectFactory';
class PointBuilderSopParamsConfig extends BasePointBuilderSopParamsConfig {
/** @param updateNormals */
updateNormals = ParamConfig.BOOLEAN(1);
}
const ParamsConfig = new PointBuilderSopParamsConfig();
export class PointBuilderSopNode extends BasePointBuilderSopNode<PointBuilderSopParamsConfig> {
override paramsConfig = ParamsConfig;
static override type() {
return SopType.POINT_BUILDER;
}
override readonly persisted_config: PointBuilderPersistedConfig = new PointBuilderPersistedConfig(this);
public override usedAssembler(): Readonly<AssemblerName.JS_POINT_BUILDER> {
return AssemblerName.JS_POINT_BUILDER;
}
protected _pointContainer: PointContainer = {
position: new Vector3(),
normal: new Vector3(),
ptnum: -1,
objnum: -1,
normalsUpdated: false,
};
protected _processObject<T extends CoreObjectType>(
object: ObjectContent<T>,
objnum: number,
evaluator: PointBuilderEvaluator
) {
this._pointContainer.objnum = objnum;
this._pointContainer.normalsUpdated = false;
const readAttributeOptions = this._checkRequiredReadAttributes(object);
const writeAttributeOptions = this._checkRequiredWriteAttributes(object);
const readAttribNames = readAttributeOptions ? readAttributeOptions.attribNames : [];
const readAttributeByName = readAttributeOptions ? readAttributeOptions.attributeByName : new Map();
const attribTypeByName = readAttributeOptions ? readAttributeOptions.attribTypeByName : new Map();
const writeAttribNames = writeAttributeOptions ? writeAttributeOptions.attribNames : [];
const writeAttributeByName = writeAttributeOptions ? writeAttributeOptions.attributeByName : new Map();
this._resetRequiredAttributes();
const pointsCount = pointsCountFromObject(object);
const corePointClass = corePointClassFactory(object);
const positionAttrib = corePointClass.attribute(object, Attribute.POSITION) as BufferAttribute | undefined;
const normalAttrib = corePointClass.attribute(object, Attribute.NORMAL) as BufferAttribute | undefined;
const hasPosition = positionAttrib != null;
const hasNormal = normalAttrib != null;
if (!hasPosition) {
this._pointContainer.position.set(0, 0, 0);
}
if (!hasNormal) {
this._pointContainer.normal.set(0, 1, 0);
}
for (let ptnum = 0; ptnum < pointsCount; ptnum++) {
this._pointContainer.ptnum = ptnum;
// read attributes
if (hasPosition) {
this._pointContainer.position.fromBufferAttribute(positionAttrib, ptnum);
}
if (hasNormal) {
this._pointContainer.normal.fromBufferAttribute(normalAttrib, ptnum);
}
this._readRequiredAttributes(ptnum, readAttribNames, readAttributeByName, attribTypeByName);
// eval function
evaluator();
// write back
if (hasPosition) {
positionAttrib.setXYZ(
ptnum,
this._pointContainer.position.x,
this._pointContainer.position.y,
this._pointContainer.position.z
);
}
if (hasNormal) {
normalAttrib.setXYZ(
ptnum,
this._pointContainer.normal.x,
this._pointContainer.normal.y,
this._pointContainer.normal.z
);
}
this._writeRequiredAttributes(ptnum, writeAttribNames, writeAttributeByName);
}
if (isBooleanTrue(this.pv.updateNormals) && !this._pointContainer.normalsUpdated) {
corePointClass.computeNormals(object);
}
}
}