polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
144 lines (137 loc) • 4.72 kB
text/typescript
import {DeleteSopNode} from '../../Delete';
import {ATTRIBUTE_TYPES, AttribType, AttribSize, ATTRIBUTE_SIZES} from '../../../../../core/geometry/Constant';
import {TypeAssert} from '../../../../poly/Assert';
import {Vector2} from 'three/src/math/Vector2';
import {Vector3} from 'three/src/math/Vector3';
import {Vector4} from 'three/src/math/Vector4';
import {CoreEntity} from '../../../../../core/geometry/Entity';
export enum ComparisonOperator {
EQUAL = '==',
LESS_THAN = '<',
EQUAL_OR_LESS_THAN = '<=',
EQUAL_OR_GREATER_THAN = '>=',
GREATER_THAN = '>',
DIFFERENT = '!=',
}
export const COMPARISON_OPERATORS: Array<ComparisonOperator> = [
ComparisonOperator.EQUAL,
ComparisonOperator.LESS_THAN,
ComparisonOperator.EQUAL_OR_LESS_THAN,
ComparisonOperator.EQUAL_OR_GREATER_THAN,
ComparisonOperator.GREATER_THAN,
ComparisonOperator.DIFFERENT,
];
type CompareMethodFloat = {[key in ComparisonOperator]: (n1: number, n2: number) => boolean};
const COMPARE_METHOD_FLOAT: CompareMethodFloat = {
[ComparisonOperator.EQUAL]: (n1: number, n2: number) => {
return n1 == n2;
},
[ComparisonOperator.LESS_THAN]: (n1: number, n2: number) => {
return n1 < n2;
},
[ComparisonOperator.EQUAL_OR_LESS_THAN]: (n1: number, n2: number) => {
return n1 <= n2;
},
[ComparisonOperator.EQUAL_OR_GREATER_THAN]: (n1: number, n2: number) => {
return n1 >= n2;
},
[ComparisonOperator.GREATER_THAN]: (n1: number, n2: number) => {
return n1 > n2;
},
[ComparisonOperator.DIFFERENT]: (n1: number, n2: number) => {
return n1 != n2;
},
};
export const ComparisonOperatorMenuEntries = COMPARISON_OPERATORS.map((name, value) => {
return {name, value};
});
export class ByAttributeHelper {
constructor(private node: DeleteSopNode) {}
eval_for_entities(entities: CoreEntity[]) {
const attribType = ATTRIBUTE_TYPES[this.node.pv.attribType];
switch (attribType) {
case AttribType.NUMERIC: {
this._eval_for_numeric(entities);
return;
}
case AttribType.STRING: {
this._eval_for_string(entities);
return;
}
}
TypeAssert.unreachable(attribType);
}
private _eval_for_string(entities: CoreEntity[]) {
let value: string | undefined;
for (let entity of entities) {
value = entity.stringAttribValue(this.node.pv.attribName);
if (value == this.node.pv.attrib_string) {
this.node.entity_selection_helper.select(entity);
}
}
}
private _eval_for_numeric(entities: CoreEntity[]) {
const attribSize: AttribSize = ATTRIBUTE_SIZES[this.node.pv.attribSize - 1];
switch (attribSize) {
case AttribSize.FLOAT: {
return this._eval_for_points_numeric_float(entities);
}
case AttribSize.VECTOR2: {
return this._eval_for_points_numeric_vector2(entities);
}
case AttribSize.VECTOR3: {
return this._eval_for_points_numeric_vector3(entities);
}
case AttribSize.VECTOR4: {
return this._eval_for_points_numeric_vector4(entities);
}
}
TypeAssert.unreachable(attribSize);
}
private _eval_for_points_numeric_float(entities: CoreEntity[]) {
let attribName = this.node.pv.attribName;
const compared_value = this.node.pv.attribValue1;
let value: number;
const comparison_operator: ComparisonOperator = COMPARISON_OPERATORS[this.node.pv.attribComparisonOperator];
const compare_method = COMPARE_METHOD_FLOAT[comparison_operator];
for (let entity of entities) {
value = entity.attribValue(attribName) as number;
if (compare_method(value, compared_value)) {
this.node.entity_selection_helper.select(entity);
}
}
}
private _eval_for_points_numeric_vector2(entities: CoreEntity[]) {
let attribName = this.node.pv.attribName;
const compared_value = this.node.pv.attribValue2;
let target = new Vector2();
for (let entity of entities) {
const value = entity.attribValue(attribName, target) as Vector2;
if (compared_value.equals(value)) {
this.node.entity_selection_helper.select(entity);
}
}
}
private _eval_for_points_numeric_vector3(entities: CoreEntity[]) {
let attribName = this.node.pv.attribName;
const compared_value = this.node.pv.attribValue3;
let target = new Vector3();
for (let entity of entities) {
const value = entity.attribValue(attribName, target) as Vector3;
if (compared_value.equals(value)) {
this.node.entity_selection_helper.select(entity);
}
}
}
private _eval_for_points_numeric_vector4(entities: CoreEntity[]) {
let attribName = this.node.pv.attribName;
const compared_value = this.node.pv.attribValue4;
let target = new Vector4();
for (let entity of entities) {
const value = entity.attribValue(attribName, target) as Vector4;
if (compared_value.equals(value)) {
this.node.entity_selection_helper.select(entity);
}
}
}
}