@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
132 lines (131 loc) • 4.46 kB
JavaScript
;
import {
Vector2,
Vector3,
Vector4,
BufferAttribute,
RGBAFormat,
FloatType,
DataTexture,
NearestFilter,
RepeatWrapping,
Mesh
} from "three";
import { nearestPower2 } from "../../math/_Module";
import { CoreAttribute } from "../Attribute";
import { pointsCountFromObject } from "../entities/point/CorePointUtils";
const _textureSize = new Vector2();
const _v2 = new Vector2();
const _v3 = new Vector3();
const _v4 = new Vector4();
function _vectorFromAttribSize(attribSize) {
switch (attribSize) {
case 2:
return _v2;
case 3:
return _v3;
case 4:
return _v4;
}
}
export var AttribLookup = /* @__PURE__ */ ((AttribLookup2) => {
AttribLookup2["ID"] = "attribLookupId";
AttribLookup2["UV"] = "attribLookupUv";
return AttribLookup2;
})(AttribLookup || {});
const dummyMesh = new Mesh();
export function textureFromAttributePointsCount(geometry) {
dummyMesh.geometry = geometry;
return pointsCountFromObject(dummyMesh);
}
export function textureSizeFromPointsCount(geometry, target) {
const pointsCount = textureFromAttributePointsCount(geometry);
const nearestPowerOfTwo = nearestPower2(Math.sqrt(pointsCount));
target.x = nearestPowerOfTwo;
target.y = nearestPowerOfTwo;
}
export function textureFromAttributesMissingAttributes(geometry, attribNames) {
const missingAttributes = [];
for (const attribName of attribNames) {
const attributeName = CoreAttribute.remapName(attribName);
const attribute = geometry.getAttribute(attributeName);
if (!attribute) {
missingAttributes.push(attribName);
}
}
return missingAttributes;
}
export function textureFromAttributesTotalAttribSizes(geometry, attribNames) {
let currentSize = 0;
for (const attribName of attribNames) {
const attributeName = CoreAttribute.remapName(attribName);
const attribute = geometry.getAttribute(attributeName);
if (attribute) {
currentSize += attribute.itemSize;
}
}
return currentSize;
}
export function textureFromAttributes(geometry, attribNames) {
textureSizeFromPointsCount(geometry, _textureSize);
const pointsCount = textureFromAttributePointsCount(geometry);
const width = _textureSize.x;
const height = _textureSize.y;
const size = width * height * 4;
const pixelBuffer = new Float32Array(size);
let currentIndex = 0;
for (let attribName of attribNames) {
attribName = CoreAttribute.remapName(attribName);
const attribute = geometry.getAttribute(attribName);
if (attribute) {
const attribSize = attribute.itemSize;
const attribArray = attribute.array;
if (attribSize == 1) {
for (let i = 0; i < pointsCount; i++) {
pixelBuffer[i * 4 + currentIndex] = attribArray[i];
}
} else {
const vector = _vectorFromAttribSize(attribSize);
if (!vector) {
return;
}
for (let i = 0; i < pointsCount; i++) {
vector.fromArray(attribArray, i * attribSize);
vector.toArray(pixelBuffer, i * 4 + currentIndex);
}
}
currentIndex += attribSize;
}
}
const texture = new DataTexture(pixelBuffer, width, height, RGBAFormat, FloatType);
texture.minFilter = texture.magFilter = NearestFilter;
texture.wrapS = texture.wrapT = RepeatWrapping;
texture.needsUpdate = true;
return texture;
}
export function textureFromAttribLookupUv(geometry) {
const attribSize = 2;
const pointsCount = textureFromAttributePointsCount(geometry);
textureSizeFromPointsCount(geometry, _textureSize);
const uvSize = 2;
const values = new Array(pointsCount * uvSize);
for (let pointIndex = 0; pointIndex < pointsCount; pointIndex++) {
_v2.x = pointIndex % _textureSize.x;
_v2.y = Math.floor(pointIndex / _textureSize.x);
_v2.addScalar(0.5);
_v2.divide(_textureSize);
_v2.toArray(values, pointIndex * uvSize);
}
const uvArray = new Float32Array(values);
geometry.setAttribute("attribLookupUv" /* UV */, new BufferAttribute(uvArray, attribSize));
}
export function textureFromAttribLookupId(geometry) {
const pointsCount = textureFromAttributePointsCount(geometry);
const idSize = 1;
const values = new Array(pointsCount * idSize);
for (let pointIndex = 0; pointIndex < pointsCount; pointIndex++) {
values[pointIndex] = pointIndex;
}
const idArray = new Float32Array(values);
geometry.setAttribute("attribLookupId" /* ID */, new BufferAttribute(idArray, idSize));
}