@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
213 lines (212 loc) • 6.06 kB
JavaScript
"use strict";
import {
Float32BufferAttribute,
Int32BufferAttribute,
InstancedBufferAttribute
} from "three";
import { CorePoint } from "../../entities/point/CorePoint";
import { Attribute } from "../../Attribute";
import { objectCloneDeep } from "../../../ObjectUtils";
import { markedAsInstance } from "../../GeometryUtils";
import { pointsCountFromBufferGeometry, positionAttributeNameFromBufferGeometry } from "./CoreThreejsPointUtils";
import { attributeNumericValues } from "../../entities/utils/Common";
import { ThreejsVertex } from "./ThreejsVertex";
import { pointsCountFromObject } from "../../entities/point/CorePointUtils";
const INDEX_ATTRIB_VALUES = "indexedAttribValues";
const target = {
attributeAdded: false,
values: []
};
export class ThreejsPoint extends CorePoint {
constructor(object, index) {
super(object, index);
this._updateGeometry();
}
setIndex(index, object) {
this._index = index;
if (object) {
this._object = object;
this._updateGeometry();
}
return this;
}
_updateGeometry() {
const geometry = this._object.geometry;
if (geometry) {
this._geometry = geometry;
}
}
geometry() {
return this._geometry;
}
static addAttribute(object, attribName, attribute) {
const geometry = object.geometry;
if (!geometry) {
return;
}
geometry.setAttribute(attribName, attribute);
}
static attributes(object) {
const geometry = object.geometry;
if (!geometry) {
return;
}
return geometry.attributes;
}
static entitiesCount(object) {
const geometry = object.geometry;
if (!geometry) {
return 0;
}
return pointsCountFromBufferGeometry(geometry);
}
static positionAttributeName(object) {
const geometry = object.geometry;
if (!geometry) {
return null;
}
return positionAttributeNameFromBufferGeometry(geometry);
}
static position(object, index, target2) {
const geometry = object.geometry;
if (!geometry) {
return null;
}
const { array } = geometry.getAttribute(Attribute.POSITION);
return target2.fromArray(array, index * 3);
}
position(target2) {
if (!this._geometry) {
return target2;
}
const { array } = this._geometry.getAttribute(Attribute.POSITION);
return target2.fromArray(array, this._index * 3);
}
normal(target2) {
if (!this._geometry) {
return target2;
}
const { array } = this._geometry.getAttribute(Attribute.NORMAL);
return target2.fromArray(array, this._index * 3);
}
static computeNormals(object) {
const geometry = object.geometry;
if (!geometry) {
return null;
}
geometry.computeVertexNormals();
}
static markAttribAsNeedsUpdate(object, attribName) {
const geometry = object.geometry;
if (!geometry) {
return null;
}
const attribute = geometry.getAttribute(attribName);
if (!attribute) {
return;
}
attribute.needsUpdate = true;
}
//
//
//
//
//
static userDataAttribs(object) {
const geometry = object.geometry;
if (!geometry) {
return {};
}
return geometry.userData[INDEX_ATTRIB_VALUES] = geometry.userData[INDEX_ATTRIB_VALUES] || {};
}
static setIndexedAttribute(object, attribName, values, indices) {
const geometry = object.geometry;
if (!geometry) {
return;
}
this.setIndexedAttributeValues(object, attribName, values);
geometry.setAttribute(attribName, new Int32BufferAttribute(indices, 1));
geometry.getAttribute(attribName).needsUpdate = true;
}
static attribValueIndex(object, index, attribName) {
if (this.isAttribIndexed(object, attribName)) {
const geometry = object.geometry;
if (geometry) {
return geometry.getAttribute(attribName).array[index];
}
}
return -1;
}
//
//
//
//
//
static renameAttribute(object, oldName, newName) {
const geometry = object.geometry;
if (!geometry) {
return;
}
if (this.isAttribIndexed(object, oldName)) {
this.userDataAttribs(object)[newName] = objectCloneDeep(this.userDataAttribs(object)[oldName]);
delete this.userDataAttribs(object)[oldName];
}
const oldAttrib = geometry.getAttribute(oldName);
geometry.setAttribute(newName, new Float32BufferAttribute(oldAttrib.array, oldAttrib.itemSize));
return geometry.deleteAttribute(oldName);
}
static deleteAttribute(object, attribName) {
const geometry = object.geometry;
if (!geometry) {
return;
}
if (this.isAttribIndexed(object, attribName)) {
delete this.userDataAttribs(object)[attribName];
}
return geometry.deleteAttribute(attribName);
}
static addNumericAttribute(object, attribName, size = 1, defaultValue = 0) {
const geometry = object.geometry;
if (!geometry) {
return;
}
attributeNumericValues(object, pointsCountFromObject, size, defaultValue, target);
if (target.attributeAdded) {
if (markedAsInstance(geometry)) {
const valuesAsTypedArray = new Float32Array(target.values);
geometry.setAttribute(attribName.trim(), new InstancedBufferAttribute(valuesAsTypedArray, size));
} else {
geometry.setAttribute(attribName.trim(), new Float32BufferAttribute(target.values, size));
}
} else {
console.warn(defaultValue);
throw `CoreThreejsPoint.addNumericAttrib error: no other default value allowed for now (default given: ${defaultValue})`;
}
}
//
//
// RELATED ENTITIES
//
//
static relatedVertexIds(object, pointIndex, target2, traversedRelatedEntityData) {
const geometry = object.geometry;
if (!geometry) {
return;
}
const index = geometry.getIndex();
if (!index) {
return;
}
const indexArray = index.array;
let i = 0;
for (const indexValue of indexArray) {
if (indexValue == pointIndex) {
target2.push(i);
}
i++;
}
}
static relatedVertexClass(object) {
return ThreejsVertex;
}
}