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