@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
171 lines (164 loc) • 4.9 kB
text/typescript
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;
}
}
}
}
}