Files
workinf_Blender_Wasm/web/app/src/three-adapter/volume.ts
2026-08-14 22:32:09 -04:00

45 lines
2.2 KiB
TypeScript

import {
BufferGeometry,
DataTexture,
DoubleSide,
Float32BufferAttribute,
Mesh,
MeshBasicMaterial,
RGBAFormat,
Uint32BufferAttribute,
UnsignedByteType,
} from "../vendor/three/three.module.js";
import type { SceneNodeIR } from "../../../protocol/scene-ir";
import type { NanoVDBViewportRenderResultIR } from "../volume/nanovdb-viewport";
import { applyNonMeshTransform } from "./nonmesh";
export function createNanoVDBViewportObject(result: NanoVDBViewportRenderResultIR, node: SceneNodeIR): Mesh {
const { min, max } = result.grid.worldBounds;
const center = [(min[0] + max[0]) / 2, (min[1] + max[1]) / 2, (min[2] + max[2]) / 2];
const blenderPositions = result.viewAxis === "X"
? [[center[0], min[1], min[2]], [center[0], max[1], min[2]], [center[0], max[1], max[2]], [center[0], min[1], max[2]]]
: result.viewAxis === "Y"
? [[min[0], center[1], min[2]], [max[0], center[1], min[2]], [max[0], center[1], max[2]], [min[0], center[1], max[2]]]
: [[min[0], min[1], center[2]], [max[0], min[1], center[2]], [max[0], max[1], center[2]], [min[0], max[1], center[2]]];
const positions = blenderPositions.flatMap(([x, y, z]) => [x, z, -y]);
const geometry = new BufferGeometry();
geometry.setAttribute("position", new Float32BufferAttribute(positions, 3));
geometry.setAttribute("uv", new Float32BufferAttribute([0, 0, 1, 0, 1, 1, 0, 1], 2));
geometry.setIndex(new Uint32BufferAttribute([0, 1, 2, 0, 2, 3], 1));
const texture = new DataTexture(result.pixels, result.width, result.height, RGBAFormat, UnsignedByteType);
texture.needsUpdate = true;
const material = new MeshBasicMaterial({ map: texture, transparent: true, depthWrite: false, side: DoubleSide, toneMapped: false });
const mesh = new Mesh(geometry, material);
mesh.name = `${node.name} (NanoVDB)`;
mesh.renderOrder = 4;
mesh.userData.sceneNodeId = node.id;
mesh.userData.blenderId = node.id;
mesh.userData.nonMeshDataId = result.dataId;
mesh.userData.nanoVDBVolume = true;
mesh.userData.nanoVDBGrid = result.grid.name;
mesh.userData.nanoVDBImageSize = [result.width, result.height];
mesh.userData.nanoVDBViewAxis = result.viewAxis;
applyNonMeshTransform(mesh, node);
return mesh;
}