From a2e117a20d6e50e2d1239f2e746f550ea120e061 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 9 May 2022 23:17:48 -0400 Subject: [PATCH 1/5] Skybox enhancements --- .../com/mbrlabs/mundus/commons/Scene.java | 1 + .../mundus/commons/assets/AssetManager.java | 60 ++++-- .../mundus/commons/assets/AssetType.java | 4 +- .../mundus/commons/assets/SkyboxAsset.java | 73 +++++++ .../mundus/commons/assets/meta/Meta.java | 10 + .../commons/assets/meta/MetaLoader.java | 16 ++ .../commons/assets/meta/MetaSkybox.java | 89 +++++++++ .../mbrlabs/mundus/commons/dto/SceneDTO.java | 9 + .../mbrlabs/mundus/commons/skybox/Skybox.java | 3 +- .../main/com/mbrlabs/mundus/editor/Editor.kt | 2 - .../editor/assets/EditorAssetManager.kt | 60 ++++++ .../mbrlabs/mundus/editor/assets/MetaSaver.kt | 15 ++ .../editor/core/converter/SceneConverter.java | 2 + .../editor/core/project/ProjectManager.java | 60 +++++- .../editor/ui/modules/dialogs/SkyboxDialog.kt | 178 +++++++++++++++--- .../mundus/editor/utils/SkyboxBuilder.kt | 22 ++- 16 files changed, 543 insertions(+), 61 deletions(-) create mode 100644 commons/src/main/com/mbrlabs/mundus/commons/assets/SkyboxAsset.java create mode 100644 commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaSkybox.java diff --git a/commons/src/main/com/mbrlabs/mundus/commons/Scene.java b/commons/src/main/com/mbrlabs/mundus/commons/Scene.java index 2d4ac5816..6f2d23ab6 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/Scene.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/Scene.java @@ -48,6 +48,7 @@ public class Scene implements Disposable { public SceneGraph sceneGraph; public MundusEnvironment environment; public Skybox skybox; + public String skyboxAssetId; public float waterHeight = 0f; public WaterResolution waterResolution = WaterResolution.DEFAULT_WATER_RESOLUTION; diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/AssetManager.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/AssetManager.java index f42388bdd..aa1cee124 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/assets/AssetManager.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/assets/AssetManager.java @@ -68,6 +68,19 @@ public Asset findAssetByID(String id) { return assetIndex.get(id); } + /** + * Returns an asset by filename, else null if not found. + * @param fileName the filename to search + * @return matching asset or null + */ + public Asset findAssetByFileName(String fileName) { + for (Asset asset : assets) { + if (asset.file.name().equals(fileName)) + return asset; + } + return null; + } + public Map getAssetMap() { return assetIndex; } @@ -239,32 +252,41 @@ public Asset loadAsset(Meta meta) throws MetaFileParseException, AssetNotFoundEx // load actual asset Asset asset = null; switch (meta.getType()) { - case TEXTURE: - asset = loadTextureAsset(meta, assetFile); - break; - case PIXMAP_TEXTURE: - asset = loadPixmapTextureAsset(meta, assetFile); - break; - case TERRAIN: - asset = loadTerrainAsset(meta, assetFile); - break; - case MODEL: - asset = loadModelAsset(meta, assetFile); - break; - case MATERIAL: - asset = loadMaterialAsset(meta, assetFile); - break; + case TEXTURE: + asset = loadTextureAsset(meta, assetFile); + break; + case PIXMAP_TEXTURE: + asset = loadPixmapTextureAsset(meta, assetFile); + break; + case TERRAIN: + asset = loadTerrainAsset(meta, assetFile); + break; + case MODEL: + asset = loadModelAsset(meta, assetFile); + break; + case MATERIAL: + asset = loadMaterialAsset(meta, assetFile); + break; case WATER: - asset = loadWaterAsset(meta, assetFile); - break; - default: - return null; + asset = loadWaterAsset(meta, assetFile); + break; + case SKYBOX: + asset = loadSkyboxAsset(meta, assetFile); + break; + default: + return null; } addAsset(asset); return asset; } + private Asset loadSkyboxAsset(Meta meta, FileHandle assetFile) { + SkyboxAsset asset = new SkyboxAsset(meta, assetFile); + asset.load(); + return asset; + } + private MaterialAsset loadMaterialAsset(Meta meta, FileHandle assetFile) { MaterialAsset asset = new MaterialAsset(meta, assetFile); asset.load(); diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/AssetType.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/AssetType.java index 807d2345d..dcd9225ed 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/assets/AssetType.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/assets/AssetType.java @@ -32,5 +32,7 @@ public enum AssetType { /** Material file. Mundus material file contains material information. */ MATERIAL, /** Water file. Contains data for water. */ - WATER + WATER, + /** Skybox file. Holds reference to skybox textures. **/ + SKYBOX } diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/SkyboxAsset.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/SkyboxAsset.java new file mode 100644 index 000000000..5c1b70ea5 --- /dev/null +++ b/commons/src/main/com/mbrlabs/mundus/commons/assets/SkyboxAsset.java @@ -0,0 +1,73 @@ +package com.mbrlabs.mundus.commons.assets; + +import com.badlogic.gdx.files.FileHandle; +import com.mbrlabs.mundus.commons.assets.meta.Meta; + +import java.util.Map; + +public class SkyboxAsset extends Asset { + + public TextureAsset positiveX; + public TextureAsset negativeX; + public TextureAsset positiveY; + public TextureAsset negativeY; + public TextureAsset positiveZ; + public TextureAsset negativeZ; + + public SkyboxAsset(Meta meta, FileHandle assetFile) { + super(meta, assetFile); + } + + @Override + public void load() { + // nothing to load for now + } + + @Override + public void resolveDependencies(Map assets) { + if (assets.containsKey(meta.getMetaSkybox().getPositiveX())) { + positiveX = (TextureAsset) assets.get(meta.getMetaSkybox().getPositiveX()); + } + if (assets.containsKey(meta.getMetaSkybox().getNegativeX())) { + negativeX = (TextureAsset) assets.get(meta.getMetaSkybox().getNegativeX()); + } + if (assets.containsKey(meta.getMetaSkybox().getPositiveY())) { + positiveY = (TextureAsset) assets.get(meta.getMetaSkybox().getPositiveY()); + } + if (assets.containsKey(meta.getMetaSkybox().getNegativeY())) { + negativeY = (TextureAsset) assets.get(meta.getMetaSkybox().getNegativeY()); + } + if (assets.containsKey(meta.getMetaSkybox().getPositiveZ())) { + positiveZ = (TextureAsset) assets.get(meta.getMetaSkybox().getPositiveZ()); + } + if (assets.containsKey(meta.getMetaSkybox().getNegativeZ())) { + negativeZ = (TextureAsset) assets.get(meta.getMetaSkybox().getNegativeZ()); + } + } + + @Override + public void applyDependencies() { + + } + + @Override + public void dispose() { + positiveX.dispose(); + negativeX.dispose(); + positiveY.dispose(); + negativeY.dispose(); + positiveZ.dispose(); + negativeZ.dispose(); + } + + @Override + public boolean usesAsset(Asset assetToCheck) { + if (assetToCheck == positiveX || assetToCheck == negativeX || + assetToCheck == positiveY || assetToCheck == negativeY || + assetToCheck == positiveZ || assetToCheck == negativeZ) { + return true; + } + + return false; + } +} diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/Meta.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/Meta.java index 1f38ac157..aae392182 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/Meta.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/Meta.java @@ -37,6 +37,7 @@ public class Meta { public static final String JSON_TERRAIN = "ter"; public static final String JSON_WATER = "wat"; public static final String JSON_MODEL = "mdl"; + public static final String JSON_SKY_BOX = "sky"; private int version; private long lastModified; @@ -46,6 +47,7 @@ public class Meta { private MetaModel model; private MetaTerrain terrain; private MetaWater water; + private MetaSkybox metaSkybox; private FileHandle file; @@ -113,6 +115,14 @@ public void setWater(MetaWater water) { this.water = water; } + public MetaSkybox getMetaSkybox() { + return metaSkybox; + } + + public void setMetaSkybox(MetaSkybox metaSkybox) { + this.metaSkybox = metaSkybox; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaLoader.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaLoader.java index f74451366..444456c4c 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaLoader.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaLoader.java @@ -44,6 +44,8 @@ public Meta load(FileHandle file) throws MetaFileParseException { parseModel(meta, json.get(Meta.JSON_MODEL)); } else if(meta.getType() == AssetType.WATER) { parseWater(meta, json.get(Meta.JSON_WATER)); + } else if(meta.getType() == AssetType.SKYBOX) { + parseSkybox(meta, json.get(Meta.JSON_SKY_BOX)); } return meta; @@ -104,6 +106,20 @@ private void parseModel(Meta meta, JsonValue jsonModel) { meta.setModel(model); } + private void parseSkybox(Meta meta, JsonValue jsonValue) { + if(jsonValue == null) return; + + final MetaSkybox skybox = new MetaSkybox(); + skybox.setPositiveX(jsonValue.getString(MetaSkybox.JSON_POSITIVE_X)); + skybox.setNegativeX(jsonValue.getString(MetaSkybox.JSON_NEGATIVE_X)); + skybox.setPositiveY(jsonValue.getString(MetaSkybox.JSON_POSITIVE_Y)); + skybox.setNegativeY(jsonValue.getString(MetaSkybox.JSON_NEGATIVE_Y)); + skybox.setPositiveZ(jsonValue.getString(MetaSkybox.JSON_POSITIVE_Z)); + skybox.setNegativeZ(jsonValue.getString(MetaSkybox.JSON_NEGATIVE_Z)); + + meta.setMetaSkybox(skybox); + } + /** * When new values are added and cannot be found on jsonValue.getXXX(), * an IllegalArgumentException is thrown. diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaSkybox.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaSkybox.java new file mode 100644 index 000000000..a6d5ad536 --- /dev/null +++ b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaSkybox.java @@ -0,0 +1,89 @@ +package com.mbrlabs.mundus.commons.assets.meta; + +public class MetaSkybox { + public static final String JSON_POSITIVE_X = "positiveX"; + public static final String JSON_NEGATIVE_X = "negativeX"; + public static final String JSON_POSITIVE_Y = "positiveY"; + public static final String JSON_NEGATIVE_Y = "negativeY"; + public static final String JSON_POSITIVE_Z = "positiveZ"; + public static final String JSON_NEGATIVE_Z = "negativeZ"; + + public String positiveX; + public String negativeX; + public String positiveY; + public String negativeY; + public String positiveZ; + public String negativeZ; + + public MetaSkybox() { + } + + public MetaSkybox(String positiveX, String negativeX, String positiveY, String negativeY, String positiveZ, String negativeZ) { + this.positiveX = positiveX; + this.negativeX = negativeX; + this.positiveY = positiveY; + this.negativeY = negativeY; + this.positiveZ = positiveZ; + this.negativeZ = negativeZ; + } + + public String getPositiveX() { + return positiveX; + } + + public void setPositiveX(String positiveX) { + this.positiveX = positiveX; + } + + public String getNegativeX() { + return negativeX; + } + + public void setNegativeX(String negativeX) { + this.negativeX = negativeX; + } + + public String getPositiveY() { + return positiveY; + } + + public void setPositiveY(String positiveY) { + this.positiveY = positiveY; + } + + public String getNegativeY() { + return negativeY; + } + + public void setNegativeY(String negativeY) { + this.negativeY = negativeY; + } + + public String getPositiveZ() { + return positiveZ; + } + + public void setPositiveZ(String positiveZ) { + this.positiveZ = positiveZ; + } + + public String getNegativeZ() { + return negativeZ; + } + + public void setNegativeZ(String negativeZ) { + this.negativeZ = negativeZ; + } + + @Override + public String toString() { + return "MetaSkybox{" + + "positiveX='" + positiveX + '\'' + + ", negativeX='" + negativeX + '\'' + + ", positiveY='" + positiveY + '\'' + + ", negativeY='" + negativeY + '\'' + + ", positiveZ='" + positiveZ + '\'' + + ", negativeZ='" + negativeZ + '\'' + + '}'; + } +} diff --git a/commons/src/main/com/mbrlabs/mundus/commons/dto/SceneDTO.java b/commons/src/main/com/mbrlabs/mundus/commons/dto/SceneDTO.java index e2b787de6..66725e1b8 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/dto/SceneDTO.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/dto/SceneDTO.java @@ -29,6 +29,7 @@ public class SceneDTO { private long id; private String name; + private String skyboxAssetId; private List gameObjects; private FogDTO fog; private BaseLightDTO ambientLight; @@ -148,4 +149,12 @@ public void setWaterHeight(float waterHeight) { public float getWaterHeight() { return waterHeight; } + + public void setSkyboxAssetId(String skyboxAssetId) { + this.skyboxAssetId = skyboxAssetId; + } + + public String getSkyboxAssetId() { + return skyboxAssetId; + } } diff --git a/commons/src/main/com/mbrlabs/mundus/commons/skybox/Skybox.java b/commons/src/main/com/mbrlabs/mundus/commons/skybox/Skybox.java index 467e9337d..73e1c7174 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/skybox/Skybox.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/skybox/Skybox.java @@ -47,9 +47,10 @@ public class Skybox implements Disposable { private FileHandle negativeZ; public Skybox(FileHandle positiveX, FileHandle negativeX, FileHandle positiveY, FileHandle negativeY, - FileHandle positiveZ, FileHandle negativeZ) { + FileHandle positiveZ, FileHandle negativeZ, Shader shader) { set(positiveX, negativeX, positiveY, negativeY, positiveZ, negativeZ); + this.shader = shader; boxModel = createModel(); boxInstance = new ModelInstance(boxModel); } diff --git a/editor/src/main/com/mbrlabs/mundus/editor/Editor.kt b/editor/src/main/com/mbrlabs/mundus/editor/Editor.kt index 55ca20f0b..d87f1839a 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/Editor.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/Editor.kt @@ -32,7 +32,6 @@ import com.mbrlabs.mundus.editor.events.SceneChangedEvent import com.mbrlabs.mundus.editor.input.FreeCamController import com.mbrlabs.mundus.editor.input.InputManager import com.mbrlabs.mundus.editor.input.ShortcutController -import com.mbrlabs.mundus.editor.shader.Shaders import com.mbrlabs.mundus.editor.tools.ToolManager import com.mbrlabs.mundus.editor.ui.UI import com.mbrlabs.mundus.editor.utils.Compass @@ -113,7 +112,6 @@ class Editor : Lwjgl3WindowAdapter(), ApplicationListener, val context = projectManager.current() val scene = context.currScene val sg = scene.sceneGraph - scene.skybox.shader = Shaders.skyboxShader UI.sceneWidget.setCam(context.currScene.cam) UI.sceneWidget.setRenderer { diff --git a/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt b/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt index 24e205f7e..d1b5bc43c 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt @@ -21,10 +21,12 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.graphics.Pixmap import com.badlogic.gdx.graphics.PixmapIO +import com.badlogic.gdx.utils.Array import com.badlogic.gdx.utils.ObjectSet import com.kotcrab.vis.ui.util.dialog.Dialogs import com.mbrlabs.mundus.commons.assets.* import com.mbrlabs.mundus.commons.assets.meta.Meta +import com.mbrlabs.mundus.commons.assets.meta.MetaSkybox import com.mbrlabs.mundus.commons.assets.meta.MetaTerrain import com.mbrlabs.mundus.commons.assets.meta.MetaWater import com.mbrlabs.mundus.commons.scene3d.GameObject @@ -290,6 +292,47 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { return asset } + /** + * Creates a new texture asset if it does not exist, else + * returns an existing one. + * + * @param texture + * @return + * @throws IOException + */ + fun getOrCreateTextureAsset(texture: FileHandle): TextureAsset { + val existingTexture = findAssetByFileName(texture.name()) + if (existingTexture != null) + return existingTexture as TextureAsset + + return createTextureAsset(texture) + } + + @Throws(IOException::class, AssetAlreadyExistsException::class) + fun createSkyBoxAsset(name : String, positiveX : String, negativeX : String, positiveY : String, negativeY : String, positiveZ : String, negativeZ : String): SkyboxAsset { + val fileName = "$name.sky" + val metaFilename = "$fileName.meta" + + // create meta file + val metaPath = FilenameUtils.concat(rootFolder.path(), metaFilename) + val meta = createNewMetaFile(FileHandle(metaPath), AssetType.SKYBOX) + meta.metaSkybox = MetaSkybox(positiveX, negativeX, + positiveY, negativeY, positiveZ, negativeZ) + + // create file + val filePath = FilenameUtils.concat(rootFolder.path(), fileName) + val file = File(filePath) + FileUtils.touch(file) + + // load & apply asset + val asset = SkyboxAsset(meta, FileHandle(file)) + asset.load() + + saveAsset(asset) + addAsset(asset) + return asset + } + /** * Creates a new & empty material asset. * @@ -326,6 +369,8 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { saveModelAsset(asset) } else if (asset is WaterAsset) { saveWaterAsset(asset) + } else if (asset is SkyboxAsset) { + saveSkyboxAsset(asset) } // TODO other assets ? } @@ -348,6 +393,8 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { val objectsUsingAsset = findAssetUsagesInScenes(projectManager, asset) val assetsUsingAsset = findAssetUsagesInAssets(asset) + //TODO check for SkyboxAsset usages + if (objectsUsingAsset.isNotEmpty() || assetsUsingAsset.isNotEmpty()) { showUsagesFoundDialog(objectsUsingAsset, assetsUsingAsset) return @@ -516,6 +563,10 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { metaSaver.save(asset.meta) } + private fun saveSkyboxAsset(asset: SkyboxAsset) { + metaSaver.save(asset.meta) + } + @Throws(IOException::class, AssetAlreadyExistsException::class) private fun createMetaFileFromAsset(assetFile: FileHandle, type: AssetType): Meta { val metaName = assetFile.name() + "." + Meta.META_EXTENSION @@ -563,4 +614,13 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { return asset } + fun getSkyboxAssets(): Array { + val skyboxes = Array() + for (asset in assets) { + if (asset.meta.type == AssetType.SKYBOX) + skyboxes.add(asset as SkyboxAsset) + } + return skyboxes + } + } diff --git a/editor/src/main/com/mbrlabs/mundus/editor/assets/MetaSaver.kt b/editor/src/main/com/mbrlabs/mundus/editor/assets/MetaSaver.kt index 4b4140b4b..2a1a2ff8e 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/assets/MetaSaver.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/assets/MetaSaver.kt @@ -21,6 +21,7 @@ import com.badlogic.gdx.utils.JsonWriter import com.mbrlabs.mundus.commons.assets.AssetType import com.mbrlabs.mundus.commons.assets.meta.Meta import com.mbrlabs.mundus.commons.assets.meta.MetaModel +import com.mbrlabs.mundus.commons.assets.meta.MetaSkybox import com.mbrlabs.mundus.commons.assets.meta.MetaTerrain import com.mbrlabs.mundus.commons.assets.meta.MetaWater @@ -41,6 +42,8 @@ class MetaSaver { addModel(meta, json) } else if(meta.type == AssetType.WATER) { addWater(meta, json) + } else if(meta.type == AssetType.SKYBOX) { + addSkyBox(meta, json) } json.writeObjectEnd() @@ -103,5 +106,17 @@ class MetaSaver { json.writeObjectEnd() } + private fun addSkyBox(meta: Meta, json: Json) { + val skybox = meta.metaSkybox ?: return + json.writeObjectStart(Meta.JSON_SKY_BOX) + + json.writeValue(MetaSkybox.JSON_POSITIVE_X, skybox.positiveX) + json.writeValue(MetaSkybox.JSON_NEGATIVE_X, skybox.negativeX) + json.writeValue(MetaSkybox.JSON_POSITIVE_Y, skybox.positiveY) + json.writeValue(MetaSkybox.JSON_NEGATIVE_Y, skybox.negativeY) + json.writeValue(MetaSkybox.JSON_POSITIVE_Z, skybox.positiveZ) + json.writeValue(MetaSkybox.JSON_NEGATIVE_Z, skybox.negativeZ) + } + } \ No newline at end of file diff --git a/editor/src/main/com/mbrlabs/mundus/editor/core/converter/SceneConverter.java b/editor/src/main/com/mbrlabs/mundus/editor/core/converter/SceneConverter.java index 76b614760..2658d826c 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/core/converter/SceneConverter.java +++ b/editor/src/main/com/mbrlabs/mundus/editor/core/converter/SceneConverter.java @@ -44,6 +44,7 @@ public static SceneDTO convert(Scene scene) { // meta dto.setName(scene.getName()); dto.setId(scene.getId()); + dto.setSkyboxAssetId(scene.skyboxAssetId); // scene graph for (GameObject go : scene.sceneGraph.getGameObjects()) { @@ -75,6 +76,7 @@ public static EditorScene convert(SceneDTO dto, Map assets) { // meta scene.setId(dto.getId()); scene.setName(dto.getName()); + scene.skyboxAssetId = dto.getSkyboxAssetId(); // environment stuff scene.environment.setFog(FogConverter.convert(dto.getFog())); diff --git a/editor/src/main/com/mbrlabs/mundus/editor/core/project/ProjectManager.java b/editor/src/main/com/mbrlabs/mundus/editor/core/project/ProjectManager.java index b098dbfd9..9f88625b6 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/core/project/ProjectManager.java +++ b/editor/src/main/com/mbrlabs/mundus/editor/core/project/ProjectManager.java @@ -18,14 +18,18 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Disposable; +import com.badlogic.gdx.utils.GdxRuntimeException; import com.mbrlabs.mundus.commons.Scene; import com.mbrlabs.mundus.commons.assets.Asset; import com.mbrlabs.mundus.commons.assets.AssetManager; import com.mbrlabs.mundus.commons.assets.AssetNotFoundException; import com.mbrlabs.mundus.commons.assets.ModelAsset; +import com.mbrlabs.mundus.commons.assets.SkyboxAsset; +import com.mbrlabs.mundus.commons.assets.TextureAsset; import com.mbrlabs.mundus.commons.assets.meta.MetaFileParseException; import com.mbrlabs.mundus.commons.dto.SceneDTO; import com.mbrlabs.mundus.commons.env.Fog; @@ -37,6 +41,7 @@ import com.mbrlabs.mundus.commons.scene3d.components.WaterComponent; import com.mbrlabs.mundus.editor.Main; import com.mbrlabs.mundus.editor.Mundus; +import com.mbrlabs.mundus.editor.assets.AssetAlreadyExistsException; import com.mbrlabs.mundus.editor.assets.EditorAssetManager; import com.mbrlabs.mundus.editor.core.EditorScene; import com.mbrlabs.mundus.editor.core.converter.SceneConverter; @@ -49,6 +54,7 @@ import com.mbrlabs.mundus.editor.events.ProjectChangedEvent; import com.mbrlabs.mundus.editor.events.SceneChangedEvent; import com.mbrlabs.mundus.editor.scene3d.components.PickableComponent; +import com.mbrlabs.mundus.editor.shader.Shaders; import com.mbrlabs.mundus.editor.utils.Log; import com.mbrlabs.mundus.editor.utils.SkyboxBuilder; @@ -132,7 +138,8 @@ public ProjectContext createProject(String name, String folder) { // create default scene & save .mundus EditorScene scene = new EditorScene(); scene.setName(DEFAULT_SCENE_NAME); - scene.skybox = SkyboxBuilder.createDefaultSkybox(); + scene.skybox = SkyboxBuilder.createDefaultSkybox(Shaders.INSTANCE.getSkyboxShader()); + scene.skyboxAssetId = getDefaultSkyboxAsset(newProjectContext, true).getID(); scene.environment.setFog(new Fog()); scene.setId(newProjectContext.obtainID()); SceneManager.saveScene(newProjectContext, scene); @@ -149,6 +156,45 @@ public ProjectContext createProject(String name, String folder) { return newProjectContext; } + /** + * Gets the default skybox, if it can be found. + * + * @param projectContext the project context to use + * @param createIfMissing if true, creates default skybox if it's missing + * @return skybox asset + */ + public SkyboxAsset getDefaultSkyboxAsset(ProjectContext projectContext, boolean createIfMissing) { + + // See if the default skybox already exists + SkyboxAsset defaultSkybox = (SkyboxAsset) projectContext.assetManager.findAssetByFileName("default.sky"); + + if (defaultSkybox == null && createIfMissing) { + FileHandle texture = Gdx.files.internal("textures/skybox/default/skybox_default.png"); + TextureAsset textureAsset = projectContext.assetManager.getOrCreateTextureAsset(texture); + + String id = textureAsset.getID(); + // Create it if it does not exist + try { + defaultSkybox = projectContext.assetManager.createSkyBoxAsset("default", id, id, id, id, id, id); + defaultSkybox.positiveX = textureAsset; + defaultSkybox.negativeX = textureAsset; + defaultSkybox.positiveY = textureAsset; + defaultSkybox.negativeY = textureAsset; + defaultSkybox.positiveZ = textureAsset; + defaultSkybox.negativeZ = textureAsset; + } catch (IOException e) { + e.printStackTrace(); + } catch (AssetAlreadyExistsException e) { + e.printStackTrace(); + } + + if (defaultSkybox == null) + throw new GdxRuntimeException("Unable to get or create default skybox."); + } + + return defaultSkybox; + } + /** * Imports (opens) a mundus project, that is not in the registry. * @@ -315,7 +361,9 @@ public Scene createScene(ProjectContext project, String name) { long id = project.obtainID(); scene.setId(id); scene.setName(name); - scene.skybox = SkyboxBuilder.createDefaultSkybox(); + scene.skyboxAssetId = getDefaultSkyboxAsset(project, false).getID(); + if (scene.skyboxAssetId != null) + scene.skybox = SkyboxBuilder.createDefaultSkybox(Shaders.INSTANCE.getSkyboxShader()); project.scenes.add(scene.getName()); SceneManager.saveScene(project, scene); @@ -339,7 +387,13 @@ public EditorScene loadScene(ProjectContext context, String sceneName) throws Fi SceneDTO sceneDTO = SceneManager.loadScene(context, sceneName); EditorScene scene = SceneConverter.convert(sceneDTO, context.assetManager.getAssetMap()); - scene.skybox = SkyboxBuilder.createDefaultSkybox(); + + // load skybox + if (scene.skyboxAssetId != null && context.assetManager.getAssetMap().containsKey(scene.skyboxAssetId)) { + SkyboxAsset asset = (SkyboxAsset) context.assetManager.getAssetMap().get(scene.skyboxAssetId); + scene.skybox = SkyboxBuilder.createSkyboxFromAsset(asset, Shaders.INSTANCE.getSkyboxShader()); + } + scene.batch = modelBatch; SceneGraph sceneGraph = scene.sceneGraph; diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt index 5fb7cac0a..22b53d3f7 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt @@ -16,18 +16,32 @@ package com.mbrlabs.mundus.editor.ui.modules.dialogs +import com.badlogic.gdx.files.FileHandle +import com.badlogic.gdx.scenes.scene2d.Actor import com.badlogic.gdx.scenes.scene2d.InputEvent +import com.badlogic.gdx.scenes.scene2d.Stage +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener import com.badlogic.gdx.scenes.scene2d.utils.ClickListener +import com.kotcrab.vis.ui.widget.VisDialog import com.kotcrab.vis.ui.widget.VisLabel +import com.kotcrab.vis.ui.widget.VisSelectBox import com.kotcrab.vis.ui.widget.VisTable import com.kotcrab.vis.ui.widget.VisTextButton +import com.kotcrab.vis.ui.widget.VisTextField +import com.mbrlabs.mundus.commons.assets.Asset +import com.mbrlabs.mundus.commons.assets.SkyboxAsset import com.mbrlabs.mundus.commons.skybox.Skybox import com.mbrlabs.mundus.editor.Mundus +import com.mbrlabs.mundus.editor.assets.AssetAlreadyExistsException import com.mbrlabs.mundus.editor.core.project.ProjectManager +import com.mbrlabs.mundus.editor.events.LogEvent +import com.mbrlabs.mundus.editor.events.LogType import com.mbrlabs.mundus.editor.events.ProjectChangedEvent import com.mbrlabs.mundus.editor.events.SceneChangedEvent +import com.mbrlabs.mundus.editor.shader.Shaders import com.mbrlabs.mundus.editor.ui.widgets.ImageChooserField import com.mbrlabs.mundus.editor.utils.createDefaultSkybox +import com.mbrlabs.mundus.editor.utils.createSkyboxFromAsset /** * @author Marcus Brummer @@ -36,6 +50,9 @@ import com.mbrlabs.mundus.editor.utils.createDefaultSkybox class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedListener, SceneChangedEvent.SceneChangedListener { + private lateinit var root: VisTable + private lateinit var selectBox: VisSelectBox + private val positiveX: ImageChooserField = ImageChooserField(100) private var negativeX: ImageChooserField = ImageChooserField(100) private var positiveY: ImageChooserField = ImageChooserField(100) @@ -44,9 +61,11 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis private var negativeZ: ImageChooserField = ImageChooserField(100) private var createBtn = VisTextButton("Create skybox") - private var defaultBtn = VisTextButton("Create default skybox") + private var defaultBtn = VisTextButton("Create default skybox") private var deletBtn = VisTextButton("Remove Skybox") + private var skyboxName = VisTextField() + private val projectManager: ProjectManager = Mundus.inject() init { @@ -57,55 +76,132 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis } private fun setupUI() { - positiveX.setButtonText("positiveX") - negativeX.setButtonText("negativeX") - positiveY.setButtonText("positiveY") - negativeY.setButtonText("negativeY") - positiveZ.setButtonText("positiveZ") - negativeZ.setButtonText("negativeZ") - - val root = VisTable() - // root.debugAll(); - root.padTop(6f).padRight(6f).padBottom(22f) + positiveX.setButtonText("Right (+X)") + negativeX.setButtonText("Left (-X)") + positiveY.setButtonText("Top (+Y)") + negativeY.setButtonText("Bottom (-Y)") + positiveZ.setButtonText("Front (+Z)") + negativeZ.setButtonText("Back (-Z)") + + root = VisTable() add(root).left().top() - root.add(VisLabel("The 6 images must be square and of equal size")).colspan(3).row() - root.addSeparator().colspan(3).row() - root.add(positiveX) - root.add(negativeX) - root.add(positiveY).row() - root.add(negativeY) - root.add(positiveZ) - root.add(negativeZ).row() - root.add(createBtn).padTop(15f).padLeft(6f).padRight(6f).expandX().fillX().colspan(3).row() + + root.add(VisLabel("Set Skybox")).left().row() + root.addSeparator().row() + + // Skybox selector + val selectorsTable = VisTable(true) + selectorsTable.add(VisLabel("Set Skybox From Existing:")) + selectBox = VisSelectBox() + selectorsTable.add(selectBox).left() + root.add(selectorsTable).row() + + // Image pickers + root.add(VisLabel("Create a Skybox")).left().padTop(10f).row() + val imageChooserTable = VisTable() + imageChooserTable.addSeparator().colspan(3).row() + imageChooserTable.add(VisLabel("The 6 images must be square and of equal size")).colspan(3).row() + imageChooserTable.padTop(6f).padRight(6f) + imageChooserTable.add(positiveX) + imageChooserTable.add(negativeX) + imageChooserTable.add(positiveY).row() + imageChooserTable.add(negativeY) + imageChooserTable.add(positiveZ) + imageChooserTable.add(negativeZ).row() + root.add(imageChooserTable).left().top().row() + + // Create skybox buttons + val createTable = VisTable() + createTable.defaults().padTop(15f).padLeft(6f).padRight(6f) + createTable.add(VisLabel("Skybox Name: ")).left() + createTable.add(skyboxName).row() + createTable.add(createBtn).colspan(2).center() + root.add(createTable).row() + + // Options + root.add(VisLabel("Options")).left().padTop(10f).row() + root.addSeparator().row() val tab = VisTable() - tab.add(defaultBtn).expandX().padRight(3f).fillX() - tab.add(deletBtn).expandX().fillX().padLeft(3f).row() - root.add(tab).fillX().expandX().padTop(5f).padLeft(6f).padRight(6f).colspan(3).row() + tab.defaults().padTop(15f).padLeft(6f).padRight(6f).padBottom(15f) + tab.add(defaultBtn).expandX().fillX() + tab.add(deletBtn).expandX().fillX().row() + root.add(tab).fillX().expandX().row() } private fun setupListeners() { - val projectContext = projectManager.current() + var projectContext = projectManager.current() + + // skybox select + selectBox.addListener(object : ChangeListener() { + override fun changed(event: ChangeEvent?, actor: Actor?) { + projectContext.currScene.skybox?.dispose() + + projectManager.current().currScene.skybox = createSkyboxFromAsset(selectBox.selected, Shaders.skyboxShader) + projectManager.current().currScene.skyboxAssetId = selectBox.selected.id + resetImages() + } + }) // create btn createBtn.addListener(object : ClickListener() { override fun clicked(event: InputEvent?, x: Float, y: Float) { + //TODO validations on name input and if .sky file already exists + // probably via listener on the name text field + val oldSkybox = projectContext.currScene.skybox oldSkybox?.dispose() + // Set actual skybox projectManager.current().currScene.skybox = Skybox(positiveX.file, negativeX.file, - positiveY.file, negativeY.file, positiveZ.file, negativeZ.file) + positiveY.file, negativeY.file, positiveZ.file, negativeZ.file, Shaders.skyboxShader) + + val files = ArrayList() + files.add(positiveX.file) + files.add(negativeX.file) + files.add(positiveY.file) + files.add(negativeY.file) + files.add(positiveZ.file) + files.add(negativeZ.file) + + val textureAssets = ArrayList() + + // Create texture assets for each skybox image + for (file in files) { + var asset: Asset + + try { + asset = projectManager.current().assetManager.createTextureAsset(file) + } catch (e: AssetAlreadyExistsException) { + Mundus.postEvent(LogEvent(LogType.ERROR, "Skybox texture already exists. " + file.name())) + asset = projectManager.current().assetManager.findAssetByFileName(file.name()) + } + + textureAssets.add(asset.id) + } + + // Create the skybox asset + val skyboxAsset = projectManager.current().assetManager.createSkyBoxAsset(skyboxName.text, textureAssets[0], textureAssets[1], + textureAssets[2], textureAssets[3], textureAssets[4], textureAssets[5]) + skyboxAsset.resolveDependencies(projectManager.current().assetManager.assetMap) + + projectManager.current().currScene.skyboxAssetId = skyboxAsset.id resetImages() + refreshSelectBox() } }) // default skybox btn defaultBtn.addListener(object : ClickListener() { override fun clicked(event: InputEvent?, x: Float, y: Float) { - if (projectContext.currScene.skybox != null) { - projectContext.currScene.skybox.dispose() - } - projectContext.currScene.skybox = createDefaultSkybox() + projectContext = projectManager.current() + projectContext.currScene.skybox?.dispose() + + projectContext.currScene.skybox = createDefaultSkybox(Shaders.skyboxShader) + val defaultSkybox = projectManager.getDefaultSkyboxAsset(projectContext, true) + + projectManager.current().currScene.skyboxAssetId = defaultSkybox.id + refreshSelectBox() resetImages() } }) @@ -113,14 +209,34 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis // delete skybox btn deletBtn.addListener(object : ClickListener() { override fun clicked(event: InputEvent?, x: Float, y: Float) { - projectContext.currScene.skybox.dispose() + projectContext = projectManager.current() + projectContext.currScene.skybox?.dispose() + projectContext.currScene.skybox = null + projectContext.currScene.skyboxAssetId = null resetImages() } }) } + override fun show(stage: Stage?): VisDialog { + // Update select box on dialog show + refreshSelectBox() + + return super.show(stage) + } + + private fun refreshSelectBox() { + val skyboxes = projectManager.current().assetManager.getSkyboxAssets() + val currentId = projectManager.current().currScene.skyboxAssetId + + // Refresh skyboxes + selectBox.items.clear() + selectBox.items = skyboxes + selectBox.selected = projectManager.current().assetManager.findAssetByID(currentId) as SkyboxAsset? + } + private fun resetImages() { val skybox = projectManager.current().currScene.skybox if (skybox != null) { @@ -128,7 +244,7 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis negativeX.setImage(skybox.negativeX) positiveY.setImage(skybox.positiveY) negativeY.setImage(skybox.negativeY) - positiveZ.setImage(skybox.positiveY) + positiveZ.setImage(skybox.positiveZ) negativeZ.setImage(skybox.negativeZ) } else { positiveX.setImage(null) diff --git a/editor/src/main/com/mbrlabs/mundus/editor/utils/SkyboxBuilder.kt b/editor/src/main/com/mbrlabs/mundus/editor/utils/SkyboxBuilder.kt index 7370a8d8c..f33c9fa47 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/utils/SkyboxBuilder.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/utils/SkyboxBuilder.kt @@ -19,16 +19,30 @@ package com.mbrlabs.mundus.editor.utils import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.g3d.Shader +import com.mbrlabs.mundus.commons.assets.SkyboxAsset import com.mbrlabs.mundus.commons.skybox.Skybox -fun createDefaultSkybox(): Skybox { +fun createDefaultSkybox(shader : Shader): Skybox { val texture = Gdx.files.internal("textures/skybox/default/skybox_default.png") - return Skybox(texture, texture, texture, texture, texture, texture) + return Skybox(texture, texture, texture, texture, texture, texture, + shader) } -fun createNightSkybox(): Skybox { +fun createNightSkybox(shader : Shader): Skybox { val texture = Gdx.files.internal("textures/skybox/star_night.png") - return Skybox(texture, texture, texture, texture, texture, texture) + return Skybox(texture, texture, texture, texture, texture, texture, + shader) +} + +fun createSkyboxFromAsset(skyboxAsset: SkyboxAsset, shader: Shader): Skybox { + return Skybox(skyboxAsset.positiveX.file, + skyboxAsset.negativeX.file, + skyboxAsset.positiveY.file, + skyboxAsset.negativeY.file, + skyboxAsset.positiveZ.file, + skyboxAsset.negativeZ.file, + shader) } From be653eb0b0229432210637a67c0fbee9769bd7fb Mon Sep 17 00:00:00 2001 From: James Date: Tue, 10 May 2022 15:20:41 -0400 Subject: [PATCH 2/5] Use Asset file, not meta, to store skybox data --- .../mundus/commons/assets/SkyboxAsset.java | 79 +++++++++++++--- .../mundus/commons/assets/meta/Meta.java | 9 -- .../commons/assets/meta/MetaLoader.java | 16 ---- .../commons/assets/meta/MetaSkybox.java | 89 ------------------- .../editor/assets/EditorAssetManager.kt | 25 +++++- .../mbrlabs/mundus/editor/assets/MetaSaver.kt | 16 ---- .../editor/ui/modules/dialogs/SkyboxDialog.kt | 1 - 7 files changed, 86 insertions(+), 149 deletions(-) delete mode 100644 commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaSkybox.java diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/SkyboxAsset.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/SkyboxAsset.java index 5c1b70ea5..c18862895 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/assets/SkyboxAsset.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/assets/SkyboxAsset.java @@ -1,12 +1,34 @@ package com.mbrlabs.mundus.commons.assets; import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.ObjectMap; +import com.badlogic.gdx.utils.PropertiesUtils; import com.mbrlabs.mundus.commons.assets.meta.Meta; +import java.io.IOException; +import java.io.Reader; import java.util.Map; public class SkyboxAsset extends Asset { + private static final ObjectMap MAP = new ObjectMap<>(); + + // property keys + public static final String PROP_POSITIVE_X = "positiveX"; + public static final String PROP_NEGATIVE_X = "negativeX"; + public static final String PROP_POSITIVE_Y = "positiveY"; + public static final String PROP_NEGATIVE_Y = "negativeY"; + public static final String PROP_POSITIVE_Z = "positiveZ"; + public static final String PROP_NEGATIVE_Z = "negativeZ"; + + // ids of dependent assets + public String positiveXID; + public String negativeXID; + public String positiveYID; + public String negativeYID; + public String positiveZID; + public String negativeZID; + public TextureAsset positiveX; public TextureAsset negativeX; public TextureAsset positiveY; @@ -20,34 +42,51 @@ public SkyboxAsset(Meta meta, FileHandle assetFile) { @Override public void load() { - // nothing to load for now + MAP.clear(); + try { + Reader reader = file.reader(); + PropertiesUtils.load(MAP, reader); + reader.close(); + + // asset dependencies, load ids + positiveXID = MAP.get(PROP_POSITIVE_X, null); + negativeXID = MAP.get(PROP_NEGATIVE_X, null); + + positiveYID = MAP.get(PROP_POSITIVE_Y, null); + negativeYID = MAP.get(PROP_NEGATIVE_Y, null); + + positiveZID = MAP.get(PROP_POSITIVE_Z, null); + negativeZID = MAP.get(PROP_NEGATIVE_Z, null); + } catch (IOException e) { + e.printStackTrace(); + } } @Override public void resolveDependencies(Map assets) { - if (assets.containsKey(meta.getMetaSkybox().getPositiveX())) { - positiveX = (TextureAsset) assets.get(meta.getMetaSkybox().getPositiveX()); + if (assets.containsKey(positiveXID)) { + positiveX = (TextureAsset) assets.get(positiveXID); } - if (assets.containsKey(meta.getMetaSkybox().getNegativeX())) { - negativeX = (TextureAsset) assets.get(meta.getMetaSkybox().getNegativeX()); + if (assets.containsKey(negativeXID)) { + negativeX = (TextureAsset) assets.get(negativeXID); } - if (assets.containsKey(meta.getMetaSkybox().getPositiveY())) { - positiveY = (TextureAsset) assets.get(meta.getMetaSkybox().getPositiveY()); + if (assets.containsKey(positiveYID)) { + positiveY = (TextureAsset) assets.get(positiveYID); } - if (assets.containsKey(meta.getMetaSkybox().getNegativeY())) { - negativeY = (TextureAsset) assets.get(meta.getMetaSkybox().getNegativeY()); + if (assets.containsKey(negativeYID)) { + negativeY = (TextureAsset) assets.get(negativeYID); } - if (assets.containsKey(meta.getMetaSkybox().getPositiveZ())) { - positiveZ = (TextureAsset) assets.get(meta.getMetaSkybox().getPositiveZ()); + if (assets.containsKey(positiveZID)) { + positiveZ = (TextureAsset) assets.get(positiveZID); } - if (assets.containsKey(meta.getMetaSkybox().getNegativeZ())) { - negativeZ = (TextureAsset) assets.get(meta.getMetaSkybox().getNegativeZ()); + if (assets.containsKey(negativeZID)) { + negativeZ = (TextureAsset) assets.get(negativeZID); } } @Override public void applyDependencies() { - + // not needed } @Override @@ -70,4 +109,16 @@ public boolean usesAsset(Asset assetToCheck) { return false; } + + /** + * Set TextureAsset Ids for the skybox. Useful for first initial creation of skybox + */ + public void setIds(String positiveX, String negativeX, String positiveY, String negativeY, String positiveZ, String negativeZ) { + this.positiveXID = positiveX; + this.negativeXID = negativeX; + this.positiveYID = positiveY; + this.negativeYID = negativeY; + this.positiveZID = positiveZ; + this.negativeZID = negativeZ; + } } diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/Meta.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/Meta.java index aae392182..f73497021 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/Meta.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/Meta.java @@ -47,7 +47,6 @@ public class Meta { private MetaModel model; private MetaTerrain terrain; private MetaWater water; - private MetaSkybox metaSkybox; private FileHandle file; @@ -115,14 +114,6 @@ public void setWater(MetaWater water) { this.water = water; } - public MetaSkybox getMetaSkybox() { - return metaSkybox; - } - - public void setMetaSkybox(MetaSkybox metaSkybox) { - this.metaSkybox = metaSkybox; - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaLoader.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaLoader.java index 444456c4c..f74451366 100644 --- a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaLoader.java +++ b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaLoader.java @@ -44,8 +44,6 @@ public Meta load(FileHandle file) throws MetaFileParseException { parseModel(meta, json.get(Meta.JSON_MODEL)); } else if(meta.getType() == AssetType.WATER) { parseWater(meta, json.get(Meta.JSON_WATER)); - } else if(meta.getType() == AssetType.SKYBOX) { - parseSkybox(meta, json.get(Meta.JSON_SKY_BOX)); } return meta; @@ -106,20 +104,6 @@ private void parseModel(Meta meta, JsonValue jsonModel) { meta.setModel(model); } - private void parseSkybox(Meta meta, JsonValue jsonValue) { - if(jsonValue == null) return; - - final MetaSkybox skybox = new MetaSkybox(); - skybox.setPositiveX(jsonValue.getString(MetaSkybox.JSON_POSITIVE_X)); - skybox.setNegativeX(jsonValue.getString(MetaSkybox.JSON_NEGATIVE_X)); - skybox.setPositiveY(jsonValue.getString(MetaSkybox.JSON_POSITIVE_Y)); - skybox.setNegativeY(jsonValue.getString(MetaSkybox.JSON_NEGATIVE_Y)); - skybox.setPositiveZ(jsonValue.getString(MetaSkybox.JSON_POSITIVE_Z)); - skybox.setNegativeZ(jsonValue.getString(MetaSkybox.JSON_NEGATIVE_Z)); - - meta.setMetaSkybox(skybox); - } - /** * When new values are added and cannot be found on jsonValue.getXXX(), * an IllegalArgumentException is thrown. diff --git a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaSkybox.java b/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaSkybox.java deleted file mode 100644 index a6d5ad536..000000000 --- a/commons/src/main/com/mbrlabs/mundus/commons/assets/meta/MetaSkybox.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.mbrlabs.mundus.commons.assets.meta; - -public class MetaSkybox { - public static final String JSON_POSITIVE_X = "positiveX"; - public static final String JSON_NEGATIVE_X = "negativeX"; - public static final String JSON_POSITIVE_Y = "positiveY"; - public static final String JSON_NEGATIVE_Y = "negativeY"; - public static final String JSON_POSITIVE_Z = "positiveZ"; - public static final String JSON_NEGATIVE_Z = "negativeZ"; - - public String positiveX; - public String negativeX; - public String positiveY; - public String negativeY; - public String positiveZ; - public String negativeZ; - - public MetaSkybox() { - } - - public MetaSkybox(String positiveX, String negativeX, String positiveY, String negativeY, String positiveZ, String negativeZ) { - this.positiveX = positiveX; - this.negativeX = negativeX; - this.positiveY = positiveY; - this.negativeY = negativeY; - this.positiveZ = positiveZ; - this.negativeZ = negativeZ; - } - - public String getPositiveX() { - return positiveX; - } - - public void setPositiveX(String positiveX) { - this.positiveX = positiveX; - } - - public String getNegativeX() { - return negativeX; - } - - public void setNegativeX(String negativeX) { - this.negativeX = negativeX; - } - - public String getPositiveY() { - return positiveY; - } - - public void setPositiveY(String positiveY) { - this.positiveY = positiveY; - } - - public String getNegativeY() { - return negativeY; - } - - public void setNegativeY(String negativeY) { - this.negativeY = negativeY; - } - - public String getPositiveZ() { - return positiveZ; - } - - public void setPositiveZ(String positiveZ) { - this.positiveZ = positiveZ; - } - - public String getNegativeZ() { - return negativeZ; - } - - public void setNegativeZ(String negativeZ) { - this.negativeZ = negativeZ; - } - - @Override - public String toString() { - return "MetaSkybox{" + - "positiveX='" + positiveX + '\'' + - ", negativeX='" + negativeX + '\'' + - ", positiveY='" + positiveY + '\'' + - ", negativeY='" + negativeY + '\'' + - ", positiveZ='" + positiveZ + '\'' + - ", negativeZ='" + negativeZ + '\'' + - '}'; - } -} diff --git a/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt b/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt index d1b5bc43c..748ad9202 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt @@ -26,7 +26,6 @@ import com.badlogic.gdx.utils.ObjectSet import com.kotcrab.vis.ui.util.dialog.Dialogs import com.mbrlabs.mundus.commons.assets.* import com.mbrlabs.mundus.commons.assets.meta.Meta -import com.mbrlabs.mundus.commons.assets.meta.MetaSkybox import com.mbrlabs.mundus.commons.assets.meta.MetaTerrain import com.mbrlabs.mundus.commons.assets.meta.MetaWater import com.mbrlabs.mundus.commons.scene3d.GameObject @@ -316,8 +315,6 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { // create meta file val metaPath = FilenameUtils.concat(rootFolder.path(), metaFilename) val meta = createNewMetaFile(FileHandle(metaPath), AssetType.SKYBOX) - meta.metaSkybox = MetaSkybox(positiveX, negativeX, - positiveY, negativeY, positiveZ, negativeZ) // create file val filePath = FilenameUtils.concat(rootFolder.path(), fileName) @@ -326,7 +323,9 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { // load & apply asset val asset = SkyboxAsset(meta, FileHandle(file)) - asset.load() + asset.setIds(positiveX, negativeX, + positiveY, negativeY, positiveZ, negativeZ) + asset.resolveDependencies(assetMap) saveAsset(asset) addAsset(asset) @@ -564,6 +563,24 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { } private fun saveSkyboxAsset(asset: SkyboxAsset) { + // save .sky + val props = Properties() + + props.setProperty(SkyboxAsset.PROP_POSITIVE_X, asset.positiveX.id) + props.setProperty(SkyboxAsset.PROP_NEGATIVE_X, asset.negativeX.id) + + props.setProperty(SkyboxAsset.PROP_POSITIVE_Y, asset.positiveY.id) + props.setProperty(SkyboxAsset.PROP_NEGATIVE_Y, asset.negativeY.id) + + props.setProperty(SkyboxAsset.PROP_POSITIVE_Z, asset.positiveZ.id) + props.setProperty(SkyboxAsset.PROP_NEGATIVE_Z, asset.negativeZ.id) + + val fileOutputStream = FileOutputStream(asset.file.file()) + props.store(fileOutputStream, null) + fileOutputStream.flush() + fileOutputStream.close() + + // save meta file metaSaver.save(asset.meta) } diff --git a/editor/src/main/com/mbrlabs/mundus/editor/assets/MetaSaver.kt b/editor/src/main/com/mbrlabs/mundus/editor/assets/MetaSaver.kt index 2a1a2ff8e..2d3661092 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/assets/MetaSaver.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/assets/MetaSaver.kt @@ -21,7 +21,6 @@ import com.badlogic.gdx.utils.JsonWriter import com.mbrlabs.mundus.commons.assets.AssetType import com.mbrlabs.mundus.commons.assets.meta.Meta import com.mbrlabs.mundus.commons.assets.meta.MetaModel -import com.mbrlabs.mundus.commons.assets.meta.MetaSkybox import com.mbrlabs.mundus.commons.assets.meta.MetaTerrain import com.mbrlabs.mundus.commons.assets.meta.MetaWater @@ -42,8 +41,6 @@ class MetaSaver { addModel(meta, json) } else if(meta.type == AssetType.WATER) { addWater(meta, json) - } else if(meta.type == AssetType.SKYBOX) { - addSkyBox(meta, json) } json.writeObjectEnd() @@ -106,17 +103,4 @@ class MetaSaver { json.writeObjectEnd() } - private fun addSkyBox(meta: Meta, json: Json) { - val skybox = meta.metaSkybox ?: return - json.writeObjectStart(Meta.JSON_SKY_BOX) - - json.writeValue(MetaSkybox.JSON_POSITIVE_X, skybox.positiveX) - json.writeValue(MetaSkybox.JSON_NEGATIVE_X, skybox.negativeX) - json.writeValue(MetaSkybox.JSON_POSITIVE_Y, skybox.positiveY) - json.writeValue(MetaSkybox.JSON_NEGATIVE_Y, skybox.negativeY) - json.writeValue(MetaSkybox.JSON_POSITIVE_Z, skybox.positiveZ) - json.writeValue(MetaSkybox.JSON_NEGATIVE_Z, skybox.negativeZ) - } - - } \ No newline at end of file diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt index 22b53d3f7..12da4da35 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt @@ -183,7 +183,6 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis // Create the skybox asset val skyboxAsset = projectManager.current().assetManager.createSkyBoxAsset(skyboxName.text, textureAssets[0], textureAssets[1], textureAssets[2], textureAssets[3], textureAssets[4], textureAssets[5]) - skyboxAsset.resolveDependencies(projectManager.current().assetManager.assetMap) projectManager.current().currScene.skyboxAssetId = skyboxAsset.id resetImages() From 0f7d4ebe2da4e896622d8670459b1af92a1ed4e3 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 10 May 2022 16:14:40 -0400 Subject: [PATCH 3/5] Handle skybox usage deletion --- .../editor/assets/EditorAssetManager.kt | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt b/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt index 748ad9202..e46747b36 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/assets/EditorAssetManager.kt @@ -389,14 +389,20 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { * Delete the asset from the project */ fun deleteAsset(asset: Asset, projectManager: ProjectManager) { - val objectsUsingAsset = findAssetUsagesInScenes(projectManager, asset) - val assetsUsingAsset = findAssetUsagesInAssets(asset) - - //TODO check for SkyboxAsset usages + if (asset is SkyboxAsset) { + val skyboxUsages = findSkyboxUsagesInScenes(projectManager, asset) + if (skyboxUsages.isNotEmpty()) { + Dialogs.showDetailsDialog(UI, "Before deleting a skybox, remove usages of the skybox and save the scene. See details for usages.", "Asset deletion", skyboxUsages.toString()) + return + } + } else { + val objectsUsingAsset = findAssetUsagesInScenes(projectManager, asset) + val assetsUsingAsset = findAssetUsagesInAssets(asset) - if (objectsUsingAsset.isNotEmpty() || assetsUsingAsset.isNotEmpty()) { - showUsagesFoundDialog(objectsUsingAsset, assetsUsingAsset) - return + if (objectsUsingAsset.isNotEmpty() || assetsUsingAsset.isNotEmpty()) { + showUsagesFoundDialog(objectsUsingAsset, assetsUsingAsset) + return + } } // continue with deletion @@ -501,6 +507,20 @@ class EditorAssetManager(assetsRoot: FileHandle) : AssetManager(assetsRoot) { } } + private fun findSkyboxUsagesInScenes(projectManager: ProjectManager, asset: SkyboxAsset): ArrayList { + val scenesWithSkybox = ArrayList() + + // we check for usages in all scenes + for (sceneName in projectManager.current().scenes) { + val scene = projectManager.loadScene(projectManager.current(), sceneName) + if (scene.skyboxAssetId == asset.id) { + scenesWithSkybox.add(scene.name) + } + } + + return scenesWithSkybox + } + /** * Saves an existing terrainAsset asset. * From 55f929b2ce675d26bfd44deb42943fe4b6ea0d49 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 10 May 2022 19:23:44 -0400 Subject: [PATCH 4/5] Add validations for skybox creation --- .../editor/ui/modules/dialogs/SkyboxDialog.kt | 76 +++++++++++++++++-- .../editor/ui/widgets/ImageChooserField.java | 19 ++++- 2 files changed, 85 insertions(+), 10 deletions(-) diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt index 12da4da35..1a96504d1 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt @@ -22,6 +22,7 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent import com.badlogic.gdx.scenes.scene2d.Stage import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener import com.badlogic.gdx.scenes.scene2d.utils.ClickListener +import com.kotcrab.vis.ui.util.dialog.Dialogs import com.kotcrab.vis.ui.widget.VisDialog import com.kotcrab.vis.ui.widget.VisLabel import com.kotcrab.vis.ui.widget.VisSelectBox @@ -48,17 +49,17 @@ import com.mbrlabs.mundus.editor.utils.createSkyboxFromAsset * @version 10-01-2016 */ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedListener, - SceneChangedEvent.SceneChangedListener { + SceneChangedEvent.SceneChangedListener, ImageChooserField.ImageChosenListener { private lateinit var root: VisTable private lateinit var selectBox: VisSelectBox - private val positiveX: ImageChooserField = ImageChooserField(100) - private var negativeX: ImageChooserField = ImageChooserField(100) - private var positiveY: ImageChooserField = ImageChooserField(100) - private var negativeY: ImageChooserField = ImageChooserField(100) - private var positiveZ: ImageChooserField = ImageChooserField(100) - private var negativeZ: ImageChooserField = ImageChooserField(100) + private val positiveX: ImageChooserField = ImageChooserField(100, this) + private var negativeX: ImageChooserField = ImageChooserField(100, this) + private var positiveY: ImageChooserField = ImageChooserField(100, this) + private var negativeY: ImageChooserField = ImageChooserField(100, this) + private var positiveZ: ImageChooserField = ImageChooserField(100, this) + private var negativeZ: ImageChooserField = ImageChooserField(100, this) private var createBtn = VisTextButton("Create skybox") private var defaultBtn = VisTextButton("Create default skybox") @@ -127,6 +128,9 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis tab.add(defaultBtn).expandX().fillX() tab.add(deletBtn).expandX().fillX().row() root.add(tab).fillX().expandX().row() + + // Disable by default until name field is populated + createBtn.isDisabled = true } private fun setupListeners() { @@ -143,9 +147,31 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis } }) + // Name field listener for enabling create button + skyboxName.addListener(object : ChangeListener() { + override fun changed(event: ChangeEvent?, actor: Actor?) { + validateFields() + } + }) + // create btn createBtn.addListener(object : ClickListener() { override fun clicked(event: InputEvent?, x: Float, y: Float) { + if (createBtn.isDisabled) + return + + // check if skybox asset with same name exists + for (asset in projectManager.current().assetManager.getSkyboxAssets()) { + // drop the .sky file extension + val name = asset.name.dropLast(4) + + if (name == skyboxName.text) { + skyboxName.isInputValid = false + Dialogs.showErrorDialog(stage, "A skybox with the same name already exists.") + return + } + } + //TODO validations on name input and if .sky file already exists // probably via listener on the name text field @@ -219,6 +245,35 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis } + /** + * Validate fields for Skybox creation. Checks the Name field + * and image fields than disables/enables the create button accordingly. + */ + private fun validateFields() { + skyboxName.isInputValid = !skyboxName.isEmpty + + if (skyboxName.isEmpty || !imagesValid()) { + createBtn.isDisabled = true + return + } + + createBtn.isDisabled = false + } + + /** + * Validates images in the Image Choosers. If any image is null + * then it returns false. + */ + private fun imagesValid(): Boolean { + if (null === positiveX.file || null === negativeX.file || + null === positiveY.file || null === negativeY.file || + null === positiveZ.file || null === negativeZ.file) { + + return false + } + return true + } + override fun show(stage: Stage?): VisDialog { // Update select box on dialog show refreshSelectBox() @@ -252,6 +307,9 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis negativeY.setImage(null) positiveZ.setImage(null) negativeZ.setImage(null) + + // Cannot create if no images set + createBtn.isDisabled = true } } @@ -263,4 +321,8 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis resetImages() } + override fun onImageChosen() { + validateFields() + } + } diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/widgets/ImageChooserField.java b/editor/src/main/com/mbrlabs/mundus/editor/ui/widgets/ImageChooserField.java index f078cc076..9612f9839 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/ui/widgets/ImageChooserField.java +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/widgets/ImageChooserField.java @@ -42,14 +42,16 @@ public class ImageChooserField extends VisTable { private static final Drawable PLACEHOLDER_IMG = new TextureRegionDrawable( new TextureRegion(new Texture(Gdx.files.internal("ui/img_placeholder.png")))); - private int width; + private final int width; - private VisTextButton fcBtn; + private final VisTextButton fcBtn; - private Image img; + private final Image img; private Texture texture; private FileHandle fileHandle; + private ImageChosenListener listener = null; + public ImageChooserField(int width) { super(); this.width = width; @@ -60,6 +62,11 @@ public ImageChooserField(int width) { setupListeners(); } + public ImageChooserField(int width, ImageChosenListener listener) { + this(width); + this.listener = listener; + } + public FileHandle getFile() { return this.fileHandle; } @@ -104,6 +111,8 @@ public void clicked(InputEvent event, float x, float y) { public void selected(FileHandle file) { if (FileFormatUtils.isImage(file)) { setImage(file); + if (listener != null) + listener.onImageChosen(); } else { Dialogs.showErrorDialog(UI.INSTANCE, "This is no image"); } @@ -114,4 +123,8 @@ public void selected(FileHandle file) { }); } + public interface ImageChosenListener { + void onImageChosen(); + } + } From 0f1bb84353096d154050a076256ba1c777f37aef Mon Sep 17 00:00:00 2001 From: James Date: Tue, 10 May 2022 23:40:08 -0400 Subject: [PATCH 5/5] remove completed todo --- .../mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt index 1a96504d1..54d38f238 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dialogs/SkyboxDialog.kt @@ -172,9 +172,6 @@ class SkyboxDialog : BaseDialog("Skybox"), ProjectChangedEvent.ProjectChangedLis } } - //TODO validations on name input and if .sky file already exists - // probably via listener on the name text field - val oldSkybox = projectContext.currScene.skybox oldSkybox?.dispose()