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; }