feat: Add UV reprojection and texture baking via WebGL
Build and Deploy / build-and-push (push) Successful in 1m27s
Build and Deploy / build-and-push (push) Successful in 1m27s
This commit is contained in:
@@ -7,6 +7,8 @@ import { useTexturePipeline } from "../hooks/useTexturePipeline";
|
||||
interface ModelViewerProps {
|
||||
object: THREE.Object3D | null;
|
||||
sceneObjects: any[];
|
||||
bakeRequest?: { id: string, type: 'planar' | 'cylinder' | 'sphere' | 'box', timestamp: number } | null;
|
||||
onBakeComplete?: (dataUrl: string) => void;
|
||||
}
|
||||
|
||||
interface MeshMaterialManagerProps {
|
||||
@@ -211,7 +213,9 @@ const FillMesh = ({ fillProps, originalMesh }: { fillProps: any, originalMesh: T
|
||||
return createPortal(fillNode, originalMesh);
|
||||
};
|
||||
|
||||
export const ModelViewer = forwardRef<THREE.Group, ModelViewerProps>(({ object, sceneObjects }, ref) => {
|
||||
import { reprojectUVs, bakeTextureToNewUVs } from '../lib/bakingUtils';
|
||||
|
||||
export const ModelViewer = forwardRef<THREE.Group, ModelViewerProps>(({ object, sceneObjects, bakeRequest, onBakeComplete }, ref) => {
|
||||
const internalRef = useRef<THREE.Group>(null);
|
||||
const groupRef = (ref as any) || internalRef;
|
||||
const textureCache = useRef<Map<string, THREE.Texture>>(new Map());
|
||||
@@ -241,6 +245,43 @@ export const ModelViewer = forwardRef<THREE.Group, ModelViewerProps>(({ object,
|
||||
};
|
||||
}, []);
|
||||
|
||||
const { gl } = useThree();
|
||||
|
||||
// Handle Baking Request
|
||||
useEffect(() => {
|
||||
if (bakeRequest && onBakeComplete && meshCache.size > 0) {
|
||||
const sceneObj = sceneObjects.find(obj => obj.id === bakeRequest.id);
|
||||
if (!sceneObj) return;
|
||||
|
||||
// Find the primary mesh for this object (we assume the first mesh for now)
|
||||
let targetMesh: THREE.Mesh | null = null;
|
||||
for (const mesh of meshCache.values()) {
|
||||
targetMesh = mesh;
|
||||
break;
|
||||
}
|
||||
|
||||
if (targetMesh && sceneObj.materialProps?.map) {
|
||||
const tex = textureCache.current.get(sceneObj.materialProps.map);
|
||||
if (tex) {
|
||||
// Keep old UVs
|
||||
const oldUVArray = targetMesh.geometry.attributes.uv.array.slice() as Float32Array;
|
||||
|
||||
// Apply new UV mapping (mutates geometry.attributes.uv)
|
||||
reprojectUVs(targetMesh.geometry, bakeRequest.type);
|
||||
|
||||
// Bake
|
||||
try {
|
||||
const dataUrl = bakeTextureToNewUVs(targetMesh, oldUVArray, tex, gl, 1024);
|
||||
onBakeComplete(dataUrl);
|
||||
} catch (e) {
|
||||
console.error("Baking failed", e);
|
||||
onBakeComplete(sceneObj.materialProps.map); // Fallback to original
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [bakeRequest, meshCache, sceneObjects, gl, onBakeComplete]);
|
||||
|
||||
// Main transform update for the core model
|
||||
useEffect(() => {
|
||||
if (object && sceneObjects) {
|
||||
|
||||
Reference in New Issue
Block a user