@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
164 lines (163 loc) • 4.84 kB
JavaScript
;
import { Vector3, Vector4, Triangle } from "three";
import { quadObjectFromPrimitives } from "./builders/QuadPrimitiveBuilder";
import { CorePrimitive } from "../../entities/primitive/CorePrimitive";
import { attributeNumericValues } from "../../entities/utils/Common";
import { QuadVertex } from "./QuadVertex";
import { primitivesCountFromObject } from "../../entities/primitive/CorePrimitiveUtils";
import { Attribute } from "../../Attribute";
import { quadGraphFromQuadObject } from "./graph/QuadGraphUtils";
import { QuadCoreObject } from "./QuadCoreObject";
const _triangle = new Triangle();
const _p0 = new Vector3();
const _p1 = new Vector3();
const _p2 = new Vector3();
const _p3 = new Vector3();
const _n0 = new Vector3();
const _n1 = new Vector3();
const _v4 = new Vector4();
const target = {
attributeAdded: false,
values: []
};
const STRIDE = 4;
export class QuadPrimitive extends CorePrimitive {
constructor(object, index) {
super(object, index);
this._geometry = object.geometry;
}
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 entitiesCount(object) {
return object.geometry.quadsCount();
}
builder() {
return quadObjectFromPrimitives;
}
//
//
// ATTRIBUTES
//
//
static addAttribute(object, attribName, attribute) {
const attributes = this.attributes(object);
if (!attributes) {
return;
}
attributes[attribName] = attribute;
}
static addNumericAttribute(object, attribName, size = 1, defaultValue = 0) {
const verticesCount = this.entitiesCount(object);
target.values = new Array(verticesCount * size);
attributeNumericValues(object, primitivesCountFromObject, size, defaultValue, target);
const attribute = {
isString: false,
array: target.values,
itemSize: size
};
this.addAttribute(object, attribName, attribute);
}
static attributesFromGeometry(geometry) {
if (!geometry.userData.primAttributes) {
geometry.userData.primAttributes = {};
}
return geometry.userData.primAttributes;
}
static attributes(object) {
const geometry = object.geometry;
if (!geometry) {
return;
}
return this.attributesFromGeometry(geometry);
}
//
//
// POSITION AND NORMAL
//
//
static position(quadObject, primitiveIndex, target2) {
if (!(quadObject && quadObject.geometry)) {
return target2;
}
const positionAttribute = quadObject.geometry.attributes[Attribute.POSITION];
if (!positionAttribute) {
return target2;
}
const positionArray = positionAttribute.array;
const index = quadObject.geometry.index;
_v4.fromArray(index, primitiveIndex * STRIDE);
_p0.fromArray(positionArray, _v4.x * 3);
_p1.fromArray(positionArray, _v4.y * 3);
_p2.fromArray(positionArray, _v4.z * 3);
_p3.fromArray(positionArray, _v4.w * 3);
target2.copy(_p0).add(_p1).add(_p2).add(_p3).divideScalar(4);
return target2;
}
static normal(quadObject, primitiveIndex, target2) {
if (!(quadObject && quadObject.geometry)) {
return target2;
}
const positionAttribute = quadObject.geometry.attributes[Attribute.POSITION];
if (!positionAttribute) {
return target2;
}
const positionArray = positionAttribute.array;
const index = quadObject.geometry.index;
_v4.fromArray(index, primitiveIndex * STRIDE);
_triangle.a.fromArray(positionArray, _v4.x * 3);
_triangle.b.fromArray(positionArray, _v4.y * 3);
_triangle.c.fromArray(positionArray, _v4.z * 3);
_triangle.getNormal(_n0);
_triangle.a.fromArray(positionArray, _v4.z * 3);
_triangle.b.fromArray(positionArray, _v4.w * 3);
_triangle.c.fromArray(positionArray, _v4.x * 3);
_triangle.getNormal(_n1);
return target2.copy(_n0).add(_n1).divideScalar(2);
}
position(target2) {
return this.constructor.position(this._object, this._index, target2);
}
normal(target2) {
return this.constructor.normal(this._object, this._index, target2);
}
//
//
// RELATED ENTITIES
//
//
static relatedVertexIds(object, primitiveIndex, target2) {
const geometry = object.geometry;
if (!geometry) {
target2.length = 0;
return;
}
target2.length = STRIDE;
for (let i = 0; i < STRIDE; i++) {
target2[i] = primitiveIndex * STRIDE + i;
}
}
static relatedVertexClass(object) {
return QuadVertex;
}
static relatedObjectClass(object) {
return QuadCoreObject;
}
static graph(object) {
return quadGraphFromQuadObject(object);
}
}