From 0162a5d805ee80c08ac101ff1d8dfba0030646e5 Mon Sep 17 00:00:00 2001 From: Kalila <69767640+digisomni@users.noreply.github.com> Date: Thu, 8 Feb 2024 15:39:50 +1100 Subject: [PATCH] Init v0.1 of LightmapManager. --- .../components/components/ModelComponent.ts | 5 + src/modules/scene/LODManager.ts | 25 ++--- src/modules/scene/LightmapManager.ts | 53 ++++++++- staging/lightmap_support_glb.js | 89 --------------- staging/lightmap_support_gltf.js | 103 ------------------ types/vircadia_gameUse.ts | 33 ++++-- 6 files changed, 87 insertions(+), 221 deletions(-) delete mode 100644 staging/lightmap_support_glb.js delete mode 100644 staging/lightmap_support_gltf.js diff --git a/src/modules/entity/components/components/ModelComponent.ts b/src/modules/entity/components/components/ModelComponent.ts index 78cdf7ab..9bf16f61 100644 --- a/src/modules/entity/components/components/ModelComponent.ts +++ b/src/modules/entity/components/components/ModelComponent.ts @@ -23,6 +23,7 @@ import { updateContentLoadingProgress } from "@Modules/scene/LoadingScreen"; import { applicationStore } from "@Stores/index"; import Log from "@Modules/debugging/log"; import { LODManager } from "@Modules/scene/LODManager"; +import { LightmapManager } from "@Modules/scene/LightmapManager"; const InteractiveModelTypes = [ { name: "chair", condition: /^(?:animate_sitting|animate_seat)/iu }, @@ -70,6 +71,10 @@ export class ModelComponent extends MeshComponent { let meshes = result.meshes; // LOD Handling meshes = LODManager.setLODLevels(meshes); + // Lightmap Handling + if (this._gameObject?.getScene()) { + meshes = LightmapManager.applySceneLightmapsToMeshes(meshes, this._gameObject.getScene()); + } this.mesh = meshes[0]; this.renderGroupId = DEFAULT_MESH_RENDER_GROUP_ID; diff --git a/src/modules/scene/LODManager.ts b/src/modules/scene/LODManager.ts index 8c22ebd1..3d126ae2 100644 --- a/src/modules/scene/LODManager.ts +++ b/src/modules/scene/LODManager.ts @@ -16,7 +16,7 @@ import { Mesh } from "@babylonjs/core"; import Log from "../debugging/log"; -import { Mesh as MeshTypes } from "../../../types/vircadia_gameUse"; +import { glTF as MeshTypes } from "../../../types/vircadia_gameUse"; export const StringsAsBillboardModes: { [key: string]: MeshTypes.BillboardModes } = { none: MeshTypes.BillboardModes.BILLBOARDMODE_NONE, @@ -97,14 +97,7 @@ export class LODManager { const meshExtras = mesh.metadata?.gltf?.extras; const parentExtras = mesh.parent?.metadata?.gltf?.extras; - const meshMetadata: MeshTypes.Metadata = { - vircadia_lod_mode: undefined, - vircadia_lod_auto: undefined, - vircadia_lod_distance: undefined, - vircadia_lod_size: undefined, - vircadia_lod_hide: undefined, - vircadia_billboard_mode: undefined - }; + const meshMetadata = new MeshTypes.Metadata(); if (meshExtras === null || meshExtras === undefined && parentExtras !== null || parentExtras !== undefined) { meshMetadata.vircadia_lod_mode = parentExtras?.vircadia_lod_mode; @@ -127,9 +120,9 @@ export class LODManager { private static setBillboardMode( mesh: Mesh | AbstractMesh | InstancedMesh, - modeAsString: string | undefined + modeAsString: string | null ): void { - if (modeAsString !== undefined) { + if (modeAsString !== null) { const mode = StringsAsBillboardModes[modeAsString]; mesh.scaling.x *= -1; mesh.billboardMode = mode; @@ -142,9 +135,9 @@ export class LODManager { private static setLODHide( mesh: Mesh, - hideAtDistance: number | undefined + hideAtDistance: number | null ): void { - if (hideAtDistance !== undefined) { + if (hideAtDistance !== null) { mesh.addLODLevel(hideAtDistance, null); Log.debug( Log.types.ENTITIES, @@ -282,7 +275,6 @@ export class LODManager { ); const level = parse.lodLevel; - let mode = MeshTypes.LOD.Modes.DISTANCE; if ( !level || @@ -294,9 +286,7 @@ export class LODManager { continue; } - if (metadata.vircadia_lod_mode) { - mode = metadata.vircadia_lod_mode; - } + const mode = metadata.vircadia_lod_mode ?? MeshTypes.LOD.Modes.DISTANCE; switch (mode) { case MeshTypes.LOD.Modes.DISTANCE: { @@ -317,6 +307,7 @@ export class LODManager { break; } + // FIXME: ??? TS case MeshTypes.LOD.Modes.SIZE: { let sizeTarget = SizeTargets[level as keyof typeof SizeTargets]; diff --git a/src/modules/scene/LightmapManager.ts b/src/modules/scene/LightmapManager.ts index 115731d4..2250bc47 100644 --- a/src/modules/scene/LightmapManager.ts +++ b/src/modules/scene/LightmapManager.ts @@ -9,4 +9,55 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// WIP +import { + type AbstractMesh, + type Scene, +} from "@babylonjs/core"; +import Log from "../debugging/log"; +import { glTF as MeshTypes } from "../../../types/vircadia_gameUse"; + +export class LightmapManager { + public static applySceneLightmapsToMeshes(meshes: AbstractMesh[], scene: Scene): AbstractMesh[] { + meshes.forEach((mesh) => { + if ( + mesh.metadata && + mesh.metadata.gltf && + mesh.metadata.gltf.extras && + mesh.metadata.gltf.extras.vircadia_lightmap_default + ) { + Log.debug( + Log.types.ENTITIES, + `Mesh ${mesh.name} has lightmap metadata: ${mesh.metadata.gltf.extras.vircadia_lightmap_default}` + ); + const lightmapMaterialName = mesh.metadata.gltf.extras.vircadia_lightmap_default; + // Search for the material by name + const material = scene.materials.find( + (m) => m.name === lightmapMaterialName + ); + + if (material && material.albedoTexture) { + mesh.material.lightmapTexture = material.albedoTexture; + mesh.material.useLightmapAsShadowmap = true; + mesh.material.lightmapTexture.coordinatesIndex = + mesh.metadata.gltf.extras.vircadia_lightmap_texcoord; + Log.info( + Log.types.ENTITIES, + `Applied albedo texture as lightmap texture for: ${mesh.name}` + ); + } else { + Log.error( + Log.types.ENTITIES, + `Could not find material or albedo texture for: ${mesh.name}` + ); + } + } + + if (mesh.name.startsWith(MeshTypes.Lightmap.DATA_MESH_NAME)) { + mesh.dispose(false, true); // This deletes the mesh without removing child textures or materials + Log.debug(Log.types.ENTITIES, `Deleting lightmap data mesh: ${mesh.name}`); + } + }); + + return meshes; + } +} diff --git a/staging/lightmap_support_glb.js b/staging/lightmap_support_glb.js deleted file mode 100644 index 6f914c6e..00000000 --- a/staging/lightmap_support_glb.js +++ /dev/null @@ -1,89 +0,0 @@ -/* eslint-disable */ - -const createScene = function () { - const scene = new BABYLON.Scene(engine); - const camera = new BABYLON.ArcRotateCamera( - "camera2", - Math.PI / 2, - Math.PI / 4, - 10, - new BABYLON.Vector3.Zero(), - scene - ); - camera.attachControl(canvas, true); - const light = new BABYLON.HemisphericLight( - "light2", - new BABYLON.Vector3(0, 1, 0), - scene - ); - light.intensity = 0.7; - - BABYLON.SceneLoader.ImportMesh( - "", - "https://digisomni-singapore-1.ap-south-1.linodeobjects.com/falah-tech/virtual-collaboration/Testing/Vircadia/Lightmaps/Test3/", - "LightmapTest_jpg.glb", - scene, - function (newMeshes) { - newMeshes.forEach((mesh) => { - console.info( - "Mesh:", - mesh.name, - "has metadata:", - mesh.metadata - ); - - if ( - mesh.metadata && - mesh.metadata.gltf && - mesh.metadata.gltf.extras && - mesh.metadata.gltf.extras.vircadia_lightmap_default - ) { - console.info( - "Found lightmap in metadata:", - mesh.metadata.gltf.extras.vircadia_lightmap_default - ); - // Attempt to find the embedded lightmap texture by name - const lightmapName = - mesh.metadata.gltf.extras.vircadia_lightmap_default; - - console.info( - "Before checking, here are the lightmaps:", - scene.textures - ); - const embeddedLightmap = lightmaps.find( - (texture) => texture.name === lightmapName - ); - - console.info( - "Found embedded lightmap texture:", - embeddedLightmap - ); - if (embeddedLightmap) { - mesh.material.lightmapTexture = embeddedLightmap; - mesh.material.useLightmapAsShadowmap = true; - mesh.material.lightmapTexture.coordinatesIndex = - mesh.metadata.gltf.extras.vircadia_lightmap_texcoord; - console.info( - "Successfully applied embedded lightmap texture:", - lightmapName - ); - } else { - console.error( - "Failed to find embedded lightmap texture for:", - mesh.name, - "with lightmap name:", - lightmapName - ); - } - } - // Check if the mesh name matches 'vircadia_lightmapData' and hide it - if (mesh.name === "vircadia_lightmapData") { - mesh.isVisible = false; // This hides the mesh - console.info("Mesh vircadia_lightmapData is now hidden"); - } - }); - } - ); - - return scene; -}; diff --git a/staging/lightmap_support_gltf.js b/staging/lightmap_support_gltf.js deleted file mode 100644 index 07323711..00000000 --- a/staging/lightmap_support_gltf.js +++ /dev/null @@ -1,103 +0,0 @@ -/* eslint-disable */ - -const createScene = function () { - const scene = new BABYLON.Scene(engine); - const camera = new BABYLON.ArcRotateCamera( - "camera1", - Math.PI / 2, - Math.PI / 4, - 10, - BABYLON.Vector3.Zero(), - scene - ); - camera.attachControl(canvas, true); - const light = new BABYLON.HemisphericLight( - "light", - new BABYLON.Vector3(0, 1, 0), - scene - ); - light.intensity = 0.7; - - BABYLON.SceneLoader.ImportMesh( - "", - "https://digisomni-singapore-1.ap-south-1.linodeobjects.com/falah-tech/virtual-collaboration/Testing/Vircadia/Lightmaps/Test2/", - "LightmapTest_jpg.gltf", - scene, - function (newMeshes) { - newMeshes.forEach((mesh) => { - if ( - mesh.metadata && - mesh.metadata.gltf && - mesh.metadata.gltf.extras && - mesh.metadata.gltf.extras.vircadia_lightmap_default - ) { - console.info( - "Found lightmap in metadata:", - mesh.metadata.gltf.extras.vircadia_lightmap_default - ); - const baseLightmapUrl = - "https://digisomni-singapore-1.ap-south-1.linodeobjects.com/falah-tech/virtual-collaboration/Testing/Vircadia/Lightmaps/Test2/" + - mesh.metadata.gltf.extras.vircadia_lightmap_default; - const extensions = [ - ".png", - ".webp", - ".exr", - ".jpg", - ".jpeg", - ]; - let lightmapTextureLoaded = false; - - extensions.forEach((ext) => { - const lightmapTextureUrl = baseLightmapUrl + ext; - console.info( - "Trying to load lightmap texture:", - lightmapTextureUrl - ); - var lightmapTexture = new BABYLON.Texture( - lightmapTextureUrl, - scene, - true, - false, - BABYLON.Texture.TRILINEAR_SAMPLINGMODE, - () => { - mesh.material.lightmapTexture = lightmapTexture; - mesh.material.useLightmapAsShadowmap = true; - mesh.material.lightmapTexture.coordinatesIndex = - mesh.metadata.gltf.extras.vircadia_lightmap_texcoord; - console.info( - "Successfully loaded lightmap texture:", - lightmapTextureUrl - ); - lightmapTextureLoaded = true; - }, - (message, exception) => { - console.error( - "Failed to load lightmap texture:", - lightmapTextureUrl, - message, - exception - ); - }, - null, - true - ); - }); - - if (!lightmapTextureLoaded) { - console.error( - "Failed to load lightmap texture for:", - mesh.name - ); - } - } - // Check if the mesh name matches 'vircadia_lightmapData' and hide it - if (mesh.name === "vircadia_lightmapData") { - mesh.isVisible = false; // This hides the mesh - console.info("Mesh vircadia_lightmapData is now hidden"); - } - }); - } - ); - - return scene; -}; diff --git a/types/vircadia_gameUse.ts b/types/vircadia_gameUse.ts index 7b4bb4cd..9dc2e0e2 100644 --- a/types/vircadia_gameUse.ts +++ b/types/vircadia_gameUse.ts @@ -1,14 +1,25 @@ -export namespace Mesh { - export interface Metadata { - vircadia_lod_mode?: LOD.Modes; - vircadia_lod_auto?: boolean; - vircadia_lod_distance?: number; - vircadia_lod_size?: number; - vircadia_lod_hide?: number; - vircadia_billboard_mode?: string; +export namespace glTF { + export interface MetadataInterface { + vircadia_lod_mode: LOD.Modes | null; + vircadia_lod_auto: boolean | null; + vircadia_lod_distance: number | null; + vircadia_lod_size: number | null; + vircadia_lod_hide: number | null; + vircadia_billboard_mode: string | null; // Lightmap - vircadia_lightmap_default?: string, - vircadia_lightmap_texcoord?: number + vircadia_lightmap_default: string | null; + vircadia_lightmap_texcoord: number | null; + } + + export class Metadata implements MetadataInterface { + public vircadia_lod_mode = null; + public vircadia_lod_auto = null; + public vircadia_lod_distance = null; + public vircadia_lod_size = null; + public vircadia_lod_hide = null; + public vircadia_billboard_mode = null; + public vircadia_lightmap_default = null; + public vircadia_lightmap_texcoord = null; } export namespace LOD { @@ -35,6 +46,6 @@ export namespace Mesh { } export namespace Lightmap { - export const LightmapDataMesh = "vircadia_lightmapData_"; // + lightmap name + export const DATA_MESH_NAME = "vircadia_lightmapData"; } }