import { getObjectVoxelGroups } from "../graphics/voxelGroup"; import type { ObjectInstance, ObjectType, RuntimeObjectInstance, V3, World } from "../../types"; import { buildObjectTrimesh } from "../graphics/mesh"; export function computeBoundingBox(objectType: ObjectType): { min: V3; max: V3 } { if (!objectType.voxels.length) return { min: [0, 0, 0], max: [1, 1, 1] }; let minX = Infinity, minY = Infinity, minZ = Infinity; let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity; for (const v of objectType.voxels) { minX = Math.min(minX, v.position[0]); minY = Math.min(minY, v.position[1]); minZ = Math.min(minZ, v.position[2]); maxX = Math.max(maxX, v.position[0] + 1); maxY = Math.max(maxY, v.position[1] + 1); maxZ = Math.max(maxZ, v.position[2] + 1); } return { min: [minX, minY, minZ], max: [maxX, maxY, maxZ] }; } export function populateRuntimeObject(object: ObjectInstance, world: World): RuntimeObjectInstance { const objectType = world.objectTypes[object.typeId]; return { ...object, cache: { voxelGroups: getObjectVoxelGroups(objectType, world.voxelTypes), colliderMesh: buildObjectTrimesh(objectType, world.voxelTypes), boundingBox: computeBoundingBox(objectType), updatedAt: 0, }, pendingActions: {}, }; } export function depopulateRuntimeObject(object: RuntimeObjectInstance, _world: World): ObjectInstance { const { cache, ...result } = object; return result; }