UNPKG

@polygonjs/polygonjs

Version:

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

181 lines (172 loc) 5.88 kB
import {BufferGeometry, Object3D, Mesh, Vector3, BufferAttribute} from 'three'; import {CoreObjectType, ObjectContent} from '../../ObjectContent'; import {CoreVertex} from '../../entities/vertex/CoreVertex'; import {VertexAttributesDict, UserDataWithVertexAttributes} from '../../entities/vertex/Common'; import {BaseVertexAttribute, VertexNumberAttribute} from '../../entities/vertex/VertexAttribute'; import {verticesCountFromObject} from '../../entities/vertex/CoreVertexUtils'; import {primitiveClassFactoryNonAbstract, primitiveVerticesCountFactory} from './ThreeModule'; import {ThreejsPoint} from './ThreejsPoint'; import {NumericAttribValue} from '../../../../types/GlobalTypes'; import {AttributeNumericValuesOptions, attributeNumericValues} from '../../entities/utils/Common'; import {CoreEntityWithObject} from '../../CoreEntity'; export interface BufferGeometryWithVertexAttributes extends BufferGeometry { userData: UserDataWithVertexAttributes; } const target: AttributeNumericValuesOptions = { attributeAdded: false, values: [], }; export class ThreejsVertex extends CoreVertex<CoreObjectType.THREEJS> { protected _geometry?: BufferGeometry; constructor(object: Object3D, index: number) { super(object, index); this._updateGeometry(); } override setIndex(index: number, object?: Object3D) { this._index = index; if (object) { this._object = object; this._updateGeometry(); } return this; } private _updateGeometry() { const geometry = (this._object as Mesh).geometry as BufferGeometryWithVertexAttributes | undefined; if (geometry) { this._geometry = geometry; } } geometry() { return this._geometry; } static override addAttribute(object: Object3D, attribName: string, attribute: BaseVertexAttribute) { const attributes = this.attributes(object); if (!attributes) { return; } attributes[attribName] = attribute; } static override addNumericAttribute( object: Object3D, attribName: string, size: number = 1, defaultValue: NumericAttribValue = 0 ) { const verticesCount = this.entitiesCount(object); target.values = new Array(verticesCount * size); attributeNumericValues(object, verticesCountFromObject, size, defaultValue, target); const attribute: VertexNumberAttribute = { isString: false, array: target.values, itemSize: size, }; this.addAttribute(object, attribName, attribute); } static override attributes<T extends CoreObjectType>(object: ObjectContent<T>): VertexAttributesDict | undefined { const geometry = (object as any as Mesh).geometry as BufferGeometryWithVertexAttributes | undefined; if (!geometry) { return; } if (!geometry.userData.vertexAttributes) { geometry.userData.vertexAttributes = {}; } return geometry.userData.vertexAttributes; } static override indexAttribute<T extends CoreObjectType>( object: ObjectContent<T> ): BufferAttribute | undefined | null { const geometry = (object as any as Mesh).geometry as BufferGeometry | undefined; if (!geometry) { return; } return geometry.getIndex(); } static override setIndexAttribute<T extends CoreObjectType>( object: ObjectContent<T>, index: BufferAttribute | number[] ): BufferAttribute | undefined { const geometry = (object as any as Mesh).geometry as BufferGeometry | undefined; if (!geometry) { return; } geometry.setIndex(index); } static override entitiesCount<T extends CoreObjectType>(object: ObjectContent<T>) { const geometry = (object as any as Mesh).geometry as BufferGeometry | undefined; if (!geometry) { return 0; } const index = geometry.getIndex(); if (!index) { return 0; } return index.count; } override position(target: Vector3): Vector3 { console.warn('CoreThreejsVertex.position not implemented'); return target; } override normal(target: Vector3): Vector3 { console.warn('CoreThreejsVertex.normal not implemented'); return target; } // // // RELATED ENTITIES // // static override relatedPrimitiveIds<T extends CoreObjectType>( object: ObjectContent<T>, pointIndex: number, target: number[] ): void { target.length = 1; const index = Math.floor(pointIndex / primitiveVerticesCountFactory(object as any as Mesh)); target[0] = index; } // static override relatedPrimitives<T extends CoreObjectType>(object:BaseCoreObject<T>,vertexIndex:number,target: CorePrimitive<T>[]): void { // this.relatedPrimitiveIds(object,vertexIndex,_ids) // target.length = _ids.length; // let i=0 // for(const id of _ids){ // target[i]=(primitiveInstanceFactory(object as any as Mesh,id)) as CorePrimitive<T> // i++ // } // } // override relatedPrimitives<T extends CoreObjectType>(target: CorePrimitive<T>[]): void { // target.length = 0; // if (!this._object) { // return; // } // const index = Math.floor(this._index / primitiveVerticesCountFactory(this._object)); // const primitive = primitiveInstanceFactory(this._object, index) as CorePrimitive<T> | undefined; // if (!primitive) { // return; // } // target.push(primitive); // } static override relatedPointIds<T extends CoreObjectType>( object: ObjectContent<T>, pointIndex: number, target: number[] ): void { target.length = 0; const geometry = (object as any as Mesh).geometry as BufferGeometry | undefined; if (!geometry) { return; } const index = geometry.getIndex(); if (!index) { return; } const indexArray = index.array; const indexValue = indexArray[pointIndex]; target[0] = indexValue; } static override relatedPointClass<T extends CoreObjectType>(object: ObjectContent<T>) { return ThreejsPoint as any as typeof CoreEntityWithObject<T>; } static override relatedPrimitiveClass<T extends CoreObjectType>(object: ObjectContent<T>) { return primitiveClassFactoryNonAbstract(object as any as Mesh) as any as typeof CoreEntityWithObject<T>; } }