@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
89 lines (88 loc) • 2.67 kB
JavaScript
"use strict";
import { Vector3, Line3, Box3 } from "three";
import { Attribute } from "../Attribute";
export const DEFAULT_POSITIONS = [
new Vector3(0, 0, 0),
new Vector3(1, 0, 0),
new Vector3(1, 0, 1),
new Vector3(0, 0, 1),
//
new Vector3(0, 1, 0),
new Vector3(1, 1, 0),
new Vector3(1, 1, 1),
new Vector3(0, 1, 1)
];
const _v3 = new Vector3();
const lb0 = new Line3();
const lb1 = new Line3();
const lt0 = new Line3();
const lt1 = new Line3();
const pb0 = new Vector3();
const pb1 = new Vector3();
const pt0 = new Vector3();
const pt1 = new Vector3();
const pb = new Vector3();
const pt = new Vector3();
const target = new Vector3();
const _box3 = new Box3();
const _box3Size = new Vector3();
const _originalObjectPosition = new Vector3();
const _positionDelta = new Vector3();
const _positionRatio = new Vector3();
export function cubeLatticeDeform(object, points, options) {
const geometry = object.geometry;
if (!geometry) {
return;
}
const positionAttribute = geometry.attributes[Attribute.POSITION];
if (!positionAttribute) {
return;
}
const positionArray = positionAttribute.array;
const { offset, moveObjectPosition } = options;
if (moveObjectPosition) {
_box3.setFromObject(object);
_box3.getSize(_box3Size);
_originalObjectPosition.copy(object.position);
_positionRatio.copy(object.position).sub(_box3.min).divide(_box3Size);
}
lb0.start = points[0];
lb0.end = points[1];
lb1.start = points[3];
lb1.end = points[2];
lt0.start = points[4];
lt0.end = points[5];
lt1.start = points[7];
lt1.end = points[6];
const pointsCount = positionArray.length / 3;
for (let i = 0; i < pointsCount; i++) {
_v3.fromArray(positionArray, i * 3);
_v3.add(offset);
interpolate(_v3, lb0, lb1, lt0, lt1, target);
target.toArray(positionArray, i * 3);
}
if (moveObjectPosition) {
geometry.computeBoundingBox();
_box3.setFromObject(object);
_box3.getCenter(_positionDelta);
_positionDelta.sub(_originalObjectPosition);
object.position.add(_positionDelta);
object.updateMatrix();
for (let i = 0; i < pointsCount; i++) {
_v3.fromArray(positionArray, i * 3);
_v3.sub(_positionDelta);
_v3.toArray(positionArray, i * 3);
}
}
positionAttribute.needsUpdate = true;
geometry.computeVertexNormals();
}
function interpolate(p, lb02, lb12, lt02, lt12, target2) {
pb0.copy(lb02.start).lerp(lb02.end, p.x);
pb1.copy(lb12.start).lerp(lb12.end, p.x);
pt0.copy(lt02.start).lerp(lt02.end, p.x);
pt1.copy(lt12.start).lerp(lt12.end, p.x);
pb.copy(pb0).lerp(pb1, p.z);
pt.copy(pt0).lerp(pt1, p.z);
target2.copy(pb).lerp(pt, p.y);
}