@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
105 lines (104 loc) • 3.46 kB
JavaScript
;
import { Vector3 } from "three";
import { Attribute, markAttributeAsNeedsUpdateForFrame } from "../../core/geometry/Attribute";
import { isBooleanTrue } from "../../core/Type";
import { ObjectNamedFunction1, ObjectNamedFunction2, ObjectNamedFunction5 } from "./_Base";
import { _setArrayLength } from "./_ArrayUtils";
import { dummyReadRefVal } from "./_Param";
const tmpV3 = new Vector3();
const nextV3 = new Vector3();
const STRIDE = 3;
export class getGeometryPositions extends ObjectNamedFunction1 {
static type() {
return "getGeometryPositions";
}
func(object3D, target) {
const geometry = object3D.geometry;
if (!geometry) {
return target;
}
const positionAttribute = geometry.getAttribute(Attribute.POSITION);
if (!positionAttribute) {
return target;
}
const positionArray = positionAttribute.array;
const pointsCount = positionArray.length / STRIDE;
_setArrayLength(target, pointsCount, () => new Vector3());
for (let i = 0; i < pointsCount; i++) {
const _v = target[i];
const i3 = i * STRIDE;
_v.x = positionArray[i3];
_v.y = positionArray[i3 + 1];
_v.z = positionArray[i3 + 2];
}
return target;
}
}
export class getGeometryBoundingBox extends ObjectNamedFunction2 {
static type() {
return "getGeometryBoundingBox";
}
func(object3D, forceCompute, target) {
dummyReadRefVal(this.timeController.timeUniform().value);
const geometry = object3D.geometry;
if (!geometry) {
return target;
}
if (!geometry.boundingBox || forceCompute) {
geometry.computeBoundingBox();
}
if (!geometry.boundingBox) {
return target;
}
target.copy(geometry.boundingBox);
return target;
}
}
export class setGeometryPositions extends ObjectNamedFunction5 {
static type() {
return "setGeometryPositions";
}
func(object3D, values, lerp, attributeNeedsUpdate, computeNormals, computeTangents) {
const geometry = object3D.geometry;
if (!geometry) {
return;
}
if (!values) {
return;
}
const positionAttribute = geometry.getAttribute(Attribute.POSITION);
if (!positionAttribute) {
return;
}
const doLerp = lerp < 1;
const positionArray = positionAttribute.array;
const geoPointsCount = positionArray.length / STRIDE;
const valuesCount = values.length;
const minCount = Math.min(geoPointsCount, valuesCount);
if (doLerp) {
for (let i = 0; i < minCount; i++) {
const value = values[i];
const j = i * STRIDE;
nextV3.copy(value);
tmpV3.fromArray(positionArray, j);
tmpV3.lerp(nextV3, lerp);
tmpV3.toArray(positionArray, j);
}
} else {
for (let i = 0; i < minCount; i++) {
const value = values[i];
const j = i * STRIDE;
value.toArray(positionArray, j);
}
}
if (isBooleanTrue(attributeNeedsUpdate)) {
markAttributeAsNeedsUpdateForFrame(positionAttribute, this.timeController.frame());
}
if (positionAttribute != null && isBooleanTrue(computeNormals) && geometry.getAttribute(Attribute.NORMAL) != null) {
geometry.computeVertexNormals();
}
if (isBooleanTrue(computeTangents) && positionAttribute != null && geometry.getAttribute(Attribute.UV) != null && geometry.getAttribute(Attribute.NORMAL) != null && geometry.getIndex() != null) {
geometry.computeTangents();
}
}
}