UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

171 lines (164 loc) 4.9 kB
import {CoreEntity} from '../../CoreEntity'; import { AttribValue, NumericAttribValue, Vector2Like, Vector3Like, Vector4Like, ColorLike, } from '../../../../types/GlobalTypes'; import {Color, Vector2, Vector3, Vector4} from 'three'; import {CoreObjectType, ObjectContent} from '../../ObjectContent'; import {AttribSize} from '../../Constant'; import {isNumber, isArray} from '../../../Type'; type GetRelatedCallback<T extends CoreEntity, E extends CoreEntity> = (entity: T) => E[]; type GetRelatedIdCallback<E extends CoreEntity> = (id: number, target: number[]) => void; export function uniqRelatedEntities<T extends CoreEntity, E extends CoreEntity>( entities: T[], callback: GetRelatedCallback<T, E>, target: E[] ): void { target.length = 0; const entityByIndex: Map<number, E> = new Map(); for (const entity of entities) { const relatedEntities = callback(entity); for (const relatedEntity of relatedEntities) { let newEntity = entityByIndex.get(relatedEntity.index()); if (!newEntity) { newEntity = relatedEntity; entityByIndex.set(newEntity.index(), newEntity); } } } entityByIndex.forEach((entity) => { target.push(entity); }); } const _relatedEntityIds: number[] = []; const _entityIndices: Set<number> = new Set(); export function uniqRelatedEntityIds<E extends CoreEntity>( entityIds: number[], callback: GetRelatedIdCallback<E>, target: number[] ): void { target.length = 0; _entityIndices.clear(); for (const entityId of entityIds) { callback(entityId, _relatedEntityIds); for (const _relatedEntityId of _relatedEntityIds) { _entityIndices.add(_relatedEntityId); } } _entityIndices.forEach((entityId) => { target.push(entityId); }); } export function attribValueNonPrimitive(src: AttribValue) { return src instanceof Color || src instanceof Vector2 || src instanceof Vector3 || src instanceof Vector4; } export function copyAttribValue(src: AttribValue, target: AttribValue) { if (target instanceof Color && src instanceof Color) { target.copy(src); } if (target instanceof Vector2 && src instanceof Vector2) { target.copy(src); } if (target instanceof Vector3 && src instanceof Vector3) { target.copy(src); } if (target instanceof Vector4 && src instanceof Vector4) { target.copy(src); } } export function cloneAttribValue(src: AttribValue) { if (src instanceof Color) { return src.clone(); } if (src instanceof Vector2) { return src.clone(); } if (src instanceof Vector3) { return src.clone(); } if (src instanceof Vector4) { return src.clone(); } } export interface AttributeNumericValuesOptions { attributeAdded: boolean; values: number[]; } type EntitiesCountFunction<T extends CoreObjectType> = (object: ObjectContent<T>) => number; export function attributeNumericValues<T extends CoreObjectType>( object: ObjectContent<T>, entitiesCountFunction: EntitiesCountFunction<T>, attribSize: AttribSize = 1, defaultValue: NumericAttribValue = 0, target: AttributeNumericValuesOptions ) { target.values.length = 0; const values = target.values; const entitiesCount = entitiesCountFunction(object); if (isNumber(defaultValue)) { // adding number for (let i = 0; i < entitiesCount; i++) { for (let j = 0; j < attribSize; j++) { values.push(defaultValue); } } target.attributeAdded = true; } else { if (attribSize > 1) { if (isArray(defaultValue)) { // adding array for (let i = 0; i < entitiesCount; i++) { for (let j = 0; j < attribSize; j++) { values.push(defaultValue[j]); } } target.attributeAdded = true; } else { // adding Vector2 const vec2 = defaultValue as Vector2Like; if (attribSize == 2 && vec2.x != null && vec2.y != null) { for (let i = 0; i < entitiesCount; i++) { values.push(vec2.x); values.push(vec2.y); } target.attributeAdded = true; } // adding Vector3 const vec3 = defaultValue as Vector3Like; if (attribSize == 3 && vec3.x != null && vec3.y != null && vec3.z != null) { for (let i = 0; i < entitiesCount; i++) { values.push(vec3.x); values.push(vec3.y); values.push(vec3.z); } target.attributeAdded = true; } // adding Color const col = defaultValue as ColorLike; if (attribSize == 3 && col.r != null && col.g != null && col.b != null) { for (let i = 0; i < entitiesCount; i++) { values.push(col.r); values.push(col.g); values.push(col.b); } target.attributeAdded = true; } // adding Vector4 const vec4 = defaultValue as Vector4Like; if (attribSize == 4 && vec4.x != null && vec4.y != null && vec4.z != null && vec4.w != null) { for (let i = 0; i < entitiesCount; i++) { values.push(vec4.x); values.push(vec4.y); values.push(vec4.z); values.push(vec4.w); } target.attributeAdded = true; } } } } }