@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
106 lines (105 loc) • 4.01 kB
JavaScript
"use strict";
import { RGBAFormat, FloatType, DataTexture, Vector3 } from "three";
import { Attribute } from "../../geometry/Attribute";
import { ClothGeometryAttributeName } from "../ClothAttribute";
import { textureFromAttributes } from "../../geometry/operation/TextureFromAttribute";
const _v3 = new Vector3();
const _v3b = new Vector3();
export function positionTexture(geometry, resolution) {
const data = new Float32Array(resolution.x * resolution.y * 4);
const positionAttribute = geometry.getAttribute(Attribute.POSITION);
const array = positionAttribute.array;
const pointsCount = positionAttribute.count;
for (let i = 0; i < pointsCount; i++) {
_v3.fromArray(array, i * 3);
const i4 = i * 4;
_v3.toArray(data, i4);
}
const texture = new DataTexture(data, resolution.x, resolution.y, RGBAFormat, FloatType);
texture.needsUpdate = true;
return texture;
}
export function adjacencyTexture(geometry, resolution, adjacency, k) {
const data = new Float32Array(resolution.x * resolution.y * 4);
const positionAttribute = geometry.getAttribute(Attribute.POSITION);
const pointsCount = positionAttribute.count;
for (let i = 0; i < pointsCount; i++) {
const i4 = i * 4;
const adj = adjacency[i];
for (let j = 0; j < 4; j++) {
const adjacentIndex = adj[k * 4 + j];
if (adjacentIndex != null) {
data[i4 + j] = adjacentIndex;
} else {
data[i4 + j] = -1;
}
}
}
const texture = new DataTexture(data, resolution.x, resolution.y, RGBAFormat, FloatType);
texture.needsUpdate = true;
return texture;
}
export function distancesTexture(geometry, resolution, adjacency, k) {
const data = new Float32Array(resolution.x * resolution.y * 4).fill(-1);
const positionAttribute = geometry.getAttribute(Attribute.POSITION);
const pointsCount = positionAttribute.count;
const array = positionAttribute.array;
for (let i = 0; i < pointsCount; i++) {
_v3.fromArray(array, i * 3);
const i4 = i * 4;
const adj = adjacency[i];
const len = adj.length - 1;
for (let j = 0; j < 4; j++) {
if (len < k * 4 + j) {
data[i4 + j] = -1;
} else {
const adjacentIndex = adj[k * 4 + j];
if (adjacentIndex < 0) {
data[i4 + j] = -1;
} else {
_v3b.fromArray(array, adjacentIndex * 3);
const dist = _v3.distanceTo(_v3b);
data[i4 + j] = dist;
if (dist < 1e-4) {
console.log("bad dist");
}
}
}
}
}
const texture = new DataTexture(data, resolution.x, resolution.y, RGBAFormat, FloatType);
texture.needsUpdate = true;
return texture;
}
export function viscositySpringTexture(geometry, resolution) {
return textureFromAttributes(geometry, [ClothGeometryAttributeName.VISCOSITY, ClothGeometryAttributeName.SPRING]);
}
export function createTexturesFromAllocation(geometry, resolution, allocationsController) {
const data = {};
const positionAttribute = geometry.getAttribute(Attribute.POSITION);
const pointsCount = positionAttribute.count;
allocationsController.readonlyAllocations().forEach((allocation) => {
var _a;
const textureData = new Float32Array(resolution.x * resolution.y * 4);
const texture = new DataTexture(textureData, resolution.x, resolution.y, RGBAFormat, FloatType);
data[allocation.textureName()] = texture;
let offset = 0;
(_a = allocation.variables()) == null ? void 0 : _a.forEach((variable) => {
const attribName = variable.name();
const attribSize = variable.size();
const attribute = geometry.getAttribute(attribName);
if (attribute) {
const array = attribute.array;
for (let i = 0; i < pointsCount; i++) {
const i4 = i * 4 + offset;
for (let j = 0; j < attribSize; j++) {
textureData[i4 + j] = array[i * attribSize + j];
}
}
texture.needsUpdate = true;
}
offset += attribSize;
});
});
return data;
}