@onerjs/loaders 8.54.1 → 8.54.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FBX/fbxFileLoader.pure.d.ts +1 -0
- package/FBX/fbxFileLoader.pure.js +54 -12
- package/FBX/fbxFileLoader.pure.js.map +1 -1
- package/FBX/interpreter/connections.js.map +1 -1
- package/SPLAT/gaussianSplattingBlockAllocator.js.map +1 -1
- package/SPLAT/gaussianSplattingWorkBuffer.d.ts +5 -1
- package/SPLAT/gaussianSplattingWorkBuffer.js +7 -2
- package/SPLAT/gaussianSplattingWorkBuffer.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.js +1 -1
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.js.map +1 -1
- package/glTF/2.0/glTFLoader.d.ts +1 -0
- package/glTF/2.0/glTFLoader.js +1 -0
- package/glTF/2.0/glTFLoader.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connections.js","sourceRoot":"","sources":["../../../../../dev/loaders/src/FBX/interpreter/connections.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */\r\nimport { type FBXDocument, type FBXNode, cleanFBXName, findDocumentNode, getPropertyValue, getSafeFBXObjectId } from \"../types/fbxTypes\";\r\n\r\n/** Connection type: OO = object-to-object, OP = object-to-property */\r\nexport type ConnectionType = \"OO\" | \"OP\";\r\n\r\n/** A resolved FBX object connection. */\r\nexport interface FBXConnection {\r\n /** Connection type. */\r\n type: ConnectionType;\r\n /** Child object ID. */\r\n childId: number;\r\n /** Parent object ID. */\r\n parentId: number;\r\n /** For OP connections, the property name on the parent (e.g. \"DiffuseColor\") */\r\n propertyName?: string;\r\n}\r\n\r\n/** Object table entry used by the FBX connection graph. */\r\nexport interface FBXObjectEntry {\r\n /** Object ID. */\r\n id: number;\r\n /** Object node. */\r\n node: FBXNode;\r\n /** Source of the object entry. */\r\n source: \"Objects\" | \"legacySyntheticGeometry\";\r\n /** Legacy string object name, when applicable. */\r\n legacyName?: string;\r\n /** True if the object was synthesized for legacy compatibility. */\r\n synthetic: boolean;\r\n}\r\n\r\n/** Raw connection-table entry and import status. */\r\nexport interface FBXConnectionEntry {\r\n /** Source node name. */\r\n source: \"C\" | \"Connect\";\r\n /** Raw connection type. */\r\n rawType?: string;\r\n /** Child object ID, when resolved. */\r\n childId?: number;\r\n /** Parent object ID, when resolved. */\r\n parentId?: number;\r\n /** OP connection property name, when present. */\r\n propertyName?: string;\r\n /** True if the connection was accepted into the resolved graph. */\r\n accepted: boolean;\r\n}\r\n\r\n/** Reason a connection produced a diagnostic. */\r\nexport type FBXConnectionDiagnosticReason =\r\n | \"unsupported-connection-type\"\r\n | \"missing-connection-endpoint\"\r\n | \"unresolved-legacy-endpoint\"\r\n | \"unresolved-object-reference\"\r\n | \"duplicate-parent\"\r\n | \"self-loop\";\r\n\r\n/** Recoverable connection graph issue. */\r\nexport interface FBXConnectionDiagnostic {\r\n /** Diagnostic reason. */\r\n reason: FBXConnectionDiagnosticReason;\r\n /** Human-readable diagnostic message. */\r\n message: string;\r\n /** Connection-table index associated with the diagnostic, if applicable. */\r\n connectionIndex?: number;\r\n /** Connection type associated with the diagnostic, if applicable. */\r\n type?: string;\r\n /** Child object ID associated with the diagnostic, if applicable. */\r\n childId?: number;\r\n /** Parent object ID associated with the diagnostic, if applicable. */\r\n parentId?: number;\r\n /** OP connection property name associated with the diagnostic, if applicable. */\r\n propertyName?: string;\r\n}\r\n\r\n/** Resolved FBX object and connection graph. */\r\nexport interface FBXObjectMap {\r\n /** All objects by their unique ID */\r\n objects: Map<number, FBXNode>;\r\n /** Object table entries, including synthetic compatibility objects */\r\n objectEntries: FBXObjectEntry[];\r\n /** Children of each object ID */\r\n childrenOf: Map<number, { id: number; propertyName?: string }[]>;\r\n /** Parent of each object ID */\r\n parentOf: Map<number, { id: number; propertyName?: string }>;\r\n /** Raw connection list */\r\n connections: FBXConnection[];\r\n /** Raw connection-table entries and whether they were accepted into the graph */\r\n connectionEntries: FBXConnectionEntry[];\r\n /** Unsupported or suspicious connection shapes encountered while preserving graph behavior */\r\n diagnostics: FBXConnectionDiagnostic[];\r\n}\r\n\r\n/**\r\n * Build a connection graph from a parsed FBX document.\r\n * Maps object IDs to their FBXNode and resolves parent-child relationships.\r\n */\r\nexport function resolveConnections(doc: FBXDocument): FBXObjectMap {\r\n const objects = new Map<number, FBXNode>();\r\n const objectEntries: FBXObjectEntry[] = [];\r\n const childrenOf = new Map<number, { id: number; propertyName?: string }[]>();\r\n const parentOf = new Map<number, { id: number; propertyName?: string }>();\r\n const connections: FBXConnection[] = [];\r\n const connectionEntries: FBXConnectionEntry[] = [];\r\n const diagnostics: FBXConnectionDiagnostic[] = [];\r\n const legacyIds = new Map<string, number>();\r\n const syntheticLegacyIds = new Map<string, Map<string, number>>();\r\n let nextLegacyId = -1;\r\n\r\n const getLegacyId = (name: string): number => {\r\n let id = legacyIds.get(name);\r\n if (id === undefined) {\r\n id = nextLegacyId--;\r\n legacyIds.set(name, id);\r\n }\r\n return id;\r\n };\r\n\r\n const getSyntheticLegacyId = (role: string, name: string): number => {\r\n let idsByName = syntheticLegacyIds.get(role);\r\n if (!idsByName) {\r\n idsByName = new Map();\r\n syntheticLegacyIds.set(role, idsByName);\r\n }\r\n\r\n let id = idsByName.get(name);\r\n if (id === undefined) {\r\n id = nextLegacyId--;\r\n idsByName.set(name, id);\r\n }\r\n return id;\r\n };\r\n\r\n // Build object map from Objects section\r\n const objectsNode = findDocumentNode(doc, \"Objects\");\r\n if (objectsNode) {\r\n for (const obj of objectsNode.children) {\r\n const idProp = obj.properties[0];\r\n if (idProp) {\r\n const id = toObjectNumber(idProp.value);\r\n if (id !== undefined) {\r\n objects.set(id, obj);\r\n objectEntries.push({ id, node: obj, source: \"Objects\", synthetic: false });\r\n } else if (typeof idProp.value === \"string\") {\r\n const legacyName = cleanFBXName(idProp.value);\r\n const id = getLegacyId(legacyName);\r\n const normalized = normalizeLegacyObject(obj, id);\r\n objects.set(id, normalized);\r\n objectEntries.push({ id, node: normalized, source: \"Objects\", legacyName, synthetic: false });\r\n\r\n if (obj.name === \"Model\" && getPropertyValue<string>(obj, 1) === \"Mesh\") {\r\n const geometryId = getSyntheticLegacyId(\"Geometry\", legacyName);\r\n const geometry = createLegacyGeometry(obj, geometryId);\r\n objects.set(geometryId, geometry);\r\n objectEntries.push({ id: geometryId, node: geometry, source: \"legacySyntheticGeometry\", legacyName, synthetic: true });\r\n addConnection(connections, childrenOf, parentOf, diagnostics, \"OO\", geometryId, id);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Parse connections\r\n const connectionsNode = findDocumentNode(doc, \"Connections\");\r\n if (connectionsNode) {\r\n for (const c of connectionsNode.children) {\r\n if (c.name !== \"C\" && c.name !== \"Connect\") {\r\n continue;\r\n }\r\n\r\n const connectionIndex = connectionEntries.length;\r\n const type = getPropertyValue<string>(c, 0);\r\n const childIdRaw = c.properties[1]?.value;\r\n const parentIdRaw = c.properties[2]?.value;\r\n const entry: FBXConnectionEntry = {\r\n source: c.name,\r\n rawType: type,\r\n accepted: false,\r\n };\r\n connectionEntries.push(entry);\r\n\r\n if (type !== \"OO\" && type !== \"OP\") {\r\n const childId = childIdRaw === undefined ? undefined : toObjectId(childIdRaw, legacyIds);\r\n const parentId = parentIdRaw === undefined ? undefined : toObjectId(parentIdRaw, legacyIds);\r\n diagnostics.push({\r\n reason: \"unsupported-connection-type\",\r\n message: `Unsupported FBX connection type '${type ?? \"\"}' was not added to the graph.`,\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n });\r\n continue;\r\n }\r\n\r\n if (childIdRaw === undefined || parentIdRaw === undefined) {\r\n diagnostics.push({\r\n reason: \"missing-connection-endpoint\",\r\n message: \"FBX connection is missing a child or parent endpoint.\",\r\n connectionIndex,\r\n type,\r\n });\r\n continue;\r\n }\r\n\r\n const childId = toObjectId(childIdRaw, legacyIds);\r\n const parentId = toObjectId(parentIdRaw, legacyIds);\r\n if (childId === undefined || parentId === undefined) {\r\n diagnostics.push({\r\n reason: \"unresolved-legacy-endpoint\",\r\n message: \"FBX connection references a legacy string endpoint that is not present in the object table.\",\r\n connectionIndex,\r\n type,\r\n });\r\n continue;\r\n }\r\n\r\n const propertyName = type === \"OP\" && c.properties.length > 3 ? getPropertyValue<string>(c, 3) : undefined;\r\n\r\n entry.childId = childId;\r\n entry.parentId = parentId;\r\n entry.propertyName = propertyName;\r\n\r\n if (childId === parentId) {\r\n diagnostics.push({\r\n reason: \"self-loop\",\r\n message: \"FBX connection references the same object as child and parent.\",\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n propertyName,\r\n });\r\n }\r\n if (!objects.has(childId)) {\r\n diagnostics.push({\r\n reason: \"unresolved-object-reference\",\r\n message: \"FBX connection child ID is not present in the object table.\",\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n propertyName,\r\n });\r\n }\r\n if (parentId !== 0 && !objects.has(parentId)) {\r\n diagnostics.push({\r\n reason: \"unresolved-object-reference\",\r\n message: \"FBX connection parent ID is not present in the object table.\",\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n propertyName,\r\n });\r\n }\r\n\r\n addConnection(connections, childrenOf, parentOf, diagnostics, type, childId, parentId, propertyName, connectionIndex);\r\n entry.accepted = true;\r\n }\r\n }\r\n\r\n return { objects, objectEntries, childrenOf, parentOf, connections, connectionEntries, diagnostics };\r\n}\r\n\r\n/** Get all child objects of a given parent ID, optionally filtered by node name */\r\nexport function getChildren(map: FBXObjectMap, parentId: number, nodeName?: string): { id: number; node: FBXNode; propertyName?: string }[] {\r\n const children = map.childrenOf.get(parentId) ?? [];\r\n const result: { id: number; node: FBXNode; propertyName?: string }[] = [];\r\n\r\n for (const child of children) {\r\n const node = map.objects.get(child.id);\r\n if (node && (!nodeName || node.name === nodeName)) {\r\n result.push({ id: child.id, node, propertyName: child.propertyName });\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction toObjectNumber(value: unknown): number | undefined {\r\n return getSafeFBXObjectId(value);\r\n}\r\n\r\nfunction toObjectId(value: unknown, legacyIds: Map<string, number>): number | undefined {\r\n const numericId = toObjectNumber(value);\r\n if (numericId !== undefined) {\r\n return numericId;\r\n }\r\n if (typeof value !== \"string\") {\r\n return undefined;\r\n }\r\n const legacyName = cleanFBXName(value);\r\n if (legacyName === \"Scene\") {\r\n return 0;\r\n }\r\n return legacyIds.get(legacyName);\r\n}\r\n\r\nfunction addConnection(\r\n connections: FBXConnection[],\r\n childrenOf: Map<number, { id: number; propertyName?: string }[]>,\r\n parentOf: Map<number, { id: number; propertyName?: string }>,\r\n diagnostics: FBXConnectionDiagnostic[],\r\n type: ConnectionType,\r\n childId: number,\r\n parentId: number,\r\n propertyName?: string,\r\n connectionIndex?: number\r\n): void {\r\n connections.push({ type, childId, parentId, propertyName });\r\n\r\n if (!childrenOf.has(parentId)) {\r\n childrenOf.set(parentId, []);\r\n }\r\n childrenOf.get(parentId)!.push({ id: childId, propertyName });\r\n const existingParent = parentOf.get(childId);\r\n if (existingParent) {\r\n diagnostics.push({\r\n reason: \"duplicate-parent\",\r\n message: \"FBX object has multiple parents; preserving the existing last-parent behavior.\",\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n propertyName,\r\n });\r\n }\r\n parentOf.set(childId, { id: parentId, propertyName });\r\n}\r\n\r\nfunction normalizeLegacyObject(node: FBXNode, id: number): FBXNode {\r\n const name = cleanFBXName(getPropertyValue<string>(node, 0) ?? node.name);\r\n const subType = getPropertyValue<string>(node, 1) ?? \"\";\r\n return {\r\n ...node,\r\n properties: [\r\n { type: \"int64\", value: id },\r\n { type: \"string\", value: name },\r\n { type: \"string\", value: subType },\r\n ],\r\n };\r\n}\r\n\r\nfunction createLegacyGeometry(modelNode: FBXNode, geometryId: number): FBXNode {\r\n const name = cleanFBXName(getPropertyValue<string>(modelNode, 0) ?? \"Geometry\");\r\n return {\r\n name: \"Geometry\",\r\n properties: [\r\n { type: \"int64\", value: geometryId },\r\n { type: \"string\", value: name },\r\n { type: \"string\", value: \"Mesh\" },\r\n ],\r\n children: modelNode.children,\r\n };\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"connections.js","sourceRoot":"","sources":["../../../../../dev/loaders/src/FBX/interpreter/connections.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */\r\nimport { type FBXDocument, type FBXNode, cleanFBXName, findDocumentNode, getPropertyValue, getSafeFBXObjectId } from \"../types/fbxTypes\";\r\n\r\n/** Connection type: OO = object-to-object, OP = object-to-property */\r\nexport type ConnectionType = \"OO\" | \"OP\";\r\n\r\n/** A resolved FBX object connection. */\r\nexport interface FBXConnection {\r\n /** Connection type. */\r\n type: ConnectionType;\r\n /** Child object ID. */\r\n childId: number;\r\n /** Parent object ID. */\r\n parentId: number;\r\n /** For OP connections, the property name on the parent (e.g. \"DiffuseColor\") */\r\n propertyName?: string;\r\n}\r\n\r\n/** Object table entry used by the FBX connection graph. */\r\nexport interface FBXObjectEntry {\r\n /** Object ID. */\r\n id: number;\r\n /** Object node. */\r\n node: FBXNode;\r\n /** Source of the object entry. */\r\n source: \"Objects\" | \"legacySyntheticGeometry\";\r\n /** Legacy string object name, when applicable. */\r\n legacyName?: string;\r\n /** True if the object was synthesized for legacy compatibility. */\r\n synthetic: boolean;\r\n}\r\n\r\n/** Raw connection-table entry and import status. */\r\nexport interface FBXConnectionEntry {\r\n /** Source node name. */\r\n source: \"C\" | \"Connect\";\r\n /** Raw connection type. */\r\n rawType?: string;\r\n /** Child object ID, when resolved. */\r\n childId?: number;\r\n /** Parent object ID, when resolved. */\r\n parentId?: number;\r\n /** OP connection property name, when present. */\r\n propertyName?: string;\r\n /** True if the connection was accepted into the resolved graph. */\r\n accepted: boolean;\r\n}\r\n\r\n/** Reason a connection produced a diagnostic. */\r\nexport type FBXConnectionDiagnosticReason =\r\n \"unsupported-connection-type\" | \"missing-connection-endpoint\" | \"unresolved-legacy-endpoint\" | \"unresolved-object-reference\" | \"duplicate-parent\" | \"self-loop\";\r\n\r\n/** Recoverable connection graph issue. */\r\nexport interface FBXConnectionDiagnostic {\r\n /** Diagnostic reason. */\r\n reason: FBXConnectionDiagnosticReason;\r\n /** Human-readable diagnostic message. */\r\n message: string;\r\n /** Connection-table index associated with the diagnostic, if applicable. */\r\n connectionIndex?: number;\r\n /** Connection type associated with the diagnostic, if applicable. */\r\n type?: string;\r\n /** Child object ID associated with the diagnostic, if applicable. */\r\n childId?: number;\r\n /** Parent object ID associated with the diagnostic, if applicable. */\r\n parentId?: number;\r\n /** OP connection property name associated with the diagnostic, if applicable. */\r\n propertyName?: string;\r\n}\r\n\r\n/** Resolved FBX object and connection graph. */\r\nexport interface FBXObjectMap {\r\n /** All objects by their unique ID */\r\n objects: Map<number, FBXNode>;\r\n /** Object table entries, including synthetic compatibility objects */\r\n objectEntries: FBXObjectEntry[];\r\n /** Children of each object ID */\r\n childrenOf: Map<number, { id: number; propertyName?: string }[]>;\r\n /** Parent of each object ID */\r\n parentOf: Map<number, { id: number; propertyName?: string }>;\r\n /** Raw connection list */\r\n connections: FBXConnection[];\r\n /** Raw connection-table entries and whether they were accepted into the graph */\r\n connectionEntries: FBXConnectionEntry[];\r\n /** Unsupported or suspicious connection shapes encountered while preserving graph behavior */\r\n diagnostics: FBXConnectionDiagnostic[];\r\n}\r\n\r\n/**\r\n * Build a connection graph from a parsed FBX document.\r\n * Maps object IDs to their FBXNode and resolves parent-child relationships.\r\n */\r\nexport function resolveConnections(doc: FBXDocument): FBXObjectMap {\r\n const objects = new Map<number, FBXNode>();\r\n const objectEntries: FBXObjectEntry[] = [];\r\n const childrenOf = new Map<number, { id: number; propertyName?: string }[]>();\r\n const parentOf = new Map<number, { id: number; propertyName?: string }>();\r\n const connections: FBXConnection[] = [];\r\n const connectionEntries: FBXConnectionEntry[] = [];\r\n const diagnostics: FBXConnectionDiagnostic[] = [];\r\n const legacyIds = new Map<string, number>();\r\n const syntheticLegacyIds = new Map<string, Map<string, number>>();\r\n let nextLegacyId = -1;\r\n\r\n const getLegacyId = (name: string): number => {\r\n let id = legacyIds.get(name);\r\n if (id === undefined) {\r\n id = nextLegacyId--;\r\n legacyIds.set(name, id);\r\n }\r\n return id;\r\n };\r\n\r\n const getSyntheticLegacyId = (role: string, name: string): number => {\r\n let idsByName = syntheticLegacyIds.get(role);\r\n if (!idsByName) {\r\n idsByName = new Map();\r\n syntheticLegacyIds.set(role, idsByName);\r\n }\r\n\r\n let id = idsByName.get(name);\r\n if (id === undefined) {\r\n id = nextLegacyId--;\r\n idsByName.set(name, id);\r\n }\r\n return id;\r\n };\r\n\r\n // Build object map from Objects section\r\n const objectsNode = findDocumentNode(doc, \"Objects\");\r\n if (objectsNode) {\r\n for (const obj of objectsNode.children) {\r\n const idProp = obj.properties[0];\r\n if (idProp) {\r\n const id = toObjectNumber(idProp.value);\r\n if (id !== undefined) {\r\n objects.set(id, obj);\r\n objectEntries.push({ id, node: obj, source: \"Objects\", synthetic: false });\r\n } else if (typeof idProp.value === \"string\") {\r\n const legacyName = cleanFBXName(idProp.value);\r\n const id = getLegacyId(legacyName);\r\n const normalized = normalizeLegacyObject(obj, id);\r\n objects.set(id, normalized);\r\n objectEntries.push({ id, node: normalized, source: \"Objects\", legacyName, synthetic: false });\r\n\r\n if (obj.name === \"Model\" && getPropertyValue<string>(obj, 1) === \"Mesh\") {\r\n const geometryId = getSyntheticLegacyId(\"Geometry\", legacyName);\r\n const geometry = createLegacyGeometry(obj, geometryId);\r\n objects.set(geometryId, geometry);\r\n objectEntries.push({ id: geometryId, node: geometry, source: \"legacySyntheticGeometry\", legacyName, synthetic: true });\r\n addConnection(connections, childrenOf, parentOf, diagnostics, \"OO\", geometryId, id);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Parse connections\r\n const connectionsNode = findDocumentNode(doc, \"Connections\");\r\n if (connectionsNode) {\r\n for (const c of connectionsNode.children) {\r\n if (c.name !== \"C\" && c.name !== \"Connect\") {\r\n continue;\r\n }\r\n\r\n const connectionIndex = connectionEntries.length;\r\n const type = getPropertyValue<string>(c, 0);\r\n const childIdRaw = c.properties[1]?.value;\r\n const parentIdRaw = c.properties[2]?.value;\r\n const entry: FBXConnectionEntry = {\r\n source: c.name,\r\n rawType: type,\r\n accepted: false,\r\n };\r\n connectionEntries.push(entry);\r\n\r\n if (type !== \"OO\" && type !== \"OP\") {\r\n const childId = childIdRaw === undefined ? undefined : toObjectId(childIdRaw, legacyIds);\r\n const parentId = parentIdRaw === undefined ? undefined : toObjectId(parentIdRaw, legacyIds);\r\n diagnostics.push({\r\n reason: \"unsupported-connection-type\",\r\n message: `Unsupported FBX connection type '${type ?? \"\"}' was not added to the graph.`,\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n });\r\n continue;\r\n }\r\n\r\n if (childIdRaw === undefined || parentIdRaw === undefined) {\r\n diagnostics.push({\r\n reason: \"missing-connection-endpoint\",\r\n message: \"FBX connection is missing a child or parent endpoint.\",\r\n connectionIndex,\r\n type,\r\n });\r\n continue;\r\n }\r\n\r\n const childId = toObjectId(childIdRaw, legacyIds);\r\n const parentId = toObjectId(parentIdRaw, legacyIds);\r\n if (childId === undefined || parentId === undefined) {\r\n diagnostics.push({\r\n reason: \"unresolved-legacy-endpoint\",\r\n message: \"FBX connection references a legacy string endpoint that is not present in the object table.\",\r\n connectionIndex,\r\n type,\r\n });\r\n continue;\r\n }\r\n\r\n const propertyName = type === \"OP\" && c.properties.length > 3 ? getPropertyValue<string>(c, 3) : undefined;\r\n\r\n entry.childId = childId;\r\n entry.parentId = parentId;\r\n entry.propertyName = propertyName;\r\n\r\n if (childId === parentId) {\r\n diagnostics.push({\r\n reason: \"self-loop\",\r\n message: \"FBX connection references the same object as child and parent.\",\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n propertyName,\r\n });\r\n }\r\n if (!objects.has(childId)) {\r\n diagnostics.push({\r\n reason: \"unresolved-object-reference\",\r\n message: \"FBX connection child ID is not present in the object table.\",\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n propertyName,\r\n });\r\n }\r\n if (parentId !== 0 && !objects.has(parentId)) {\r\n diagnostics.push({\r\n reason: \"unresolved-object-reference\",\r\n message: \"FBX connection parent ID is not present in the object table.\",\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n propertyName,\r\n });\r\n }\r\n\r\n addConnection(connections, childrenOf, parentOf, diagnostics, type, childId, parentId, propertyName, connectionIndex);\r\n entry.accepted = true;\r\n }\r\n }\r\n\r\n return { objects, objectEntries, childrenOf, parentOf, connections, connectionEntries, diagnostics };\r\n}\r\n\r\n/** Get all child objects of a given parent ID, optionally filtered by node name */\r\nexport function getChildren(map: FBXObjectMap, parentId: number, nodeName?: string): { id: number; node: FBXNode; propertyName?: string }[] {\r\n const children = map.childrenOf.get(parentId) ?? [];\r\n const result: { id: number; node: FBXNode; propertyName?: string }[] = [];\r\n\r\n for (const child of children) {\r\n const node = map.objects.get(child.id);\r\n if (node && (!nodeName || node.name === nodeName)) {\r\n result.push({ id: child.id, node, propertyName: child.propertyName });\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction toObjectNumber(value: unknown): number | undefined {\r\n return getSafeFBXObjectId(value);\r\n}\r\n\r\nfunction toObjectId(value: unknown, legacyIds: Map<string, number>): number | undefined {\r\n const numericId = toObjectNumber(value);\r\n if (numericId !== undefined) {\r\n return numericId;\r\n }\r\n if (typeof value !== \"string\") {\r\n return undefined;\r\n }\r\n const legacyName = cleanFBXName(value);\r\n if (legacyName === \"Scene\") {\r\n return 0;\r\n }\r\n return legacyIds.get(legacyName);\r\n}\r\n\r\nfunction addConnection(\r\n connections: FBXConnection[],\r\n childrenOf: Map<number, { id: number; propertyName?: string }[]>,\r\n parentOf: Map<number, { id: number; propertyName?: string }>,\r\n diagnostics: FBXConnectionDiagnostic[],\r\n type: ConnectionType,\r\n childId: number,\r\n parentId: number,\r\n propertyName?: string,\r\n connectionIndex?: number\r\n): void {\r\n connections.push({ type, childId, parentId, propertyName });\r\n\r\n if (!childrenOf.has(parentId)) {\r\n childrenOf.set(parentId, []);\r\n }\r\n childrenOf.get(parentId)!.push({ id: childId, propertyName });\r\n const existingParent = parentOf.get(childId);\r\n if (existingParent) {\r\n diagnostics.push({\r\n reason: \"duplicate-parent\",\r\n message: \"FBX object has multiple parents; preserving the existing last-parent behavior.\",\r\n connectionIndex,\r\n type,\r\n childId,\r\n parentId,\r\n propertyName,\r\n });\r\n }\r\n parentOf.set(childId, { id: parentId, propertyName });\r\n}\r\n\r\nfunction normalizeLegacyObject(node: FBXNode, id: number): FBXNode {\r\n const name = cleanFBXName(getPropertyValue<string>(node, 0) ?? node.name);\r\n const subType = getPropertyValue<string>(node, 1) ?? \"\";\r\n return {\r\n ...node,\r\n properties: [\r\n { type: \"int64\", value: id },\r\n { type: \"string\", value: name },\r\n { type: \"string\", value: subType },\r\n ],\r\n };\r\n}\r\n\r\nfunction createLegacyGeometry(modelNode: FBXNode, geometryId: number): FBXNode {\r\n const name = cleanFBXName(getPropertyValue<string>(modelNode, 0) ?? \"Geometry\");\r\n return {\r\n name: \"Geometry\",\r\n properties: [\r\n { type: \"int64\", value: geometryId },\r\n { type: \"string\", value: name },\r\n { type: \"string\", value: \"Mesh\" },\r\n ],\r\n children: modelNode.children,\r\n };\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gaussianSplattingBlockAllocator.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingBlockAllocator.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,OAAO,yBAAyB;IAAtC;QACI,+CAA+C;QACxC,YAAO,GAAG,CAAC,CAAC;QACnB,oCAAoC;QAC7B,UAAK,GAAG,CAAC,CAAC;QACjB,mEAAmE;QAC5D,UAAK,GAAG,IAAI,CAAC;QACpB,4EAA4E;QACrE,UAAK,GAAwC,IAAI,CAAC;QACzD,wEAAwE;QACjE,UAAK,GAAwC,IAAI,CAAC;QACzD,uDAAuD;QAChD,cAAS,GAAwC,IAAI,CAAC;QAC7D,mDAAmD;QAC5C,cAAS,GAAwC,IAAI,CAAC;QAC7D,iGAAiG;QAC1F,YAAO,GAAG,CAAC,CAAC,CAAC;IAexB,CAAC;IAbG;;OAEG;IACH,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;CACJ;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,+BAA+B;IAgBxC;;;;OAIG;IACH,YAAmB,QAAQ,GAAG,CAAC,EAAE,cAAc,GAAG,GAAG;QApBrD,2DAA2D;QACnD,aAAQ,GAAwC,IAAI,CAAC;QACrD,aAAQ,GAAwC,IAAI,CAAC;QAC7D,+GAA+G;QAC9F,qBAAgB,GAA+C,EAAE,CAAC;QACnF,qCAAqC;QACpB,UAAK,GAAgC,EAAE,CAAC;QACjD,cAAS,GAAG,CAAC,CAAC;QACd,cAAS,GAAG,CAAC,CAAC;QACd,cAAS,GAAG,CAAC,CAAC;QACtB,wEAAwE;QAChE,qBAAgB,GAAG,CAAC,CAAC;QAUzB,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;QACtC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACf,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;YAC1B,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;YAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;IAED;;OAEG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACI,QAAQ,CAAC,IAAY;QACxB,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC;QACvB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC;QAEvB,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACrB,gDAAgD;YAChD,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAC5B,OAAO,GAAG,CAAC;QACf,CAAC;QAED,6DAA6D;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACrD,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;QACpB,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC;QAClB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;;OAGG;IACI,IAAI,CAAC,KAAgC;QACxC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACxB,OAAO;QACX,CAAC;QAED,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC;QAC9B,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC;QAE9B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC;QAEpC,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;YACvB,kDAAkD;YAClD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACvC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YAClB,uCAAuC;YACvC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;YAC1B,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YAClB,gDAAgD;YAChD,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC;YAC1B,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACJ,6CAA6C;YAC7C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,IAAI,CAAC,WAAmB;QAC3B,IAAI,WAAW,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAChC,OAAO;QACX,CAAC;QAED,MAAM,KAAK,GAAG,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC;QAC7B,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;QAExB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACvC,mCAAmC;YACnC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,KAAK,CAAC;YAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACJ,yBAAyB;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAChE,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE,SAAyC,IAAI,GAAG,EAAE;QAC1E,MAAM,CAAC,KAAK,EAAE,CAAC;QAEf,IAAI,IAAI,CAAC,gBAAgB,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;;;;OAOG;IACI,gBAAgB,CAAC,MAAmC,EAAE,UAAqD;QAC9G,4BAA4B;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QAED,2CAA2C;QAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAW,CAAC;YACrC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,KAAK,EAAE,CAAC;gBACR,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACJ,yFAAyF;gBACzF,IAAI,cAAc,GAAG,IAAI,CAAC;gBAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7C,cAAc,IAAI,UAAU,CAAC,CAAC,CAAW,CAAC;gBAC9C,CAAC;gBAED,gEAAgE;gBAChE,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,GAAG,cAAc,CAAC;gBACvD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;gBAC1E,IAAI,gBAAgB,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBAChC,CAAC;gBAED,wFAAwF;gBACxF,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACzC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAW,CAAE,CAAC;gBAC5D,CAAC;gBAED,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACK,UAAU,CAAC,IAAY;QAC3B,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAEO,YAAY,CAAC,KAAgC;QACjD,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;QAClB,OAAO,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAE,CAAC,SAAS,GAAG,KAAK,CAAC;QAChD,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QACjC,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAEO,iBAAiB,CAAC,KAAgC;QACtD,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;QACxB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAClB,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QAC/C,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAClB,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QAChD,CAAC;QACD,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAEO,SAAS,CAAC,KAAgC;QAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,SAAS,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;IAEO,OAAO,CAAC,MAAc,EAAE,IAAY,EAAE,IAAa;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAG,CAAC,CAAC,CAAC,IAAI,yBAAyB,EAAE,CAAC;QAC1F,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QACvB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACnB,OAAO,KAAK,CAAC;IACjB,CAAC;IAEO,QAAQ,CAAC,KAAgC;QAC7C,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAEO,sBAAsB,CAAC,KAAgC,EAAE,KAA0C;QACvG,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACjB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;YACnB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC5B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChB,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;YAChC,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACjB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YAC1B,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YACpB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAC1B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YAC9B,CAAC;YACD,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YACpB,IAAI,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;gBAC1B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YAC1B,CAAC;QACL,CAAC;IACL,CAAC;IAEO,mBAAmB,CAAC,KAAgC;QACxD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACpC,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;QAChC,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACpC,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;QAChC,CAAC;QACD,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;IACvB,CAAC;IAEO,cAAc,CAAC,IAAY;QAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;QAEzC,oDAAoD;QACpD,IAAI,WAAW,GAAG,GAAG,EAAE,CAAC;YACpB,IAAI,IAAI,GAAwC,IAAI,CAAC;YACrD,IAAI,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;YAC9C,OAAO,IAAI,EAAE,CAAC;gBACV,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;oBACrB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;wBACnC,IAAI,GAAG,IAAI,CAAC;wBACZ,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;4BACtB,MAAM;wBACV,CAAC;oBACL,CAAC;gBACL,CAAC;gBACD,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAC1B,CAAC;YACD,IAAI,IAAI,EAAE,CAAC;gBACP,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QAED,yDAAyD;QACzD,KAAK,IAAI,CAAC,GAAG,WAAW,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3B,OAAO,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACpC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,WAAW,CAAC,MAAsC;QACtD,yDAAyD;QACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,IAAI,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACpC,OAAO,IAAI,EAAE,CAAC;gBACV,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;gBAChC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;gBAC/B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;gBAClB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtB,IAAI,GAAG,QAAQ,CAAC;YACpB,CAAC;YACD,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAE1B,uEAAuE;QACvE,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1B,OAAO,KAAK,EAAE,CAAC;YACX,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;gBAC3B,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;gBACvB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC;YACtB,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACxB,CAAC;QAED,wEAAwE;QACxE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QAC1C,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YACxD,IAAI,CAAC,sBAAsB,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtD,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;IACL,CAAC;IAEO,kBAAkB,CAAC,QAAgB,EAAE,MAAsC;QAC/E,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;QAE3C,mGAAmG;QACnG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,IAAI,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC9B,OAAO,SAAS,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;gBAClC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC;YAChC,CAAC;YACD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACb,MAAM;YACV,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACjD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;gBAC3C,MAAM;YACV,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAChC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAED,mGAAmG;QACnG,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,IAAI,KAAK,GAAI,CAAC;YACzC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;YAEzB,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACrC,MAAM,UAAU,GAAG,IAAI,CAAC;gBACxB,MAAM,SAAS,GAAG,KAAK,CAAC;gBAExB,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;gBACvC,SAAS,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC;gBAE1D,yBAAyB;gBACzB,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC;gBAC1B,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;gBAE3B,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC;gBACrB,UAAU,CAAC,KAAK,GAAG,SAAS,CAAC;gBAC7B,SAAS,CAAC,KAAK,GAAG,UAAU,CAAC;gBAC7B,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC;gBACpB,IAAI,CAAC,EAAE,CAAC;oBACJ,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC;gBAC/B,CAAC;gBACD,IAAI,CAAC,EAAE,CAAC;oBACJ,CAAC,CAAC,KAAK,GAAG,SAAS,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;gBAC9B,CAAC;gBAED,iEAAiE;gBACjE,IAAI,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;oBAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;oBAC9B,SAAS,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;oBAC/B,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;oBAChC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;oBAC9B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;oBACrB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBAC9B,CAAC;gBAED,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACvB,CAAC,EAAE,CAAC;gBAEJ,sEAAsE;gBACtE,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;YAC5B,CAAC;iBAAM,CAAC;gBACJ,KAAK,GAAG,IAAI,CAAC;YACjB,CAAC;QACL,CAAC;IACL,CAAC;IAEO,UAAU,CAAC,KAAgC,EAAE,GAA8B;QAC/E,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC;QAE9B,qEAAqE;QACrE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAEhC,4CAA4C;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAC3D,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAEzB,uCAAuC;QACvC,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAC1B,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,sCAAsC;QACtC,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;YACzB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;YAC1B,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAED,iCAAiC;QACjC,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC;QAE1B,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1B,+CAA+C;YAC/C,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC;YAC1B,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACnB,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,2DAA2D;YAC3D,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;YACzB,GAAG,CAAC,KAAK,IAAI,SAAS,CAAC;YACvB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACpB,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;IACL,CAAC;CACJ","sourcesContent":["import { type Nullable } from \"core/types\";\r\n\r\n/**\r\n * A node in the {@link GaussianSplattingBlockAllocator}'s linked list, representing either an allocated\r\n * block or a free region. Callers receive {@link GaussianSplattingMemBlock} instances as handles from\r\n * {@link GaussianSplattingBlockAllocator.allocate} and must treat their {@link offset}/{@link size} as\r\n * read-only.\r\n *\r\n * Ported from the PlayCanvas engine (`src/core/block-allocator.js`).\r\n * @experimental\r\n */\r\nexport class GaussianSplattingMemBlock {\r\n /** @internal Position in the address space. */\r\n public _offset = 0;\r\n /** @internal Size of this block. */\r\n public _size = 0;\r\n /** @internal True if this is a free region, false if allocated. */\r\n public _free = true;\r\n /** @internal Previous node in the main (all-nodes, offset-ordered) list. */\r\n public _prev: Nullable<GaussianSplattingMemBlock> = null;\r\n /** @internal Next node in the main (all-nodes, offset-ordered) list. */\r\n public _next: Nullable<GaussianSplattingMemBlock> = null;\r\n /** @internal Previous node in the bucket free-list. */\r\n public _prevFree: Nullable<GaussianSplattingMemBlock> = null;\r\n /** @internal Next node in the bucket free-list. */\r\n public _nextFree: Nullable<GaussianSplattingMemBlock> = null;\r\n /** @internal Index of the size bucket this free block belongs to, or -1 if not in any bucket. */\r\n public _bucket = -1;\r\n\r\n /**\r\n * The offset of this block in the address space.\r\n */\r\n public get offset(): number {\r\n return this._offset;\r\n }\r\n\r\n /**\r\n * The size of this block.\r\n */\r\n public get size(): number {\r\n return this._size;\r\n }\r\n}\r\n\r\n/**\r\n * A general-purpose 1D block allocator backed by a doubly-linked list with segregated free-list buckets.\r\n * Manages a linear address space where contiguous blocks can be allocated and freed.\r\n *\r\n * Free blocks are organized into power-of-2 size buckets for best-fit allocation, which reduces\r\n * fragmentation compared to a single first-fit free list. Supports incremental defragmentation and\r\n * automatic growth. Used to place streamed Gaussian Splatting LOD files into the unified GPU work buffer.\r\n *\r\n * Ported from the PlayCanvas engine (`src/core/block-allocator.js`).\r\n * @experimental\r\n */\r\nexport class GaussianSplattingBlockAllocator {\r\n // Head/tail of the main list (all blocks, offset-ordered).\r\n private _headAll: Nullable<GaussianSplattingMemBlock> = null;\r\n private _tailAll: Nullable<GaussianSplattingMemBlock> = null;\r\n // Segregated free-list bucket heads. Bucket i covers sizes [2^i, 2^(i+1)). Grows as larger free blocks appear.\r\n private readonly _freeBucketHeads: Array<Nullable<GaussianSplattingMemBlock>> = [];\r\n // Pool of recycled MemBlock objects.\r\n private readonly _pool: GaussianSplattingMemBlock[] = [];\r\n private _capacity = 0;\r\n private _usedSize = 0;\r\n private _freeSize = 0;\r\n // Number of free regions; maintained O(1) for the fragmentation metric.\r\n private _freeRegionCount = 0;\r\n // Multiplicative growth factor used by updateAllocation.\r\n private readonly _growMultiplier: number;\r\n\r\n /**\r\n * Creates a new block allocator.\r\n * @param capacity initial address space capacity (defaults to 0)\r\n * @param growMultiplier multiplicative growth factor for auto-grow in {@link updateAllocation} (defaults to 1.1)\r\n */\r\n public constructor(capacity = 0, growMultiplier = 1.1) {\r\n this._growMultiplier = growMultiplier;\r\n if (capacity > 0) {\r\n this._capacity = capacity;\r\n this._freeSize = capacity;\r\n const block = this._obtain(0, capacity, true);\r\n this._headAll = block;\r\n this._tailAll = block;\r\n this._addToBucket(block);\r\n }\r\n }\r\n\r\n /**\r\n * Total address space capacity.\r\n */\r\n public get capacity(): number {\r\n return this._capacity;\r\n }\r\n\r\n /**\r\n * Total size of all allocated blocks.\r\n */\r\n public get usedSize(): number {\r\n return this._usedSize;\r\n }\r\n\r\n /**\r\n * Total size of all free regions.\r\n */\r\n public get freeSize(): number {\r\n return this._freeSize;\r\n }\r\n\r\n /**\r\n * Fragmentation ratio in the range [0, 1]. Returns 0 when all free space is one contiguous block\r\n * (ideal), and approaches 1 when free space is split into many pieces. Computed O(1).\r\n */\r\n public get fragmentation(): number {\r\n return this._freeSize > 0 ? 1 - 1 / this._freeRegionCount : 0;\r\n }\r\n\r\n /**\r\n * Allocates a contiguous block of the given size.\r\n * @param size the number of units to allocate (must be \\> 0)\r\n * @returns a block handle, or null if no space is available\r\n */\r\n public allocate(size: number): Nullable<GaussianSplattingMemBlock> {\r\n if (size <= 0) {\r\n return null;\r\n }\r\n\r\n const gap = this._findFreeBlock(size);\r\n if (!gap) {\r\n return null;\r\n }\r\n\r\n this._usedSize += size;\r\n this._freeSize -= size;\r\n\r\n if (gap._size === size) {\r\n // Perfect fit: convert free block to allocated.\r\n gap._free = false;\r\n this._removeFromBucket(gap);\r\n return gap;\r\n }\r\n\r\n // Split: create allocated block at start of gap, shrink gap.\r\n const alloc = this._obtain(gap._offset, size, false);\r\n gap._offset += size;\r\n gap._size -= size;\r\n this._rebucket(gap);\r\n this._insertAfterInMainList(alloc, gap._prev);\r\n return alloc;\r\n }\r\n\r\n /**\r\n * Frees a previously allocated block. Adjacent free regions are merged automatically.\r\n * @param block the block to free (must have been returned by {@link allocate})\r\n */\r\n public free(block: GaussianSplattingMemBlock): void {\r\n if (!block || block._free) {\r\n return;\r\n }\r\n\r\n block._free = true;\r\n this._usedSize -= block._size;\r\n this._freeSize += block._size;\r\n\r\n const prev = block._prev;\r\n const next = block._next;\r\n const prevFree = prev && prev._free;\r\n const nextFree = next && next._free;\r\n\r\n if (prevFree && nextFree) {\r\n // Both neighbors free: merge all three into prev.\r\n prev._size += block._size + next._size;\r\n this._removeFromMainList(block);\r\n this._removeFromMainList(next);\r\n this._removeFromBucket(next);\r\n this._release(block);\r\n this._release(next);\r\n this._rebucket(prev);\r\n } else if (prevFree) {\r\n // Left neighbor free: merge into prev.\r\n prev._size += block._size;\r\n this._removeFromMainList(block);\r\n this._release(block);\r\n this._rebucket(prev);\r\n } else if (nextFree) {\r\n // Right neighbor free: absorb right into block.\r\n block._size += next._size;\r\n this._removeFromMainList(next);\r\n this._removeFromBucket(next);\r\n this._release(next);\r\n this._addToBucket(block);\r\n } else {\r\n // Neither neighbor free: insert into bucket.\r\n this._addToBucket(block);\r\n }\r\n }\r\n\r\n /**\r\n * Grows the address space. Only increases capacity, never decreases.\r\n * @param newCapacity the new capacity (must be \\> current capacity)\r\n */\r\n public grow(newCapacity: number): void {\r\n if (newCapacity <= this._capacity) {\r\n return;\r\n }\r\n\r\n const added = newCapacity - this._capacity;\r\n this._capacity = newCapacity;\r\n this._freeSize += added;\r\n\r\n if (this._tailAll && this._tailAll._free) {\r\n // Extend existing tail free block.\r\n this._tailAll._size += added;\r\n this._rebucket(this._tailAll);\r\n } else {\r\n // Append new free block.\r\n const block = this._obtain(this._capacity - added, added, true);\r\n this._insertAfterInMainList(block, this._tailAll);\r\n this._addToBucket(block);\r\n }\r\n }\r\n\r\n /**\r\n * Defragments the allocator by moving allocated blocks to reduce fragmentation.\r\n *\r\n * When maxMoves is 0, performs a full compaction in a single O(n) pass: all allocated blocks are packed\r\n * contiguously from offset 0 and a single free block is placed at the end. When maxMoves \\> 0, performs\r\n * incremental defragmentation (relocate the last block into the first fitting gap, then slide blocks left).\r\n *\r\n * Moved blocks have their {@link GaussianSplattingMemBlock.offset} updated in place (handles stay valid),\r\n * so callers must relocate the corresponding GPU data for every block in the returned set.\r\n * @param maxMoves maximum number of block moves (0 = full compaction, the default)\r\n * @param result optional set to receive the moved blocks (defaults to a new set)\r\n * @returns the set of blocks that were moved\r\n */\r\n public defrag(maxMoves = 0, result: Set<GaussianSplattingMemBlock> = new Set()): Set<GaussianSplattingMemBlock> {\r\n result.clear();\r\n\r\n if (this._freeRegionCount === 0) {\r\n return result;\r\n }\r\n\r\n if (maxMoves === 0) {\r\n this._defragFull(result);\r\n } else {\r\n this._defragIncremental(maxMoves, result);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Batch update: frees a set of blocks and allocates new ones. Handles growth and compaction internally\r\n * when allocations cannot be satisfied. The `toAllocate` array is modified in place: each numeric size\r\n * entry is replaced with the allocated block.\r\n * @param toFree blocks to release\r\n * @param toAllocate sizes to allocate; modified in place (numbers are replaced with block handles)\r\n * @returns true if a full defrag was performed (all existing blocks have new offsets and must be re-rendered)\r\n */\r\n public updateAllocation(toFree: GaussianSplattingMemBlock[], toAllocate: Array<number | GaussianSplattingMemBlock>): boolean {\r\n // Phase 1: free old blocks.\r\n for (let i = 0; i < toFree.length; i++) {\r\n this.free(toFree[i]);\r\n }\r\n\r\n // Phase 2: try to allocate all new blocks.\r\n for (let i = 0; i < toAllocate.length; i++) {\r\n const size = toAllocate[i] as number;\r\n const block = this.allocate(size);\r\n if (block) {\r\n toAllocate[i] = block;\r\n } else {\r\n // Allocation failed at index i; entries [0..i-1] are blocks, [i..n-1] are still numbers.\r\n let totalRemaining = size;\r\n for (let j = i + 1; j < toAllocate.length; j++) {\r\n totalRemaining += toAllocate[j] as number;\r\n }\r\n\r\n // Grow if the free space would be below the headroom threshold.\r\n const neededCapacity = this._usedSize + totalRemaining;\r\n const headroomCapacity = Math.ceil(neededCapacity * this._growMultiplier);\r\n if (headroomCapacity > this._capacity) {\r\n this.grow(headroomCapacity);\r\n }\r\n\r\n // Full defrag: compact everything, then allocate the remainder (guaranteed to succeed).\r\n this.defrag(0);\r\n for (let j = i; j < toAllocate.length; j++) {\r\n toAllocate[j] = this.allocate(toAllocate[j] as number)!;\r\n }\r\n\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Computes the bucket index for a given block size (= floor(log2(size))).\r\n * @param size block size (must be \\> 0)\r\n * @returns the bucket index\r\n */\r\n private _bucketFor(size: number): number {\r\n return 31 - Math.clz32(size);\r\n }\r\n\r\n private _addToBucket(block: GaussianSplattingMemBlock): void {\r\n const b = this._bucketFor(block._size);\r\n block._bucket = b;\r\n while (b >= this._freeBucketHeads.length) {\r\n this._freeBucketHeads.push(null);\r\n }\r\n block._prevFree = null;\r\n block._nextFree = this._freeBucketHeads[b];\r\n if (this._freeBucketHeads[b]) {\r\n this._freeBucketHeads[b]!._prevFree = block;\r\n }\r\n this._freeBucketHeads[b] = block;\r\n this._freeRegionCount++;\r\n }\r\n\r\n private _removeFromBucket(block: GaussianSplattingMemBlock): void {\r\n const b = block._bucket;\r\n if (block._prevFree) {\r\n block._prevFree._nextFree = block._nextFree;\r\n } else {\r\n this._freeBucketHeads[b] = block._nextFree;\r\n }\r\n if (block._nextFree) {\r\n block._nextFree._prevFree = block._prevFree;\r\n }\r\n block._prevFree = null;\r\n block._nextFree = null;\r\n block._bucket = -1;\r\n this._freeRegionCount--;\r\n }\r\n\r\n private _rebucket(block: GaussianSplattingMemBlock): void {\r\n const newBucket = this._bucketFor(block._size);\r\n if (newBucket !== block._bucket) {\r\n this._removeFromBucket(block);\r\n this._addToBucket(block);\r\n }\r\n }\r\n\r\n private _obtain(offset: number, size: number, free: boolean): GaussianSplattingMemBlock {\r\n const block = this._pool.length > 0 ? this._pool.pop()! : new GaussianSplattingMemBlock();\r\n block._offset = offset;\r\n block._size = size;\r\n block._free = free;\r\n block._prev = null;\r\n block._next = null;\r\n block._prevFree = null;\r\n block._nextFree = null;\r\n block._bucket = -1;\r\n return block;\r\n }\r\n\r\n private _release(block: GaussianSplattingMemBlock): void {\r\n block._prev = null;\r\n block._next = null;\r\n block._prevFree = null;\r\n block._nextFree = null;\r\n block._bucket = -1;\r\n this._pool.push(block);\r\n }\r\n\r\n private _insertAfterInMainList(block: GaussianSplattingMemBlock, after: Nullable<GaussianSplattingMemBlock>): void {\r\n if (after === null) {\r\n block._prev = null;\r\n block._next = this._headAll;\r\n if (this._headAll) {\r\n this._headAll._prev = block;\r\n }\r\n this._headAll = block;\r\n if (!this._tailAll) {\r\n this._tailAll = block;\r\n }\r\n } else {\r\n block._prev = after;\r\n block._next = after._next;\r\n if (after._next) {\r\n after._next._prev = block;\r\n }\r\n after._next = block;\r\n if (this._tailAll === after) {\r\n this._tailAll = block;\r\n }\r\n }\r\n }\r\n\r\n private _removeFromMainList(block: GaussianSplattingMemBlock): void {\r\n if (block._prev) {\r\n block._prev._next = block._next;\r\n } else {\r\n this._headAll = block._next;\r\n }\r\n if (block._next) {\r\n block._next._prev = block._prev;\r\n } else {\r\n this._tailAll = block._prev;\r\n }\r\n block._prev = null;\r\n block._next = null;\r\n }\r\n\r\n private _findFreeBlock(size: number): Nullable<GaussianSplattingMemBlock> {\r\n const startBucket = this._bucketFor(size);\r\n const len = this._freeBucketHeads.length;\r\n\r\n // Target bucket: best-fit (smallest block >= size).\r\n if (startBucket < len) {\r\n let best: Nullable<GaussianSplattingMemBlock> = null;\r\n let node = this._freeBucketHeads[startBucket];\r\n while (node) {\r\n if (node._size >= size) {\r\n if (!best || node._size < best._size) {\r\n best = node;\r\n if (node._size === size) {\r\n break;\r\n }\r\n }\r\n }\r\n node = node._nextFree;\r\n }\r\n if (best) {\r\n return best;\r\n }\r\n }\r\n\r\n // Higher buckets: first-fit (any block is large enough).\r\n for (let b = startBucket + 1; b < len; b++) {\r\n if (this._freeBucketHeads[b]) {\r\n return this._freeBucketHeads[b];\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n private _defragFull(result: Set<GaussianSplattingMemBlock>): void {\r\n // Remove all free blocks from all buckets and pool them.\r\n for (let b = 0; b < this._freeBucketHeads.length; b++) {\r\n let node = this._freeBucketHeads[b];\r\n while (node) {\r\n const nextFree = node._nextFree;\r\n this._removeFromMainList(node);\r\n node._prevFree = null;\r\n node._nextFree = null;\r\n node._bucket = -1;\r\n this._pool.push(node);\r\n node = nextFree;\r\n }\r\n this._freeBucketHeads[b] = null;\r\n }\r\n this._freeRegionCount = 0;\r\n\r\n // Walk remaining (all allocated) blocks, assigning sequential offsets.\r\n let offset = 0;\r\n let block = this._headAll;\r\n while (block) {\r\n if (block._offset !== offset) {\r\n block._offset = offset;\r\n result.add(block);\r\n }\r\n offset += block._size;\r\n block = block._next;\r\n }\r\n\r\n // Create a single free block at the end if there is remaining capacity.\r\n const remaining = this._capacity - offset;\r\n if (remaining > 0) {\r\n const freeBlock = this._obtain(offset, remaining, true);\r\n this._insertAfterInMainList(freeBlock, this._tailAll);\r\n this._addToBucket(freeBlock);\r\n }\r\n }\r\n\r\n private _defragIncremental(maxMoves: number, result: Set<GaussianSplattingMemBlock>): void {\r\n const phase1Moves = Math.ceil(maxMoves / 2);\r\n const phase2Moves = maxMoves - phase1Moves;\r\n\r\n // Phase 1: relocate the last allocated block to the first fitting gap (maximizes tail free space).\r\n for (let i = 0; i < phase1Moves; i++) {\r\n let lastAlloc = this._tailAll;\r\n while (lastAlloc && lastAlloc._free) {\r\n lastAlloc = lastAlloc._prev;\r\n }\r\n if (!lastAlloc) {\r\n break;\r\n }\r\n\r\n const gap = this._findFreeBlock(lastAlloc._size);\r\n if (!gap || gap._offset >= lastAlloc._offset) {\r\n break;\r\n }\r\n\r\n this._moveBlock(lastAlloc, gap);\r\n result.add(lastAlloc);\r\n }\r\n\r\n // Phase 2: slide allocated blocks left into adjacent free gaps (cleans up interior fragmentation).\r\n let block = this._headAll;\r\n for (let i = 0; i < phase2Moves && block; ) {\r\n const next = block._next;\r\n\r\n if (block._free && next && !next._free) {\r\n const allocBlock = next;\r\n const freeBlock = block;\r\n\r\n allocBlock._offset = freeBlock._offset;\r\n freeBlock._offset = allocBlock._offset + allocBlock._size;\r\n\r\n // Swap in the main list.\r\n const a = freeBlock._prev;\r\n const b = allocBlock._next;\r\n\r\n allocBlock._prev = a;\r\n allocBlock._next = freeBlock;\r\n freeBlock._prev = allocBlock;\r\n freeBlock._next = b;\r\n if (a) {\r\n a._next = allocBlock;\r\n } else {\r\n this._headAll = allocBlock;\r\n }\r\n if (b) {\r\n b._prev = freeBlock;\r\n } else {\r\n this._tailAll = freeBlock;\r\n }\r\n\r\n // Merge the free block with its new right neighbor if also free.\r\n if (freeBlock._next && freeBlock._next._free) {\r\n const right = freeBlock._next;\r\n freeBlock._size += right._size;\r\n this._removeFromMainList(right);\r\n this._removeFromBucket(right);\r\n this._release(right);\r\n this._rebucket(freeBlock);\r\n }\r\n\r\n result.add(allocBlock);\r\n i++;\r\n\r\n // Continue from the block after freeBlock to find more opportunities.\r\n block = freeBlock._next;\r\n } else {\r\n block = next;\r\n }\r\n }\r\n }\r\n\r\n private _moveBlock(block: GaussianSplattingMemBlock, gap: GaussianSplattingMemBlock): void {\r\n const blockSize = block._size;\r\n const newOffset = gap._offset;\r\n\r\n // 1. Remove the block from its current position, freeing that space.\r\n const prev = block._prev;\r\n this._removeFromMainList(block);\r\n\r\n // Create a free region where the block was.\r\n const freed = this._obtain(block._offset, blockSize, true);\r\n this._insertAfterInMainList(freed, prev);\r\n this._addToBucket(freed);\r\n\r\n // Merge freed with its right neighbor.\r\n if (freed._next && freed._next._free) {\r\n const right = freed._next;\r\n freed._size += right._size;\r\n this._removeFromMainList(right);\r\n this._removeFromBucket(right);\r\n this._release(right);\r\n this._rebucket(freed);\r\n }\r\n // Merge freed with its left neighbor.\r\n if (freed._prev && freed._prev._free) {\r\n const left = freed._prev;\r\n left._size += freed._size;\r\n this._removeFromMainList(freed);\r\n this._removeFromBucket(freed);\r\n this._release(freed);\r\n this._rebucket(left);\r\n }\r\n\r\n // 2. Place the block at the gap.\r\n block._offset = newOffset;\r\n\r\n if (gap._size === blockSize) {\r\n // Perfect fit: replace the gap with the block.\r\n const gapPrev = gap._prev;\r\n this._removeFromMainList(gap);\r\n this._removeFromBucket(gap);\r\n this._release(gap);\r\n this._insertAfterInMainList(block, gapPrev);\r\n } else {\r\n // Partial fit: shrink the gap, insert the block before it.\r\n gap._offset += blockSize;\r\n gap._size -= blockSize;\r\n this._rebucket(gap);\r\n this._insertAfterInMainList(block, gap._prev);\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"gaussianSplattingBlockAllocator.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingBlockAllocator.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Nullable } from \"core/types\";\r\n\r\n/**\r\n * A node in the {@link GaussianSplattingBlockAllocator}'s linked list, representing either an allocated\r\n * block or a free region. Callers receive {@link GaussianSplattingMemBlock} instances as handles from\r\n * {@link GaussianSplattingBlockAllocator.allocate} and must treat their {@link offset}/{@link size} as\r\n * read-only.\r\n *\r\n * Ported from the PlayCanvas engine (`src/core/block-allocator.js`).\r\n * @experimental\r\n */\r\nexport class GaussianSplattingMemBlock {\r\n /** @internal Position in the address space. */\r\n public _offset = 0;\r\n /** @internal Size of this block. */\r\n public _size = 0;\r\n /** @internal True if this is a free region, false if allocated. */\r\n public _free = true;\r\n /** @internal Previous node in the main (all-nodes, offset-ordered) list. */\r\n public _prev: Nullable<GaussianSplattingMemBlock> = null;\r\n /** @internal Next node in the main (all-nodes, offset-ordered) list. */\r\n public _next: Nullable<GaussianSplattingMemBlock> = null;\r\n /** @internal Previous node in the bucket free-list. */\r\n public _prevFree: Nullable<GaussianSplattingMemBlock> = null;\r\n /** @internal Next node in the bucket free-list. */\r\n public _nextFree: Nullable<GaussianSplattingMemBlock> = null;\r\n /** @internal Index of the size bucket this free block belongs to, or -1 if not in any bucket. */\r\n public _bucket = -1;\r\n\r\n /**\r\n * The offset of this block in the address space.\r\n */\r\n public get offset(): number {\r\n return this._offset;\r\n }\r\n\r\n /**\r\n * The size of this block.\r\n */\r\n public get size(): number {\r\n return this._size;\r\n }\r\n}\r\n\r\n/**\r\n * A general-purpose 1D block allocator backed by a doubly-linked list with segregated free-list buckets.\r\n * Manages a linear address space where contiguous blocks can be allocated and freed.\r\n *\r\n * Free blocks are organized into power-of-2 size buckets for best-fit allocation, which reduces\r\n * fragmentation compared to a single first-fit free list. Supports incremental defragmentation and\r\n * automatic growth. Used to place streamed Gaussian Splatting LOD files into the unified GPU work buffer.\r\n *\r\n * Ported from the PlayCanvas engine (`src/core/block-allocator.js`).\r\n * @experimental\r\n */\r\nexport class GaussianSplattingBlockAllocator {\r\n // Head/tail of the main list (all blocks, offset-ordered).\r\n private _headAll: Nullable<GaussianSplattingMemBlock> = null;\r\n private _tailAll: Nullable<GaussianSplattingMemBlock> = null;\r\n // Segregated free-list bucket heads. Bucket i covers sizes [2^i, 2^(i+1)). Grows as larger free blocks appear.\r\n private readonly _freeBucketHeads: Array<Nullable<GaussianSplattingMemBlock>> = [];\r\n // Pool of recycled MemBlock objects.\r\n private readonly _pool: GaussianSplattingMemBlock[] = [];\r\n private _capacity = 0;\r\n private _usedSize = 0;\r\n private _freeSize = 0;\r\n // Number of free regions; maintained O(1) for the fragmentation metric.\r\n private _freeRegionCount = 0;\r\n // Multiplicative growth factor used by updateAllocation.\r\n private readonly _growMultiplier: number;\r\n\r\n /**\r\n * Creates a new block allocator.\r\n * @param capacity initial address space capacity (defaults to 0)\r\n * @param growMultiplier multiplicative growth factor for auto-grow in {@link updateAllocation} (defaults to 1.1)\r\n */\r\n public constructor(capacity = 0, growMultiplier = 1.1) {\r\n this._growMultiplier = growMultiplier;\r\n if (capacity > 0) {\r\n this._capacity = capacity;\r\n this._freeSize = capacity;\r\n const block = this._obtain(0, capacity, true);\r\n this._headAll = block;\r\n this._tailAll = block;\r\n this._addToBucket(block);\r\n }\r\n }\r\n\r\n /**\r\n * Total address space capacity.\r\n */\r\n public get capacity(): number {\r\n return this._capacity;\r\n }\r\n\r\n /**\r\n * Total size of all allocated blocks.\r\n */\r\n public get usedSize(): number {\r\n return this._usedSize;\r\n }\r\n\r\n /**\r\n * Total size of all free regions.\r\n */\r\n public get freeSize(): number {\r\n return this._freeSize;\r\n }\r\n\r\n /**\r\n * Fragmentation ratio in the range [0, 1]. Returns 0 when all free space is one contiguous block\r\n * (ideal), and approaches 1 when free space is split into many pieces. Computed O(1).\r\n */\r\n public get fragmentation(): number {\r\n return this._freeSize > 0 ? 1 - 1 / this._freeRegionCount : 0;\r\n }\r\n\r\n /**\r\n * Allocates a contiguous block of the given size.\r\n * @param size the number of units to allocate (must be \\> 0)\r\n * @returns a block handle, or null if no space is available\r\n */\r\n public allocate(size: number): Nullable<GaussianSplattingMemBlock> {\r\n if (size <= 0) {\r\n return null;\r\n }\r\n\r\n const gap = this._findFreeBlock(size);\r\n if (!gap) {\r\n return null;\r\n }\r\n\r\n this._usedSize += size;\r\n this._freeSize -= size;\r\n\r\n if (gap._size === size) {\r\n // Perfect fit: convert free block to allocated.\r\n gap._free = false;\r\n this._removeFromBucket(gap);\r\n return gap;\r\n }\r\n\r\n // Split: create allocated block at start of gap, shrink gap.\r\n const alloc = this._obtain(gap._offset, size, false);\r\n gap._offset += size;\r\n gap._size -= size;\r\n this._rebucket(gap);\r\n this._insertAfterInMainList(alloc, gap._prev);\r\n return alloc;\r\n }\r\n\r\n /**\r\n * Frees a previously allocated block. Adjacent free regions are merged automatically.\r\n * @param block the block to free (must have been returned by {@link allocate})\r\n */\r\n public free(block: GaussianSplattingMemBlock): void {\r\n if (!block || block._free) {\r\n return;\r\n }\r\n\r\n block._free = true;\r\n this._usedSize -= block._size;\r\n this._freeSize += block._size;\r\n\r\n const prev = block._prev;\r\n const next = block._next;\r\n const prevFree = prev && prev._free;\r\n const nextFree = next && next._free;\r\n\r\n if (prevFree && nextFree) {\r\n // Both neighbors free: merge all three into prev.\r\n prev._size += block._size + next._size;\r\n this._removeFromMainList(block);\r\n this._removeFromMainList(next);\r\n this._removeFromBucket(next);\r\n this._release(block);\r\n this._release(next);\r\n this._rebucket(prev);\r\n } else if (prevFree) {\r\n // Left neighbor free: merge into prev.\r\n prev._size += block._size;\r\n this._removeFromMainList(block);\r\n this._release(block);\r\n this._rebucket(prev);\r\n } else if (nextFree) {\r\n // Right neighbor free: absorb right into block.\r\n block._size += next._size;\r\n this._removeFromMainList(next);\r\n this._removeFromBucket(next);\r\n this._release(next);\r\n this._addToBucket(block);\r\n } else {\r\n // Neither neighbor free: insert into bucket.\r\n this._addToBucket(block);\r\n }\r\n }\r\n\r\n /**\r\n * Grows the address space. Only increases capacity, never decreases.\r\n * @param newCapacity the new capacity (must be \\> current capacity)\r\n */\r\n public grow(newCapacity: number): void {\r\n if (newCapacity <= this._capacity) {\r\n return;\r\n }\r\n\r\n const added = newCapacity - this._capacity;\r\n this._capacity = newCapacity;\r\n this._freeSize += added;\r\n\r\n if (this._tailAll && this._tailAll._free) {\r\n // Extend existing tail free block.\r\n this._tailAll._size += added;\r\n this._rebucket(this._tailAll);\r\n } else {\r\n // Append new free block.\r\n const block = this._obtain(this._capacity - added, added, true);\r\n this._insertAfterInMainList(block, this._tailAll);\r\n this._addToBucket(block);\r\n }\r\n }\r\n\r\n /**\r\n * Defragments the allocator by moving allocated blocks to reduce fragmentation.\r\n *\r\n * When maxMoves is 0, performs a full compaction in a single O(n) pass: all allocated blocks are packed\r\n * contiguously from offset 0 and a single free block is placed at the end. When maxMoves \\> 0, performs\r\n * incremental defragmentation (relocate the last block into the first fitting gap, then slide blocks left).\r\n *\r\n * Moved blocks have their {@link GaussianSplattingMemBlock.offset} updated in place (handles stay valid),\r\n * so callers must relocate the corresponding GPU data for every block in the returned set.\r\n * @param maxMoves maximum number of block moves (0 = full compaction, the default)\r\n * @param result optional set to receive the moved blocks (defaults to a new set)\r\n * @returns the set of blocks that were moved\r\n */\r\n public defrag(maxMoves = 0, result: Set<GaussianSplattingMemBlock> = new Set()): Set<GaussianSplattingMemBlock> {\r\n result.clear();\r\n\r\n if (this._freeRegionCount === 0) {\r\n return result;\r\n }\r\n\r\n if (maxMoves === 0) {\r\n this._defragFull(result);\r\n } else {\r\n this._defragIncremental(maxMoves, result);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Batch update: frees a set of blocks and allocates new ones. Handles growth and compaction internally\r\n * when allocations cannot be satisfied. The `toAllocate` array is modified in place: each numeric size\r\n * entry is replaced with the allocated block.\r\n * @param toFree blocks to release\r\n * @param toAllocate sizes to allocate; modified in place (numbers are replaced with block handles)\r\n * @returns true if a full defrag was performed (all existing blocks have new offsets and must be re-rendered)\r\n */\r\n public updateAllocation(toFree: GaussianSplattingMemBlock[], toAllocate: Array<number | GaussianSplattingMemBlock>): boolean {\r\n // Phase 1: free old blocks.\r\n for (let i = 0; i < toFree.length; i++) {\r\n this.free(toFree[i]);\r\n }\r\n\r\n // Phase 2: try to allocate all new blocks.\r\n for (let i = 0; i < toAllocate.length; i++) {\r\n const size = toAllocate[i] as number;\r\n const block = this.allocate(size);\r\n if (block) {\r\n toAllocate[i] = block;\r\n } else {\r\n // Allocation failed at index i; entries [0..i-1] are blocks, [i..n-1] are still numbers.\r\n let totalRemaining = size;\r\n for (let j = i + 1; j < toAllocate.length; j++) {\r\n totalRemaining += toAllocate[j] as number;\r\n }\r\n\r\n // Grow if the free space would be below the headroom threshold.\r\n const neededCapacity = this._usedSize + totalRemaining;\r\n const headroomCapacity = Math.ceil(neededCapacity * this._growMultiplier);\r\n if (headroomCapacity > this._capacity) {\r\n this.grow(headroomCapacity);\r\n }\r\n\r\n // Full defrag: compact everything, then allocate the remainder (guaranteed to succeed).\r\n this.defrag(0);\r\n for (let j = i; j < toAllocate.length; j++) {\r\n toAllocate[j] = this.allocate(toAllocate[j] as number)!;\r\n }\r\n\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Computes the bucket index for a given block size (= floor(log2(size))).\r\n * @param size block size (must be \\> 0)\r\n * @returns the bucket index\r\n */\r\n private _bucketFor(size: number): number {\r\n return 31 - Math.clz32(size);\r\n }\r\n\r\n private _addToBucket(block: GaussianSplattingMemBlock): void {\r\n const b = this._bucketFor(block._size);\r\n block._bucket = b;\r\n while (b >= this._freeBucketHeads.length) {\r\n this._freeBucketHeads.push(null);\r\n }\r\n block._prevFree = null;\r\n block._nextFree = this._freeBucketHeads[b];\r\n if (this._freeBucketHeads[b]) {\r\n this._freeBucketHeads[b]!._prevFree = block;\r\n }\r\n this._freeBucketHeads[b] = block;\r\n this._freeRegionCount++;\r\n }\r\n\r\n private _removeFromBucket(block: GaussianSplattingMemBlock): void {\r\n const b = block._bucket;\r\n if (block._prevFree) {\r\n block._prevFree._nextFree = block._nextFree;\r\n } else {\r\n this._freeBucketHeads[b] = block._nextFree;\r\n }\r\n if (block._nextFree) {\r\n block._nextFree._prevFree = block._prevFree;\r\n }\r\n block._prevFree = null;\r\n block._nextFree = null;\r\n block._bucket = -1;\r\n this._freeRegionCount--;\r\n }\r\n\r\n private _rebucket(block: GaussianSplattingMemBlock): void {\r\n const newBucket = this._bucketFor(block._size);\r\n if (newBucket !== block._bucket) {\r\n this._removeFromBucket(block);\r\n this._addToBucket(block);\r\n }\r\n }\r\n\r\n private _obtain(offset: number, size: number, free: boolean): GaussianSplattingMemBlock {\r\n const block = this._pool.length > 0 ? this._pool.pop()! : new GaussianSplattingMemBlock();\r\n block._offset = offset;\r\n block._size = size;\r\n block._free = free;\r\n block._prev = null;\r\n block._next = null;\r\n block._prevFree = null;\r\n block._nextFree = null;\r\n block._bucket = -1;\r\n return block;\r\n }\r\n\r\n private _release(block: GaussianSplattingMemBlock): void {\r\n block._prev = null;\r\n block._next = null;\r\n block._prevFree = null;\r\n block._nextFree = null;\r\n block._bucket = -1;\r\n this._pool.push(block);\r\n }\r\n\r\n private _insertAfterInMainList(block: GaussianSplattingMemBlock, after: Nullable<GaussianSplattingMemBlock>): void {\r\n if (after === null) {\r\n block._prev = null;\r\n block._next = this._headAll;\r\n if (this._headAll) {\r\n this._headAll._prev = block;\r\n }\r\n this._headAll = block;\r\n if (!this._tailAll) {\r\n this._tailAll = block;\r\n }\r\n } else {\r\n block._prev = after;\r\n block._next = after._next;\r\n if (after._next) {\r\n after._next._prev = block;\r\n }\r\n after._next = block;\r\n if (this._tailAll === after) {\r\n this._tailAll = block;\r\n }\r\n }\r\n }\r\n\r\n private _removeFromMainList(block: GaussianSplattingMemBlock): void {\r\n if (block._prev) {\r\n block._prev._next = block._next;\r\n } else {\r\n this._headAll = block._next;\r\n }\r\n if (block._next) {\r\n block._next._prev = block._prev;\r\n } else {\r\n this._tailAll = block._prev;\r\n }\r\n block._prev = null;\r\n block._next = null;\r\n }\r\n\r\n private _findFreeBlock(size: number): Nullable<GaussianSplattingMemBlock> {\r\n const startBucket = this._bucketFor(size);\r\n const len = this._freeBucketHeads.length;\r\n\r\n // Target bucket: best-fit (smallest block >= size).\r\n if (startBucket < len) {\r\n let best: Nullable<GaussianSplattingMemBlock> = null;\r\n let node = this._freeBucketHeads[startBucket];\r\n while (node) {\r\n if (node._size >= size) {\r\n if (!best || node._size < best._size) {\r\n best = node;\r\n if (node._size === size) {\r\n break;\r\n }\r\n }\r\n }\r\n node = node._nextFree;\r\n }\r\n if (best) {\r\n return best;\r\n }\r\n }\r\n\r\n // Higher buckets: first-fit (any block is large enough).\r\n for (let b = startBucket + 1; b < len; b++) {\r\n if (this._freeBucketHeads[b]) {\r\n return this._freeBucketHeads[b];\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n private _defragFull(result: Set<GaussianSplattingMemBlock>): void {\r\n // Remove all free blocks from all buckets and pool them.\r\n for (let b = 0; b < this._freeBucketHeads.length; b++) {\r\n let node = this._freeBucketHeads[b];\r\n while (node) {\r\n const nextFree = node._nextFree;\r\n this._removeFromMainList(node);\r\n node._prevFree = null;\r\n node._nextFree = null;\r\n node._bucket = -1;\r\n this._pool.push(node);\r\n node = nextFree;\r\n }\r\n this._freeBucketHeads[b] = null;\r\n }\r\n this._freeRegionCount = 0;\r\n\r\n // Walk remaining (all allocated) blocks, assigning sequential offsets.\r\n let offset = 0;\r\n let block = this._headAll;\r\n while (block) {\r\n if (block._offset !== offset) {\r\n block._offset = offset;\r\n result.add(block);\r\n }\r\n offset += block._size;\r\n block = block._next;\r\n }\r\n\r\n // Create a single free block at the end if there is remaining capacity.\r\n const remaining = this._capacity - offset;\r\n if (remaining > 0) {\r\n const freeBlock = this._obtain(offset, remaining, true);\r\n this._insertAfterInMainList(freeBlock, this._tailAll);\r\n this._addToBucket(freeBlock);\r\n }\r\n }\r\n\r\n private _defragIncremental(maxMoves: number, result: Set<GaussianSplattingMemBlock>): void {\r\n const phase1Moves = Math.ceil(maxMoves / 2);\r\n const phase2Moves = maxMoves - phase1Moves;\r\n\r\n // Phase 1: relocate the last allocated block to the first fitting gap (maximizes tail free space).\r\n for (let i = 0; i < phase1Moves; i++) {\r\n let lastAlloc = this._tailAll;\r\n while (lastAlloc && lastAlloc._free) {\r\n lastAlloc = lastAlloc._prev;\r\n }\r\n if (!lastAlloc) {\r\n break;\r\n }\r\n\r\n const gap = this._findFreeBlock(lastAlloc._size);\r\n if (!gap || gap._offset >= lastAlloc._offset) {\r\n break;\r\n }\r\n\r\n this._moveBlock(lastAlloc, gap);\r\n result.add(lastAlloc);\r\n }\r\n\r\n // Phase 2: slide allocated blocks left into adjacent free gaps (cleans up interior fragmentation).\r\n let block = this._headAll;\r\n for (let i = 0; i < phase2Moves && block;) {\r\n const next = block._next;\r\n\r\n if (block._free && next && !next._free) {\r\n const allocBlock = next;\r\n const freeBlock = block;\r\n\r\n allocBlock._offset = freeBlock._offset;\r\n freeBlock._offset = allocBlock._offset + allocBlock._size;\r\n\r\n // Swap in the main list.\r\n const a = freeBlock._prev;\r\n const b = allocBlock._next;\r\n\r\n allocBlock._prev = a;\r\n allocBlock._next = freeBlock;\r\n freeBlock._prev = allocBlock;\r\n freeBlock._next = b;\r\n if (a) {\r\n a._next = allocBlock;\r\n } else {\r\n this._headAll = allocBlock;\r\n }\r\n if (b) {\r\n b._prev = freeBlock;\r\n } else {\r\n this._tailAll = freeBlock;\r\n }\r\n\r\n // Merge the free block with its new right neighbor if also free.\r\n if (freeBlock._next && freeBlock._next._free) {\r\n const right = freeBlock._next;\r\n freeBlock._size += right._size;\r\n this._removeFromMainList(right);\r\n this._removeFromBucket(right);\r\n this._release(right);\r\n this._rebucket(freeBlock);\r\n }\r\n\r\n result.add(allocBlock);\r\n i++;\r\n\r\n // Continue from the block after freeBlock to find more opportunities.\r\n block = freeBlock._next;\r\n } else {\r\n block = next;\r\n }\r\n }\r\n }\r\n\r\n private _moveBlock(block: GaussianSplattingMemBlock, gap: GaussianSplattingMemBlock): void {\r\n const blockSize = block._size;\r\n const newOffset = gap._offset;\r\n\r\n // 1. Remove the block from its current position, freeing that space.\r\n const prev = block._prev;\r\n this._removeFromMainList(block);\r\n\r\n // Create a free region where the block was.\r\n const freed = this._obtain(block._offset, blockSize, true);\r\n this._insertAfterInMainList(freed, prev);\r\n this._addToBucket(freed);\r\n\r\n // Merge freed with its right neighbor.\r\n if (freed._next && freed._next._free) {\r\n const right = freed._next;\r\n freed._size += right._size;\r\n this._removeFromMainList(right);\r\n this._removeFromBucket(right);\r\n this._release(right);\r\n this._rebucket(freed);\r\n }\r\n // Merge freed with its left neighbor.\r\n if (freed._prev && freed._prev._free) {\r\n const left = freed._prev;\r\n left._size += freed._size;\r\n this._removeFromMainList(freed);\r\n this._removeFromBucket(freed);\r\n this._release(freed);\r\n this._rebucket(left);\r\n }\r\n\r\n // 2. Place the block at the gap.\r\n block._offset = newOffset;\r\n\r\n if (gap._size === blockSize) {\r\n // Perfect fit: replace the gap with the block.\r\n const gapPrev = gap._prev;\r\n this._removeFromMainList(gap);\r\n this._removeFromBucket(gap);\r\n this._release(gap);\r\n this._insertAfterInMainList(block, gapPrev);\r\n } else {\r\n // Partial fit: shrink the gap, insert the block before it.\r\n gap._offset += blockSize;\r\n gap._size -= blockSize;\r\n this._rebucket(gap);\r\n this._insertAfterInMainList(block, gap._prev);\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -45,7 +45,11 @@ export declare class GaussianSplattingWorkBuffer {
|
|
|
45
45
|
*/
|
|
46
46
|
constructor(scene: Scene, capacity: number);
|
|
47
47
|
/**
|
|
48
|
-
* Creates a 4-attachment MRT (centers F32 / covA
|
|
48
|
+
* Creates a 4-attachment MRT (centers F32 / covA / covB / colors U8) sized to the work buffer. covA/covB
|
|
49
|
+
* use HALF_FLOAT when the engine can render to it, matching the precision the non-streamed
|
|
50
|
+
* GaussianSplattingMesh path already uses for these same two textures (see
|
|
51
|
+
* `gaussianSplattingMeshBase.pure.ts`'s `createTextureFromDataF16` covA/covB textures); centers stays F32
|
|
52
|
+
* and colors stays U8 in both paths.
|
|
49
53
|
* @param name MRT and attachment base name
|
|
50
54
|
* @param disableClear when true, clearing is suppressed so renders accumulate (the decode buffer); when
|
|
51
55
|
* false the MRT clears to zero on each render (the temporary relayout buffer, so gaps stay zeroed)
|
|
@@ -69,15 +69,20 @@ export class GaussianSplattingWorkBuffer {
|
|
|
69
69
|
this._quad.material = this._material;
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
|
-
* Creates a 4-attachment MRT (centers F32 / covA
|
|
72
|
+
* Creates a 4-attachment MRT (centers F32 / covA / covB / colors U8) sized to the work buffer. covA/covB
|
|
73
|
+
* use HALF_FLOAT when the engine can render to it, matching the precision the non-streamed
|
|
74
|
+
* GaussianSplattingMesh path already uses for these same two textures (see
|
|
75
|
+
* `gaussianSplattingMeshBase.pure.ts`'s `createTextureFromDataF16` covA/covB textures); centers stays F32
|
|
76
|
+
* and colors stays U8 in both paths.
|
|
73
77
|
* @param name MRT and attachment base name
|
|
74
78
|
* @param disableClear when true, clearing is suppressed so renders accumulate (the decode buffer); when
|
|
75
79
|
* false the MRT clears to zero on each render (the temporary relayout buffer, so gaps stay zeroed)
|
|
76
80
|
* @returns the created MRT
|
|
77
81
|
*/
|
|
78
82
|
_createMrt(name, disableClear) {
|
|
83
|
+
const covType = this._scene.getEngine()._caps.textureHalfFloatRender ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_FLOAT;
|
|
79
84
|
const mrt = new MultiRenderTarget(name, { width: this._textureSize, height: this._textureSize }, 4, this._scene, {
|
|
80
|
-
types: [Constants.TEXTURETYPE_FLOAT,
|
|
85
|
+
types: [Constants.TEXTURETYPE_FLOAT, covType, covType, Constants.TEXTURETYPE_UNSIGNED_BYTE],
|
|
81
86
|
samplingModes: [
|
|
82
87
|
Constants.TEXTURE_NEAREST_SAMPLINGMODE,
|
|
83
88
|
Constants.TEXTURE_NEAREST_SAMPLINGMODE,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gaussianSplattingWorkBuffer.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingWorkBuffer.ts"],"names":[],"mappings":"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","sourcesContent":["import { MultiRenderTarget } from \"core/Materials/Textures/multiRenderTarget\";\r\nimport { ShaderMaterial } from \"core/Materials/shaderMaterial\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { type Texture } from \"core/Materials/Textures/texture\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type ISogTexturePack } from \"./splatDefs\";\r\nimport {\r\n GaussianSplattingWorkBufferVertexShaderGLSL,\r\n GaussianSplattingWorkBufferFragmentShaderGLSL,\r\n GaussianSplattingWorkBufferVertexShaderWGSL,\r\n GaussianSplattingWorkBufferFragmentShaderWGSL,\r\n GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL,\r\n GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL,\r\n GaussianSplattingWorkBufferRelayoutShaderName,\r\n} from \"./gaussianSplattingWorkBufferShaders\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\n\r\n/**\r\n * A unified, GPU-decoded Gaussian Splatting work buffer.\r\n *\r\n * Holds a square MRT texture set (centers / covA / covB / colors) sized to a fixed splat capacity\r\n * (PlayCanvas-style: `ceil(sqrt(capacity))`). Each streamed SOG file is decoded directly on the GPU\r\n * (no CPU readback) into its allocated pixel range. The decoded textures are consumed unchanged by the\r\n * standard (non-SOG) Gaussian Splatting draw path.\r\n *\r\n * @experimental\r\n */\r\nexport class GaussianSplattingWorkBuffer {\r\n private readonly _scene: Scene;\r\n private readonly _mrt: MultiRenderTarget;\r\n private readonly _textureSize: number;\r\n private readonly _shaderLanguage: ShaderLanguage;\r\n private readonly _material: ShaderMaterial;\r\n private readonly _quad: Mesh;\r\n // Relayout (defrag) copy material, created lazily on first relayout.\r\n private _copyMaterial: Nullable<ShaderMaterial> = null;\r\n // Reusable destination->source index map for the relayout pass (created lazily, sized to the work buffer).\r\n private _relayoutMapData: Nullable<Float32Array> = null;\r\n private _relayoutMapTexture: Nullable<RawTexture> = null;\r\n private _disposed = false;\r\n // Reused WebGL framebuffer for the async centers readback (created lazily, freed in dispose).\r\n private _readFbo: Nullable<WebGLFramebuffer> = null;\r\n\r\n /**\r\n * True when the engine supports the non-blocking GPU readback used by {@link readCentersRangeAsync}:\r\n * WebGL2 (PBO + fence) or WebGPU (copyTextureToBuffer + mapAsync). When false (e.g. WebGL1), callers must\r\n * decode positions on the CPU instead.\r\n */\r\n public get supportsAsyncCentersReadback(): boolean {\r\n const engine = this._scene.getEngine();\r\n if (engine.isWebGPU) {\r\n return true;\r\n }\r\n const glEngine = engine as unknown as { _gl?: WebGL2RenderingContext; _readPixelsAsync?: unknown; webGLVersion?: number };\r\n return !!glEngine._gl && typeof glEngine._readPixelsAsync === \"function\" && (glEngine.webGLVersion ?? 0) >= 2;\r\n }\r\n\r\n /**\r\n * Square edge length (in pixels) of the work-buffer textures.\r\n */\r\n public get textureSize(): number {\r\n return this._textureSize;\r\n }\r\n\r\n /**\r\n * The decoded work-buffer textures: [centers, covA, covB, colors].\r\n */\r\n public get textures(): Texture[] {\r\n return this._mrt.textures;\r\n }\r\n\r\n /**\r\n * Creates a work buffer sized to hold `capacity` splats.\r\n * @param scene hosting scene\r\n * @param capacity total number of splats the work buffer must address\r\n */\r\n constructor(scene: Scene, capacity: number) {\r\n this._scene = scene;\r\n this._shaderLanguage = scene.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\r\n this._textureSize = Math.max(1, Math.ceil(Math.sqrt(Math.max(1, capacity))));\r\n\r\n // The decode buffer accumulates (clear disabled) so each decode preserves previously-decoded files.\r\n this._mrt = this._createMrt(\"gsWorkBuffer\", true);\r\n\r\n // One persistent decode material + fullscreen-triangle quad, reused (with per-file uniforms)\r\n // for every decode so the shader is compiled only once.\r\n this._material = this._createMaterial();\r\n this._quad = this._createQuad();\r\n this._quad.material = this._material;\r\n }\r\n\r\n /**\r\n * Creates a 4-attachment MRT (centers F32 / covA F32 / covB F32 / colors U8) sized to the work buffer.\r\n * @param name MRT and attachment base name\r\n * @param disableClear when true, clearing is suppressed so renders accumulate (the decode buffer); when\r\n * false the MRT clears to zero on each render (the temporary relayout buffer, so gaps stay zeroed)\r\n * @returns the created MRT\r\n */\r\n private _createMrt(name: string, disableClear: boolean): MultiRenderTarget {\r\n const mrt = new MultiRenderTarget(\r\n name,\r\n { width: this._textureSize, height: this._textureSize },\r\n 4,\r\n this._scene,\r\n {\r\n types: [Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n samplingModes: [\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n ],\r\n formats: [Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA],\r\n generateDepthBuffer: false,\r\n generateDepthTexture: false,\r\n generateMipMaps: false,\r\n },\r\n [`${name}Centers`, `${name}CovA`, `${name}CovB`, `${name}Colors`]\r\n );\r\n mrt.clearColor = new Color4(0, 0, 0, 0);\r\n mrt.renderList = [];\r\n if (disableClear) {\r\n mrt.onClearObservable.add(() => {});\r\n }\r\n return mrt;\r\n }\r\n\r\n /**\r\n * Decodes one SOG file into the work buffer at the given splat offset (accumulating; previously\r\n * decoded files are preserved). Resolves once the GPU decode has been issued. The caller may\r\n * dispose the source pack textures after this resolves.\r\n * @param pack the SOG texture pack (GPU source textures + per-file decode parameters)\r\n * @param offset first splat index (pixel offset) for this file in the work buffer\r\n */\r\n public async decodeAsync(pack: ISogTexturePack, offset: number): Promise<void> {\r\n if (this._disposed) {\r\n return;\r\n }\r\n this._applyPack(pack, offset);\r\n // Render the decode pass at the start of a frame (the safe point for custom render targets),\r\n // once the shader is compiled — never re-entrantly from a promise/observable continuation.\r\n await new Promise<void>((resolve) => {\r\n const attempt = () => {\r\n if (this._disposed) {\r\n resolve();\r\n return;\r\n }\r\n if (!this._material.isReady(this._quad)) {\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n return;\r\n }\r\n this._mrt.renderList = [this._quad];\r\n this._mrt.render();\r\n resolve();\r\n };\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n });\r\n }\r\n\r\n /**\r\n * Whether the relayout copy shader is compiled and ready. Lazily creates the copy material on first call.\r\n * Callers should poll this before {@link relayoutSync} (which must only run when ready).\r\n * @returns true when {@link relayoutSync} can run this frame\r\n */\r\n public isRelayoutReady(): boolean {\r\n if (this._disposed) {\r\n return false;\r\n }\r\n if (!this._copyMaterial) {\r\n this._copyMaterial = this._createCopyMaterial();\r\n }\r\n return this._copyMaterial.isReady(this._quad);\r\n }\r\n\r\n /**\r\n * Relayouts the decoded work-buffer textures to a new (defragmented) splat layout, keeping the same\r\n * texture instances so the consuming mesh does not need to re-bind. `srcIndexByDst[d]` is the source splat\r\n * index whose decoded data should end up at destination index `d`, or a negative value for a gap (left\r\n * zeroed). Uses a temporary MRT ping-pong (old -> temp via the map, then temp -> old identity) so\r\n * overlapping moves stay correct. Must be called at a frame-safe point (inside `onBeforeRender`) and only\r\n * when {@link isRelayoutReady} returns true.\r\n * @param srcIndexByDst per-destination source splat index (negative = gap)\r\n */\r\n public relayoutSync(srcIndexByDst: Float32Array): void {\r\n if (this._disposed || !this._copyMaterial) {\r\n return;\r\n }\r\n const size = this._textureSize;\r\n // Reuse the map buffer and its GPU texture across relayouts (the work-buffer size is fixed).\r\n if (!this._relayoutMapData) {\r\n this._relayoutMapData = new Float32Array(size * size);\r\n }\r\n const mapData = this._relayoutMapData;\r\n mapData.fill(-1);\r\n mapData.set(srcIndexByDst.subarray(0, Math.min(srcIndexByDst.length, mapData.length)));\r\n if (!this._relayoutMapTexture) {\r\n this._relayoutMapTexture = new RawTexture(\r\n mapData,\r\n size,\r\n size,\r\n Constants.TEXTUREFORMAT_R,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_FLOAT\r\n );\r\n } else {\r\n this._relayoutMapTexture.update(mapData);\r\n }\r\n const mapTexture = this._relayoutMapTexture;\r\n // The temporary ping-pong MRT is (re)created per relayout rather than kept resident: it is the same size\r\n // as the work buffer, so a persistent copy would double GPU memory and defeat the streaming memory budget.\r\n const temp = this._createMrt(\"gsRelayoutTemp\", false);\r\n try {\r\n // Pass 1: old -> temp using the map (temp gets the new layout; gaps stay zeroed by the clear).\r\n this._renderRelayoutPass(temp, this._mrt.textures, mapTexture, 1);\r\n // Pass 2: temp -> old, identity (old textures get the new layout, full overwrite).\r\n this._renderRelayoutPass(this._mrt, temp.textures, mapTexture, 0);\r\n } finally {\r\n temp.dispose();\r\n this._quad.material = this._material;\r\n }\r\n }\r\n\r\n /**\r\n * Renders one relayout copy pass into the target MRT, sampling the given source textures.\r\n * @param target destination MRT\r\n * @param sources the four source work-buffer textures\r\n * @param mapTexture the R32F destination-to-source index map\r\n * @param useMap 1 to read source indices from the map (gaps discarded), 0 for an identity copy\r\n */\r\n private _renderRelayoutPass(target: MultiRenderTarget, sources: Texture[], mapTexture: RawTexture, useMap: number): void {\r\n const material = this._copyMaterial!;\r\n material.setTexture(\"uMapTex\", mapTexture);\r\n material.setTexture(\"uSrc0\", sources[0]);\r\n material.setTexture(\"uSrc1\", sources[1]);\r\n material.setTexture(\"uSrc2\", sources[2]);\r\n material.setTexture(\"uSrc3\", sources[3]);\r\n material.setInt(\"uDstWidth\", this._textureSize);\r\n material.setInt(\"uSrcWidth\", this._textureSize);\r\n material.setInt(\"uUseMap\", useMap);\r\n this._quad.material = material;\r\n target.renderList = [this._quad];\r\n target.render();\r\n }\r\n\r\n private _createCopyMaterial(): ShaderMaterial {\r\n const isWGSL = this._shaderLanguage === ShaderLanguage.WGSL;\r\n const material = new ShaderMaterial(\r\n GaussianSplattingWorkBufferRelayoutShaderName,\r\n this._scene,\r\n {\r\n vertexSource: isWGSL ? GaussianSplattingWorkBufferVertexShaderWGSL : GaussianSplattingWorkBufferVertexShaderGLSL,\r\n fragmentSource: isWGSL ? GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL : GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL,\r\n },\r\n {\r\n attributes: [\"position\"],\r\n uniforms: [\"uDstWidth\", \"uSrcWidth\", \"uUseMap\"],\r\n samplers: [\"uMapTex\", \"uSrc0\", \"uSrc1\", \"uSrc2\", \"uSrc3\"],\r\n shaderLanguage: this._shaderLanguage,\r\n }\r\n );\r\n material.backFaceCulling = false;\r\n material.disableDepthWrite = true;\r\n return material;\r\n }\r\n\r\n /**\r\n * Asynchronously reads back the decoded splat centers (stride-4 xyzw, w=1) for a contiguous splat range\r\n * from the work buffer's centers texture, using a non-blocking GPU readback (WebGL2 PBO + fence, or WebGPU\r\n * copyTextureToBuffer + mapAsync) so it never stalls the frame the way a CPU image decode does. The centers\r\n * texture already holds the GPU-decoded positions (identical to the CPU decode), so this replaces decoding\r\n * positions on the CPU from the means images. Returns null when async readback is unsupported (caller should\r\n * fall back to CPU decoding).\r\n * @param splatOffset first splat index of the range\r\n * @param splatCount number of splats in the range\r\n * @returns a stride-4 Float32Array of length `splatCount * 4`, or null when unsupported/failed\r\n */\r\n public async readCentersRangeAsync(splatOffset: number, splatCount: number): Promise<Nullable<Float32Array>> {\r\n if (this._disposed || splatCount <= 0 || !this.supportsAsyncCentersReadback) {\r\n return null;\r\n }\r\n\r\n const width = this._textureSize;\r\n // The range maps to whole texel rows [rowStart, rowEnd); read that rectangle and slice the exact range.\r\n // Splat i lives at texel (i % width, floor(i / width)) in both decode and draw, so the readback (which\r\n // indexes the same texture storage directly, with no UV/flip) yields splat i at buffer position\r\n // i - rowStart * width on every backend.\r\n const rowStart = Math.floor(splatOffset / width);\r\n const rowEnd = Math.ceil((splatOffset + splatCount) / width);\r\n const rowCount = rowEnd - rowStart;\r\n const startInBuffer = (splatOffset - rowStart * width) * 4;\r\n const sliceEnd = startInBuffer + splatCount * 4;\r\n const centers = this._mrt.textures[0];\r\n\r\n const engine = this._scene.getEngine();\r\n\r\n if (engine.isWebGPU) {\r\n // WebGPU: copyTextureToBuffer of the row span + mapAsync (genuinely non-blocking). noDataConversion\r\n // returns the raw RGBA32F floats tightly packed (the 256-byte row alignment is removed internally).\r\n const result = await centers.readPixels(0, 0, null, true, true, 0, rowStart, width, rowCount);\r\n if (this._disposed || !result) {\r\n return null;\r\n }\r\n const floats = result instanceof Float32Array ? result : new Float32Array(result.buffer, result.byteOffset, result.byteLength / 4);\r\n return floats.length >= sliceEnd ? (floats.subarray(startInBuffer, sliceEnd) as Float32Array) : null;\r\n }\r\n\r\n // WebGL2: read directly from the centers texture via a reused FBO + async PBO readback.\r\n const glEngine = engine as unknown as {\r\n _gl: WebGL2RenderingContext;\r\n _currentFramebuffer: Nullable<WebGLFramebuffer>;\r\n _readPixelsAsync(x: number, y: number, w: number, h: number, format: number, type: number, o: ArrayBufferView): Nullable<Promise<ArrayBufferView>>;\r\n };\r\n const gl = glEngine._gl;\r\n const hardware = centers.getInternalTexture()?._hardwareTexture?.underlyingResource as Nullable<WebGLTexture>;\r\n if (!hardware) {\r\n return null;\r\n }\r\n const buffer = new Float32Array(width * rowCount * 4);\r\n if (!this._readFbo) {\r\n this._readFbo = gl.createFramebuffer();\r\n }\r\n const previousFbo = glEngine._currentFramebuffer;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._readFbo);\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, hardware, 0);\r\n gl.readBuffer(gl.COLOR_ATTACHMENT0);\r\n\r\n // _readPixelsAsync issues the readPixels into a PBO synchronously, then resolves once the GPU fence\r\n // signals — so the framebuffer can be restored immediately while the transfer completes off-thread.\r\n const promise = glEngine._readPixelsAsync(0, rowStart, width, rowCount, gl.RGBA, gl.FLOAT, buffer);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, previousFbo);\r\n // gl.readBuffer is global state: restore the default-framebuffer read source (BACK) so later\r\n // readPixels on the default framebuffer aren't left pointing at COLOR_ATTACHMENT0. When restoring to\r\n // another FBO, COLOR_ATTACHMENT0 is the correct default read buffer, so only reset for the default one.\r\n if (!previousFbo) {\r\n gl.readBuffer(gl.BACK);\r\n }\r\n if (!promise) {\r\n return null;\r\n }\r\n await promise;\r\n if (this._disposed || buffer.length < sliceEnd) {\r\n return null;\r\n }\r\n return buffer.subarray(startInBuffer, sliceEnd) as Float32Array;\r\n }\r\n\r\n /**\r\n * Disposes the work buffer and its decode resources.\r\n */\r\n public dispose(): void {\r\n this._disposed = true;\r\n if (this._readFbo) {\r\n (this._scene.getEngine() as unknown as { _gl?: WebGL2RenderingContext })._gl?.deleteFramebuffer(this._readFbo);\r\n this._readFbo = null;\r\n }\r\n this._quad.dispose();\r\n this._material.dispose(true, false);\r\n this._copyMaterial?.dispose(true, false);\r\n this._relayoutMapTexture?.dispose();\r\n this._mrt.dispose();\r\n }\r\n\r\n private _createQuad(): Mesh {\r\n const quad = new Mesh(\"gsWorkBufferQuad\", this._scene);\r\n const vertexData = new VertexData();\r\n // Fullscreen triangle in clip space (the vertex shader passes positions straight through).\r\n vertexData.positions = [-1, -1, 0, 3, -1, 0, -1, 3, 0];\r\n vertexData.indices = [0, 1, 2];\r\n vertexData.applyToMesh(quad);\r\n // Render only inside the work-buffer MRT, never in the main scene pass.\r\n this._scene.removeMesh(quad);\r\n return quad;\r\n }\r\n\r\n private _createMaterial(): ShaderMaterial {\r\n const isWGSL = this._shaderLanguage === ShaderLanguage.WGSL;\r\n const material = new ShaderMaterial(\r\n \"gsSogDecode\",\r\n this._scene,\r\n {\r\n vertexSource: isWGSL ? GaussianSplattingWorkBufferVertexShaderWGSL : GaussianSplattingWorkBufferVertexShaderGLSL,\r\n fragmentSource: isWGSL ? GaussianSplattingWorkBufferFragmentShaderWGSL : GaussianSplattingWorkBufferFragmentShaderGLSL,\r\n },\r\n {\r\n attributes: [\"position\"],\r\n uniforms: [\"sogMeansMin\", \"sogMeansMax\", \"sogScalesMin\", \"sogScalesMax\", \"sogSh0Min\", \"sogSh0Max\", \"uVersion\", \"uOffset\", \"uCount\", \"uDestWidth\", \"uSrcWidth\"],\r\n samplers: [\"sogMeansLTex\", \"sogMeansUTex\", \"sogScalesTex\", \"sogQuatsTex\", \"sogSh0Tex\", \"sogCodebookTex\"],\r\n shaderLanguage: this._shaderLanguage,\r\n }\r\n );\r\n material.backFaceCulling = false;\r\n material.disableDepthWrite = true;\r\n return material;\r\n }\r\n\r\n private _applyPack(pack: ISogTexturePack, offset: number): void {\r\n const material = this._material;\r\n const srcWidth = (pack.meansTextureL as Texture).getSize().width;\r\n\r\n material.setTexture(\"sogMeansLTex\", pack.meansTextureL);\r\n material.setTexture(\"sogMeansUTex\", pack.meansTextureU);\r\n material.setTexture(\"sogScalesTex\", pack.scalesTexture);\r\n material.setTexture(\"sogQuatsTex\", pack.quatsTexture);\r\n material.setTexture(\"sogSh0Tex\", pack.sh0Texture);\r\n // Codebook only used for v2; bind a harmless placeholder otherwise so the sampler is always set.\r\n material.setTexture(\"sogCodebookTex\", pack.codebookTexture ?? pack.sh0Texture);\r\n\r\n material.setVector3(\"sogMeansMin\", new Vector3(pack.meansMin[0], pack.meansMin[1], pack.meansMin[2]));\r\n material.setVector3(\"sogMeansMax\", new Vector3(pack.meansMax[0], pack.meansMax[1], pack.meansMax[2]));\r\n const sMin = pack.scalesMin ?? [0, 0, 0];\r\n const sMax = pack.scalesMax ?? [0, 0, 0];\r\n material.setVector3(\"sogScalesMin\", new Vector3(sMin[0], sMin[1], sMin[2]));\r\n material.setVector3(\"sogScalesMax\", new Vector3(sMax[0], sMax[1], sMax[2]));\r\n const c0Min = pack.sh0Min ?? [0, 0, 0, 0];\r\n const c0Max = pack.sh0Max ?? [0, 0, 0, 0];\r\n material.setVector4(\"sogSh0Min\", new Vector4(c0Min[0], c0Min[1], c0Min[2], c0Min[3]));\r\n material.setVector4(\"sogSh0Max\", new Vector4(c0Max[0], c0Max[1], c0Max[2], c0Max[3]));\r\n\r\n material.setInt(\"uVersion\", pack.version);\r\n material.setInt(\"uOffset\", offset);\r\n material.setInt(\"uCount\", pack.splatCount);\r\n material.setInt(\"uDestWidth\", this._textureSize);\r\n material.setInt(\"uSrcWidth\", srcWidth);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"gaussianSplattingWorkBuffer.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingWorkBuffer.ts"],"names":[],"mappings":"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","sourcesContent":["import { MultiRenderTarget } from \"core/Materials/Textures/multiRenderTarget\";\r\nimport { ShaderMaterial } from \"core/Materials/shaderMaterial\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { type Texture } from \"core/Materials/Textures/texture\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type ISogTexturePack } from \"./splatDefs\";\r\nimport {\r\n GaussianSplattingWorkBufferVertexShaderGLSL,\r\n GaussianSplattingWorkBufferFragmentShaderGLSL,\r\n GaussianSplattingWorkBufferVertexShaderWGSL,\r\n GaussianSplattingWorkBufferFragmentShaderWGSL,\r\n GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL,\r\n GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL,\r\n GaussianSplattingWorkBufferRelayoutShaderName,\r\n} from \"./gaussianSplattingWorkBufferShaders\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\n\r\n/**\r\n * A unified, GPU-decoded Gaussian Splatting work buffer.\r\n *\r\n * Holds a square MRT texture set (centers / covA / covB / colors) sized to a fixed splat capacity\r\n * (PlayCanvas-style: `ceil(sqrt(capacity))`). Each streamed SOG file is decoded directly on the GPU\r\n * (no CPU readback) into its allocated pixel range. The decoded textures are consumed unchanged by the\r\n * standard (non-SOG) Gaussian Splatting draw path.\r\n *\r\n * @experimental\r\n */\r\nexport class GaussianSplattingWorkBuffer {\r\n private readonly _scene: Scene;\r\n private readonly _mrt: MultiRenderTarget;\r\n private readonly _textureSize: number;\r\n private readonly _shaderLanguage: ShaderLanguage;\r\n private readonly _material: ShaderMaterial;\r\n private readonly _quad: Mesh;\r\n // Relayout (defrag) copy material, created lazily on first relayout.\r\n private _copyMaterial: Nullable<ShaderMaterial> = null;\r\n // Reusable destination->source index map for the relayout pass (created lazily, sized to the work buffer).\r\n private _relayoutMapData: Nullable<Float32Array> = null;\r\n private _relayoutMapTexture: Nullable<RawTexture> = null;\r\n private _disposed = false;\r\n // Reused WebGL framebuffer for the async centers readback (created lazily, freed in dispose).\r\n private _readFbo: Nullable<WebGLFramebuffer> = null;\r\n\r\n /**\r\n * True when the engine supports the non-blocking GPU readback used by {@link readCentersRangeAsync}:\r\n * WebGL2 (PBO + fence) or WebGPU (copyTextureToBuffer + mapAsync). When false (e.g. WebGL1), callers must\r\n * decode positions on the CPU instead.\r\n */\r\n public get supportsAsyncCentersReadback(): boolean {\r\n const engine = this._scene.getEngine();\r\n if (engine.isWebGPU) {\r\n return true;\r\n }\r\n const glEngine = engine as unknown as { _gl?: WebGL2RenderingContext; _readPixelsAsync?: unknown; webGLVersion?: number };\r\n return !!glEngine._gl && typeof glEngine._readPixelsAsync === \"function\" && (glEngine.webGLVersion ?? 0) >= 2;\r\n }\r\n\r\n /**\r\n * Square edge length (in pixels) of the work-buffer textures.\r\n */\r\n public get textureSize(): number {\r\n return this._textureSize;\r\n }\r\n\r\n /**\r\n * The decoded work-buffer textures: [centers, covA, covB, colors].\r\n */\r\n public get textures(): Texture[] {\r\n return this._mrt.textures;\r\n }\r\n\r\n /**\r\n * Creates a work buffer sized to hold `capacity` splats.\r\n * @param scene hosting scene\r\n * @param capacity total number of splats the work buffer must address\r\n */\r\n constructor(scene: Scene, capacity: number) {\r\n this._scene = scene;\r\n this._shaderLanguage = scene.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\r\n this._textureSize = Math.max(1, Math.ceil(Math.sqrt(Math.max(1, capacity))));\r\n\r\n // The decode buffer accumulates (clear disabled) so each decode preserves previously-decoded files.\r\n this._mrt = this._createMrt(\"gsWorkBuffer\", true);\r\n\r\n // One persistent decode material + fullscreen-triangle quad, reused (with per-file uniforms)\r\n // for every decode so the shader is compiled only once.\r\n this._material = this._createMaterial();\r\n this._quad = this._createQuad();\r\n this._quad.material = this._material;\r\n }\r\n\r\n /**\r\n * Creates a 4-attachment MRT (centers F32 / covA / covB / colors U8) sized to the work buffer. covA/covB\r\n * use HALF_FLOAT when the engine can render to it, matching the precision the non-streamed\r\n * GaussianSplattingMesh path already uses for these same two textures (see\r\n * `gaussianSplattingMeshBase.pure.ts`'s `createTextureFromDataF16` covA/covB textures); centers stays F32\r\n * and colors stays U8 in both paths.\r\n * @param name MRT and attachment base name\r\n * @param disableClear when true, clearing is suppressed so renders accumulate (the decode buffer); when\r\n * false the MRT clears to zero on each render (the temporary relayout buffer, so gaps stay zeroed)\r\n * @returns the created MRT\r\n */\r\n private _createMrt(name: string, disableClear: boolean): MultiRenderTarget {\r\n const covType = this._scene.getEngine()._caps.textureHalfFloatRender ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_FLOAT;\r\n const mrt = new MultiRenderTarget(\r\n name,\r\n { width: this._textureSize, height: this._textureSize },\r\n 4,\r\n this._scene,\r\n {\r\n types: [Constants.TEXTURETYPE_FLOAT, covType, covType, Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n samplingModes: [\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n ],\r\n formats: [Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA],\r\n generateDepthBuffer: false,\r\n generateDepthTexture: false,\r\n generateMipMaps: false,\r\n },\r\n [`${name}Centers`, `${name}CovA`, `${name}CovB`, `${name}Colors`]\r\n );\r\n mrt.clearColor = new Color4(0, 0, 0, 0);\r\n mrt.renderList = [];\r\n if (disableClear) {\r\n mrt.onClearObservable.add(() => {});\r\n }\r\n return mrt;\r\n }\r\n\r\n /**\r\n * Decodes one SOG file into the work buffer at the given splat offset (accumulating; previously\r\n * decoded files are preserved). Resolves once the GPU decode has been issued. The caller may\r\n * dispose the source pack textures after this resolves.\r\n * @param pack the SOG texture pack (GPU source textures + per-file decode parameters)\r\n * @param offset first splat index (pixel offset) for this file in the work buffer\r\n */\r\n public async decodeAsync(pack: ISogTexturePack, offset: number): Promise<void> {\r\n if (this._disposed) {\r\n return;\r\n }\r\n this._applyPack(pack, offset);\r\n // Render the decode pass at the start of a frame (the safe point for custom render targets),\r\n // once the shader is compiled — never re-entrantly from a promise/observable continuation.\r\n await new Promise<void>((resolve) => {\r\n const attempt = () => {\r\n if (this._disposed) {\r\n resolve();\r\n return;\r\n }\r\n if (!this._material.isReady(this._quad)) {\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n return;\r\n }\r\n this._mrt.renderList = [this._quad];\r\n this._mrt.render();\r\n resolve();\r\n };\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n });\r\n }\r\n\r\n /**\r\n * Whether the relayout copy shader is compiled and ready. Lazily creates the copy material on first call.\r\n * Callers should poll this before {@link relayoutSync} (which must only run when ready).\r\n * @returns true when {@link relayoutSync} can run this frame\r\n */\r\n public isRelayoutReady(): boolean {\r\n if (this._disposed) {\r\n return false;\r\n }\r\n if (!this._copyMaterial) {\r\n this._copyMaterial = this._createCopyMaterial();\r\n }\r\n return this._copyMaterial.isReady(this._quad);\r\n }\r\n\r\n /**\r\n * Relayouts the decoded work-buffer textures to a new (defragmented) splat layout, keeping the same\r\n * texture instances so the consuming mesh does not need to re-bind. `srcIndexByDst[d]` is the source splat\r\n * index whose decoded data should end up at destination index `d`, or a negative value for a gap (left\r\n * zeroed). Uses a temporary MRT ping-pong (old -> temp via the map, then temp -> old identity) so\r\n * overlapping moves stay correct. Must be called at a frame-safe point (inside `onBeforeRender`) and only\r\n * when {@link isRelayoutReady} returns true.\r\n * @param srcIndexByDst per-destination source splat index (negative = gap)\r\n */\r\n public relayoutSync(srcIndexByDst: Float32Array): void {\r\n if (this._disposed || !this._copyMaterial) {\r\n return;\r\n }\r\n const size = this._textureSize;\r\n // Reuse the map buffer and its GPU texture across relayouts (the work-buffer size is fixed).\r\n if (!this._relayoutMapData) {\r\n this._relayoutMapData = new Float32Array(size * size);\r\n }\r\n const mapData = this._relayoutMapData;\r\n mapData.fill(-1);\r\n mapData.set(srcIndexByDst.subarray(0, Math.min(srcIndexByDst.length, mapData.length)));\r\n if (!this._relayoutMapTexture) {\r\n this._relayoutMapTexture = new RawTexture(\r\n mapData,\r\n size,\r\n size,\r\n Constants.TEXTUREFORMAT_R,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_FLOAT\r\n );\r\n } else {\r\n this._relayoutMapTexture.update(mapData);\r\n }\r\n const mapTexture = this._relayoutMapTexture;\r\n // The temporary ping-pong MRT is (re)created per relayout rather than kept resident: it is the same size\r\n // as the work buffer, so a persistent copy would double GPU memory and defeat the streaming memory budget.\r\n const temp = this._createMrt(\"gsRelayoutTemp\", false);\r\n try {\r\n // Pass 1: old -> temp using the map (temp gets the new layout; gaps stay zeroed by the clear).\r\n this._renderRelayoutPass(temp, this._mrt.textures, mapTexture, 1);\r\n // Pass 2: temp -> old, identity (old textures get the new layout, full overwrite).\r\n this._renderRelayoutPass(this._mrt, temp.textures, mapTexture, 0);\r\n } finally {\r\n temp.dispose();\r\n this._quad.material = this._material;\r\n }\r\n }\r\n\r\n /**\r\n * Renders one relayout copy pass into the target MRT, sampling the given source textures.\r\n * @param target destination MRT\r\n * @param sources the four source work-buffer textures\r\n * @param mapTexture the R32F destination-to-source index map\r\n * @param useMap 1 to read source indices from the map (gaps discarded), 0 for an identity copy\r\n */\r\n private _renderRelayoutPass(target: MultiRenderTarget, sources: Texture[], mapTexture: RawTexture, useMap: number): void {\r\n const material = this._copyMaterial!;\r\n material.setTexture(\"uMapTex\", mapTexture);\r\n material.setTexture(\"uSrc0\", sources[0]);\r\n material.setTexture(\"uSrc1\", sources[1]);\r\n material.setTexture(\"uSrc2\", sources[2]);\r\n material.setTexture(\"uSrc3\", sources[3]);\r\n material.setInt(\"uDstWidth\", this._textureSize);\r\n material.setInt(\"uSrcWidth\", this._textureSize);\r\n material.setInt(\"uUseMap\", useMap);\r\n this._quad.material = material;\r\n target.renderList = [this._quad];\r\n target.render();\r\n }\r\n\r\n private _createCopyMaterial(): ShaderMaterial {\r\n const isWGSL = this._shaderLanguage === ShaderLanguage.WGSL;\r\n const material = new ShaderMaterial(\r\n GaussianSplattingWorkBufferRelayoutShaderName,\r\n this._scene,\r\n {\r\n vertexSource: isWGSL ? GaussianSplattingWorkBufferVertexShaderWGSL : GaussianSplattingWorkBufferVertexShaderGLSL,\r\n fragmentSource: isWGSL ? GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL : GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL,\r\n },\r\n {\r\n attributes: [\"position\"],\r\n uniforms: [\"uDstWidth\", \"uSrcWidth\", \"uUseMap\"],\r\n samplers: [\"uMapTex\", \"uSrc0\", \"uSrc1\", \"uSrc2\", \"uSrc3\"],\r\n shaderLanguage: this._shaderLanguage,\r\n }\r\n );\r\n material.backFaceCulling = false;\r\n material.disableDepthWrite = true;\r\n return material;\r\n }\r\n\r\n /**\r\n * Asynchronously reads back the decoded splat centers (stride-4 xyzw, w=1) for a contiguous splat range\r\n * from the work buffer's centers texture, using a non-blocking GPU readback (WebGL2 PBO + fence, or WebGPU\r\n * copyTextureToBuffer + mapAsync) so it never stalls the frame the way a CPU image decode does. The centers\r\n * texture already holds the GPU-decoded positions (identical to the CPU decode), so this replaces decoding\r\n * positions on the CPU from the means images. Returns null when async readback is unsupported (caller should\r\n * fall back to CPU decoding).\r\n * @param splatOffset first splat index of the range\r\n * @param splatCount number of splats in the range\r\n * @returns a stride-4 Float32Array of length `splatCount * 4`, or null when unsupported/failed\r\n */\r\n public async readCentersRangeAsync(splatOffset: number, splatCount: number): Promise<Nullable<Float32Array>> {\r\n if (this._disposed || splatCount <= 0 || !this.supportsAsyncCentersReadback) {\r\n return null;\r\n }\r\n\r\n const width = this._textureSize;\r\n // The range maps to whole texel rows [rowStart, rowEnd); read that rectangle and slice the exact range.\r\n // Splat i lives at texel (i % width, floor(i / width)) in both decode and draw, so the readback (which\r\n // indexes the same texture storage directly, with no UV/flip) yields splat i at buffer position\r\n // i - rowStart * width on every backend.\r\n const rowStart = Math.floor(splatOffset / width);\r\n const rowEnd = Math.ceil((splatOffset + splatCount) / width);\r\n const rowCount = rowEnd - rowStart;\r\n const startInBuffer = (splatOffset - rowStart * width) * 4;\r\n const sliceEnd = startInBuffer + splatCount * 4;\r\n const centers = this._mrt.textures[0];\r\n\r\n const engine = this._scene.getEngine();\r\n\r\n if (engine.isWebGPU) {\r\n // WebGPU: copyTextureToBuffer of the row span + mapAsync (genuinely non-blocking). noDataConversion\r\n // returns the raw RGBA32F floats tightly packed (the 256-byte row alignment is removed internally).\r\n const result = await centers.readPixels(0, 0, null, true, true, 0, rowStart, width, rowCount);\r\n if (this._disposed || !result) {\r\n return null;\r\n }\r\n const floats = result instanceof Float32Array ? result : new Float32Array(result.buffer, result.byteOffset, result.byteLength / 4);\r\n return floats.length >= sliceEnd ? (floats.subarray(startInBuffer, sliceEnd) as Float32Array) : null;\r\n }\r\n\r\n // WebGL2: read directly from the centers texture via a reused FBO + async PBO readback.\r\n const glEngine = engine as unknown as {\r\n _gl: WebGL2RenderingContext;\r\n _currentFramebuffer: Nullable<WebGLFramebuffer>;\r\n _readPixelsAsync(x: number, y: number, w: number, h: number, format: number, type: number, o: ArrayBufferView): Nullable<Promise<ArrayBufferView>>;\r\n };\r\n const gl = glEngine._gl;\r\n const hardware = centers.getInternalTexture()?._hardwareTexture?.underlyingResource as Nullable<WebGLTexture>;\r\n if (!hardware) {\r\n return null;\r\n }\r\n const buffer = new Float32Array(width * rowCount * 4);\r\n if (!this._readFbo) {\r\n this._readFbo = gl.createFramebuffer();\r\n }\r\n const previousFbo = glEngine._currentFramebuffer;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._readFbo);\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, hardware, 0);\r\n gl.readBuffer(gl.COLOR_ATTACHMENT0);\r\n\r\n // _readPixelsAsync issues the readPixels into a PBO synchronously, then resolves once the GPU fence\r\n // signals — so the framebuffer can be restored immediately while the transfer completes off-thread.\r\n const promise = glEngine._readPixelsAsync(0, rowStart, width, rowCount, gl.RGBA, gl.FLOAT, buffer);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, previousFbo);\r\n // gl.readBuffer is global state: restore the default-framebuffer read source (BACK) so later\r\n // readPixels on the default framebuffer aren't left pointing at COLOR_ATTACHMENT0. When restoring to\r\n // another FBO, COLOR_ATTACHMENT0 is the correct default read buffer, so only reset for the default one.\r\n if (!previousFbo) {\r\n gl.readBuffer(gl.BACK);\r\n }\r\n if (!promise) {\r\n return null;\r\n }\r\n await promise;\r\n if (this._disposed || buffer.length < sliceEnd) {\r\n return null;\r\n }\r\n return buffer.subarray(startInBuffer, sliceEnd) as Float32Array;\r\n }\r\n\r\n /**\r\n * Disposes the work buffer and its decode resources.\r\n */\r\n public dispose(): void {\r\n this._disposed = true;\r\n if (this._readFbo) {\r\n (this._scene.getEngine() as unknown as { _gl?: WebGL2RenderingContext })._gl?.deleteFramebuffer(this._readFbo);\r\n this._readFbo = null;\r\n }\r\n this._quad.dispose();\r\n this._material.dispose(true, false);\r\n this._copyMaterial?.dispose(true, false);\r\n this._relayoutMapTexture?.dispose();\r\n this._mrt.dispose();\r\n }\r\n\r\n private _createQuad(): Mesh {\r\n const quad = new Mesh(\"gsWorkBufferQuad\", this._scene);\r\n const vertexData = new VertexData();\r\n // Fullscreen triangle in clip space (the vertex shader passes positions straight through).\r\n vertexData.positions = [-1, -1, 0, 3, -1, 0, -1, 3, 0];\r\n vertexData.indices = [0, 1, 2];\r\n vertexData.applyToMesh(quad);\r\n // Render only inside the work-buffer MRT, never in the main scene pass.\r\n this._scene.removeMesh(quad);\r\n return quad;\r\n }\r\n\r\n private _createMaterial(): ShaderMaterial {\r\n const isWGSL = this._shaderLanguage === ShaderLanguage.WGSL;\r\n const material = new ShaderMaterial(\r\n \"gsSogDecode\",\r\n this._scene,\r\n {\r\n vertexSource: isWGSL ? GaussianSplattingWorkBufferVertexShaderWGSL : GaussianSplattingWorkBufferVertexShaderGLSL,\r\n fragmentSource: isWGSL ? GaussianSplattingWorkBufferFragmentShaderWGSL : GaussianSplattingWorkBufferFragmentShaderGLSL,\r\n },\r\n {\r\n attributes: [\"position\"],\r\n uniforms: [\"sogMeansMin\", \"sogMeansMax\", \"sogScalesMin\", \"sogScalesMax\", \"sogSh0Min\", \"sogSh0Max\", \"uVersion\", \"uOffset\", \"uCount\", \"uDestWidth\", \"uSrcWidth\"],\r\n samplers: [\"sogMeansLTex\", \"sogMeansUTex\", \"sogScalesTex\", \"sogQuatsTex\", \"sogSh0Tex\", \"sogCodebookTex\"],\r\n shaderLanguage: this._shaderLanguage,\r\n }\r\n );\r\n material.backFaceCulling = false;\r\n material.disableDepthWrite = true;\r\n return material;\r\n }\r\n\r\n private _applyPack(pack: ISogTexturePack, offset: number): void {\r\n const material = this._material;\r\n const srcWidth = (pack.meansTextureL as Texture).getSize().width;\r\n\r\n material.setTexture(\"sogMeansLTex\", pack.meansTextureL);\r\n material.setTexture(\"sogMeansUTex\", pack.meansTextureU);\r\n material.setTexture(\"sogScalesTex\", pack.scalesTexture);\r\n material.setTexture(\"sogQuatsTex\", pack.quatsTexture);\r\n material.setTexture(\"sogSh0Tex\", pack.sh0Texture);\r\n // Codebook only used for v2; bind a harmless placeholder otherwise so the sampler is always set.\r\n material.setTexture(\"sogCodebookTex\", pack.codebookTexture ?? pack.sh0Texture);\r\n\r\n material.setVector3(\"sogMeansMin\", new Vector3(pack.meansMin[0], pack.meansMin[1], pack.meansMin[2]));\r\n material.setVector3(\"sogMeansMax\", new Vector3(pack.meansMax[0], pack.meansMax[1], pack.meansMax[2]));\r\n const sMin = pack.scalesMin ?? [0, 0, 0];\r\n const sMax = pack.scalesMax ?? [0, 0, 0];\r\n material.setVector3(\"sogScalesMin\", new Vector3(sMin[0], sMin[1], sMin[2]));\r\n material.setVector3(\"sogScalesMax\", new Vector3(sMax[0], sMax[1], sMax[2]));\r\n const c0Min = pack.sh0Min ?? [0, 0, 0, 0];\r\n const c0Max = pack.sh0Max ?? [0, 0, 0, 0];\r\n material.setVector4(\"sogSh0Min\", new Vector4(c0Min[0], c0Min[1], c0Min[2], c0Min[3]));\r\n material.setVector4(\"sogSh0Max\", new Vector4(c0Max[0], c0Max[1], c0Max[2], c0Max[3]));\r\n\r\n material.setInt(\"uVersion\", pack.version);\r\n material.setInt(\"uOffset\", offset);\r\n material.setInt(\"uCount\", pack.splatCount);\r\n material.setInt(\"uDestWidth\", this._textureSize);\r\n material.setInt(\"uSrcWidth\", srcWidth);\r\n }\r\n}\r\n"]}
|
|
@@ -74,7 +74,7 @@ export class EXT_lights_ies {
|
|
|
74
74
|
const bufferView = ArrayItem.Get(`${context}/bufferView`, this._loader.gltf.bufferViews, light.bufferView);
|
|
75
75
|
bufferData = await this._loader.loadBufferViewAsync(`/bufferViews/${bufferView.index}`, bufferView);
|
|
76
76
|
}
|
|
77
|
-
babylonSpotLight.iesProfileTexture = new Texture(name + "_iesProfile", this._loader.babylonScene, true, false, undefined, null, null, bufferData, true, undefined, undefined, undefined, undefined, ".ies");
|
|
77
|
+
babylonSpotLight.iesProfileTexture = new Texture(babylonSpotLight.name + "_iesProfile", this._loader.babylonScene, true, false, undefined, null, null, bufferData, true, undefined, undefined, undefined, undefined, ".ies");
|
|
78
78
|
return transformNode;
|
|
79
79
|
});
|
|
80
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EXT_lights_ies.pure.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/EXT_lights_ies.pure.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"EXT_lights_ies.pure.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/EXT_lights_ies.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"core/types\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { Color3 } from \"core/Maths/math.color.pure\";\r\nimport { SpotLight } from \"core/Lights/spotLight.pure\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport { type TransformNode } from \"core/Meshes/transformNode.pure\";\r\n\r\nimport { type IEXTLightsIES_LightReference } from \"babylonjs-gltf2interface\";\r\nimport { type IEXTLightsIES_Light, type INode } from \"../glTFLoaderInterfaces\";\r\nimport { type IGLTFLoaderExtension } from \"../glTFLoaderExtension\";\r\nimport { GLTFLoader, ArrayItem } from \"../glTFLoader.pure\";\r\nimport { registerGLTFExtension, unregisterGLTFExtension } from \"../glTFLoaderExtensionRegistry\";\r\nimport { Texture } from \"core/Materials/Textures/texture.pure\";\r\n\r\nconst NAME = \"EXT_lights_ies\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Vendor/EXT_lights_ies)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_lights_ies implements IGLTFLoaderExtension {\r\n /**\r\n * The name of this extension.\r\n */\r\n public readonly name = NAME;\r\n\r\n /**\r\n * Defines whether this extension is enabled.\r\n */\r\n public enabled: boolean;\r\n\r\n /** hidden */\r\n private _loader: GLTFLoader;\r\n private _lights?: IEXTLightsIES_Light[];\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(loader: GLTFLoader) {\r\n this._loader = loader;\r\n this.enabled = this._loader.isExtensionUsed(NAME);\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._loader as any) = null;\r\n delete this._lights;\r\n }\r\n\r\n /** @internal */\r\n public onLoading(): void {\r\n const extensions = this._loader.gltf.extensions;\r\n if (extensions && extensions[this.name]) {\r\n const extension = extensions[this.name];\r\n this._lights = extension.lights;\r\n ArrayItem.Assign(this._lights);\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n // eslint-disable-next-line no-restricted-syntax\r\n public loadNodeAsync(context: string, node: INode, assign: (babylonTransformNode: TransformNode) => void): Nullable<Promise<TransformNode>> {\r\n return GLTFLoader.LoadExtensionAsync<IEXTLightsIES_LightReference, TransformNode>(context, node, this.name, async (extensionContext, extension) => {\r\n this._loader._allMaterialsDirtyRequired = true;\r\n\r\n let babylonSpotLight: SpotLight;\r\n let light: IEXTLightsIES_Light;\r\n\r\n const transformNode = await this._loader.loadNodeAsync(context, node, (babylonMesh) => {\r\n light = ArrayItem.Get(extensionContext, this._lights, extension.light);\r\n const name = light.name || babylonMesh.name;\r\n\r\n this._loader.babylonScene._blockEntityCollection = !!this._loader._assetContainer;\r\n\r\n babylonSpotLight = new SpotLight(name, Vector3.Zero(), Vector3.Backward(), 0, 1, this._loader.babylonScene);\r\n babylonSpotLight.angle = Math.PI / 2;\r\n babylonSpotLight.innerAngle = 0;\r\n\r\n babylonSpotLight._parentContainer = this._loader._assetContainer;\r\n this._loader.babylonScene._blockEntityCollection = false;\r\n light._babylonLight = babylonSpotLight;\r\n\r\n babylonSpotLight.falloffType = Light.FALLOFF_GLTF;\r\n babylonSpotLight.diffuse = extension.color ? Color3.FromArray(extension.color) : Color3.White();\r\n babylonSpotLight.intensity = extension.multiplier || 1;\r\n babylonSpotLight.range = Number.MAX_VALUE;\r\n babylonSpotLight.parent = babylonMesh;\r\n\r\n this._loader._babylonLights.push(babylonSpotLight);\r\n\r\n GLTFLoader.AddPointerMetadata(babylonSpotLight, extensionContext);\r\n\r\n assign(babylonMesh);\r\n });\r\n\r\n // Load the profile\r\n let bufferData: ArrayBufferView;\r\n if (light!.uri) {\r\n bufferData = await this._loader.loadUriAsync(context, light!, light!.uri);\r\n } else {\r\n const bufferView = ArrayItem.Get(`${context}/bufferView`, this._loader.gltf.bufferViews, light!.bufferView);\r\n bufferData = await this._loader.loadBufferViewAsync(`/bufferViews/${bufferView.index}`, bufferView);\r\n }\r\n babylonSpotLight!.iesProfileTexture = new Texture(\r\n babylonSpotLight!.name + \"_iesProfile\",\r\n this._loader.babylonScene,\r\n true,\r\n false,\r\n undefined,\r\n null,\r\n null,\r\n bufferData,\r\n true,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n \".ies\"\r\n );\r\n\r\n return transformNode;\r\n });\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Registers the EXT_lights_ies glTF loader extension.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function RegisterEXT_lights_ies(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n unregisterGLTFExtension(NAME);\r\n\r\n registerGLTFExtension(NAME, true, (loader) => new EXT_lights_ies(loader));\r\n}\r\n"]}
|
package/glTF/2.0/glTFLoader.d.ts
CHANGED
package/glTF/2.0/glTFLoader.js
CHANGED