@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
132 lines (126 loc) • 4.76 kB
text/typescript
import {Vector2, Vector3, Vector4} from 'three';
import {CoreGroup} from '../../../../../core/geometry/Group';
import {COMPONENT_NAMES, vectorByAttribSize} from './Common';
import {AttribType} from '../../../../../core/geometry/Constant';
import {TypeAssert} from '../../../../poly/Assert';
import {CoreMask} from '../../../../../core/geometry/Mask';
import {AttribCreateSopParams} from '../../../../operations/sop/AttribCreate';
import {CoreObjectType} from '../../../../../core/geometry/ObjectContent';
import {BaseCoreObject} from '../../../../../core/geometry/entities/object/BaseCoreObject';
import {AttribCreateSopNodeParams, defaultAttribValue} from '../../../../operations/sop/utils/attribCreate/Common';
export async function addObjectAttributeWithExpression(
attribType: AttribType,
coreGroup: CoreGroup,
params: AttribCreateSopNodeParams,
pv: AttribCreateSopParams
) {
const coreObjects = CoreMask.filterCoreObjects(coreGroup, pv, coreGroup.allCoreObjects());
// add attrib if non existent
const attribName = pv.name;
const allCoreObjects = coreGroup.allCoreObjects();
const defaultValue = defaultAttribValue(pv);
if (defaultValue != null) {
for (const coreObject of allCoreObjects) {
if (!coreObject.hasAttribute(attribName)) {
coreObject.setAttribValue(attribName, defaultValue);
}
}
}
switch (attribType) {
case AttribType.NUMERIC:
await _addNumericAttributeToObject(coreObjects, params, pv);
return;
case AttribType.STRING:
await _addStringAttributeToObject(coreObjects, params, pv);
return;
}
TypeAssert.unreachable(attribType);
}
async function _addNumericAttributeToObject<T extends CoreObjectType>(
coreObjects: BaseCoreObject<T>[],
params: AttribCreateSopNodeParams,
pv: AttribCreateSopParams
) {
const param = [params.value1, params.value2, params.value3, params.value4][pv.size - 1];
const attribName = pv.name;
if (param.hasExpression()) {
if (pv.size == 1) {
if (param.expressionController) {
if (param.expressionController?.entitiesDependent()) {
await param.expressionController.computeExpressionForObjects(coreObjects, (coreObject, value) => {
coreObject.setAttribValue(attribName, value);
});
} else {
for (const coreObject of coreObjects) {
coreObject.setAttribValue(attribName, param.value);
}
}
}
} else {
const vparam = [params.value2, params.value3, params.value4][pv.size - 2];
const components = vparam.components;
const valuesByCoreObjectIndex: Map<number, Vector2 | Vector3 | Vector4> = new Map();
// for (let component_param of params) {
// values.push(component_param.value);
// }
const initVector = vectorByAttribSize(pv.size);
if (initVector) {
for (const coreObject of coreObjects) {
valuesByCoreObjectIndex.set(coreObject.index(), initVector.clone());
}
for (let componentIndex = 0; componentIndex < components.length; componentIndex++) {
const component_param = components[componentIndex];
const component_name = COMPONENT_NAMES[componentIndex];
if (
component_param.hasExpression() &&
component_param.expressionController &&
component_param.expressionController.entitiesDependent()
) {
await component_param.expressionController.computeExpressionForObjects(
coreObjects,
(coreObject, value) => {
const vector = valuesByCoreObjectIndex.get(coreObject.index()) as Vector4;
vector[component_name] = value;
}
);
} else {
for (const coreObject of coreObjects) {
const vector = valuesByCoreObjectIndex.get(coreObject.index()) as Vector4;
vector[component_name] = component_param.value;
}
}
}
for (let i = 0; i < coreObjects.length; i++) {
const coreObject = coreObjects[i];
const value = valuesByCoreObjectIndex.get(coreObject.index());
if (value != null) {
coreObject.setAttribValue(attribName, value);
}
}
}
}
} else {
// no need to do work here, as this will be done in the operation
}
}
async function _addStringAttributeToObject<T extends CoreObjectType>(
coreObjects: BaseCoreObject<T>[],
params: AttribCreateSopNodeParams,
pv: AttribCreateSopParams
) {
const param = params.string;
const attribName = pv.name;
if (param.hasExpression() && param.expressionController) {
if (param.expressionController.entitiesDependent()) {
await param.expressionController.computeExpressionForObjects(coreObjects, (coreObject, value) => {
coreObject.setAttribValue(attribName, value);
});
} else {
for (const coreObject of coreObjects) {
coreObject.setAttribValue(attribName, param.value);
}
}
} else {
// no need to do work here, as this will be done in the operation
}
}