UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

163 lines (143 loc) 5.92 kB
import {RGBAFormat, FloatType, DataTexture, BufferGeometry, Vector3, BufferAttribute, Vector2} from 'three'; import {Attribute} from '../../geometry/Attribute'; import {ClothGeometryAttributeName} from '../ClothAttribute'; import {TextureAllocationsController} from '../../../engine/nodes/gl/code/utils/TextureAllocationsController'; import {textureFromAttributes} from '../../geometry/operation/TextureFromAttribute'; const _v3 = new Vector3(); const _v3b = new Vector3(); export function positionTexture(geometry: BufferGeometry, resolution: Vector2): DataTexture { const data = new Float32Array(resolution.x * resolution.y * 4); const positionAttribute = geometry.getAttribute(Attribute.POSITION) as BufferAttribute; 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: BufferGeometry, resolution: Vector2, adjacency: number[][], k: number ): DataTexture { const data = new Float32Array(resolution.x * resolution.y * 4); // const geoVertices = this.mainController.geometryInit.vertices; // const adjacency = this.mainController.geometryInit.adjacency; // const length = geoVertices.length; const positionAttribute = geometry.getAttribute(Attribute.POSITION) as BufferAttribute; const pointsCount = positionAttribute.count; for (let i = 0; i < pointsCount; i++) { const i4 = i * 4; const adj = adjacency[i]; // const len = adj.length - 1; // for (let j = 0; j < 4; j++) data[i4 + j] = len < k * 4 + j ? -1 : adj[k * 4 + j]; 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; } } } // console.log('createAdjacentsTexture', k, data); const texture = new DataTexture(data, resolution.x, resolution.y, RGBAFormat, FloatType); texture.needsUpdate = true; return texture; } export function distancesTexture(geometry: BufferGeometry, resolution: Vector2, adjacency: number[][], k: number) { const data = new Float32Array(resolution.x * resolution.y * 4).fill(-1); // const geoVertices = this.mainController.geometryInit.vertices; const positionAttribute = geometry.getAttribute(Attribute.POSITION) as BufferAttribute; 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; // const v = vertices[i]; // for (let j = 0; j < 4; j++) data[i4 + j] = len < k * 4 + j ? -1 : v.distanceTo(geoVertices[adj[k * 4 + j]]); 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 < 0.0001) { console.log('bad dist'); } } } } } const texture = new DataTexture(data, resolution.x, resolution.y, RGBAFormat, FloatType); texture.needsUpdate = true; return texture; } export function viscositySpringTexture(geometry: BufferGeometry, resolution: Vector2): DataTexture | undefined { return textureFromAttributes(geometry, [ClothGeometryAttributeName.VISCOSITY, ClothGeometryAttributeName.SPRING]); // console.log(t); // // return t; // // console.log(t); // const data = new Float32Array(resolution.x * resolution.y * 4); // const positionAttribute = geometry.getAttribute(Attribute.POSITION) as BufferAttribute; // const pointsCount = positionAttribute.count; // const viscosityAttribute = geometry.getAttribute(ClothGeometryAttributeName.VISCOSITY) as // | BufferAttribute // | undefined; // const springAttribute = geometry.getAttribute(ClothGeometryAttributeName.SPRING) as BufferAttribute | undefined; // const viscosityArray = viscosityAttribute ? viscosityAttribute.array : undefined; // const springArray = springAttribute ? springAttribute.array : undefined; // for (let i = 0; i < pointsCount; i++) { // const i4 = i * 4; // data[i4] = viscosityArray ? viscosityArray[i] : 1; // data[i4 + 1] = springArray ? springArray[i] : 1; // } // const texture = new DataTexture(data, resolution.x, resolution.y, RGBAFormat, FloatType); // texture.needsUpdate = true; // console.log(texture); // return texture; } export function createTexturesFromAllocation( geometry: BufferGeometry, resolution: Vector2, allocationsController: TextureAllocationsController ): Record<string, DataTexture> { const data: Record<string, DataTexture> = {}; const positionAttribute = geometry.getAttribute(Attribute.POSITION) as BufferAttribute; const pointsCount = positionAttribute.count; allocationsController.readonlyAllocations().forEach((allocation) => { 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; allocation.variables()?.forEach((variable) => { const attribName = variable.name(); const attribSize = variable.size(); const attribute = geometry.getAttribute(attribName) as BufferAttribute | undefined; 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; }