From 454a0904434a3a11937c8763a4b1712bd3368079 Mon Sep 17 00:00:00 2001 From: Ryu Seowoong Date: Wed, 8 Oct 2025 20:23:50 +0900 Subject: [PATCH 1/5] fix: all entities, including players, held items become white, losing textures reformatted codes --- README.md | 16 +- build.gradle | 108 +- gradle.properties | 19 +- .../util/mikktspace/MikkTSpaceContext.java | 34 +- .../MikktspaceTangentGenerator.java | 110 +- .../com/jme3/util/mikktspace/Vector3f.java | 180 +- .../modularmods/mcgltf/AccessorDataUtils.java | 187 +- .../mcgltf/AccessorModelCreation.java | 93 +- .../mcgltf/IGltfModelReceiver.java | 19 +- .../java/com/modularmods/mcgltf/MCglTF.java | 890 +- .../modularmods/mcgltf/RenderedGltfModel.java | 10092 ++++++++-------- .../mcgltf/RenderedGltfModelGL30.java | 209 +- .../mcgltf/RenderedGltfModelGL33.java | 2268 ++-- .../mcgltf/RenderedGltfModelGL40.java | 367 +- .../modularmods/mcgltf/RenderedGltfScene.java | 214 +- .../mcgltf/RenderedGltfSceneGL30.java | 156 +- .../mcgltf/RenderedGltfSceneGL33.java | 197 +- .../mcgltf/RenderedGltfSceneGL40.java | 202 +- .../CubicSplineInterpolatedChannel.java | 104 +- .../animation/GltfAnimationCreator.java | 740 +- .../mcgltf/animation/InterpolatedChannel.java | 70 +- .../animation/LinearInterpolatedChannel.java | 74 +- .../SphericalLinearInterpolatedChannel.java | 142 +- .../animation/StepInterpolatedChannel.java | 32 +- .../mcgltf/iris/IrisRenderingHook.java | 378 +- .../iris/RenderedGltfModelGL30Iris.java | 142 +- .../iris/RenderedGltfModelGL33Iris.java | 150 +- .../iris/RenderedGltfModelGL40Iris.java | 150 +- .../mcgltf/iris/RenderedGltfModelIris.java | 417 +- .../iris/RenderedGltfSceneGL30Iris.java | 30 +- .../iris/RenderedGltfSceneGL33Iris.java | 71 +- .../iris/RenderedGltfSceneGL40Iris.java | 76 +- .../mcgltf/iris/RenderedGltfSceneIris.java | 76 +- .../iris/mixin/IrisCompatMixinPlugin.java | 51 +- .../iris/mixin/MixinBufferUploader.java | 15 +- .../iris/mixin/MixinRenderStateShard.java | 14 +- .../mcgltf/iris/mixin/MixinVertexBuffer.java | 13 +- .../de/javagl/jgltf/impl/v1/Accessor.java | 388 +- .../de/javagl/jgltf/impl/v1/Animation.java | 281 +- .../jgltf/impl/v1/AnimationChannel.java | 76 +- .../jgltf/impl/v1/AnimationChannelTarget.java | 84 +- .../jgltf/impl/v1/AnimationSampler.java | 140 +- .../java/de/javagl/jgltf/impl/v1/Asset.java | 190 +- .../de/javagl/jgltf/impl/v1/AssetProfile.java | 104 +- .../java/de/javagl/jgltf/impl/v1/Buffer.java | 150 +- .../de/javagl/jgltf/impl/v1/BufferView.java | 172 +- .../java/de/javagl/jgltf/impl/v1/Camera.java | 128 +- .../jgltf/impl/v1/CameraOrthographic.java | 144 +- .../jgltf/impl/v1/CameraPerspective.java | 166 +- .../java/de/javagl/jgltf/impl/v1/GlTF.java | 1383 ++- .../impl/v1/GlTFChildOfRootProperty.java | 42 +- .../de/javagl/jgltf/impl/v1/GlTFProperty.java | 100 +- .../java/de/javagl/jgltf/impl/v1/Image.java | 46 +- .../de/javagl/jgltf/impl/v1/Material.java | 113 +- .../java/de/javagl/jgltf/impl/v1/Mesh.java | 113 +- .../javagl/jgltf/impl/v1/MeshPrimitive.java | 209 +- .../java/de/javagl/jgltf/impl/v1/Node.java | 627 +- .../java/de/javagl/jgltf/impl/v1/Program.java | 157 +- .../java/de/javagl/jgltf/impl/v1/Sampler.java | 242 +- .../java/de/javagl/jgltf/impl/v1/Scene.java | 99 +- .../java/de/javagl/jgltf/impl/v1/Shader.java | 84 +- .../java/de/javagl/jgltf/impl/v1/Skin.java | 195 +- .../de/javagl/jgltf/impl/v1/Technique.java | 323 +- .../jgltf/impl/v1/TechniqueParameters.java | 198 +- .../javagl/jgltf/impl/v1/TechniqueStates.java | 151 +- .../impl/v1/TechniqueStatesFunctions.java | 918 +- .../java/de/javagl/jgltf/impl/v1/Texture.java | 290 +- .../de/javagl/jgltf/impl/v2/Accessor.java | 404 +- .../javagl/jgltf/impl/v2/AccessorSparse.java | 132 +- .../jgltf/impl/v2/AccessorSparseIndices.java | 166 +- .../jgltf/impl/v2/AccessorSparseValues.java | 122 +- .../de/javagl/jgltf/impl/v2/Animation.java | 215 +- .../jgltf/impl/v2/AnimationChannel.java | 78 +- .../jgltf/impl/v2/AnimationChannelTarget.java | 126 +- .../jgltf/impl/v2/AnimationSampler.java | 134 +- .../java/de/javagl/jgltf/impl/v2/Asset.java | 142 +- .../java/de/javagl/jgltf/impl/v2/Buffer.java | 82 +- .../de/javagl/jgltf/impl/v2/BufferView.java | 218 +- .../java/de/javagl/jgltf/impl/v2/Camera.java | 140 +- .../jgltf/impl/v2/CameraOrthographic.java | 180 +- .../jgltf/impl/v2/CameraPerspective.java | 170 +- .../java/de/javagl/jgltf/impl/v2/GlTF.java | 1393 ++- .../impl/v2/GlTFChildOfRootProperty.java | 42 +- .../de/javagl/jgltf/impl/v2/GlTFProperty.java | 100 +- .../java/de/javagl/jgltf/impl/v2/Image.java | 114 +- .../de/javagl/jgltf/impl/v2/Material.java | 356 +- .../impl/v2/MaterialNormalTextureInfo.java | 64 +- .../impl/v2/MaterialOcclusionTextureInfo.java | 80 +- .../impl/v2/MaterialPbrMetallicRoughness.java | 276 +- .../java/de/javagl/jgltf/impl/v2/Mesh.java | 201 +- .../javagl/jgltf/impl/v2/MeshPrimitive.java | 299 +- .../java/de/javagl/jgltf/impl/v2/Node.java | 593 +- .../java/de/javagl/jgltf/impl/v2/Sampler.java | 202 +- .../java/de/javagl/jgltf/impl/v2/Scene.java | 105 +- .../java/de/javagl/jgltf/impl/v2/Skin.java | 157 +- .../java/de/javagl/jgltf/impl/v2/Texture.java | 94 +- .../de/javagl/jgltf/impl/v2/TextureInfo.java | 102 +- .../jgltf/model/AbstractAccessorData.java | 142 +- .../javagl/jgltf/model/AccessorByteData.java | 265 +- .../de/javagl/jgltf/model/AccessorData.java | 29 +- .../de/javagl/jgltf/model/AccessorDatas.java | 639 +- .../javagl/jgltf/model/AccessorFloatData.java | 202 +- .../javagl/jgltf/model/AccessorIntData.java | 267 +- .../de/javagl/jgltf/model/AccessorModel.java | 97 +- .../javagl/jgltf/model/AccessorShortData.java | 269 +- .../java/de/javagl/jgltf/model/Accessors.java | 149 +- .../de/javagl/jgltf/model/AnimationModel.java | 58 +- .../de/javagl/jgltf/model/AssetModel.java | 13 +- .../de/javagl/jgltf/model/BoundingBox.java | 77 +- .../jgltf/model/BoundingBoxComputer.java | 189 +- .../de/javagl/jgltf/model/BoundingBoxes.java | 43 +- .../de/javagl/jgltf/model/BufferModel.java | 21 +- .../javagl/jgltf/model/BufferViewModel.java | 31 +- .../de/javagl/jgltf/model/CameraModel.java | 41 +- .../jgltf/model/CameraOrthographicModel.java | 17 +- .../jgltf/model/CameraPerspectiveModel.java | 19 +- .../de/javagl/jgltf/model/ElementType.java | 131 +- .../javagl/jgltf/model/ExtensionsModel.java | 11 +- .../de/javagl/jgltf/model/GltfAnimations.java | 311 +- .../de/javagl/jgltf/model/GltfConstants.java | 440 +- .../de/javagl/jgltf/model/GltfException.java | 19 +- .../java/de/javagl/jgltf/model/GltfModel.java | 69 +- .../de/javagl/jgltf/model/GltfModels.java | 39 +- .../java/de/javagl/jgltf/model/GltfUtils.java | 33 +- .../de/javagl/jgltf/model/ImageModel.java | 23 +- .../de/javagl/jgltf/model/MaterialModel.java | 3 +- .../java/de/javagl/jgltf/model/MathUtils.java | 741 +- .../java/de/javagl/jgltf/model/MeshModel.java | 13 +- .../jgltf/model/MeshPrimitiveModel.java | 23 +- .../de/javagl/jgltf/model/ModelElement.java | 11 +- .../javagl/jgltf/model/NamedModelElement.java | 5 +- .../java/de/javagl/jgltf/model/NodeModel.java | 149 +- .../de/javagl/jgltf/model/NumberArrays.java | 47 +- .../java/de/javagl/jgltf/model/Optionals.java | 119 +- .../de/javagl/jgltf/model/SceneModel.java | 7 +- .../java/de/javagl/jgltf/model/SkinModel.java | 39 +- .../java/de/javagl/jgltf/model/Suppliers.java | 38 +- .../de/javagl/jgltf/model/TextureModel.java | 15 +- .../java/de/javagl/jgltf/model/Utils.java | 28 +- .../jgltf/model/animation/Animation.java | 114 +- .../model/animation/AnimationListener.java | 9 +- .../model/animation/AnimationManager.java | 210 +- .../animation/AnimationManagerListener.java | 5 +- .../model/animation/AnimationRunner.java | 65 +- .../jgltf/model/animation/Interpolator.java | 21 +- .../model/animation/InterpolatorKeys.java | 57 +- .../model/animation/InterpolatorType.java | 11 +- .../jgltf/model/animation/Interpolators.java | 35 +- .../model/animation/LinearInterpolator.java | 11 +- .../SlerpQuaternionInterpolator.java | 24 +- .../model/animation/StepInterpolator.java | 6 +- .../model/extensions/GltfExtensions.java | 106 +- .../jgltf/model/extensions/package-info.java | 2 +- .../javagl/jgltf/model/gl/ProgramModel.java | 19 +- .../de/javagl/jgltf/model/gl/Semantic.java | 61 +- .../de/javagl/jgltf/model/gl/ShaderModel.java | 58 +- .../javagl/jgltf/model/gl/TechniqueModel.java | 43 +- .../model/gl/TechniqueParametersModel.java | 25 +- .../gl/TechniqueStatesFunctionsModel.java | 49 +- .../jgltf/model/gl/TechniqueStatesModel.java | 53 +- .../model/gl/impl/DefaultProgramModel.java | 70 +- .../model/gl/impl/DefaultShaderModel.java | 65 +- .../model/gl/impl/DefaultTechniqueModel.java | 126 +- .../impl/DefaultTechniqueParametersModel.java | 47 +- .../DefaultTechniqueStatesFunctionsModel.java | 74 +- .../gl/impl/DefaultTechniqueStatesModel.java | 33 +- .../model/gl/impl/TechniqueStatesModels.java | 66 +- .../jgltf/model/gl/impl/package-info.java | 2 +- .../javagl/jgltf/model/gl/package-info.java | 2 +- .../jgltf/model/image/DefaultPixelData.java | 29 +- .../jgltf/model/image/ImageReaders.java | 53 +- .../javagl/jgltf/model/image/ImageUtils.java | 228 +- .../javagl/jgltf/model/image/PixelData.java | 11 +- .../javagl/jgltf/model/image/PixelDatas.java | 52 +- .../model/impl/AbstractModelElement.java | 83 +- .../model/impl/AbstractNamedModelElement.java | 19 +- .../de/javagl/jgltf/model/impl/Cameras.java | 96 +- .../model/impl/DefaultAccessorModel.java | 207 +- .../model/impl/DefaultAnimationModel.java | 162 +- .../jgltf/model/impl/DefaultAssetModel.java | 29 +- .../jgltf/model/impl/DefaultBufferModel.java | 59 +- .../model/impl/DefaultBufferViewModel.java | 146 +- .../jgltf/model/impl/DefaultCameraModel.java | 69 +- .../impl/DefaultCameraOrthographicModel.java | 67 +- .../impl/DefaultCameraPerspectiveModel.java | 67 +- .../model/impl/DefaultExtensionsModel.java | 79 +- .../jgltf/model/impl/DefaultGltfModel.java | 384 +- .../jgltf/model/impl/DefaultImageModel.java | 99 +- .../jgltf/model/impl/DefaultMeshModel.java | 54 +- .../model/impl/DefaultMeshPrimitiveModel.java | 121 +- .../jgltf/model/impl/DefaultNodeModel.java | 430 +- .../jgltf/model/impl/DefaultSceneModel.java | 30 +- .../jgltf/model/impl/DefaultSkinModel.java | 121 +- .../jgltf/model/impl/DefaultTextureModel.java | 78 +- .../javagl/jgltf/model/impl/UriStrings.java | 127 +- .../javagl/jgltf/model/impl/package-info.java | 2 +- .../de/javagl/jgltf/model/io/Buffers.java | 245 +- .../jgltf/model/io/ByteBufferInputStream.java | 28 +- .../de/javagl/jgltf/model/io/GltfAsset.java | 35 +- .../jgltf/model/io/GltfAssetReader.java | 102 +- .../jgltf/model/io/GltfAssetWriter.java | 174 +- .../de/javagl/jgltf/model/io/GltfAssets.java | 108 +- .../jgltf/model/io/GltfModelReader.java | 98 +- .../jgltf/model/io/GltfModelWriter.java | 149 +- .../de/javagl/jgltf/model/io/GltfReader.java | 144 +- .../javagl/jgltf/model/io/GltfReference.java | 47 +- .../jgltf/model/io/GltfReferenceResolver.java | 82 +- .../de/javagl/jgltf/model/io/GltfWriter.java | 58 +- .../java/de/javagl/jgltf/model/io/IO.java | 326 +- .../de/javagl/jgltf/model/io/MimeTypes.java | 177 +- .../jgltf/model/io/ProgressInputStream.java | 94 +- .../de/javagl/jgltf/model/io/RawGltfData.java | 47 +- .../jgltf/model/io/RawGltfDataReader.java | 53 +- .../javagl/jgltf/model/io/UriResolvers.java | 162 +- .../javagl/jgltf/model/io/VersionUtils.java | 54 +- .../javagl/jgltf/model/io/package-info.java | 2 +- .../model/io/v1/BinaryAssetCreatorV1.java | 305 +- .../model/io/v1/DefaultAssetCreatorV1.java | 237 +- .../model/io/v1/EmbeddedAssetCreatorV1.java | 198 +- .../javagl/jgltf/model/io/v1/GltfAssetV1.java | 145 +- .../jgltf/model/io/v1/GltfAssetWriterV1.java | 59 +- .../jgltf/model/io/v1/GltfAssetsV1.java | 45 +- .../jgltf/model/io/v1/GltfModelWriterV1.java | 77 +- .../jgltf/model/io/v1/GltfReaderV1.java | 30 +- .../javagl/jgltf/model/io/v1/GltfUtilsV1.java | 82 +- .../io/v1/RawBinaryGltfDataReaderV1.java | 65 +- .../model/io/v2/BinaryAssetCreatorV2.java | 233 +- .../model/io/v2/DefaultAssetCreatorV2.java | 147 +- .../model/io/v2/EmbeddedAssetCreatorV2.java | 142 +- .../javagl/jgltf/model/io/v2/GltfAssetV2.java | 117 +- .../jgltf/model/io/v2/GltfAssetWriterV2.java | 112 +- .../jgltf/model/io/v2/GltfAssetsV2.java | 45 +- .../jgltf/model/io/v2/GltfModelWriterV2.java | 61 +- .../jgltf/model/io/v2/GltfReaderV2.java | 30 +- .../javagl/jgltf/model/io/v2/GltfUtilsV2.java | 43 +- .../io/v2/RawBinaryGltfDataReaderV2.java | 131 +- .../de/javagl/jgltf/model/package-info.java | 2 +- .../javagl/jgltf/model/v1/BinaryGltfV1.java | 137 +- .../javagl/jgltf/model/v1/GltfCreatorV1.java | 1329 +- .../jgltf/model/v1/GltfExtensionsV1.java | 171 +- .../de/javagl/jgltf/model/v1/GltfIds.java | 48 +- .../jgltf/model/v1/GltfModelCreatorV1.java | 1562 +-- .../de/javagl/jgltf/model/v1/GltfModelV1.java | 140 +- .../jgltf/model/v1/IndexMappingSet.java | 55 +- .../jgltf/model/v1/IndexMappingSets.java | 25 +- .../javagl/jgltf/model/v1/IndexMappings.java | 39 +- .../jgltf/model/v1/MaterialModelV1.java | 87 +- .../jgltf/model/v1/gl/DefaultModels.java | 208 +- .../jgltf/model/v1/gl/GltfDefaults.java | 124 +- .../javagl/jgltf/model/v1/gl/Materials.java | 33 +- .../de/javagl/jgltf/model/v1/gl/Programs.java | 35 +- .../de/javagl/jgltf/model/v1/gl/Shaders.java | 110 +- .../v1/gl/TechniqueStatesFunctionsModels.java | 51 +- .../javagl/jgltf/model/v1/gl/Techniques.java | 173 +- .../jgltf/model/v2/AccessorSparseUtils.java | 369 +- .../javagl/jgltf/model/v2/GltfCreatorV2.java | 1164 +- .../jgltf/model/v2/GltfModelCreatorV2.java | 1214 +- .../jgltf/model/v2/MaterialModelV2.java | 300 +- .../javagl/jgltf/model/v2/gl/Materials.java | 38 +- src/main/java/simplelibs/SimpleConfig.java | 198 +- src/main/resources/fabric.mod.json | 7 +- src/main/resources/mcgltf.iris.mixins.json | 4 +- 262 files changed, 25100 insertions(+), 28171 deletions(-) diff --git a/README.md b/README.md index b617f79..279eebd 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,37 @@ # MCglTF -A 3D model loader library which load glTF format file and prepare the required techniques to render the model for Minecraft Modding enviroment. + +A 3D model loader library which load glTF format file and prepare the required techniques to render the model for +Minecraft Modding enviroment. Various features from glTF spec are available but still remain a good compatibility and performance. [![](https://cf.way2muchnoise.eu/title/mcgltf.svg)](https://www.curseforge.com/minecraft/mc-mods/mcgltf) [![](https://cf.way2muchnoise.eu/versions/mcgltf.svg)](https://www.curseforge.com/minecraft/mc-mods/mcgltf) [![](https://cf.way2muchnoise.eu/mcgltf.svg)](https://www.curseforge.com/minecraft/mc-mods/mcgltf) + ## Usages + The example codes for rendering Block, Item, and Entity + - https://github.com/ModularMods/MCglTF-Example + ## Features + - [x] GLTF format (Embedded resources or via ResourceLocation) - [x] GLB format - [x] UVs - [x] Normals - [x] Tangents - [x] Vertex colors -- [x] Materials (Require [OptiFine](https://github.com/ModularMods/MCglTF/wiki/How-to-make-PBR-Materials-working-with-OptiFine) or [Iris Shaders](https://github.com/ModularMods/MCglTF/wiki/How-to-make-PBR-Materials-working-with-Iris-Shaders) and supported ShaderPack for PBR and Normal map) +- [x] Materials ( + Require [OptiFine](https://github.com/ModularMods/MCglTF/wiki/How-to-make-PBR-Materials-working-with-OptiFine) + or [Iris Shaders](https://github.com/ModularMods/MCglTF/wiki/How-to-make-PBR-Materials-working-with-Iris-Shaders) and + supported ShaderPack for PBR and Normal map) - [x] Textures - [ ] Mutiple texture coordinates (For compatibility reason with Vanilla) - [x] Rig - [x] Animations (multiple) - [x] Morph targets - [x] Zero-scale node culling (https://github.com/KhronosGroup/glTF/pull/2059) + ## Credit + - JglTF by javagl : https://github.com/javagl/JglTF - Mikk Tangent Generator by jMonkeyEngine : https://github.com/jMonkeyEngine/jmonkeyengine \ No newline at end of file diff --git a/build.gradle b/build.gradle index 1523221..8e36018 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { - id 'fabric-loom' version '1.0-SNAPSHOT' - id 'maven-publish' + id 'fabric-loom' version '1.0-SNAPSHOT' + id 'maven-publish' } sourceCompatibility = JavaVersion.VERSION_17 @@ -11,80 +11,80 @@ version = project.mod_version group = project.maven_group repositories { - // Add repositories to retrieve artifacts from in here. - // You should only use this when depending on other mods because - // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html - // for more information about repositories. - maven { - name = "Modrinth" - url = "https://api.modrinth.com/maven" - - content { - includeGroup "maven.modrinth" - } - } - flatDir { - dirs 'libs' - } + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. + maven { + name = "Modrinth" + url = "https://api.modrinth.com/maven" + + content { + includeGroup "maven.modrinth" + } + } + flatDir { + dirs 'libs' + } } dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings loom.officialMojangMappings() - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings loom.officialMojangMappings() + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - // Uncomment the following line to enable the deprecated Fabric API modules. - // These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. + // Uncomment the following line to enable the deprecated Fabric API modules. + // These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. - // modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}" - modImplementation "maven.modrinth:iris:${project.iris_version}" + // modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}" + modImplementation "maven.modrinth:iris:${project.iris_version}" } processResources { - inputs.property "version", project.version + inputs.property "version", project.version - filesMatching("fabric.mod.json") { - expand "version": project.version - } + filesMatching("fabric.mod.json") { + expand "version": project.version + } } tasks.withType(JavaCompile).configureEach { - // Minecraft 1.18 (1.18-pre2) upwards uses Java 17. - it.options.release = 17 + // Minecraft 1.18 (1.18-pre2) upwards uses Java 17. + it.options.release = 17 } java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() } jar { - from("LICENSE") { - rename { "${it}_${project.archivesBaseName}"} - } + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}" } + } } // configure the maven publication publishing { - publications { - mavenJava(MavenPublication) { - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } + publications { + mavenJava(MavenPublication) { + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } } diff --git a/gradle.properties b/gradle.properties index 952b2ff..d8f48dc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,17 +1,14 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx4G org.gradle.parallel=true - # Fabric Properties - # check these on https://fabricmc.net/develop - minecraft_version=1.20.4 - loader_version=0.16.3 - +# check these on https://fabricmc.net/develop +minecraft_version=1.20.4 +loader_version=0.16.3 # Mod Properties - mod_version = 1.20.4-Fabric-2.1.0.0 - maven_group = com.modularmods.mcgltf - archives_base_name = MCglTF - +mod_version=1.20.4-Fabric-2.1.0.0 +maven_group=com.modularmods.mcgltf +archives_base_name=MCglTF # Dependencies - fabric_version=0.97.2+1.20.4 - iris_version=1.7.2+1.20.4 +fabric_version=0.97.2+1.20.4 +iris_version=1.7.2+1.20.4 diff --git a/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java b/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java index d050d4a..3a3d93b 100644 --- a/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java +++ b/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java @@ -60,8 +60,8 @@ public interface MikkTSpaceContext { * for quads. * * @param posOut storage for the results (modified) - * @param face which face (≥0, <numFaces) - * @param vert which vertex in the face (≥0, <numVertices) + * @param face which face (≥0, <numFaces) + * @param vert which vertex in the face (≥0, <numVertices) */ public void getPosition(float posOut[], int face, int vert); @@ -75,18 +75,18 @@ public interface MikkTSpaceContext { * tangent is a unit length vector. For normal maps it is sufficient to use * the following simplified version of the bitangent which is generated at * pixel/vertex level. - * + *

* bitangent = fSign * cross(vN, tangent); - * + *

* Note that the results are returned unindexed. It is possible to generate * a new index list But averaging/overwriting tangent spaces by using an * already existing index list WILL produce INCORRECT results. DO NOT! use * an already existing index list. * * @param tangent the desired tangent vector (unaffected) - * @param sign the desired sign - * @param face which face (≥0, <numFaces) - * @param vert which vertex in the face (≥0, <numVertices) + * @param sign the desired sign + * @param face which face (≥0, <numFaces) + * @param vert which vertex in the face (≥0, <numVertices) */ public void setTSpaceBasic(float tangent[], float sign, int face, int vert); @@ -94,7 +94,7 @@ public interface MikkTSpaceContext { * This function is used to return tangent space results to the application. * tangent and biTangent are unit length vectors and fMagS and fMagT are * their true magnitudes which can be used for relief mapping effects. - * + *

* biTangent is the "real" bitangent and thus may not be perpendicular to * tangent. However, both are perpendicular to the vertex normal. For normal * maps it is sufficient to use the following simplified version of the @@ -104,21 +104,21 @@ public interface MikkTSpaceContext { * fSign = bIsOrientationPreserving ? 1.0f : (-1.0f); * bitangent = fSign * cross(vN, tangent); * - * + *

* Note that the results are returned unindexed. It is possible to generate * a new index list. But averaging/overwriting tangent spaces by using an * already existing index list WILL produce INCORRECT results. DO NOT! use * an already existing index list. * - * @param tangent the desired tangent vector (unaffected) - * @param biTangent the desired bitangent vector (unaffected) - * @param magS true magnitude of S - * @param magT true magnitude of T + * @param tangent the desired tangent vector (unaffected) + * @param biTangent the desired bitangent vector (unaffected) + * @param magS true magnitude of S + * @param magT true magnitude of T * @param isOrientationPreserving true→preserves, false→doesn't - * preserve - * @param face which face (≥0, <numFaces) - * @param vert which vertex in the face (≥0, <numVertices) + * preserve + * @param face which face (≥0, <numFaces) + * @param vert which vertex in the face (≥0, <numVertices) */ void setTSpace(float tangent[], float biTangent[], float magS, float magT, - boolean isOrientationPreserving, int face, int vert); + boolean isOrientationPreserving, int face, int vert); } diff --git a/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java b/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java index df29252..572c779 100644 --- a/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java +++ b/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java @@ -31,37 +31,35 @@ */ package com.jme3.util.mikktspace; +import net.minecraft.util.Mth; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import net.minecraft.util.Mth; - /** * This tangent generator is highly experimental. * This is the Java translation of the mikktspace generator made by Morten S. Mikkelsen * C Source code can be found here * https://developer.blender.org/diffusion/B/browse/master/intern/mikktspace/mikktspace.c * https://developer.blender.org/diffusion/B/browse/master/intern/mikktspace/mikktspace.h - * + *

* Mikktspace looks like the new standard of tangent generation in 3-D software. * Xnormal, Blender, Substance painter, and many more use it. - * + *

* Usage is : * MikktspaceTangentGenerator.generate(spatial); - * - * - * + * * @author Nehon */ public class MikktspaceTangentGenerator { + static final int CELLS = 2048; private final static int MARK_DEGENERATE = 1; private final static int QUAD_ONE_DEGEN_TRI = 2; private final static int GROUP_WITH_ANY = 4; private final static int ORIENT_PRESERVING = 8; private final static long INTERNAL_RND_SORT_SEED = 39871946 & 0xffffffffL; - static final int CELLS = 2048; /** * A private constructor to inhibit instantiation of this class. @@ -116,7 +114,7 @@ public static boolean genTangSpace(MikkTSpaceContext mikkTSpace, final float ang int iNrActiveGroups, index; final int iNrFaces = mikkTSpace.getNumFaces(); //boolean bRes = false; - final float fThresCos = Mth.cos((angularThreshold * (float)Math.PI) / 180.0f); + final float fThresCos = Mth.cos((angularThreshold * (float) Math.PI) / 180.0f); // count triangles on supported faces for (int f = 0; f < iNrFaces; f++) { @@ -238,7 +236,7 @@ public static boolean genTangSpace(MikkTSpaceContext mikkTSpace, final float ang return true; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// //////////////////////////////////////////////////////////////////////////////////////////////////////////////// // it is IMPORTANT that this function is called to evaluate the hash since // inlining could potentially reorder instructions and generate different // results for the same effective input value fVal. @@ -872,15 +870,15 @@ static int build4RuleGroups(TriInfo pTriInfos[], Group pGroups[], int piGroupTri for (int i = 0; i < 3; i++) { // if not assigned to a group if ((pTriInfos[f].flag & GROUP_WITH_ANY) == 0 && pTriInfos[f].assignedGroup[i] == null) { - boolean bOrPre; + boolean bOrPre; final int vert_index = piTriListIn[f * 3 + i]; assert (iNrActiveGroups < iNrMaxGroups); - pTriInfos[f].assignedGroup[i] = new Group(); + pTriInfos[f].assignedGroup[i] = new Group(); pGroups[iNrActiveGroups] = pTriInfos[f].assignedGroup[i]; pTriInfos[f].assignedGroup[i].vertexRepresentative = vert_index; pTriInfos[f].assignedGroup[i].orientationPreserving = (pTriInfos[f].flag & ORIENT_PRESERVING) != 0; pTriInfos[f].assignedGroup[i].nrFaces = 0; - + ++iNrActiveGroups; addTriToGroup(pTriInfos[f].assignedGroup[i], f); @@ -891,7 +889,7 @@ static int build4RuleGroups(TriInfo pTriInfos[], Group pGroups[], int piGroupTri // neighbor final boolean bAnswer = assignRecur(piTriListIn, pTriInfos, neigh_indexL, - pTriInfos[f].assignedGroup[i]); + pTriInfos[f].assignedGroup[i]); final boolean bOrPre2 = (pTriInfos[neigh_indexL].flag & ORIENT_PRESERVING) != 0; final boolean bDiff = bOrPre != bOrPre2; @@ -902,7 +900,7 @@ static int build4RuleGroups(TriInfo pTriInfos[], Group pGroups[], int piGroupTri // neighbor final boolean bAnswer = assignRecur(piTriListIn, pTriInfos, neigh_indexR, - pTriInfos[f].assignedGroup[i]); + pTriInfos[f].assignedGroup[i]); final boolean bOrPre2 = (pTriInfos[neigh_indexR].flag & ORIENT_PRESERVING) != 0; final boolean bDiff = bOrPre != bOrPre2; @@ -915,9 +913,9 @@ static int build4RuleGroups(TriInfo pTriInfos[], Group pGroups[], int piGroupTri for (int j = 0; j < faceIndices.length; j++) { faceIndices[j] = pTriInfos[f].assignedGroup[i].faceIndices.get(j); } - + //Nehon: copy back the faceIndices data into the groupTriangleBuffer. - System.arraycopy( faceIndices, 0, piGroupTrianglesBuffer, iOffset, pTriInfos[f].assignedGroup[i].nrFaces); + System.arraycopy(faceIndices, 0, piGroupTrianglesBuffer, iOffset, pTriInfos[f].assignedGroup[i].nrFaces); // update offset iOffset += pTriInfos[f].assignedGroup[i].nrFaces; // since the groups are disjoint a triangle can never @@ -995,8 +993,8 @@ static boolean assignRecur(final int piTriListIn[], TriInfo psTriInfos[], final } static boolean generateTSpaces(TSpace psTspace[], final TriInfo pTriInfos[], final Group pGroups[], - final int iNrActiveGroups, final int piTriListIn[], final float fThresCos, - final MikkTSpaceContext mikkTSpace) { + final int iNrActiveGroups, final int piTriListIn[], final float fThresCos, + final MikkTSpaceContext mikkTSpace) { TSpace[] pSubGroupTspace; SubGroup[] pUniSubGroups; int[] pTmpMembers; @@ -1141,16 +1139,16 @@ static boolean generateTSpaces(TSpace psTspace[], final TriInfo pTriInfos[], fin } static TSpace evalTspace(int face_indices[], final int iFaces, final int piTriListIn[], final TriInfo pTriInfos[], - final MikkTSpaceContext mikkTSpace, final int iVertexRepresentative) { + final MikkTSpaceContext mikkTSpace, final int iVertexRepresentative) { TSpace res = new TSpace(); - float fAngleSum = 0; + float fAngleSum = 0; for (int face = 0; face < iFaces; face++) { final int f = face_indices[face]; // only valid triangles get to add their contribution if ((pTriInfos[f].flag & GROUP_WITH_ANY) == 0) { - + int i = -1; if (piTriListIn[3 * f + 0] == iVertexRepresentative) { i = 0; @@ -1175,7 +1173,7 @@ static TSpace evalTspace(int face_indices[], final int iFaces, final int piTriLi Vector3f p0 = getPosition(mikkTSpace, i0); Vector3f p1 = getPosition(mikkTSpace, i1); - Vector3f p2 = getPosition(mikkTSpace, i2); + Vector3f p2 = getPosition(mikkTSpace, i2); Vector3f v1 = p0.subtract(p1); Vector3f v2 = p2.subtract(p1); @@ -1212,11 +1210,11 @@ static TSpace evalTspace(int face_indices[], final int iFaces, final int piTriLi } static boolean compareSubGroups(final SubGroup pg1, final SubGroup pg2) { - if(pg2 == null || (pg1.nrFaces != pg2.nrFaces)){ + if (pg2 == null || (pg1.nrFaces != pg2.nrFaces)) { return false; } boolean stillSame = true; - int i = 0; + int i = 0; while (i < pg1.nrFaces && stillSame) { stillSame = pg1.triMembers[i] == pg2.triMembers[i]; if (stillSame) { @@ -1272,7 +1270,7 @@ static void quickSort(int[] pSortBuffer, int iLeft, int iRight, long uSeed) { static void buildNeighborsFast(TriInfo pTriInfos[], Edge[] pEdges, final int piTriListIn[], final int iNrTrianglesIn) { // build array of edges long uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed? - + for (int f = 0; f < iNrTrianglesIn; f++) { for (int i = 0; i < 3; i++) { final int i0 = piTriListIn[f * 3 + i]; @@ -1365,7 +1363,7 @@ static void buildNeighborsFast(TriInfo pTriInfos[], Edge[] pEdges, final int piT } static void buildNeighborsSlow(TriInfo pTriInfos[], final int piTriListIn[], final int iNrTrianglesIn) { - + for (int f = 0; f < iNrTrianglesIn; f++) { for (int i = 0; i < 3; i++) { // if unassigned @@ -1428,7 +1426,7 @@ static void quickSortEdges(Edge[] pSortBuffer, int iLeft, int iRight, final int t = (uSeed << t) | (uSeed >> (32 - t)); uSeed = uSeed + t + 3; // Random end - + uSeed = uSeed & 0xffffffffL; int iL = iLeft; @@ -1464,7 +1462,7 @@ static void quickSortEdges(Edge[] pSortBuffer, int iLeft, int iRight, final int } } -// resolve ordering and edge number + // resolve ordering and edge number static void getEdge(int[] i0_out, int[] i1_out, int[] edgenum_out, final int[] indices, final int i0_in, final int i1_in) { edgenum_out[0] = -1; @@ -1489,7 +1487,7 @@ static void getEdge(int[] i0_out, int[] i1_out, int[] edgenum_out, final int[] i } static void degenPrologue(TriInfo pTriInfos[], int piTriList_out[], final int iNrTrianglesIn, final int iTotTris) { - + // locate quads with only one good triangle int t = 0; while (t < (iTotTris - 1)) { @@ -1521,7 +1519,7 @@ static void degenPrologue(TriInfo pTriInfos[], int piTriList_out[], final int iN if (iNextGoodTriangleSearchIndex < (t + 2)) { iNextGoodTriangleSearchIndex = t + 2; } - } else { + } else { // search for the first good triangle. boolean bJustADegenerate = true; while (bJustADegenerate && iNextGoodTriangleSearchIndex < iTotTris) { @@ -1539,7 +1537,7 @@ static void degenPrologue(TriInfo pTriInfos[], int piTriList_out[], final int iN assert (iNextGoodTriangleSearchIndex > (t + 1)); // swap triangle t0 and t1 - if (!bJustADegenerate) { + if (!bJustADegenerate) { for (int i = 0; i < 3; i++) { final int index = piTriList_out[t0 * 3 + i]; piTriList_out[t0 * 3 + i] = piTriList_out[t1 * 3 + i]; @@ -1565,7 +1563,7 @@ static void degenPrologue(TriInfo pTriInfos[], int piTriList_out[], final int iN } static void DegenEpilogue(TSpace psTspace[], TriInfo pTriInfos[], int piTriListIn[], final MikkTSpaceContext mikkTSpace, final int iNrTrianglesIn, final int iTotTris) { - + // deal with degenerate triangles // punishment for degenerate triangles is O(N^2) for (int t = iNrTrianglesIn; t < iTotTris; t++) { @@ -1608,7 +1606,7 @@ static void DegenEpilogue(TSpace psTspace[], TriInfo pTriInfos[], int piTriListI // this triangle belongs to a quad where the // other triangle is degenerate if ((pTriInfos[t].flag & QUAD_ONE_DEGEN_TRI) != 0) { - + byte[] pV = pTriInfos[t].vertNum; int iFlag = (1 << pV[0]) | (1 << pV[1]) | (1 << pV[2]); int iMissingIndex = 0; @@ -1639,7 +1637,7 @@ static void DegenEpilogue(TSpace psTspace[], TriInfo pTriInfos[], int piTriListI } } - } + } /** * SubGroup inner class @@ -1680,8 +1678,8 @@ private static class TSpace { float magT; int counter; // this is to average back into quads. boolean orient; - - void set(TSpace ts){ + + void set(TSpace ts) { os.set(ts.os); magS = ts.magS; ot.set(ts.ot); @@ -1699,31 +1697,31 @@ private static class TmpVert { private static class Edge { - void setI0(int i){ - array[0] = i; - } - - void setI1(int i){ - array[1] = i; - } - - void setF(int i){ - array[2] = i; - } - - int getI0(){ + int[] array = new int[3]; + + int getI0() { return array[0]; } - - int getI1(){ + + void setI0(int i) { + array[0] = i; + } + + int getI1() { return array[1]; } - - int getF(){ + + void setI1(int i) { + array[1] = i; + } + + int getF() { return array[2]; } - - int[] array = new int[3]; + + void setF(int i) { + array[2] = i; + } } } diff --git a/src/main/java/com/jme3/util/mikktspace/Vector3f.java b/src/main/java/com/jme3/util/mikktspace/Vector3f.java index 34b27fe..d4567bd 100644 --- a/src/main/java/com/jme3/util/mikktspace/Vector3f.java +++ b/src/main/java/com/jme3/util/mikktspace/Vector3f.java @@ -45,8 +45,6 @@ */ public final class Vector3f implements Cloneable, java.io.Serializable { - static final long serialVersionUID = 1; - private static final Logger logger = Logger.getLogger(Vector3f.class.getName()); /** * Shared instance of the all-zero vector (0,0,0). Do not modify! */ @@ -87,6 +85,8 @@ public final class Vector3f implements Cloneable, java.io.Serializable { Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); + static final long serialVersionUID = 1; + private static final Logger logger = Logger.getLogger(Vector3f.class.getName()); /** * The first (X) component. */ @@ -129,6 +129,60 @@ public Vector3f(Vector3f copy) { this.set(copy); } + /** + * Tests whether the argument is a valid vector, returning false if it's + * null or if any component is NaN or infinite. + * + * @param vector the vector to test (unaffected) + * @return true if non-null and finite, otherwise false + */ + public static boolean isValidVector(Vector3f vector) { + if (vector == null) { + return false; + } + if (Float.isNaN(vector.x) + || Float.isNaN(vector.y) + || Float.isNaN(vector.z)) { + return false; + } + if (Float.isInfinite(vector.x) + || Float.isInfinite(vector.y) + || Float.isInfinite(vector.z)) { + return false; + } + return true; + } + + public static void generateOrthonormalBasis(Vector3f u, Vector3f v, Vector3f w) { + w.normalizeLocal(); + generateComplementBasis(u, v, w); + } + + public static void generateComplementBasis(Vector3f u, Vector3f v, + Vector3f w) { + float fInvLength; + + if ((float) Math.abs(w.x) >= (float) Math.abs(w.y)) { + // w.x or w.z is the largest magnitude component, swap them + fInvLength = (float) (1.0f / Math.sqrt(w.x * w.x + w.z * w.z)); + u.x = -w.z * fInvLength; + u.y = 0.0f; + u.z = +w.x * fInvLength; + v.x = w.y * u.z; + v.y = w.z * u.x - w.x * u.z; + v.z = -w.y * u.x; + } else { + // w.y or w.z is the largest magnitude component, swap them + fInvLength = (float) (1.0f / Math.sqrt(w.y * w.y + w.z * w.z)); + u.x = 0.0f; + u.y = +w.z * fInvLength; + u.z = -w.y * fInvLength; + v.x = w.y * u.z - w.z * u.y; + v.y = -w.x * u.z; + v.z = w.x * u.y; + } + } + /** * Sets all 3 components to specified values. * @@ -177,8 +231,8 @@ public Vector3f add(Vector3f vec) { * Adds a specified vector and returns the sum in a 3rd vector. The current * instance is unaffected unless it's result. * - * @param vec the vector to add (not null, unaffected unless it's - * result) + * @param vec the vector to add (not null, unaffected unless it's + * result) * @param result storage for the sum (not null) * @return result (for chaining) */ @@ -194,7 +248,7 @@ public Vector3f add(Vector3f vec, Vector3f result) { * argument is null, null is returned. * * @param vec the vector to add (unaffected unless it's this) - * or null for none + * or null for none * @return the (modified) current instance or null */ public Vector3f addLocal(Vector3f vec) { @@ -244,8 +298,8 @@ public Vector3f addLocal(float addX, float addY, float addZ) { *

this = scalar * this + add * * @param scalar the scaling factor - * @param add the vector to add (not null, unaffected unless it's - * this) + * @param add the vector to add (not null, unaffected unless it's + * this) * @return the (modified) current instance (for chaining) */ public Vector3f scaleAdd(float scalar, Vector3f add) { @@ -263,10 +317,10 @@ public Vector3f scaleAdd(float scalar, Vector3f add) { *

this = scalar * mult + add * * @param scalar the scaling factor - * @param mult the vector to scale (not null, unaffected unless it's - * this) - * @param add the vector to add (not null, unaffected unless it's - * this) + * @param mult the vector to scale (not null, unaffected unless it's + * this) + * @param add the vector to add (not null, unaffected unless it's + * this) * @return the (modified) current instance (for chaining) */ public Vector3f scaleAdd(float scalar, Vector3f mult, Vector3f add) { @@ -307,11 +361,11 @@ public Vector3f cross(Vector3f v) { * product in a 3rd vector. The current instance is unaffected unless it's * result. * - * @param v the right factor (not null, unaffected unless it's - * result) + * @param v the right factor (not null, unaffected unless it's + * result) * @param result storage for the product, or null for a new Vector3f * @return this cross v (either - * result or a new Vector3f) + * result or a new Vector3f) */ public Vector3f cross(Vector3f v, Vector3f result) { return cross(v.x, v.y, v.z, result); @@ -327,7 +381,7 @@ public Vector3f cross(Vector3f v, Vector3f result) { * @param otherZ the Z component of the right factor * @param result storage for the product, or null for a new Vector3f * @return this cross v (either - * result or a new Vector3f) + * result or a new Vector3f) */ public Vector3f cross(float otherX, float otherY, float otherZ, Vector3f result) { if (result == null) { @@ -345,7 +399,7 @@ public Vector3f cross(float otherX, float otherY, float otherZ, Vector3f result) * (modified) current instance. * * @param v the right factor (not null, unaffected unless it's - * this) + * this) * @return the (modified) current instance (for chaining) */ public Vector3f crossLocal(Vector3f v) { @@ -387,7 +441,7 @@ public Vector3f project(Vector3f other) { * Projects onto the argument and returns the (modified) current instance. * * @param other the vector to project onto (not null, unaffected unless it's - * this) + * this) * @return the (modified) current instance (for chaining) */ public Vector3f projectLocal(Vector3f other) { @@ -401,7 +455,7 @@ public Vector3f projectLocal(Vector3f other) { * unaffected. * * @return true if the current vector's length is between 0.99 and 1.01 - * inclusive, otherwise false + * inclusive, otherwise false */ public boolean isUnitVector() { float len = length(); @@ -489,7 +543,7 @@ public Vector3f mult(float scalar) { * specified vector. The current instance is unaffected, unless it's * product. * - * @param scalar the scaling factor + * @param scalar the scaling factor * @param product storage for the product, or null for a new Vector3f * @return either product or a new Vector3f */ @@ -522,7 +576,7 @@ public Vector3f multLocal(float scalar) { * current instance. If the argument is null, null is returned. * * @param vec the scale vector (unaffected unless it's this) or - * null for none + * null for none * @return the (modified) current instance (for chaining) or null */ public Vector3f multLocal(Vector3f vec) { @@ -587,8 +641,8 @@ public Vector3f mult(float x, float y, float z) { * Either way, the current instance is unaffected, unless it's * store. * - * @param vec the scale vector (unaffected unless it's store) - * or null for none + * @param vec the scale vector (unaffected unless it's store) + * or null for none * @param store storage for the product, or null for a new Vector3f * @return either store or a new Vector3f or null */ @@ -720,7 +774,7 @@ public Vector3f subtract(Vector3f vec) { * the argument is null, null is returned. * * @param vec the vector to subtract (unaffected unless it's - * this) or null for none + * this) or null for none * @return the (modified) current instance or null */ public Vector3f subtractLocal(Vector3f vec) { @@ -739,8 +793,8 @@ public Vector3f subtractLocal(Vector3f vec) { * vector. The current instance is unaffected unless it's * result. * - * @param vec the vector to subtract (not null, unaffected unless it's - * result) + * @param vec the vector to subtract (not null, unaffected unless it's + * result) * @param result storage for the difference, or null for a new Vector3f * @return either result or a new Vector3f */ @@ -891,8 +945,8 @@ public float angleBetween(Vector3f otherVector) { * *

this = (1 - changeAmount) * this + changeAmount * finalVec * - * @param finalVec the desired value when changeAmount=1 (not null, unaffected - * unless it's this) + * @param finalVec the desired value when changeAmount=1 (not null, unaffected + * unless it's this) * @param changeAmount the fractional change amount * @return the (modified) current instance (for chaining) */ @@ -909,10 +963,10 @@ public Vector3f interpolateLocal(Vector3f finalVec, float changeAmount) { * *

this = (1 - changeAmount) * beginVec + changeAmount * finalVec * - * @param beginVec the desired value when changeAmount=0 (not null, unaffected - * unless it's this) - * @param finalVec the desired value when changeAmount=1 (not null, unaffected - * unless it's this) + * @param beginVec the desired value when changeAmount=0 (not null, unaffected + * unless it's this) + * @param finalVec the desired value when changeAmount=1 (not null, unaffected + * unless it's this) * @param changeAmount the fractional change amount * @return the (modified) current instance (for chaining) */ @@ -923,60 +977,6 @@ public Vector3f interpolateLocal(Vector3f beginVec, Vector3f finalVec, float cha return this; } - /** - * Tests whether the argument is a valid vector, returning false if it's - * null or if any component is NaN or infinite. - * - * @param vector the vector to test (unaffected) - * @return true if non-null and finite, otherwise false - */ - public static boolean isValidVector(Vector3f vector) { - if (vector == null) { - return false; - } - if (Float.isNaN(vector.x) - || Float.isNaN(vector.y) - || Float.isNaN(vector.z)) { - return false; - } - if (Float.isInfinite(vector.x) - || Float.isInfinite(vector.y) - || Float.isInfinite(vector.z)) { - return false; - } - return true; - } - - public static void generateOrthonormalBasis(Vector3f u, Vector3f v, Vector3f w) { - w.normalizeLocal(); - generateComplementBasis(u, v, w); - } - - public static void generateComplementBasis(Vector3f u, Vector3f v, - Vector3f w) { - float fInvLength; - - if ((float) Math.abs(w.x) >= (float) Math.abs(w.y)) { - // w.x or w.z is the largest magnitude component, swap them - fInvLength = (float) (1.0f / Math.sqrt(w.x * w.x + w.z * w.z)); - u.x = -w.z * fInvLength; - u.y = 0.0f; - u.z = +w.x * fInvLength; - v.x = w.y * u.z; - v.y = w.z * u.x - w.x * u.z; - v.z = -w.y * u.x; - } else { - // w.y or w.z is the largest magnitude component, swap them - fInvLength = (float) (1.0f / Math.sqrt(w.y * w.y + w.z * w.z)); - u.x = 0.0f; - u.y = +w.z * fInvLength; - u.z = -w.y * fInvLength; - v.x = w.y * u.z - w.z * u.y; - v.y = -w.x * u.z; - v.z = w.x * u.y; - } - } - /** * Creates a copy. The current instance is unaffected. * @@ -995,9 +995,9 @@ public Vector3f clone() { * Copies the vector into the argument. The current instance is unaffected. * * @param floats storage for the components (must have length≥3) or null - * for a new float[3] + * for a new float[3] * @return an array containing the X, Y, and Z components in that order - * (either floats or a new float[3]) + * (either floats or a new float[3]) */ public float[] toArray(float[] floats) { if (floats == null) { @@ -1045,7 +1045,7 @@ public boolean equals(Object o) { * specified tolerance. If {@code other} is null, false is returned. Either * way, the current instance is unaffected. * - * @param other the vector to compare (unaffected) or null for none + * @param other the vector to compare (unaffected) or null for none * @param epsilon the tolerance for each component * @return true if all 3 components are within tolerance, otherwise false */ @@ -1158,7 +1158,7 @@ public Vector3f setZ(float z) { * * @param index 0, 1, or 2 * @return the X component if index=0, the Y component if index=1, or the Z - * component if index=2 + * component if index=2 * @throws IllegalArgumentException if index is not 0, 1, or 2 */ public float get(int index) { @@ -1177,7 +1177,7 @@ public float get(int index) { * Sets the indexed component. * * @param index which component to set: 0 → the X component, 1 → - * the Y component, 2 → the Z component + * the Y component, 2 → the Z component * @param value the desired component value * @throws IllegalArgumentException if index is not 0, 1, or 2 */ diff --git a/src/main/java/com/modularmods/mcgltf/AccessorDataUtils.java b/src/main/java/com/modularmods/mcgltf/AccessorDataUtils.java index ff88fa9..faf5e6c 100644 --- a/src/main/java/com/modularmods/mcgltf/AccessorDataUtils.java +++ b/src/main/java/com/modularmods/mcgltf/AccessorDataUtils.java @@ -26,77 +26,72 @@ */ package com.modularmods.mcgltf; -import de.javagl.jgltf.model.AccessorByteData; -import de.javagl.jgltf.model.AccessorData; -import de.javagl.jgltf.model.AccessorFloatData; -import de.javagl.jgltf.model.AccessorIntData; -import de.javagl.jgltf.model.AccessorShortData; +import de.javagl.jgltf.model.*; /** * Utility methods for extracting raw data from {@link AccessorData} */ -public class AccessorDataUtils -{ +public class AccessorDataUtils { + /** + * Private constructor to prevent instantiation + */ + private AccessorDataUtils() { + // Private constructor to prevent instantiation + } + /** * Returns the values that are stored in the given {@link AccessorData}. - * + *

* This assumes the given data to be either a {@link AccessorByteData}, * {@link AccessorShortData} or {@link AccessorIntData}. - * + *

* This method writes all components from the given data into an array. - * + * * @param accessorData The {@link AccessorData} * @return The int values * @throws IllegalArgumentException If the given data does not have one - * of the valid types. + * of the valid types. */ - public static int[] readInts(AccessorData accessorData) - { + public static int[] readInts(AccessorData accessorData) { int numElements = accessorData.getNumElements(); - int numComponents = accessorData.getNumComponentsPerElement(); - if (accessorData instanceof AccessorByteData) - { - AccessorByteData accessorByteData = - (AccessorByteData) accessorData; + int numComponents = accessorData.getNumComponentsPerElement(); + if (accessorData instanceof AccessorByteData) { + AccessorByteData accessorByteData = + (AccessorByteData) accessorData; return readIntsFromBytes( - accessorByteData, numElements, numComponents); + accessorByteData, numElements, numComponents); } - if (accessorData instanceof AccessorShortData) - { - AccessorShortData accessorShortData = - (AccessorShortData) accessorData; + if (accessorData instanceof AccessorShortData) { + AccessorShortData accessorShortData = + (AccessorShortData) accessorData; return readIntsFromShorts( - accessorShortData, numElements, numComponents); + accessorShortData, numElements, numComponents); } - if (accessorData instanceof AccessorIntData) - { - AccessorIntData accessorIntData = - (AccessorIntData) accessorData; + if (accessorData instanceof AccessorIntData) { + AccessorIntData accessorIntData = + (AccessorIntData) accessorData; return readIntsFromInts( - accessorIntData, numElements, numComponents); + accessorIntData, numElements, numComponents); } throw new IllegalArgumentException( - "Not a valid index type: " + accessorData); + "Not a valid index type: " + accessorData); } - + /** * Implementation of {@link #readInts(AccessorData)} for bytes - * + * * @param accessorByteData The input data - * @param numElements The number of elements - * @param numComponents The number of components per element + * @param numElements The number of elements + * @param numComponents The number of components per element * @return The indices */ private static int[] readIntsFromBytes( - AccessorByteData accessorByteData, int numElements, int numComponents) - { + AccessorByteData accessorByteData, int numElements, int numComponents) { int n = numElements * numComponents; int result[] = new int[n]; int index = 0; - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponents; c++) - { + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponents; c++) { result[index] = accessorByteData.getInt(e, c); index++; } @@ -106,22 +101,19 @@ private static int[] readIntsFromBytes( /** * Implementation of {@link #readInts(AccessorData)} for shorts - * + * * @param accessorShortData The input data - * @param numElements The number of elements - * @param numComponents The number of components per element + * @param numElements The number of elements + * @param numComponents The number of components per element * @return The indices */ private static int[] readIntsFromShorts( - AccessorShortData accessorShortData, int numElements, int numComponents) - { + AccessorShortData accessorShortData, int numElements, int numComponents) { int n = numElements * numComponents; int result[] = new int[n]; int index = 0; - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponents; c++) - { + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponents; c++) { result[index] = accessorShortData.getInt(e, c); index++; } @@ -131,124 +123,103 @@ private static int[] readIntsFromShorts( /** * Implementation of {@link #readInts(AccessorData)} for ints - * + * * @param accessorIntData The input data - * @param numElements The number of elements - * @param numComponents The number of components per element + * @param numElements The number of elements + * @param numComponents The number of components per element * @return The indices */ private static int[] readIntsFromInts( - AccessorIntData accessorIntData, int numElements, int numComponents) - { + AccessorIntData accessorIntData, int numElements, int numComponents) { int n = numElements * numComponents; int result[] = new int[n]; int index = 0; - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponents; c++) - { + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponents; c++) { result[index] = accessorIntData.get(e, c); index++; } } return result; - } + } /** * Reads the raw data from the given {@link AccessorFloatData}. - * + *

* This reads the specified number of components for each element * from the input, and writes them into a result array, without * any padding. This means that the given number of components * may be smaller than the number of components that the accessor - * data actually has. - * - * @param accessorData The input data - * @param numElements The number of elements + * data actually has. + * + * @param accessorData The input data + * @param numElements The number of elements * @param numComponents The number of components per element * @return The indices */ public static float[] readFloats( - AccessorFloatData accessorData, int numElements, int numComponents) - { + AccessorFloatData accessorData, int numElements, int numComponents) { int n = numElements * numComponents; float result[] = new float[n]; int index = 0; - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponents; c++) - { + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponents; c++) { result[index] = accessorData.get(e, c); index++; } } return result; } - + /** * Writes the given raw data into the given {@link AccessorFloatData}. - * + *

* This reads the specified number of components for each element - * from the data, and writes them into a the given accessor data. - * This means that the given number of components may be smaller - * than the number of components that the accessor data actually has. - * - * @param accessorData The input data - * @param numElements The number of elements + * from the data, and writes them into a the given accessor data. + * This means that the given number of components may be smaller + * than the number of components that the accessor data actually has. + * + * @param accessorData The input data + * @param numElements The number of elements * @param numComponents The number of components per element - * @param data The raw data + * @param data The raw data */ public static void writeFloats( - AccessorFloatData accessorData, int numElements, int numComponents, - float data[]) - { + AccessorFloatData accessorData, int numElements, int numComponents, + float data[]) { int index = 0; - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponents; c++) - { + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponents; c++) { accessorData.set(e, c, data[index]); index++; } } } - - + /** * Set the values of the given target {@link AccessorData} to the same * values as in the given source {@link AccessorData}. If either of * them has fewer elements (or fewer components per element) than the * other, then the minimum of both will be used, respectively. - * + * * @param target The target {@link AccessorData} * @param source The source {@link AccessorData} */ public static void copyFloats( - AccessorFloatData target, - AccessorFloatData source) - { + AccessorFloatData target, + AccessorFloatData source) { int numElements = - Math.min(target.getNumElements(), source.getNumElements()); + Math.min(target.getNumElements(), source.getNumElements()); int numComponents = Math.min( - target.getNumComponentsPerElement(), - source.getNumComponentsPerElement()); - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponents; c++) - { + target.getNumComponentsPerElement(), + source.getNumComponentsPerElement()); + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponents; c++) { float value = source.get(e, c); target.set(e, c, value); } } } - - /** - * Private constructor to prevent instantiation - */ - private AccessorDataUtils() - { - // Private constructor to prevent instantiation - } - + } diff --git a/src/main/java/com/modularmods/mcgltf/AccessorModelCreation.java b/src/main/java/com/modularmods/mcgltf/AccessorModelCreation.java index 8acb285..f6c3b82 100644 --- a/src/main/java/com/modularmods/mcgltf/AccessorModelCreation.java +++ b/src/main/java/com/modularmods/mcgltf/AccessorModelCreation.java @@ -26,57 +26,56 @@ */ package com.modularmods.mcgltf; -import java.nio.ByteBuffer; - import de.javagl.jgltf.impl.v2.BufferView; -import de.javagl.jgltf.model.AccessorData; -import de.javagl.jgltf.model.AccessorDatas; -import de.javagl.jgltf.model.AccessorFloatData; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.BufferModel; -import de.javagl.jgltf.model.BufferViewModel; -import de.javagl.jgltf.model.ElementType; +import de.javagl.jgltf.model.*; import de.javagl.jgltf.model.impl.DefaultAccessorModel; import de.javagl.jgltf.model.impl.DefaultBufferModel; import de.javagl.jgltf.model.impl.DefaultBufferViewModel; import de.javagl.jgltf.model.io.Buffers; +import java.nio.ByteBuffer; + /** * Methods to create {@link AccessorModel} instances programmatically */ -public class AccessorModelCreation -{ +public class AccessorModelCreation { + /** + * Private constructor to prevent instantiation + */ + private AccessorModelCreation() { + // Private constructor to prevent instantiation + } + /** * Create a new {@link AccessorModel} that describes the same data as * the given {@link AccessorModel}, but in a compact form. The returned - * {@link AccessorModel} will refer to a newly created + * {@link AccessorModel} will refer to a newly created * {@link BufferViewModel} and a newly created {@link BufferModel} that * contain exactly the data for the accessor.
*
* The given {@link AccessorModel} is assumed to have a float * component type. - * - * @param accessorModel The {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} * @param bufferUriString The URI string for the {@link BufferModel} * @return The new {@link AccessorModel} instance. */ - public static AccessorModel instantiate( - AccessorModel accessorModel, String bufferUriString) - { + public static AccessorModel instantiate( + AccessorModel accessorModel, String bufferUriString) { AccessorModel instantiatedAccessorModel = createAccessorModel( - accessorModel.getComponentType(), accessorModel.getCount(), - accessorModel.getElementType(), bufferUriString); + accessorModel.getComponentType(), accessorModel.getCount(), + accessorModel.getElementType(), bufferUriString); AccessorData accessorData = accessorModel.getAccessorData(); - AccessorFloatData accessorFloatData = (AccessorFloatData)accessorData; - + AccessorFloatData accessorFloatData = (AccessorFloatData) accessorData; + AccessorData instantiatedAccessorData = - instantiatedAccessorModel.getAccessorData(); + instantiatedAccessorModel.getAccessorData(); AccessorFloatData instantiatedAccessorFloatData = - (AccessorFloatData)instantiatedAccessorData; + (AccessorFloatData) instantiatedAccessorData; AccessorDataUtils.copyFloats( - instantiatedAccessorFloatData, accessorFloatData); + instantiatedAccessorFloatData, accessorFloatData); return instantiatedAccessorModel; } @@ -86,62 +85,52 @@ public static AccessorModel instantiate( * refer to a newly created {@link BufferViewModel}, which in turn refers to * a newly created {@link BufferModel}, each containing exactly the data * required for the accessor. - * - * @param componentType The component type - * @param count The count - * @param elementType The element type + * + * @param componentType The component type + * @param count The count + * @param elementType The element type * @param bufferUriString The URI string for the {@link BufferModel} * @return The {@link AccessorModel} */ - public static AccessorModel createAccessorModel(int componentType, - int count, ElementType elementType, String bufferUriString) - { + public static AccessorModel createAccessorModel(int componentType, + int count, ElementType elementType, String bufferUriString) { DefaultAccessorModel accessorModel = - new DefaultAccessorModel(componentType, count, elementType); + new DefaultAccessorModel(componentType, count, elementType); int elementSize = accessorModel.getElementSizeInBytes(); accessorModel.setByteOffset(0); - + ByteBuffer bufferData = Buffers.create(count * elementSize); accessorModel.setBufferViewModel( - createBufferViewModel(bufferUriString, bufferData)); + createBufferViewModel(bufferUriString, bufferData)); accessorModel.setAccessorData(AccessorDatas.create(accessorModel)); return accessorModel; } /** * Create a new {@link BufferViewModel} with an associated - * {@link BufferModel} that serves as the basis for a sparse accessor, or + * {@link BufferModel} that serves as the basis for a sparse accessor, or * an accessor that does not refer to a {@link BufferView}) - * - * @param uriString The URI string that will be assigned to the - * {@link BufferModel} that is created internally. This string is not - * strictly required, but helpful for debugging, at least + * + * @param uriString The URI string that will be assigned to the + * {@link BufferModel} that is created internally. This string is not + * strictly required, but helpful for debugging, at least * @param bufferData The buffer data * @return The new {@link BufferViewModel} */ private static DefaultBufferViewModel createBufferViewModel( - String uriString, ByteBuffer bufferData) - { + String uriString, ByteBuffer bufferData) { DefaultBufferModel bufferModel = new DefaultBufferModel(); bufferModel.setUri(uriString); bufferModel.setBufferData(bufferData); DefaultBufferViewModel bufferViewModel = - new DefaultBufferViewModel(null); + new DefaultBufferViewModel(null); bufferViewModel.setByteOffset(0); bufferViewModel.setByteLength(bufferData.capacity()); bufferViewModel.setBufferModel(bufferModel); return bufferViewModel; } - - /** - * Private constructor to prevent instantiation - */ - private AccessorModelCreation() - { - // Private constructor to prevent instantiation - } - - + + } diff --git a/src/main/java/com/modularmods/mcgltf/IGltfModelReceiver.java b/src/main/java/com/modularmods/mcgltf/IGltfModelReceiver.java index 8e8e1dc..3424f67 100644 --- a/src/main/java/com/modularmods/mcgltf/IGltfModelReceiver.java +++ b/src/main/java/com/modularmods/mcgltf/IGltfModelReceiver.java @@ -1,17 +1,18 @@ package com.modularmods.mcgltf; -import java.util.List; - import de.javagl.jgltf.model.GltfModel; import net.minecraft.resources.ResourceLocation; +import java.util.List; + public interface IGltfModelReceiver { - ResourceLocation getModelLocation(); - - default void onReceiveSharedModel(RenderedGltfModel renderedModel) {} - - default boolean isReceiveSharedModel(GltfModel gltfModel, List gltfRenderDatas) { - return true; - } + ResourceLocation getModelLocation(); + + default void onReceiveSharedModel(RenderedGltfModel renderedModel) { + } + + default boolean isReceiveSharedModel(GltfModel gltfModel, List gltfRenderDatas) { + return true; + } } diff --git a/src/main/java/com/modularmods/mcgltf/MCglTF.java b/src/main/java/com/modularmods/mcgltf/MCglTF.java index 886257c..512a578 100644 --- a/src/main/java/com/modularmods/mcgltf/MCglTF.java +++ b/src/main/java/com/modularmods/mcgltf/MCglTF.java @@ -1,38 +1,9 @@ package com.modularmods.mcgltf; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.function.Supplier; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.tuple.MutablePair; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.lwjgl.opengl.GL; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL12; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL31; -import org.lwjgl.opengl.GL40; -import org.lwjgl.opengl.GL43; -import org.lwjgl.opengl.GLCapabilities; - import com.modularmods.mcgltf.iris.RenderedGltfModelGL30Iris; import com.modularmods.mcgltf.iris.RenderedGltfModelGL33Iris; import com.modularmods.mcgltf.iris.RenderedGltfModelGL40Iris; import com.modularmods.mcgltf.iris.RenderedGltfModelIris; - import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.io.Buffers; import de.javagl.jgltf.model.io.GltfModelReader; @@ -45,435 +16,444 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.resources.ResourceManager; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.lwjgl.opengl.*; import simplelibs.SimpleConfig; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.function.BiFunction; +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.Supplier; + public class MCglTF implements ModInitializer { - public static final String MODID = "mcgltf"; - public static final String RESOURCE_LOCATION = "resourceLocation"; - - public static final Logger logger = LogManager.getLogger(MODID); - - private static MCglTF INSTANCE; - - private final EnumRenderedModelGLProfile renderedModelGLProfile; - - private int glProgramSkinnig = -1; - private int defaultColorMap; - private int defaultNormalMap; - - private AbstractTexture lightTexture; - - private final Map> loadedBufferResources = new HashMap>(); - private final Map> loadedImageResources = new HashMap>(); - private final List gltfModelReceivers = new ArrayList(); - private final List gltfRenderData = new ArrayList(); - - private BooleanSupplier shaderModActive; - - public MCglTF() { - INSTANCE = this; - renderedModelGLProfile = EnumRenderedModelGLProfile.valueOf(SimpleConfig.of(MODID).provider(this::provider).request().getOrDefault("RenderedModelGLProfile", "AUTO")); - } - - @Override - public void onInitialize() { - Consumer>>> processRenderedGltfModelSelector; - if(FabricLoader.getInstance().isModLoaded("iris")) { - shaderModActive = net.irisshaders.iris.api.v0.IrisApi.getInstance()::isShaderPackInUse; - - processRenderedGltfModelSelector = (lookup) -> { - switch(renderedModelGLProfile) { - case GL43: - processRenderedGltfModelsGL43Iris(lookup); - break; - case GL40: - processRenderedGltfModelsGL40Iris(lookup); - break; - case GL33: - processRenderedGltfModelsGL33Iris(lookup); - break; - case GL30: - processRenderedGltfModelsGL30Iris(lookup); - break; - default: - GLCapabilities glCapabilities = GL.getCapabilities(); - if(glCapabilities.glTexBufferRange != 0) processRenderedGltfModelsGL43Iris(lookup); - else if(glCapabilities.glGenTransformFeedbacks != 0) processRenderedGltfModelsGL40Iris(lookup); - else processRenderedGltfModelsGL33Iris(lookup); - break; - } - }; - } - else { - shaderModActive = () -> false; - - processRenderedGltfModelSelector = (lookup) -> { - switch(renderedModelGLProfile) { - case GL43: - processRenderedGltfModelsGL43(lookup); - break; - case GL40: - processRenderedGltfModelsGL40(lookup); - break; - case GL33: - processRenderedGltfModelsGL33(lookup); - break; - case GL30: - processRenderedGltfModelsGL30(lookup); - break; - default: - GLCapabilities glCapabilities = GL.getCapabilities(); - if(glCapabilities.glTexBufferRange != 0) processRenderedGltfModelsGL43(lookup); - else if(glCapabilities.glGenTransformFeedbacks != 0) processRenderedGltfModelsGL40(lookup); - else processRenderedGltfModelsGL33(lookup); - break; - } - }; - } - - Minecraft.getInstance().execute(() -> { - lightTexture = Minecraft.getInstance().getTextureManager().getTexture(new ResourceLocation("dynamic/light_map_1")); - - switch(renderedModelGLProfile) { - case GL43: - createSkinningProgramGL43(); - break; - case GL40: - case GL33: - createSkinningProgramGL33(); - break; - case GL30: - break; - default: - //Since max OpenGL version on Windows from GLCapabilities will always return 3.2 as of Minecraft 1.17, this is a workaround to check if OpenGL 4.3 is available. - if(GL.getCapabilities().glTexBufferRange != 0) createSkinningProgramGL43(); - else createSkinningProgramGL33(); - break; - } - - GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4); - - int currentTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - defaultColorMap = GL11.glGenTextures(); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, defaultColorMap); - GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 2, 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, Buffers.create(new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1})); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); - - defaultNormalMap = GL11.glGenTextures(); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, defaultNormalMap); - GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 2, 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, Buffers.create(new byte[]{-128, -128, -1, -1, -128, -128, -1, -1, -128, -128, -1, -1, -128, -128, -1, -1})); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); - - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture); - }); - - ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { - - @Override - public ResourceLocation getFabricId() { - return new ResourceLocation(MODID, "gltf_reload_listener"); - } - - @Override - public void onResourceManagerReload(ResourceManager resourceManager) { - gltfRenderData.forEach(Runnable::run); - gltfRenderData.clear(); - - GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4); - - int currentTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - Map>> lookup = new HashMap>>(); - gltfModelReceivers.forEach((receiver) -> { - ResourceLocation modelLocation = receiver.getModelLocation(); - MutablePair> receivers = lookup.get(modelLocation); - if(receivers == null) { - receivers = MutablePair.of(null, new ArrayList()); - lookup.put(modelLocation, receivers); - } - receivers.getRight().add(receiver); - }); - lookup.entrySet().parallelStream().forEach((entry) -> { - try { - entry.getValue().setLeft(new GltfModelReader().readWithoutReferences(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(entry.getKey()).orElseThrow().open()))); - } catch (IOException e) { - e.printStackTrace(); - } - }); - processRenderedGltfModelSelector.accept(lookup); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); - GL30.glBindVertexArray(0); - - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture); - - loadedBufferResources.clear(); - loadedImageResources.clear(); - } - - }); - } - - public int getGlProgramSkinnig() { - return glProgramSkinnig; - } - - public int getDefaultColorMap() { - return defaultColorMap; - } - - public int getDefaultNormalMap() { - return defaultNormalMap; - } - - public int getDefaultSpecularMap() { - return 0; - } - - public AbstractTexture getLightTexture() { - return lightTexture; - } - - public ByteBuffer getBufferResource(ResourceLocation location) { - Supplier supplier; - synchronized(loadedBufferResources) { - supplier = loadedBufferResources.get(location); - if(supplier == null) { - supplier = new Supplier() { - ByteBuffer bufferData; - - @Override - public synchronized ByteBuffer get() { - if(bufferData == null) { - try { - bufferData = Buffers.create(IOUtils.toByteArray(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(location).orElseThrow().open()))); - } catch (IOException e) { - e.printStackTrace(); - } - } - return bufferData; - } - - }; - loadedBufferResources.put(location, supplier); - } - } - return supplier.get(); - } - - public ByteBuffer getImageResource(ResourceLocation location) { - Supplier supplier; - synchronized(loadedImageResources) { - supplier = loadedImageResources.get(location); - if(supplier == null) { - supplier = new Supplier() { - ByteBuffer bufferData; - - @Override - public synchronized ByteBuffer get() { - if(bufferData == null) { - try { - bufferData = Buffers.create(IOUtils.toByteArray(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(location).orElseThrow().open()))); - } catch (IOException e) { - e.printStackTrace(); - } - } - return bufferData; - } - - }; - loadedImageResources.put(location, supplier); - } - } - return supplier.get(); - } - - public synchronized void addGltfModelReceiver(IGltfModelReceiver receiver) { - gltfModelReceivers.add(receiver); - } - - public synchronized boolean removeGltfModelReceiver(IGltfModelReceiver receiver) { - return gltfModelReceivers.remove(receiver); - } - - public boolean isShaderModActive() { - return shaderModActive.getAsBoolean(); - } - - public static MCglTF getInstance() { - return INSTANCE; - } - - private void createSkinningProgramGL43() { - int glShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); - GL20.glShaderSource(glShader, - "#version 430\r\n" - + "layout(location = 0) in vec4 joint;" - + "layout(location = 1) in vec4 weight;" - + "layout(location = 2) in vec3 position;" - + "layout(location = 3) in vec3 normal;" - + "layout(location = 4) in vec4 tangent;" - + "layout(std430, binding = 0) readonly buffer jointMatrixBuffer {mat4 jointMatrices[];};" - + "out vec3 outPosition;" - + "out vec3 outNormal;" - + "out vec4 outTangent;" - + "void main() {" - + "mat4 skinMatrix =" - + " weight.x * jointMatrices[int(joint.x)] +" - + " weight.y * jointMatrices[int(joint.y)] +" - + " weight.z * jointMatrices[int(joint.z)] +" - + " weight.w * jointMatrices[int(joint.w)];" - + "outPosition = (skinMatrix * vec4(position, 1.0)).xyz;" - + "mat3 upperLeft = mat3(skinMatrix);" - + "outNormal = upperLeft * normal;" - + "outTangent.xyz = upperLeft * tangent.xyz;" - + "outTangent.w = tangent.w;" - + "}"); - GL20.glCompileShader(glShader); - - glProgramSkinnig = GL20.glCreateProgram(); - GL20.glAttachShader(glProgramSkinnig, glShader); - GL20.glDeleteShader(glShader); - GL30.glTransformFeedbackVaryings(glProgramSkinnig, new CharSequence[]{"outPosition", "outNormal", "outTangent"}, GL30.GL_SEPARATE_ATTRIBS); - GL20.glLinkProgram(glProgramSkinnig); - } - - private void createSkinningProgramGL33() { - int glShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); - GL20.glShaderSource(glShader, - "#version 330\r\n" - + "layout(location = 0) in vec4 joint;" - + "layout(location = 1) in vec4 weight;" - + "layout(location = 2) in vec3 position;" - + "layout(location = 3) in vec3 normal;" - + "layout(location = 4) in vec4 tangent;" - + "uniform samplerBuffer jointMatrices;" - + "out vec3 outPosition;" - + "out vec3 outNormal;" - + "out vec4 outTangent;" - + "void main() {" - + "int jx = int(joint.x) * 4;" - + "int jy = int(joint.y) * 4;" - + "int jz = int(joint.z) * 4;" - + "int jw = int(joint.w) * 4;" - + "mat4 skinMatrix =" - + " weight.x * mat4(texelFetch(jointMatrices, jx), texelFetch(jointMatrices, jx + 1), texelFetch(jointMatrices, jx + 2), texelFetch(jointMatrices, jx + 3)) +" - + " weight.y * mat4(texelFetch(jointMatrices, jy), texelFetch(jointMatrices, jy + 1), texelFetch(jointMatrices, jy + 2), texelFetch(jointMatrices, jy + 3)) +" - + " weight.z * mat4(texelFetch(jointMatrices, jz), texelFetch(jointMatrices, jz + 1), texelFetch(jointMatrices, jz + 2), texelFetch(jointMatrices, jz + 3)) +" - + " weight.w * mat4(texelFetch(jointMatrices, jw), texelFetch(jointMatrices, jw + 1), texelFetch(jointMatrices, jw + 2), texelFetch(jointMatrices, jw + 3));" - + "outPosition = (skinMatrix * vec4(position, 1.0)).xyz;" - + "mat3 upperLeft = mat3(skinMatrix);" - + "outNormal = upperLeft * normal;" - + "outTangent.xyz = upperLeft * tangent.xyz;" - + "outTangent.w = tangent.w;" - + "}"); - GL20.glCompileShader(glShader); - - glProgramSkinnig = GL20.glCreateProgram(); - GL20.glAttachShader(glProgramSkinnig, glShader); - GL20.glDeleteShader(glShader); - GL30.glTransformFeedbackVaryings(glProgramSkinnig, new CharSequence[]{"outPosition", "outNormal", "outTangent"}, GL30.GL_SEPARATE_ATTRIBS); - GL20.glLinkProgram(glProgramSkinnig); - } - - private void processRenderedGltfModels(Map>> lookup, BiFunction, GltfModel, RenderedGltfModel> renderedGltfModelBuilder) { - lookup.forEach((modelLocation, receivers) -> { - Iterator iterator = receivers.getRight().iterator(); - do { - IGltfModelReceiver receiver = iterator.next(); - if(receiver.isReceiveSharedModel(receivers.getLeft(), gltfRenderData)) { - RenderedGltfModel renderedModel = renderedGltfModelBuilder.apply(gltfRenderData, receivers.getLeft()); - receiver.onReceiveSharedModel(renderedModel); - while(iterator.hasNext()) { - receiver = iterator.next(); - if(receiver.isReceiveSharedModel(receivers.getLeft(), gltfRenderData)) { - receiver.onReceiveSharedModel(renderedModel); - } - } - return; - } - } - while(iterator.hasNext()); - }); - } - - private void processRenderedGltfModelsGL43(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModel::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - } - - private void processRenderedGltfModelsGL40(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL40::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - } - - private void processRenderedGltfModelsGL33(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL33::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - } - - private void processRenderedGltfModelsGL30(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL30::new); - } - - private void processRenderedGltfModelsGL43Iris(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelIris::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - } - - private void processRenderedGltfModelsGL40Iris(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL40Iris::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - } - - private void processRenderedGltfModelsGL33Iris(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL33Iris::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - } - - private void processRenderedGltfModelsGL30Iris(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL30Iris::new); - } - - public enum EnumRenderedModelGLProfile { - AUTO, - GL43, - GL40, - GL33, - GL30 - } - - public EnumRenderedModelGLProfile getRenderedModelGLProfile() { - return renderedModelGLProfile; - } - - private String provider(String filename) { - return "#Set maximum version of OpenGL to enable some optimizations for rendering glTF model.\n" - + "#The AUTO means it will select maximum OpenGL version available based on your hardware. The GL43 is highest it may select.\n" - + "#The lower OpenGL version you set, the more negative impact on performance you will probably get.\n" - + "#The GL30 is a special profile which essentially the GL33 and above but replace hardware(GPU) skinning with software(CPU) skinning. This will trade a lots of CPU performance for a few GPU performance increase.\n" - + "#Allowed Values: AUTO, GL43, GL40, GL33, GL30\n" - + "RenderedModelGLProfile=AUTO"; - } + public static final String MODID = "mcgltf"; + public static final String RESOURCE_LOCATION = "resourceLocation"; + + public static final Logger logger = LogManager.getLogger(MODID); + + private static MCglTF INSTANCE; + + private final EnumRenderedModelGLProfile renderedModelGLProfile; + private final Map> loadedBufferResources = new HashMap>(); + private final Map> loadedImageResources = new HashMap>(); + private final List gltfModelReceivers = new ArrayList(); + private final List gltfRenderData = new ArrayList(); + private int glProgramSkinnig = -1; + private int defaultColorMap; + private int defaultNormalMap; + private AbstractTexture lightTexture; + private BooleanSupplier shaderModActive; + + public MCglTF() { + INSTANCE = this; + renderedModelGLProfile = EnumRenderedModelGLProfile.valueOf(SimpleConfig.of(MODID).provider(this::provider).request().getOrDefault("RenderedModelGLProfile", "AUTO")); + } + + public static MCglTF getInstance() { + return INSTANCE; + } + + @Override + public void onInitialize() { + Consumer>>> processRenderedGltfModelSelector; + if (FabricLoader.getInstance().isModLoaded("iris")) { + shaderModActive = net.irisshaders.iris.api.v0.IrisApi.getInstance()::isShaderPackInUse; + + processRenderedGltfModelSelector = (lookup) -> { + switch (renderedModelGLProfile) { + case GL43: + processRenderedGltfModelsGL43Iris(lookup); + break; + case GL40: + processRenderedGltfModelsGL40Iris(lookup); + break; + case GL33: + processRenderedGltfModelsGL33Iris(lookup); + break; + case GL30: + processRenderedGltfModelsGL30Iris(lookup); + break; + default: + GLCapabilities glCapabilities = GL.getCapabilities(); + if (glCapabilities.glTexBufferRange != 0) processRenderedGltfModelsGL43Iris(lookup); + else if (glCapabilities.glGenTransformFeedbacks != 0) processRenderedGltfModelsGL40Iris(lookup); + else processRenderedGltfModelsGL33Iris(lookup); + break; + } + }; + } else { + shaderModActive = () -> false; + + processRenderedGltfModelSelector = (lookup) -> { + switch (renderedModelGLProfile) { + case GL43: + processRenderedGltfModelsGL43(lookup); + break; + case GL40: + processRenderedGltfModelsGL40(lookup); + break; + case GL33: + processRenderedGltfModelsGL33(lookup); + break; + case GL30: + processRenderedGltfModelsGL30(lookup); + break; + default: + GLCapabilities glCapabilities = GL.getCapabilities(); + if (glCapabilities.glTexBufferRange != 0) processRenderedGltfModelsGL43(lookup); + else if (glCapabilities.glGenTransformFeedbacks != 0) processRenderedGltfModelsGL40(lookup); + else processRenderedGltfModelsGL33(lookup); + break; + } + }; + } + + Minecraft.getInstance().execute(() -> { + lightTexture = Minecraft.getInstance().getTextureManager().getTexture(new ResourceLocation("dynamic/light_map_1")); + + switch (renderedModelGLProfile) { + case GL43: + createSkinningProgramGL43(); + break; + case GL40: + case GL33: + createSkinningProgramGL33(); + break; + case GL30: + break; + default: + //Since max OpenGL version on Windows from GLCapabilities will always return 3.2 as of Minecraft 1.17, this is a workaround to check if OpenGL 4.3 is available. + if (GL.getCapabilities().glTexBufferRange != 0) createSkinningProgramGL43(); + else createSkinningProgramGL33(); + break; + } + + GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4); + + int currentTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + defaultColorMap = GL11.glGenTextures(); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, defaultColorMap); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 2, 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, Buffers.create(new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1})); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); + + defaultNormalMap = GL11.glGenTextures(); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, defaultNormalMap); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 2, 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, Buffers.create(new byte[]{-128, -128, -1, -1, -128, -128, -1, -1, -128, -128, -1, -1, -128, -128, -1, -1})); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); + + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture); + }); + + ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { + + @Override + public ResourceLocation getFabricId() { + return new ResourceLocation(MODID, "gltf_reload_listener"); + } + + @Override + public void onResourceManagerReload(ResourceManager resourceManager) { + gltfRenderData.forEach(Runnable::run); + gltfRenderData.clear(); + + GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4); + + int currentTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + Map>> lookup = new HashMap>>(); + gltfModelReceivers.forEach((receiver) -> { + ResourceLocation modelLocation = receiver.getModelLocation(); + MutablePair> receivers = lookup.get(modelLocation); + if (receivers == null) { + receivers = MutablePair.of(null, new ArrayList()); + lookup.put(modelLocation, receivers); + } + receivers.getRight().add(receiver); + }); + lookup.entrySet().parallelStream().forEach((entry) -> { + try { + entry.getValue().setLeft(new GltfModelReader().readWithoutReferences(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(entry.getKey()).orElseThrow().open()))); + } catch (IOException e) { + e.printStackTrace(); + } + }); + processRenderedGltfModelSelector.accept(lookup); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); + GL30.glBindVertexArray(0); + + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture); + + loadedBufferResources.clear(); + loadedImageResources.clear(); + } + + }); + } + + public int getGlProgramSkinnig() { + return glProgramSkinnig; + } + + public int getDefaultColorMap() { + return defaultColorMap; + } + + public int getDefaultNormalMap() { + return defaultNormalMap; + } + + public int getDefaultSpecularMap() { + return 0; + } + + public AbstractTexture getLightTexture() { + return lightTexture; + } + + public ByteBuffer getBufferResource(ResourceLocation location) { + Supplier supplier; + synchronized (loadedBufferResources) { + supplier = loadedBufferResources.get(location); + if (supplier == null) { + supplier = new Supplier() { + ByteBuffer bufferData; + + @Override + public synchronized ByteBuffer get() { + if (bufferData == null) { + try { + bufferData = Buffers.create(IOUtils.toByteArray(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(location).orElseThrow().open()))); + } catch (IOException e) { + e.printStackTrace(); + } + } + return bufferData; + } + + }; + loadedBufferResources.put(location, supplier); + } + } + return supplier.get(); + } + + public ByteBuffer getImageResource(ResourceLocation location) { + Supplier supplier; + synchronized (loadedImageResources) { + supplier = loadedImageResources.get(location); + if (supplier == null) { + supplier = new Supplier() { + ByteBuffer bufferData; + + @Override + public synchronized ByteBuffer get() { + if (bufferData == null) { + try { + bufferData = Buffers.create(IOUtils.toByteArray(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(location).orElseThrow().open()))); + } catch (IOException e) { + e.printStackTrace(); + } + } + return bufferData; + } + + }; + loadedImageResources.put(location, supplier); + } + } + return supplier.get(); + } + + public synchronized void addGltfModelReceiver(IGltfModelReceiver receiver) { + gltfModelReceivers.add(receiver); + } + + public synchronized boolean removeGltfModelReceiver(IGltfModelReceiver receiver) { + return gltfModelReceivers.remove(receiver); + } + + public boolean isShaderModActive() { + return shaderModActive.getAsBoolean(); + } + + private void createSkinningProgramGL43() { + int glShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); + GL20.glShaderSource(glShader, + "#version 430\r\n" + + "layout(location = 0) in vec4 joint;" + + "layout(location = 1) in vec4 weight;" + + "layout(location = 2) in vec3 position;" + + "layout(location = 3) in vec3 normal;" + + "layout(location = 4) in vec4 tangent;" + + "layout(std430, binding = 0) readonly buffer jointMatrixBuffer {mat4 jointMatrices[];};" + + "out vec3 outPosition;" + + "out vec3 outNormal;" + + "out vec4 outTangent;" + + "void main() {" + + "mat4 skinMatrix =" + + " weight.x * jointMatrices[int(joint.x)] +" + + " weight.y * jointMatrices[int(joint.y)] +" + + " weight.z * jointMatrices[int(joint.z)] +" + + " weight.w * jointMatrices[int(joint.w)];" + + "outPosition = (skinMatrix * vec4(position, 1.0)).xyz;" + + "mat3 upperLeft = mat3(skinMatrix);" + + "outNormal = upperLeft * normal;" + + "outTangent.xyz = upperLeft * tangent.xyz;" + + "outTangent.w = tangent.w;" + + "}"); + GL20.glCompileShader(glShader); + + glProgramSkinnig = GL20.glCreateProgram(); + GL20.glAttachShader(glProgramSkinnig, glShader); + GL20.glDeleteShader(glShader); + GL30.glTransformFeedbackVaryings(glProgramSkinnig, new CharSequence[]{"outPosition", "outNormal", "outTangent"}, GL30.GL_SEPARATE_ATTRIBS); + GL20.glLinkProgram(glProgramSkinnig); + } + + private void createSkinningProgramGL33() { + int glShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); + GL20.glShaderSource(glShader, + "#version 330\r\n" + + "layout(location = 0) in vec4 joint;" + + "layout(location = 1) in vec4 weight;" + + "layout(location = 2) in vec3 position;" + + "layout(location = 3) in vec3 normal;" + + "layout(location = 4) in vec4 tangent;" + + "uniform samplerBuffer jointMatrices;" + + "out vec3 outPosition;" + + "out vec3 outNormal;" + + "out vec4 outTangent;" + + "void main() {" + + "int jx = int(joint.x) * 4;" + + "int jy = int(joint.y) * 4;" + + "int jz = int(joint.z) * 4;" + + "int jw = int(joint.w) * 4;" + + "mat4 skinMatrix =" + + " weight.x * mat4(texelFetch(jointMatrices, jx), texelFetch(jointMatrices, jx + 1), texelFetch(jointMatrices, jx + 2), texelFetch(jointMatrices, jx + 3)) +" + + " weight.y * mat4(texelFetch(jointMatrices, jy), texelFetch(jointMatrices, jy + 1), texelFetch(jointMatrices, jy + 2), texelFetch(jointMatrices, jy + 3)) +" + + " weight.z * mat4(texelFetch(jointMatrices, jz), texelFetch(jointMatrices, jz + 1), texelFetch(jointMatrices, jz + 2), texelFetch(jointMatrices, jz + 3)) +" + + " weight.w * mat4(texelFetch(jointMatrices, jw), texelFetch(jointMatrices, jw + 1), texelFetch(jointMatrices, jw + 2), texelFetch(jointMatrices, jw + 3));" + + "outPosition = (skinMatrix * vec4(position, 1.0)).xyz;" + + "mat3 upperLeft = mat3(skinMatrix);" + + "outNormal = upperLeft * normal;" + + "outTangent.xyz = upperLeft * tangent.xyz;" + + "outTangent.w = tangent.w;" + + "}"); + GL20.glCompileShader(glShader); + + glProgramSkinnig = GL20.glCreateProgram(); + GL20.glAttachShader(glProgramSkinnig, glShader); + GL20.glDeleteShader(glShader); + GL30.glTransformFeedbackVaryings(glProgramSkinnig, new CharSequence[]{"outPosition", "outNormal", "outTangent"}, GL30.GL_SEPARATE_ATTRIBS); + GL20.glLinkProgram(glProgramSkinnig); + } + + private void processRenderedGltfModels(Map>> lookup, BiFunction, GltfModel, RenderedGltfModel> renderedGltfModelBuilder) { + lookup.forEach((modelLocation, receivers) -> { + Iterator iterator = receivers.getRight().iterator(); + do { + IGltfModelReceiver receiver = iterator.next(); + if (receiver.isReceiveSharedModel(receivers.getLeft(), gltfRenderData)) { + RenderedGltfModel renderedModel = renderedGltfModelBuilder.apply(gltfRenderData, receivers.getLeft()); + receiver.onReceiveSharedModel(renderedModel); + while (iterator.hasNext()) { + receiver = iterator.next(); + if (receiver.isReceiveSharedModel(receivers.getLeft(), gltfRenderData)) { + receiver.onReceiveSharedModel(renderedModel); + } + } + return; + } + } + while (iterator.hasNext()); + }); + } + + private void processRenderedGltfModelsGL43(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModel::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + } + + private void processRenderedGltfModelsGL40(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL40::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + } + + private void processRenderedGltfModelsGL33(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL33::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + } + + private void processRenderedGltfModelsGL30(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL30::new); + } + + private void processRenderedGltfModelsGL43Iris(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelIris::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + } + + private void processRenderedGltfModelsGL40Iris(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL40Iris::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + } + + private void processRenderedGltfModelsGL33Iris(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL33Iris::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + } + + private void processRenderedGltfModelsGL30Iris(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL30Iris::new); + } + + public EnumRenderedModelGLProfile getRenderedModelGLProfile() { + return renderedModelGLProfile; + } + + private String provider(String filename) { + return "#Set maximum version of OpenGL to enable some optimizations for rendering glTF model.\n" + + "#The AUTO means it will select maximum OpenGL version available based on your hardware. The GL43 is highest it may select.\n" + + "#The lower OpenGL version you set, the more negative impact on performance you will probably get.\n" + + "#The GL30 is a special profile which essentially the GL33 and above but replace hardware(GPU) skinning with software(CPU) skinning. This will trade a lots of CPU performance for a few GPU performance increase.\n" + + "#Allowed Values: AUTO, GL43, GL40, GL33, GL30\n" + + "RenderedModelGLProfile=AUTO"; + } + + public enum EnumRenderedModelGLProfile { + AUTO, + GL43, + GL40, + GL33, + GL30 + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfModel.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfModel.java index bb4b3d0..6bed9d6 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfModel.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfModel.java @@ -1,5125 +1,4999 @@ package com.modularmods.mcgltf; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.tuple.Pair; -import org.apache.commons.lang3.tuple.Triple; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.lwjgl.BufferUtils; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL12; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL40; -import org.lwjgl.opengl.GL43; - import com.google.gson.Gson; import com.jme3.util.mikktspace.MikkTSpaceContext; import com.jme3.util.mikktspace.MikktspaceTangentGenerator; - -import de.javagl.jgltf.model.AccessorByteData; -import de.javagl.jgltf.model.AccessorData; -import de.javagl.jgltf.model.AccessorDatas; -import de.javagl.jgltf.model.AccessorFloatData; -import de.javagl.jgltf.model.AccessorIntData; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.AccessorShortData; -import de.javagl.jgltf.model.BufferViewModel; -import de.javagl.jgltf.model.ElementType; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.MaterialModel; -import de.javagl.jgltf.model.MathUtils; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.Optionals; -import de.javagl.jgltf.model.SceneModel; -import de.javagl.jgltf.model.SkinModel; -import de.javagl.jgltf.model.TextureModel; +import de.javagl.jgltf.model.*; import de.javagl.jgltf.model.image.PixelData; import de.javagl.jgltf.model.image.PixelDatas; import de.javagl.jgltf.model.impl.DefaultNodeModel; import de.javagl.jgltf.model.v2.MaterialModelV2; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.renderer.ShaderInstance; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.tuple.Triple; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.*; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.util.*; public class RenderedGltfModel { - /** - * ShaderMod attribute location for middle UV coordinates, used for parallax occlusion mapping.
- * This may change in different Minecraft version.
- * optifine/shaders.txt - */ - public static final int mc_midTexCoord; - - /** - * ShaderMod attribute location for Tangent.
- * This may change in different Minecraft version.
- * optifine/shaders.txt - */ - public static final int at_tangent; - - /** - * ShaderMod Texture index, this may change in different Minecraft version.
- * optifine/shaders.txt - */ - public static final int COLOR_MAP_INDEX = GL13.GL_TEXTURE0; - public static int NORMAL_MAP_INDEX = GL13.GL_TEXTURE1; - public static int SPECULAR_MAP_INDEX = GL13.GL_TEXTURE3; - - public static int MODEL_VIEW_MATRIX; - public static int MODEL_VIEW_MATRIX_INVERSE; - public static int NORMAL_MATRIX; - - public static final int vaPosition = 0; - public static final int vaColor = 1; - public static final int vaUV0 = 2; - public static final int vaUV1 = 3; - public static final int vaUV2 = 4; - public static final int vaNormal = 5; - - protected static final Runnable vanillaDefaultMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); - GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - - protected static final Runnable shaderModDefaultMaterialCommand; - - public static ShaderInstance CURRENT_SHADER_INSTANCE; - protected static Matrix4f CURRENT_POSE; - protected static Matrix3f CURRENT_NORMAL; - public static Vector3f LIGHT0_DIRECTION; - public static Vector3f LIGHT1_DIRECTION; - - protected static final int skinning_joint = 0; - protected static final int skinning_weight = 1; - protected static final int skinning_position = 2; - protected static final int skinning_normal = 3; - protected static final int skinning_tangent = 4; - - protected static final int skinning_out_position = 0; - protected static final int skinning_out_normal = 1; - protected static final int skinning_out_tangent = 2; - - protected static FloatBuffer uniformFloatBuffer = null; - - protected static final FloatBuffer BUF_FLOAT_9 = BufferUtils.createFloatBuffer(9); - protected static final FloatBuffer BUF_FLOAT_16 = BufferUtils.createFloatBuffer(16); - - public static final Map NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE = new IdentityHashMap(); - - protected final Map, List, List>> rootNodeModelToCommands = new IdentityHashMap, List, List>>(); - protected final Map positionsAccessorModelToNormalsAccessorModel = new IdentityHashMap(); - protected final Map normalsAccessorModelToTangentsAccessorModel = new IdentityHashMap(); - protected final Map colorsAccessorModelVec3ToVec4 = new IdentityHashMap(); - protected final Map jointsAccessorModelUnsignedLookup = new IdentityHashMap(); - protected final Map weightsAccessorModelDequantizedLookup = new IdentityHashMap(); - protected final Map colorsMorphTargetAccessorModelToAccessorData = new IdentityHashMap(); - protected final Map texcoordsMorphTargetAccessorModelToAccessorData = new IdentityHashMap(); - protected final Map meshPrimitiveModelToTangentsAccessorModel = new IdentityHashMap(); - protected final Map, List>>> meshPrimitiveModelToUnindexed = new IdentityHashMap, List>>>(); - protected final Map bufferViewModelToGlBufferView = new IdentityHashMap(); - protected final Map textureModelToGlTexture = new IdentityHashMap(); - protected final Map materialModelToRenderedMaterial = new IdentityHashMap(); - - public final GltfModel gltfModel; - - public final List renderedGltfScenes; - - static { - if(FabricLoader.getInstance().isModLoaded("iris")) { - mc_midTexCoord = 7; - at_tangent = 8; - - shaderModDefaultMaterialCommand = () -> { - GL13.glActiveTexture(COLOR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); - if(NORMAL_MAP_INDEX != -1) { - GL13.glActiveTexture(NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultNormalMap()); - } - if(SPECULAR_MAP_INDEX != -1) { - GL13.glActiveTexture(SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultSpecularMap()); - } - GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - } - else { - mc_midTexCoord = 12; - at_tangent = 13; - - shaderModDefaultMaterialCommand = () -> { - GL13.glActiveTexture(COLOR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); - GL13.glActiveTexture(NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultNormalMap()); - GL13.glActiveTexture(SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultSpecularMap()); - GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - } - } - - protected RenderedGltfModel(GltfModel gltfModel, List renderedGltfScenes) { - this.gltfModel = gltfModel; - this.renderedGltfScenes = renderedGltfScenes; - } - - public RenderedGltfModel(List gltfRenderData, GltfModel gltfModel) { - this.gltfModel = gltfModel; - List sceneModels = gltfModel.getSceneModels(); - renderedGltfScenes = new ArrayList(sceneModels.size()); - processSceneModels(gltfRenderData, sceneModels); - } - - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for(SceneModel sceneModel : sceneModels) { - RenderedGltfScene renderedGltfScene = new RenderedGltfScene(); - renderedGltfScenes.add(renderedGltfScene); - - for(NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if(commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } - else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List skinningCommands, List vanillaRenderCommands, List shaderModRenderCommands) { - ArrayList nodeSkinningCommands = new ArrayList(); - ArrayList vanillaNodeRenderCommands = new ArrayList(); - ArrayList shaderModNodeRenderCommands = new ArrayList(); - SkinModel skinModel = nodeModel.getSkinModel(); - if(skinModel != null) { - boolean canHaveHardwareSkinning; - checkHardwareSkinning: { - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - if(!meshPrimitiveModel.getAttributes().containsKey("JOINTS_1")) { - canHaveHardwareSkinning = true; - break checkHardwareSkinning; - } - } - } - canHaveHardwareSkinning = false; - } - - int jointCount = skinModel.getJoints().size(); - - float[][] transforms = new float[jointCount][]; - float[] invertNodeTransform = new float[16]; - float[] bindShapeMatrix = new float[16]; - - if(canHaveHardwareSkinning) { - int jointMatrixSize = jointCount * 16; - float[] jointMatrices = new float[jointMatrixSize]; - - int jointMatrixBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(jointMatrixBuffer)); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixBuffer); - GL15.glBufferData(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixSize * Float.BYTES, GL15.GL_STATIC_DRAW); - - List jointMatricesTransformCommands = new ArrayList(jointCount); - for(int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - System.arraycopy(transform, 0, jointMatrices, i * 16, 16); - }); - } - - nodeSkinningCommands.add(() -> { - for(int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixBuffer); - GL15.glBufferSubData(GL43.GL_SHADER_STORAGE_BUFFER, 0, putFloatBuffer(jointMatrices)); - - GL30.glBindBufferBase(GL43.GL_SHADER_STORAGE_BUFFER, 0, jointMatrixBuffer); - }); - - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - else { - List jointMatricesTransformCommands = new ArrayList(jointCount); - for(int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - }); - } - - Runnable jointMatricesTransformCommand = () -> { - for(int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - }; - vanillaNodeRenderCommands.add(jointMatricesTransformCommand); - shaderModNodeRenderCommands.add(jointMatricesTransformCommand); - - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } - else { - if(!nodeModel.getMeshModels().isEmpty()) { - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } - nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); - if(!nodeSkinningCommands.isEmpty()) { - // Zero-scale meshes visibility optimization - // https://github.com/KhronosGroup/glTF/pull/2059 - skinningCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - nodeSkinningCommands.forEach(Runnable::run); - } - }); - } - if(!vanillaNodeRenderCommands.isEmpty()) { - vanillaRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformVanilla(nodeModel); - - vanillaNodeRenderCommands.forEach(Runnable::run); - } - }); - shaderModRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformShaderMod(nodeModel); - - shaderModNodeRenderCommands.forEach(Runnable::run); - } - }); - } - } - - protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List vanillaRenderCommands, List shaderModRenderCommands) { - Map attributes = meshPrimitiveModel.getAttributes(); - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - if(positionsAccessorModel != null) { - List renderCommand = new ArrayList(); - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - if(normalsAccessorModel != null) { - AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); - if(tangentsAccessorModel != null) { - processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if(materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - } - else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - } - } - else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if(materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if(renderedMaterial.normalTexture != null) { - processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); - } - else { - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel); - } - } - else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel); - } - } - } - else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if(materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if(renderedMaterial.normalTexture != null) { - processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); - } - else { - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); - } - } - else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); - } - } - vanillaRenderCommands.addAll(renderCommand); - shaderModRenderCommands.addAll(renderCommand); - } - } - - protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if(indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } - else { - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - }); - } - } - - protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - } - else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - } - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if(indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } - else { - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - }); - } - } - - protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - }); - } - - protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - } - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - }); - } - - protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - }); - } - - protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, float[][] jointMatrices, List skinningCommand, List vanillaRenderCommands, List shaderModRenderCommands) { - Map attributes = meshPrimitiveModel.getAttributes(); - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - if(positionsAccessorModel != null) { - List renderCommand = new ArrayList(); - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - if(normalsAccessorModel != null) { - AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); - if(tangentsAccessorModel != null) { - if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); - else processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if(materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - } - else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - } - } - else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if(materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if(renderedMaterial.normalTexture != null) { - if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - else processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); - } - else { - if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); - else processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel); - } - } - else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); - else processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel); - } - } - } - else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if(materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if(renderedMaterial.normalTexture != null) { - if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - else processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); - } - else { - if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - else processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); - } - } - else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - else processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); - } - } - vanillaRenderCommands.addAll(renderCommand); - shaderModRenderCommands.addAll(renderCommand); - } - } - - protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if(indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } - else { - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - } - - protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if(indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } - else { - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - } - - protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - - protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - - protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - - protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, float[][] jointMatrices, List vanillaRenderCommands, List shaderModRenderCommands) { - Map attributes = meshPrimitiveModel.getAttributes(); - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - if(positionsAccessorModel != null) { - List renderCommand = new ArrayList(); - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - if(normalsAccessorModel != null) { - AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); - if(tangentsAccessorModel != null) { - processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if(materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - } - else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - } - } - else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if(materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if(renderedMaterial.normalTexture != null) { - processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - } - else { - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); - } - } - else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); - } - } - } - else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if(materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if(renderedMaterial.normalTexture != null) { - processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - } - else { - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - } - } - else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - } - } - vanillaRenderCommands.addAll(renderCommand); - shaderModRenderCommands.addAll(renderCommand); - } - } - - protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel outputPositionsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - } - - AccessorModel outputNormalsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } - else { - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - } - - AccessorModel outputTangentsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if(indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } - else { - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - } - - protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel outputPositionsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - } - - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - AccessorModel outputNormalsAccessorModel; - AccessorModel outputTangentsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if(indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } - else { - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - } - - protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel outputPositionsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - } - - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - AccessorModel outputNormalsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } - else { - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel outputTangentsAccessorModel; - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); - if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - AccessorModel outputPositionsAccessorModel; - AccessorModel outputNormalsAccessorModel; - AccessorModel outputTangentsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel outputPositionsAccessorModel; - AccessorModel outputNormalsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } - else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - AccessorModel outputTangentsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - protected void applyTransformVanilla(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - Matrix3f normal = new Matrix3f(pose); - - pose.transpose(); - pose.mulLocal(CURRENT_POSE); - - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - CURRENT_SHADER_INSTANCE.MODEL_VIEW_MATRIX.set(pose); - CURRENT_SHADER_INSTANCE.MODEL_VIEW_MATRIX.upload(); - - CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.set((new Vector3f(LIGHT0_DIRECTION)).mulTranspose(normal)); - CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.set((new Vector3f(LIGHT1_DIRECTION)).mulTranspose(normal)); - CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.upload(); - CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.upload(); - } - - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - Matrix3f normal = new Matrix3f(pose); - - pose.transpose(); - pose.mulLocal(CURRENT_POSE); - - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - - pose.invert(); - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX_INVERSE, false, BUF_FLOAT_16); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } - - public static class Material { - - public class TextureInfo { - public int index; - } - - public TextureInfo baseColorTexture; - public TextureInfo normalTexture; - public TextureInfo specularTexture; - public float[] baseColorFactor; - public Boolean doubleSided; - - public Runnable vanillaMaterialCommand; - public Runnable shaderModMaterialCommand; - - public void initMaterialCommand(List gltfRenderData, RenderedGltfModel renderedModel, MaterialModel materialModel) { - int colorMap; - int normalMap; - int specularMap; - List textureModels = renderedModel.gltfModel.getTextureModels(); - if(materialModel instanceof MaterialModelV2) { - MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; - - if(baseColorTexture == null) { - TextureModel textureModel = materialModelV2.getBaseColorTexture(); - if(textureModel != null) { - colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - baseColorTexture = new TextureInfo(); - baseColorTexture.index = textureModels.indexOf(textureModel); - } - else colorMap = MCglTF.getInstance().getDefaultColorMap(); - } - else colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); - - if(normalTexture == null) { - TextureModel textureModel = materialModelV2.getNormalTexture(); - if(textureModel != null) { - normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - normalTexture = new TextureInfo(); - normalTexture.index = textureModels.indexOf(textureModel); - } - else normalMap = MCglTF.getInstance().getDefaultNormalMap(); - } - else normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); - - if(specularTexture == null) { - TextureModel textureModel = materialModelV2.getMetallicRoughnessTexture(); - if(textureModel != null) { - specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - specularTexture = new TextureInfo(); - specularTexture.index = textureModels.indexOf(textureModel); - } - else specularMap = MCglTF.getInstance().getDefaultSpecularMap(); - } - else specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); - - if(baseColorFactor == null) baseColorFactor = materialModelV2.getBaseColorFactor(); - - if(doubleSided == null) doubleSided = materialModelV2.isDoubleSided(); - } - else { - colorMap = baseColorTexture == null ? MCglTF.getInstance().getDefaultColorMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); - normalMap = normalTexture == null ? MCglTF.getInstance().getDefaultNormalMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); - specularMap = specularTexture == null ? MCglTF.getInstance().getDefaultSpecularMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); - if(baseColorFactor == null) baseColorFactor = new float[]{1.0F, 1.0F, 1.0F, 1.0F}; - if(doubleSided == null) doubleSided = false; - } - - if(doubleSided) { - vanillaMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glDisable(GL11.GL_CULL_FACE); - }; - shaderModMaterialCommand = () -> { - GL13.glActiveTexture(COLOR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL13.glActiveTexture(NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); - GL13.glActiveTexture(SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glDisable(GL11.GL_CULL_FACE); - }; - } - else { - vanillaMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - shaderModMaterialCommand = () -> { - GL13.glActiveTexture(COLOR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL13.glActiveTexture(NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); - GL13.glActiveTexture(SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - } - } - } - - public void bindArrayBufferViewModel(List gltfRenderData, BufferViewModel bufferViewModel) { - Integer glBufferView = bufferViewModelToGlBufferView.get(bufferViewModel); - if(glBufferView == null) { - Integer glBufferViewNew = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferViewNew)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferViewNew); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, bufferViewModel.getBufferViewData(), GL15.GL_STATIC_DRAW); - bufferViewModelToGlBufferView.put(bufferViewModel, glBufferViewNew); - } - else GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - } - - public int obtainElementArrayBuffer(List gltfRenderData, BufferViewModel bufferViewModel) { - Integer glBufferView = bufferViewModelToGlBufferView.get(bufferViewModel); - if(glBufferView == null) { - Integer glBufferViewNew = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferViewNew)); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glBufferViewNew); - GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, bufferViewModel.getBufferViewData(), GL15.GL_STATIC_DRAW); - bufferViewModelToGlBufferView.put(bufferViewModel, glBufferViewNew); - return glBufferViewNew; - } - else { - return glBufferView; - } - } - - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if(material == null) { - Object extras = materialModel.getExtras(); - if(extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), Material.class); - } - else material = new Material(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } - - public int obtainGlTexture(List gltfRenderData, TextureModel textureModel) { - Integer glTexture = textureModelToGlTexture.get(textureModel); - if(glTexture == null) { - PixelData pixelData = PixelDatas.create(textureModel.getImageModel().getImageData()); - if (pixelData == null) - { - MCglTF.logger.warn("Could not extract pixel data from image"); - pixelData = PixelDatas.createErrorPixelData(); - } - - Integer glTextureNew = GL11.glGenTextures(); - gltfRenderData.add(() -> GL11.glDeleteTextures(glTextureNew)); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, glTextureNew); - GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, pixelData.getWidth(), pixelData.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixelData.getPixelsRGBA()); - - int minFilter = Optionals.of( - textureModel.getMinFilter(), - GL11.GL_NEAREST_MIPMAP_LINEAR); - int magFilter = Optionals.of( - textureModel.getMagFilter(), - GL11.GL_LINEAR); - int wrapS = Optionals.of( - textureModel.getWrapS(), - GL11.GL_REPEAT); - int wrapT = Optionals.of( - textureModel.getWrapT(), - GL11.GL_REPEAT); - - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, minFilter); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, magFilter); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrapS); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrapT); - - textureModelToGlTexture.put(textureModel, glTextureNew); - - return glTextureNew; - } - else { - return glTexture; - } - } - - public AccessorModel obtainNormalsAccessorModel(AccessorModel positionsAccessorModel) { - AccessorModel normalsAccessorModel = positionsAccessorModelToNormalsAccessorModel.get(positionsAccessorModel); - if(normalsAccessorModel == null) { - int count = positionsAccessorModel.getCount(); - int numTriangles = count / 3; - normalsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, ""); - positionsAccessorModelToNormalsAccessorModel.put(positionsAccessorModel, normalsAccessorModel); - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - float vertex0[] = new float[3]; - float vertex1[] = new float[3]; - float vertex2[] = new float[3]; - float edge01[] = new float[3]; - float edge02[] = new float[3]; - float cross[] = new float[3]; - float normal[] = new float[3]; - for(int i = 0; i < numTriangles; i++) { - int index0 = i * 3; - int index1 = index0 + 1; - int index2 = index0 + 2; - - vertex0[0] = positionsAccessorData.get(index0, 0); - vertex0[1] = positionsAccessorData.get(index0, 1); - vertex0[2] = positionsAccessorData.get(index0, 2); - - vertex1[0] = positionsAccessorData.get(index1, 0); - vertex1[1] = positionsAccessorData.get(index1, 1); - vertex1[2] = positionsAccessorData.get(index1, 2); - - vertex2[0] = positionsAccessorData.get(index2, 0); - vertex2[1] = positionsAccessorData.get(index2, 1); - vertex2[2] = positionsAccessorData.get(index2, 2); - - MathUtils.subtract(vertex1, vertex0, edge01); - MathUtils.subtract(vertex2, vertex0, edge02); - MathUtils.cross(edge01, edge02, cross); - MathUtils.normalize(cross, normal); - - normalsAccessorData.set(index0, 0, normal[0]); - normalsAccessorData.set(index0, 1, normal[1]); - normalsAccessorData.set(index0, 2, normal[2]); - - normalsAccessorData.set(index1, 0, normal[0]); - normalsAccessorData.set(index1, 1, normal[1]); - normalsAccessorData.set(index1, 2, normal[2]); - - normalsAccessorData.set(index2, 0, normal[0]); - normalsAccessorData.set(index2, 1, normal[1]); - normalsAccessorData.set(index2, 2, normal[2]); - } - } - return normalsAccessorModel; - } - - /** - * Found this simple normals to tangent algorithm here:
- * How to find a randomic Vector orthogonal to a given Vector - */ - public AccessorModel obtainTangentsAccessorModel(AccessorModel normalsAccessorModel) { - AccessorModel tangentsAccessorModel = normalsAccessorModelToTangentsAccessorModel.get(normalsAccessorModel); - if(tangentsAccessorModel == null) { - int count = normalsAccessorModel.getCount(); - tangentsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); - normalsAccessorModelToTangentsAccessorModel.put(normalsAccessorModel, tangentsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - float[] normal0 = new float[3]; - float[] normal1 = new float[3]; - float[] cross = new float[3]; - float[] tangent = new float[3]; - - for(int i = 0; i < count; i++) { - normal0[0] = normalsAccessorData.get(i, 0); - normal0[1] = normalsAccessorData.get(i, 1); - normal0[2] = normalsAccessorData.get(i, 2); - - normal1[0] = -normal0[2]; - normal1[1] = normal0[0]; - normal1[2] = normal0[1]; - - MathUtils.cross(normal0, normal1, cross); - MathUtils.normalize(cross, tangent); - - tangentsAccessorData.set(i, 0, tangent[0]); - tangentsAccessorData.set(i, 1, tangent[1]); - tangentsAccessorData.set(i, 2, tangent[2]); - tangentsAccessorData.set(i, 3, 1.0F); - } - } - return tangentsAccessorModel; - } - - public AccessorModel obtainTangentsAccessorModel(MeshPrimitiveModel meshPrimitiveModel, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel) { - AccessorModel tangentsAccessorModel = meshPrimitiveModelToTangentsAccessorModel.get(meshPrimitiveModel); - if(tangentsAccessorModel == null) { - int count = positionsAccessorModel.getCount(); - int numFaces = count / 3; - tangentsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); - meshPrimitiveModelToTangentsAccessorModel.put(meshPrimitiveModel, tangentsAccessorModel); - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0]); - tangentsAccessorData.set(index, 1, tangent[1]); - tangentsAccessorData.set(index, 2, tangent[2]); - tangentsAccessorData.set(index, 3, -sign); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - return tangentsAccessorModel; - } - - public AccessorModel obtainVec4ColorsAccessorModel(AccessorModel colorsAccessorModel) { - if(colorsAccessorModel.getElementType() == ElementType.VEC3) { - AccessorModel colorsVec4AccessorModel = colorsAccessorModelVec3ToVec4.get(colorsAccessorModel); - if(colorsVec4AccessorModel == null) { - int count = colorsAccessorModel.getCount(); - colorsVec4AccessorModel = AccessorModelCreation.createAccessorModel(colorsAccessorModel.getComponentType(), count, ElementType.VEC4, ""); - colorsAccessorModelVec3ToVec4.put(colorsAccessorModel, colorsVec4AccessorModel); - AccessorData accessorData = AccessorDatas.create(colorsVec4AccessorModel); - if(accessorData instanceof AccessorByteData) { - AccessorByteData colorsVec4AccessorData = (AccessorByteData) accessorData; - AccessorByteData colorsAccessorData = AccessorDatas.createByte(colorsAccessorModel); - if(colorsAccessorData.isUnsigned()) { - for(int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, (byte) -1); - } - } - else { - for(int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, Byte.MAX_VALUE); - } - } - } - else if(accessorData instanceof AccessorShortData) { - AccessorShortData colorsVec4AccessorData = (AccessorShortData) accessorData; - AccessorShortData colorsAccessorData = AccessorDatas.createShort(colorsAccessorModel); - if(colorsAccessorData.isUnsigned()) { - for(int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, (short) -1); - } - } - else { - for(int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, Short.MAX_VALUE); - } - } - } - else if(accessorData instanceof AccessorFloatData) { - AccessorFloatData colorsVec4AccessorData = (AccessorFloatData) accessorData; - AccessorFloatData colorsAccessorData = AccessorDatas.createFloat(colorsAccessorModel); - for(int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, 1.0F); - } - } - } - return colorsVec4AccessorModel; - } - return colorsAccessorModel; - } - - public AccessorModel obtainUnsignedJointsModel(AccessorModel accessorModel) { - AccessorModel unsignedAccessorModel = jointsAccessorModelUnsignedLookup.get(accessorModel); - if(unsignedAccessorModel == null) { - int count = accessorModel.getCount(); - unsignedAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_INT, count, ElementType.VEC4, ""); - AccessorIntData unsignedAccessorData = AccessorDatas.createInt(unsignedAccessorModel); - if(accessorModel.getComponentDataType() == short.class) { - AccessorShortData accessorData = AccessorDatas.createShort(accessorModel); - for(int i = 0; i < count; i++) { - unsignedAccessorData.set(i, 0, Short.toUnsignedInt(accessorData.get(i, 0))); - unsignedAccessorData.set(i, 1, Short.toUnsignedInt(accessorData.get(i, 1))); - unsignedAccessorData.set(i, 2, Short.toUnsignedInt(accessorData.get(i, 2))); - unsignedAccessorData.set(i, 3, Short.toUnsignedInt(accessorData.get(i, 3))); - } - } - else { - AccessorByteData accessorData = AccessorDatas.createByte(accessorModel); - for(int i = 0; i < count; i++) { - unsignedAccessorData.set(i, 0, Byte.toUnsignedInt(accessorData.get(i, 0))); - unsignedAccessorData.set(i, 1, Byte.toUnsignedInt(accessorData.get(i, 1))); - unsignedAccessorData.set(i, 2, Byte.toUnsignedInt(accessorData.get(i, 2))); - unsignedAccessorData.set(i, 3, Byte.toUnsignedInt(accessorData.get(i, 3))); - } - } - jointsAccessorModelUnsignedLookup.put(accessorModel, unsignedAccessorModel); - } - return unsignedAccessorModel; - } - - public AccessorModel obtainDequantizedWeightsModel(AccessorModel accessorModel) { - AccessorModel dequantizedAccessorModel = weightsAccessorModelDequantizedLookup.get(accessorModel); - if(dequantizedAccessorModel == null) { - if(accessorModel.getComponentDataType() != float.class) { - AccessorData accessorData = AccessorDatas.create(accessorModel); - int count = accessorModel.getCount(); - dequantizedAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); - AccessorFloatData dequantizedAccessorData = AccessorDatas.createFloat(dequantizedAccessorModel); - for(int i = 0; i < count; i++) { - dequantizedAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - dequantizedAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - dequantizedAccessorData.set(i, 2, accessorData.getFloat(i, 2)); - dequantizedAccessorData.set(i, 3, accessorData.getFloat(i, 3)); - } - weightsAccessorModelDequantizedLookup.put(accessorModel, dequantizedAccessorModel); - } - else { - return accessorModel; - } - } - return dequantizedAccessorModel; - } - - public AccessorModel obtainVec3FloatMorphedModel(NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - AccessorFloatData baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - AccessorFloatData morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - - float weights[] = new float[targetAccessorDatas.size()]; - int numComponents = 3; - int numElements = morphedAccessorData.getNumElements(); - - List morphingCommands = new ArrayList(numElements * numComponents); - for(int element = 0; element < numElements; element++) { - for(int component = 0; component < numComponents; component++) { - int e = element; - int c = component; - morphingCommands.add(() -> { - float r = baseAccessorData.get(e, c); - for(int i = 0; i < weights.length; i++) { - AccessorFloatData target = targetAccessorDatas.get(i); - if(target != null) { - r += weights[i] * target.get(e, c); - } - } - morphedAccessorData.set(e, c, r); - }); - } - } - - command.add(() -> { - if(nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); - else if(meshModel.getWeights() != null) System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); - - morphingCommands.parallelStream().forEach(Runnable::run); - }); - return morphedAccessorModel; - } - - public Pair, List>> obtainUnindexed(MeshPrimitiveModel meshPrimitiveModel) { - Pair, List>> unindexed; - AccessorModel indicesAccessorModel = meshPrimitiveModel.getIndices(); - if(indicesAccessorModel != null) { - unindexed = meshPrimitiveModelToUnindexed.get(meshPrimitiveModel); - if(unindexed == null) { - int indices[] = AccessorDataUtils.readInts(AccessorDatas.create(indicesAccessorModel)); - Map attributes = meshPrimitiveModel.getAttributes(); - Map attributesUnindexed = new LinkedHashMap(attributes.size()); - attributes.forEach((name, attribute) -> { - ElementType elementType = attribute.getElementType(); - int size = elementType.getNumComponents(); - AccessorModel accessorModel = AccessorModelCreation.createAccessorModel(attribute.getComponentType(), indices.length, elementType, ""); - attributesUnindexed.put(name, accessorModel); - AccessorData accessorData = AccessorDatas.create(accessorModel); - if(accessorData instanceof AccessorByteData) { - AccessorByteData accessorDataUnindexed = (AccessorByteData) accessorData; - AccessorByteData accessorDataIndexed = AccessorDatas.createByte(attribute); - for(int i = 0; i < indices.length; i++) { - int index = indices[i]; - for(int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - else if(accessorData instanceof AccessorShortData) { - AccessorShortData accessorDataUnindexed = (AccessorShortData) accessorData; - AccessorShortData accessorDataIndexed = AccessorDatas.createShort(attribute); - for(int i = 0; i < indices.length; i++) { - int index = indices[i]; - for(int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - else if(accessorData instanceof AccessorIntData) { - AccessorIntData accessorDataUnindexed = (AccessorIntData) accessorData; - AccessorIntData accessorDataIndexed = AccessorDatas.createInt(attribute); - for(int i = 0; i < indices.length; i++) { - int index = indices[i]; - for(int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - else if(accessorData instanceof AccessorFloatData) { - AccessorFloatData accessorDataUnindexed = (AccessorFloatData) accessorData; - AccessorFloatData accessorDataIndexed = AccessorDatas.createFloat(attribute); - for(int i = 0; i < indices.length; i++) { - int index = indices[i]; - for(int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - }); - - List> targets = meshPrimitiveModel.getTargets(); - List> targetsUnindexed = new ArrayList>(targets.size()); - targets.forEach((target) -> { - Map targetUnindexed = new LinkedHashMap(target.size()); - targetsUnindexed.add(targetUnindexed); - target.forEach((name, attribute) -> { - ElementType elementType = attribute.getElementType(); - int size = elementType.getNumComponents(); - AccessorModel accessorModel = AccessorModelCreation.createAccessorModel(attribute.getComponentType(), indices.length, elementType, ""); - targetUnindexed.put(name, accessorModel); - AccessorData accessorData = AccessorDatas.create(accessorModel); - if(accessorData instanceof AccessorByteData) { - AccessorByteData accessorDataUnindexed = (AccessorByteData) accessorData; - AccessorByteData accessorDataIndexed = AccessorDatas.createByte(attribute); - for(int i = 0; i < indices.length; i++) { - int index = indices[i]; - for(int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - else if(accessorData instanceof AccessorShortData) { - AccessorShortData accessorDataUnindexed = (AccessorShortData) accessorData; - AccessorShortData accessorDataIndexed = AccessorDatas.createShort(attribute); - for(int i = 0; i < indices.length; i++) { - int index = indices[i]; - for(int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - else if(accessorData instanceof AccessorIntData) { - AccessorIntData accessorDataUnindexed = (AccessorIntData) accessorData; - AccessorIntData accessorDataIndexed = AccessorDatas.createInt(attribute); - for(int i = 0; i < indices.length; i++) { - int index = indices[i]; - for(int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - else if(accessorData instanceof AccessorFloatData) { - AccessorFloatData accessorDataUnindexed = (AccessorFloatData) accessorData; - AccessorFloatData accessorDataIndexed = AccessorDatas.createFloat(attribute); - for(int i = 0; i < indices.length; i++) { - int index = indices[i]; - for(int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - }); - }); - unindexed = Pair.of(attributesUnindexed, targetsUnindexed); - meshPrimitiveModelToUnindexed.put(meshPrimitiveModel, unindexed); - } - } - else unindexed = Pair.of(meshPrimitiveModel.getAttributes(), meshPrimitiveModel.getTargets()); - return unindexed; - } - - public List createSoftwareSkinningCommands(int pointCount, float[][] jointMatrices, Map attributes, AccessorFloatData inputPositionsAccessorData, AccessorFloatData inputNormalsAccessorData, AccessorFloatData inputTangentsAccessorData, AccessorFloatData outputPositionsAccessorData, AccessorFloatData outputNormalsAccessorData, AccessorFloatData outputTangentsAccessorData) { - int skinningAttributeCount = 0; - for(String name : attributes.keySet()) { - if(name.startsWith("JOINTS_")) { - skinningAttributeCount += 1; - } - } - AccessorIntData[] jointsAccessorDatas = new AccessorIntData[skinningAttributeCount]; - AccessorFloatData[] weightsAccessorDatas = new AccessorFloatData[skinningAttributeCount]; - attributes.forEach((name, attribute) -> { - if(name.startsWith("JOINTS_")) jointsAccessorDatas[Integer.parseInt(name.substring("JOINTS_".length()))] = AccessorDatas.createInt(obtainUnsignedJointsModel(attribute)); - else if(name.startsWith("WEIGHTS_")) weightsAccessorDatas[Integer.parseInt(name.substring("WEIGHTS_".length()))] = AccessorDatas.createFloat(obtainDequantizedWeightsModel(attribute)); - }); - - List commands = new ArrayList(pointCount); - for(int point = 0; point < pointCount; point++) { - int p = point; - commands.add(() -> { - float sm00 = 0; - float sm01 = 0; - float sm02 = 0; - float sm03 = 0; - float sm10 = 0; - float sm11 = 0; - float sm12 = 0; - float sm13 = 0; - float sm20 = 0; - float sm21 = 0; - float sm22 = 0; - float sm23 = 0; - - for(int i = 0; i < jointsAccessorDatas.length; i++) { - AccessorIntData jointsAccessorData = jointsAccessorDatas[i]; - float[] jmx = jointMatrices[jointsAccessorData.get(p, 0)]; - float[] jmy = jointMatrices[jointsAccessorData.get(p, 1)]; - float[] jmz = jointMatrices[jointsAccessorData.get(p, 2)]; - float[] jmw = jointMatrices[jointsAccessorData.get(p, 3)]; - - AccessorFloatData weightsAccessorData = weightsAccessorDatas[i]; - float wx = weightsAccessorData.get(p, 0); - float wy = weightsAccessorData.get(p, 1); - float wz = weightsAccessorData.get(p, 2); - float ww = weightsAccessorData.get(p, 3); - - sm00 += wx * jmx[ 0] + wy * jmy[ 0] + wz * jmz[ 0] + ww * jmw[ 0]; - sm01 += wx * jmx[ 4] + wy * jmy[ 4] + wz * jmz[ 4] + ww * jmw[ 4]; - sm02 += wx * jmx[ 8] + wy * jmy[ 8] + wz * jmz[ 8] + ww * jmw[ 8]; - sm03 += wx * jmx[12] + wy * jmy[12] + wz * jmz[12] + ww * jmw[12]; - sm10 += wx * jmx[ 1] + wy * jmy[ 1] + wz * jmz[ 1] + ww * jmw[ 1]; - sm11 += wx * jmx[ 5] + wy * jmy[ 5] + wz * jmz[ 5] + ww * jmw[ 5]; - sm12 += wx * jmx[ 9] + wy * jmy[ 9] + wz * jmz[ 9] + ww * jmw[ 9]; - sm13 += wx * jmx[13] + wy * jmy[13] + wz * jmz[13] + ww * jmw[13]; - sm20 += wx * jmx[ 2] + wy * jmy[ 2] + wz * jmz[ 2] + ww * jmw[ 2]; - sm21 += wx * jmx[ 6] + wy * jmy[ 6] + wz * jmz[ 6] + ww * jmw[ 6]; - sm22 += wx * jmx[10] + wy * jmy[10] + wz * jmz[10] + ww * jmw[10]; - sm23 += wx * jmx[14] + wy * jmy[14] + wz * jmz[14] + ww * jmw[14]; - } - - float px = inputPositionsAccessorData.get(p, 0); - float py = inputPositionsAccessorData.get(p, 1); - float pz = inputPositionsAccessorData.get(p, 2); - - outputPositionsAccessorData.set(p, 0, sm00 * px + sm01 * py + sm02 * pz + sm03); - outputPositionsAccessorData.set(p, 1, sm10 * px + sm11 * py + sm12 * pz + sm13); - outputPositionsAccessorData.set(p, 2, sm20 * px + sm21 * py + sm22 * pz + sm23); - - float nx = inputNormalsAccessorData.get(p, 0); - float ny = inputNormalsAccessorData.get(p, 1); - float nz = inputNormalsAccessorData.get(p, 2); - - outputNormalsAccessorData.set(p, 0, sm00 * nx + sm01 * ny + sm02 * nz); - outputNormalsAccessorData.set(p, 1, sm10 * nx + sm11 * ny + sm12 * nz); - outputNormalsAccessorData.set(p, 2, sm20 * nx + sm21 * ny + sm22 * nz); - - float tx = inputTangentsAccessorData.get(p, 0); - float ty = inputTangentsAccessorData.get(p, 1); - float tz = inputTangentsAccessorData.get(p, 2); - - outputTangentsAccessorData.set(p, 0, sm00 * tx + sm01 * ty + sm02 * tz); - outputTangentsAccessorData.set(p, 1, sm10 * tx + sm11 * ty + sm12 * tz); - outputTangentsAccessorData.set(p, 2, sm20 * tx + sm21 * ty + sm22 * tz); - }); - } - return commands; - } - - public boolean createMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { - boolean isMorphableAttribute = false; - for(Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get(attributeName); - if(accessorModel != null) { - isMorphableAttribute = true; - targetAccessorDatas.add(AccessorDatas.createFloat(accessorModel)); - } - else targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public boolean createPositionNormalMorphTarget(List> morphTargets, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, List positionTargetAccessorDatas, List normalTargetAccessorDatas) { - boolean isMorphableAttribute = false; - int count = positionsAccessorModel.getCount(); - int numTriangles = count / 3; - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - for(Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get("POSITION"); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); - positionTargetAccessorDatas.add(deltaPositionsAccessorData); - AccessorFloatData normalTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - normalTargetAccessorDatas.add(normalTargetAccessorData); - float[] vertex0 = new float[3]; - float[] vertex1 = new float[3]; - float[] vertex2 = new float[3]; - float[] edge01 = new float[3]; - float[] edge02 = new float[3]; - float[] cross = new float[3]; - float[] normal0 = new float[3]; - float[] normal1 = new float[3]; - for(int i = 0; i < numTriangles; i++) { - int index0 = i * 3; - int index1 = index0 + 1; - int index2 = index0 + 2; - - vertex0[0] = positionsAccessorData.get(index0, 0) + deltaPositionsAccessorData.get(index0, 0); - vertex0[1] = positionsAccessorData.get(index0, 1) + deltaPositionsAccessorData.get(index0, 1); - vertex0[2] = positionsAccessorData.get(index0, 2) + deltaPositionsAccessorData.get(index0, 2); - - vertex1[0] = positionsAccessorData.get(index1, 0) + deltaPositionsAccessorData.get(index1, 0); - vertex1[1] = positionsAccessorData.get(index1, 1) + deltaPositionsAccessorData.get(index1, 1); - vertex1[2] = positionsAccessorData.get(index1, 2) + deltaPositionsAccessorData.get(index1, 2); - - vertex2[0] = positionsAccessorData.get(index2, 0) + deltaPositionsAccessorData.get(index2, 0); - vertex2[1] = positionsAccessorData.get(index2, 1) + deltaPositionsAccessorData.get(index2, 1); - vertex2[2] = positionsAccessorData.get(index2, 2) + deltaPositionsAccessorData.get(index2, 2); - - normal0[0] = normalsAccessorData.get(index0, 0); - normal0[1] = normalsAccessorData.get(index0, 1); - normal0[2] = normalsAccessorData.get(index0, 2); - - MathUtils.subtract(vertex1, vertex0, edge01); - MathUtils.subtract(vertex2, vertex0, edge02); - MathUtils.cross(edge01, edge02, cross); - MathUtils.normalize(cross, normal1); - - MathUtils.subtract(normal1, normal0, normal1); - - normalTargetAccessorData.set(index0, 0, normal1[0]); - normalTargetAccessorData.set(index0, 1, normal1[1]); - normalTargetAccessorData.set(index0, 2, normal1[2]); - - normalTargetAccessorData.set(index1, 0, normal1[0]); - normalTargetAccessorData.set(index1, 1, normal1[1]); - normalTargetAccessorData.set(index1, 2, normal1[2]); - - normalTargetAccessorData.set(index2, 0, normal1[0]); - normalTargetAccessorData.set(index2, 1, normal1[1]); - normalTargetAccessorData.set(index2, 2, normal1[2]); - } - } - else { - positionTargetAccessorDatas.add(null); - normalTargetAccessorDatas.add(null); - } - } - return isMorphableAttribute; - } - - public boolean createPositionNormalTangentMorphTarget(List> morphTargets, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel, List positionTargetAccessorDatas, List normalTargetAccessorDatas, List tangentTargetAccessorDatas) { - boolean isMorphableAttribute = false; - int count = positionsAccessorModel.getCount(); - int numTriangles = count / 3; - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - for(Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get("POSITION"); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); - positionTargetAccessorDatas.add(deltaPositionsAccessorData); - AccessorFloatData normalTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - normalTargetAccessorDatas.add(normalTargetAccessorData); - AccessorFloatData tangentTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - tangentTargetAccessorDatas.add(tangentTargetAccessorData); - float[] vertex0 = new float[3]; - float[] vertex1 = new float[3]; - float[] vertex2 = new float[3]; - float[] edge01 = new float[3]; - float[] edge02 = new float[3]; - float[] cross = new float[3]; - float[] normal0 = new float[3]; - float[] normal1 = new float[3]; - float[] normal2 = new float[3]; - float[] tangent0 = new float[3]; - float[] tangent1 = new float[3]; - for(int i = 0; i < numTriangles; i++) { - int index0 = i * 3; - int index1 = index0 + 1; - int index2 = index0 + 2; - - vertex0[0] = positionsAccessorData.get(index0, 0) + deltaPositionsAccessorData.get(index0, 0); - vertex0[1] = positionsAccessorData.get(index0, 1) + deltaPositionsAccessorData.get(index0, 1); - vertex0[2] = positionsAccessorData.get(index0, 2) + deltaPositionsAccessorData.get(index0, 2); - - vertex1[0] = positionsAccessorData.get(index1, 0) + deltaPositionsAccessorData.get(index1, 0); - vertex1[1] = positionsAccessorData.get(index1, 1) + deltaPositionsAccessorData.get(index1, 1); - vertex1[2] = positionsAccessorData.get(index1, 2) + deltaPositionsAccessorData.get(index1, 2); - - vertex2[0] = positionsAccessorData.get(index2, 0) + deltaPositionsAccessorData.get(index2, 0); - vertex2[1] = positionsAccessorData.get(index2, 1) + deltaPositionsAccessorData.get(index2, 1); - vertex2[2] = positionsAccessorData.get(index2, 2) + deltaPositionsAccessorData.get(index2, 2); - - normal0[0] = normalsAccessorData.get(index0, 0); - normal0[1] = normalsAccessorData.get(index0, 1); - normal0[2] = normalsAccessorData.get(index0, 2); - - tangent0[0] = tangentsAccessorData.get(index0, 0); - tangent0[1] = tangentsAccessorData.get(index0, 1); - tangent0[2] = tangentsAccessorData.get(index0, 2); - - MathUtils.subtract(vertex1, vertex0, edge01); - MathUtils.subtract(vertex2, vertex0, edge02); - MathUtils.cross(edge01, edge02, cross); - MathUtils.normalize(cross, normal1); - - normal2[0] = -normal1[2]; - normal2[1] = normal1[0]; - normal2[2] = normal1[1]; - - MathUtils.cross(normal1, normal2, cross); - MathUtils.normalize(cross, tangent1); - - MathUtils.subtract(normal1, normal0, normal1); - MathUtils.subtract(tangent1, tangent0, tangent1); - - normalTargetAccessorData.set(index0, 0, normal1[0]); - normalTargetAccessorData.set(index0, 1, normal1[1]); - normalTargetAccessorData.set(index0, 2, normal1[2]); - - tangentTargetAccessorData.set(index0, 0, tangent1[0]); - tangentTargetAccessorData.set(index0, 1, tangent1[1]); - tangentTargetAccessorData.set(index0, 2, tangent1[2]); - - normalTargetAccessorData.set(index1, 0, normal1[0]); - normalTargetAccessorData.set(index1, 1, normal1[1]); - normalTargetAccessorData.set(index1, 2, normal1[2]); - - tangentTargetAccessorData.set(index1, 0, tangent1[0]); - tangentTargetAccessorData.set(index1, 1, tangent1[1]); - tangentTargetAccessorData.set(index1, 2, tangent1[2]); - - normalTargetAccessorData.set(index2, 0, normal1[0]); - normalTargetAccessorData.set(index2, 1, normal1[1]); - normalTargetAccessorData.set(index2, 2, normal1[2]); - - tangentTargetAccessorData.set(index2, 0, tangent1[0]); - tangentTargetAccessorData.set(index2, 1, tangent1[1]); - tangentTargetAccessorData.set(index2, 2, tangent1[2]); - } - } - else { - positionTargetAccessorDatas.add(null); - normalTargetAccessorDatas.add(null); - tangentTargetAccessorDatas.add(null); - } - } - return isMorphableAttribute; - } - - public boolean createNormalTangentMorphTarget(List> morphTargets, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel, List normalTargetAccessorDatas, List tangentTargetAccessorDatas) { - boolean isMorphableAttribute = false; - int count = normalsAccessorModel.getCount(); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - for(Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get("NORMAL"); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); - normalTargetAccessorDatas.add(deltaNormalsAccessorData); - AccessorFloatData tangentTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - tangentTargetAccessorDatas.add(tangentTargetAccessorData); - float[] normal0 = new float[3]; - float[] normal1 = new float[3]; - float[] cross = new float[3]; - float[] tangent = new float[3]; - - for(int i = 0; i < count; i++) { - normal0[0] = normalsAccessorData.get(i, 0) + deltaNormalsAccessorData.get(i, 0); - normal0[1] = normalsAccessorData.get(i, 1) + deltaNormalsAccessorData.get(i, 1); - normal0[2] = normalsAccessorData.get(i, 2) + deltaNormalsAccessorData.get(i, 2); - - normal1[0] = -normal0[2]; - normal1[1] = normal0[0]; - normal1[2] = normal0[1]; - - MathUtils.cross(normal0, normal1, cross); - MathUtils.normalize(cross, tangent); - - tangentTargetAccessorData.set(i, 0, tangent[0] - tangentsAccessorData.get(i, 0)); - tangentTargetAccessorData.set(i, 1, tangent[1] - tangentsAccessorData.get(i, 1)); - tangentTargetAccessorData.set(i, 2, tangent[2] - tangentsAccessorData.get(i, 2)); - } - } - else { - normalTargetAccessorDatas.add(null); - tangentTargetAccessorDatas.add(null); - } - } - return isMorphableAttribute; - } - - public boolean createTangentMorphTarget(List> morphTargets, List targetAccessorDatas, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel, String texcoordsAccessorName, AccessorModel tangentsAccessorModel) { - boolean isMorphableAttribute = false; - int count = positionsAccessorModel.getCount(); - int numFaces = count / 3; - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); - for(Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get("POSITION"); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); - accessorModel = morphTarget.get("NORMAL"); - if(accessorModel != null) { - AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); - accessorModel = morphTarget.get(texcoordsAccessorName); - if(accessorModel != null) { - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - else { - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - } - else { - accessorModel = morphTarget.get(texcoordsAccessorName); - if(accessorModel != null) { - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - else { - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - } - continue; - } - accessorModel = morphTarget.get("NORMAL"); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); - accessorModel = morphTarget.get(texcoordsAccessorName); - if(accessorModel != null) { - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - else { - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - continue; - } - accessorModel = morphTarget.get(texcoordsAccessorName); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - continue; - } - targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public boolean createTangentMorphTarget(List> morphTargets, List targetAccessorDatas, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel, String texcoordsAccessorName, AccessorModel tangentsAccessorModel, List normalTargetAccessorDatas) { - boolean isMorphableAttribute = false; - int count = positionsAccessorModel.getCount(); - int numFaces = count / 3; - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); - Iterator iterator = normalTargetAccessorDatas.iterator(); - for(Map morphTarget : morphTargets) { - AccessorFloatData deltaNormalsAccessorData = iterator.next(); - AccessorModel accessorModel = morphTarget.get("POSITION"); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); - accessorModel = morphTarget.get(texcoordsAccessorName); - if(accessorModel != null) { - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - else { - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - continue; - } - accessorModel = morphTarget.get(texcoordsAccessorName); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - continue; - } - targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public boolean createColorMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { - boolean isMorphableAttribute = false; - for(Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get(attributeName); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData morphAccessorData = colorsMorphTargetAccessorModelToAccessorData.get(accessorModel); - if(morphAccessorData == null) { - if(accessorModel.getElementType() == ElementType.VEC3) { - int count = accessorModel.getCount(); - morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, "")); - AccessorData accessorData = AccessorDatas.create(accessorModel); - for(int i = 0; i < count; i++) { - morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - morphAccessorData.set(i, 2, accessorData.getFloat(i, 2)); - morphAccessorData.set(i, 3, 0.0F); - } - } - else if(accessorModel.getComponentDataType() != float.class) { - int count = accessorModel.getCount(); - morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, "")); - AccessorData accessorData = AccessorDatas.create(accessorModel); - for(int i = 0; i < count; i++) { - morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - morphAccessorData.set(i, 2, accessorData.getFloat(i, 2)); - morphAccessorData.set(i, 3, accessorData.getFloat(i, 3)); - } - } - else { - morphAccessorData = AccessorDatas.createFloat(accessorModel); - } - colorsMorphTargetAccessorModelToAccessorData.put(accessorModel, morphAccessorData); - } - targetAccessorDatas.add(morphAccessorData); - } - else targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public boolean createTexcoordMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { - boolean isMorphableAttribute = false; - for(Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get(attributeName); - if(accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData morphAccessorData = texcoordsMorphTargetAccessorModelToAccessorData.get(accessorModel); - if(morphAccessorData == null) { - if(accessorModel.getComponentDataType() != float.class) { - int count = accessorModel.getCount(); - morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC2, "")); - AccessorData accessorData = AccessorDatas.create(accessorModel); - for(int i = 0; i < count; i++) { - morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - } - } - else { - morphAccessorData = AccessorDatas.createFloat(accessorModel); - } - texcoordsMorphTargetAccessorModelToAccessorData.put(accessorModel, morphAccessorData); - } - targetAccessorDatas.add(morphAccessorData); - } - else targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public void bindVec3FloatMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - AccessorFloatData baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - AccessorFloatData morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - ByteBuffer morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - - int glBufferView = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); - - float weights[] = new float[targetAccessorDatas.size()]; - int numComponents = 3; - int numElements = morphedAccessorData.getNumElements(); - - List morphingCommands = new ArrayList(numElements * numComponents); - for(int element = 0; element < numElements; element++) { - for(int component = 0; component < numComponents; component++) { - int e = element; - int c = component; - morphingCommands.add(() -> { - float r = baseAccessorData.get(e, c); - for(int i = 0; i < weights.length; i++) { - AccessorFloatData target = targetAccessorDatas.get(i); - if(target != null) { - r += weights[i] * target.get(e, c); - } - } - morphedAccessorData.set(e, c, r); - }); - } - } - - command.add(() -> { - if(nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); - else if(meshModel.getWeights() != null) System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); - - morphingCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); - }); - } - - public AccessorModel bindColorMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { - AccessorFloatData baseAccessorData; - AccessorFloatData morphedAccessorData; - ByteBuffer morphedBufferViewData; - - if(baseAccessorModel.getComponentDataType() != float.class) { - int count = baseAccessorModel.getCount(); - AccessorData accessorData = AccessorDatas.create(baseAccessorModel); - baseAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); - baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - for(int i = 0; i < count; i++) { - baseAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - baseAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - baseAccessorData.set(i, 2, accessorData.getFloat(i, 2)); - baseAccessorData.set(i, 3, accessorData.getFloat(i, 3)); - } - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - } - else { - baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - } - - int glBufferView = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); - - float weights[] = new float[targetAccessorDatas.size()]; - int numComponents = 4; - int numElements = morphedAccessorData.getNumElements(); - - List morphingCommands = new ArrayList(numElements * numComponents); - for(int element = 0; element < numElements; element++) { - for(int component = 0; component < numComponents; component++) { - int e = element; - int c = component; - morphingCommands.add(() -> { - float r = baseAccessorData.get(e, c); - for(int i = 0; i < weights.length; i++) { - AccessorFloatData target = targetAccessorDatas.get(i); - if(target != null) { - r += weights[i] * target.get(e, c); - } - } - morphedAccessorData.set(e, c, r); - }); - } - } - - command.add(() -> { - if(nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); - else if(meshModel.getWeights() != null) System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); - - morphingCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); - }); - return baseAccessorModel; - } - - public AccessorModel bindTexcoordMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { - AccessorFloatData baseAccessorData; - AccessorFloatData morphedAccessorData; - ByteBuffer morphedBufferViewData; - - if(baseAccessorModel.getComponentDataType() != float.class) { - int count = baseAccessorModel.getCount(); - AccessorData accessorData = AccessorDatas.create(baseAccessorModel); - baseAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC2, ""); - baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - for(int i = 0; i < count; i++) { - baseAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - baseAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - } - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - } - else { - baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - } - - int glBufferView = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); - - float weights[] = new float[targetAccessorDatas.size()]; - int numComponents = 2; - int numElements = morphedAccessorData.getNumElements(); - - List morphingCommands = new ArrayList(numElements * numComponents); - for(int element = 0; element < numElements; element++) { - for(int component = 0; component < numComponents; component++) { - int e = element; - int c = component; - morphingCommands.add(() -> { - float r = baseAccessorData.get(e, c); - for(int i = 0; i < weights.length; i++) { - AccessorFloatData target = targetAccessorDatas.get(i); - if(target != null) { - r += weights[i] * target.get(e, c); - } - } - morphedAccessorData.set(e, c, r); - }); - } - } - - command.add(() -> { - if(nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); - else if(meshModel.getWeights() != null) System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); - - morphingCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); - }); - return baseAccessorModel; - } - - protected static float[] findGlobalTransform(NodeModel nodeModel) { - float[] found = NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.get(nodeModel); - if(found != null) { - return found; - } - else { - List pathToNode = new ArrayList(); - pathToNode.add(nodeModel); - nodeModel = nodeModel.getParent(); - while(nodeModel != null) { - found = NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.get(nodeModel); - if(found != null) { - int i = pathToNode.size() - 1; - do { - nodeModel = pathToNode.get(i); - float[] transform = DefaultNodeModel.computeLocalTransform(nodeModel, null); - MathUtils.mul4x4(found, transform, transform); - NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.put(nodeModel, transform); - found = transform; - } - while(--i >= 0); - return found; - } - else { - pathToNode.add(nodeModel); - nodeModel = nodeModel.getParent(); - } - } - int i = pathToNode.size() - 1; - nodeModel = pathToNode.get(i); - found = DefaultNodeModel.computeLocalTransform(nodeModel, null); - while(--i >= 0) { - nodeModel = pathToNode.get(i); - float[] transform = DefaultNodeModel.computeLocalTransform(nodeModel, null); - MathUtils.mul4x4(found, transform, transform); - NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.put(nodeModel, transform); - found = transform; - } - return found; - } - } - - /** - * Put the given values into a direct FloatBuffer and return it. - * The returned buffer may always be a slice of the same instance. - * This method is supposed to be called only from the OpenGL thread. - * - * @param value The value - * @return The FloatBuffer - */ - protected static FloatBuffer putFloatBuffer(float value[]) - { - int total = value.length; - if (uniformFloatBuffer == null || uniformFloatBuffer.capacity() < total) - { - uniformFloatBuffer = BufferUtils.createFloatBuffer(total); - } - uniformFloatBuffer.position(0); - uniformFloatBuffer.limit(uniformFloatBuffer.capacity()); - uniformFloatBuffer.put(value); - uniformFloatBuffer.flip(); - return uniformFloatBuffer; - } - - public static void setCurrentPose(Matrix4f currentPose) { - CURRENT_POSE = currentPose; - } - - public static void setCurrentNormal(Matrix3f currentNormal) { - CURRENT_NORMAL = currentNormal; - } + /** + * ShaderMod attribute location for middle UV coordinates, used for parallax occlusion mapping.
+ * This may change in different Minecraft version.
+ * optifine/shaders.txt + */ + public static final int mc_midTexCoord; + + /** + * ShaderMod attribute location for Tangent.
+ * This may change in different Minecraft version.
+ * optifine/shaders.txt + */ + public static final int at_tangent; + + /** + * ShaderMod Texture index, this may change in different Minecraft version.
+ * optifine/shaders.txt + */ + public static final int COLOR_MAP_INDEX = GL13.GL_TEXTURE0; + public static final int vaPosition = 0; + public static final int vaColor = 1; + public static final int vaUV0 = 2; + public static final int vaUV1 = 3; + public static final int vaUV2 = 4; + public static final int vaNormal = 10; + public static final Map NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE = new IdentityHashMap(); + protected static final Runnable vanillaDefaultMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); + GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); + GL11.glEnable(GL11.GL_CULL_FACE); + }; + protected static final Runnable shaderModDefaultMaterialCommand; + protected static final int skinning_joint = 0; + protected static final int skinning_weight = 1; + protected static final int skinning_position = 2; + protected static final int skinning_normal = 3; + protected static final int skinning_tangent = 4; + protected static final int skinning_out_position = 0; + protected static final int skinning_out_normal = 1; + protected static final int skinning_out_tangent = 2; + protected static final FloatBuffer BUF_FLOAT_9 = BufferUtils.createFloatBuffer(9); + protected static final FloatBuffer BUF_FLOAT_16 = BufferUtils.createFloatBuffer(16); + public static int NORMAL_MAP_INDEX = GL13.GL_TEXTURE2; + public static int SPECULAR_MAP_INDEX = GL13.GL_TEXTURE1; + public static int MODEL_VIEW_MATRIX; + public static int MODEL_VIEW_MATRIX_INVERSE; + public static int NORMAL_MATRIX; + public static ShaderInstance CURRENT_SHADER_INSTANCE; + public static Vector3f LIGHT0_DIRECTION; + public static Vector3f LIGHT1_DIRECTION; + protected static Matrix4f CURRENT_POSE; + protected static Matrix3f CURRENT_NORMAL; + protected static FloatBuffer uniformFloatBuffer = null; + + static { + if (FabricLoader.getInstance().isModLoaded("iris")) { + mc_midTexCoord = 12; + at_tangent = 13; + + shaderModDefaultMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); + + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + int normalMapLocation = GL20.glGetUniformLocation(currentProgram, "normals"); + if (normalMapLocation != -1) { + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 2); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultNormalMap()); + GL20.glUniform1i(normalMapLocation, 2); + } + int specularMapLocation = GL20.glGetUniformLocation(currentProgram, "specular"); + if (specularMapLocation != -1) { + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultSpecularMap()); + GL20.glUniform1i(specularMapLocation, 1); + } + + // Enhanced color attribute with proper alpha handling + GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); + + // Add entityColor uniform support for shader packs like SEUS PTGI + int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); + if (entityColorLocation != -1) { + GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); + } + + // Ensure proper blending state for Iris rendering + GL11.glDisable(GL11.GL_BLEND); + + GL11.glEnable(GL11.GL_CULL_FACE); + }; + } else { + mc_midTexCoord = 12; + at_tangent = 13; + + shaderModDefaultMaterialCommand = () -> { + GL13.glActiveTexture(COLOR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); + GL13.glActiveTexture(NORMAL_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultNormalMap()); + GL13.glActiveTexture(SPECULAR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultSpecularMap()); + + // Enhanced color attribute with proper alpha handling + GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); + + // Add entityColor uniform support for shader packs like SEUS PTGI + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); + if (entityColorLocation != -1) { + GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); + } + + // Ensure proper blending state for non-Iris rendering + GL11.glDisable(GL11.GL_BLEND); + + GL11.glEnable(GL11.GL_CULL_FACE); + }; + } + } + + public final GltfModel gltfModel; + public final List renderedGltfScenes; + protected final Map, List, List>> rootNodeModelToCommands = new IdentityHashMap, List, List>>(); + protected final Map positionsAccessorModelToNormalsAccessorModel = new IdentityHashMap(); + protected final Map normalsAccessorModelToTangentsAccessorModel = new IdentityHashMap(); + protected final Map colorsAccessorModelVec3ToVec4 = new IdentityHashMap(); + protected final Map jointsAccessorModelUnsignedLookup = new IdentityHashMap(); + protected final Map weightsAccessorModelDequantizedLookup = new IdentityHashMap(); + protected final Map colorsMorphTargetAccessorModelToAccessorData = new IdentityHashMap(); + protected final Map texcoordsMorphTargetAccessorModelToAccessorData = new IdentityHashMap(); + protected final Map meshPrimitiveModelToTangentsAccessorModel = new IdentityHashMap(); + protected final Map, List>>> meshPrimitiveModelToUnindexed = new IdentityHashMap, List>>>(); + protected final Map bufferViewModelToGlBufferView = new IdentityHashMap(); + protected final Map textureModelToGlTexture = new IdentityHashMap(); + protected final Map materialModelToRenderedMaterial = new IdentityHashMap(); + + protected RenderedGltfModel(GltfModel gltfModel, List renderedGltfScenes) { + this.gltfModel = gltfModel; + this.renderedGltfScenes = renderedGltfScenes; + } + + public RenderedGltfModel(List gltfRenderData, GltfModel gltfModel) { + this.gltfModel = gltfModel; + List sceneModels = gltfModel.getSceneModels(); + renderedGltfScenes = new ArrayList(sceneModels.size()); + processSceneModels(gltfRenderData, sceneModels); + } + + protected static float[] findGlobalTransform(NodeModel nodeModel) { + float[] found = NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.get(nodeModel); + if (found != null) { + return found; + } else { + List pathToNode = new ArrayList(); + pathToNode.add(nodeModel); + nodeModel = nodeModel.getParent(); + while (nodeModel != null) { + found = NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.get(nodeModel); + if (found != null) { + int i = pathToNode.size() - 1; + do { + nodeModel = pathToNode.get(i); + float[] transform = DefaultNodeModel.computeLocalTransform(nodeModel, null); + MathUtils.mul4x4(found, transform, transform); + NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.put(nodeModel, transform); + found = transform; + } + while (--i >= 0); + return found; + } else { + pathToNode.add(nodeModel); + nodeModel = nodeModel.getParent(); + } + } + int i = pathToNode.size() - 1; + nodeModel = pathToNode.get(i); + found = DefaultNodeModel.computeLocalTransform(nodeModel, null); + while (--i >= 0) { + nodeModel = pathToNode.get(i); + float[] transform = DefaultNodeModel.computeLocalTransform(nodeModel, null); + MathUtils.mul4x4(found, transform, transform); + NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.put(nodeModel, transform); + found = transform; + } + return found; + } + } + + /** + * Put the given values into a direct FloatBuffer and return it. + * The returned buffer may always be a slice of the same instance. + * This method is supposed to be called only from the OpenGL thread. + * + * @param value The value + * @return The FloatBuffer + */ + protected static FloatBuffer putFloatBuffer(float value[]) { + int total = value.length; + if (uniformFloatBuffer == null || uniformFloatBuffer.capacity() < total) { + uniformFloatBuffer = BufferUtils.createFloatBuffer(total); + } + uniformFloatBuffer.position(0); + uniformFloatBuffer.limit(uniformFloatBuffer.capacity()); + uniformFloatBuffer.put(value); + uniformFloatBuffer.flip(); + return uniformFloatBuffer; + } + + public static void setCurrentPose(Matrix4f currentPose) { + CURRENT_POSE = currentPose; + } + + public static void setCurrentNormal(Matrix3f currentNormal) { + CURRENT_NORMAL = currentNormal; + } + + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for (SceneModel sceneModel : sceneModels) { + RenderedGltfScene renderedGltfScene = new RenderedGltfScene(); + renderedGltfScenes.add(renderedGltfScene); + + for (NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if (commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List skinningCommands, List vanillaRenderCommands, List shaderModRenderCommands) { + ArrayList nodeSkinningCommands = new ArrayList(); + ArrayList vanillaNodeRenderCommands = new ArrayList(); + ArrayList shaderModNodeRenderCommands = new ArrayList(); + SkinModel skinModel = nodeModel.getSkinModel(); + if (skinModel != null) { + boolean canHaveHardwareSkinning; + checkHardwareSkinning: + { + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + if (!meshPrimitiveModel.getAttributes().containsKey("JOINTS_1")) { + canHaveHardwareSkinning = true; + break checkHardwareSkinning; + } + } + } + canHaveHardwareSkinning = false; + } + + int jointCount = skinModel.getJoints().size(); + + float[][] transforms = new float[jointCount][]; + float[] invertNodeTransform = new float[16]; + float[] bindShapeMatrix = new float[16]; + + if (canHaveHardwareSkinning) { + int jointMatrixSize = jointCount * 16; + float[] jointMatrices = new float[jointMatrixSize]; + + int jointMatrixBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(jointMatrixBuffer)); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixBuffer); + GL15.glBufferData(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixSize * Float.BYTES, GL15.GL_STATIC_DRAW); + + List jointMatricesTransformCommands = new ArrayList(jointCount); + for (int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + System.arraycopy(transform, 0, jointMatrices, i * 16, 16); + }); + } + + nodeSkinningCommands.add(() -> { + for (int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixBuffer); + GL15.glBufferSubData(GL43.GL_SHADER_STORAGE_BUFFER, 0, putFloatBuffer(jointMatrices)); + + GL30.glBindBufferBase(GL43.GL_SHADER_STORAGE_BUFFER, 0, jointMatrixBuffer); + }); + + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } else { + List jointMatricesTransformCommands = new ArrayList(jointCount); + for (int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + }); + } + + Runnable jointMatricesTransformCommand = () -> { + for (int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + }; + vanillaNodeRenderCommands.add(jointMatricesTransformCommand); + shaderModNodeRenderCommands.add(jointMatricesTransformCommand); + + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } else { + if (!nodeModel.getMeshModels().isEmpty()) { + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } + nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); + if (!nodeSkinningCommands.isEmpty()) { + // Zero-scale meshes visibility optimization + // https://github.com/KhronosGroup/glTF/pull/2059 + skinningCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + nodeSkinningCommands.forEach(Runnable::run); + } + }); + } + if (!vanillaNodeRenderCommands.isEmpty()) { + vanillaRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformVanilla(nodeModel); + + vanillaNodeRenderCommands.forEach(Runnable::run); + } + }); + shaderModRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformShaderMod(nodeModel); + + shaderModNodeRenderCommands.forEach(Runnable::run); + } + }); + } + } + + protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List vanillaRenderCommands, List shaderModRenderCommands) { + Map attributes = meshPrimitiveModel.getAttributes(); + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + if (positionsAccessorModel != null) { + List renderCommand = new ArrayList(); + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + if (normalsAccessorModel != null) { + AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); + if (tangentsAccessorModel != null) { + processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if (materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + } else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + } + } else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if (materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if (renderedMaterial.normalTexture != null) { + processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); + } else { + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel); + } + } else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel); + } + } + } else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if (materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if (renderedMaterial.normalTexture != null) { + processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); + } else { + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); + } + } else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); + } + } + vanillaRenderCommands.addAll(renderCommand); + shaderModRenderCommands.addAll(renderCommand); + } + } + + protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if (indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } else { + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + } + + protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + } else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + } + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if (indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } else { + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + } + + protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + + protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + } + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + + protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + + protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, float[][] jointMatrices, List skinningCommand, List vanillaRenderCommands, List shaderModRenderCommands) { + Map attributes = meshPrimitiveModel.getAttributes(); + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + if (positionsAccessorModel != null) { + List renderCommand = new ArrayList(); + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + if (normalsAccessorModel != null) { + AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); + if (tangentsAccessorModel != null) { + if (attributes.containsKey("JOINTS_1")) + processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); + else + processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if (materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + } else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + } + } else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if (materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if (renderedMaterial.normalTexture != null) { + if (attributes.containsKey("JOINTS_1")) + processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + else + processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); + } else { + if (attributes.containsKey("JOINTS_1")) + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); + else + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel); + } + } else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + if (attributes.containsKey("JOINTS_1")) + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); + else + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel); + } + } + } else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if (materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if (renderedMaterial.normalTexture != null) { + if (attributes.containsKey("JOINTS_1")) + processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + else + processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); + } else { + if (attributes.containsKey("JOINTS_1")) + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + else + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); + } + } else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + if (attributes.containsKey("JOINTS_1")) + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + else + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); + } + } + vanillaRenderCommands.addAll(renderCommand); + shaderModRenderCommands.addAll(renderCommand); + } + } + + protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if (indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } else { + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } + } + + protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if (indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } else { + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } + } + + protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } + + protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } + + protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } + + protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, float[][] jointMatrices, List vanillaRenderCommands, List shaderModRenderCommands) { + Map attributes = meshPrimitiveModel.getAttributes(); + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + if (positionsAccessorModel != null) { + List renderCommand = new ArrayList(); + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + if (normalsAccessorModel != null) { + AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); + if (tangentsAccessorModel != null) { + processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if (materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + } else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + } + } else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if (materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if (renderedMaterial.normalTexture != null) { + processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + } else { + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); + } + } else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); + } + } + } else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if (materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if (renderedMaterial.normalTexture != null) { + processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + } else { + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + } + } else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + } + } + vanillaRenderCommands.addAll(renderCommand); + shaderModRenderCommands.addAll(renderCommand); + } + } + + protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel outputPositionsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + } + + AccessorModel outputNormalsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } else { + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + } + + AccessorModel outputTangentsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if (indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } else { + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + } + + protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel outputPositionsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + } + + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + AccessorModel outputNormalsAccessorModel; + AccessorModel outputTangentsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if (indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } else { + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + } + + protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel outputPositionsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + } + + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + AccessorModel outputNormalsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } else { + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel outputTangentsAccessorModel; + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); + if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + AccessorModel outputPositionsAccessorModel; + AccessorModel outputNormalsAccessorModel; + AccessorModel outputTangentsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel outputPositionsAccessorModel; + AccessorModel outputNormalsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + AccessorModel outputTangentsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + protected void applyTransformVanilla(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + Matrix3f normal = new Matrix3f(pose); + + pose.transpose(); + pose.mulLocal(CURRENT_POSE); + + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + CURRENT_SHADER_INSTANCE.MODEL_VIEW_MATRIX.set(pose); + CURRENT_SHADER_INSTANCE.MODEL_VIEW_MATRIX.upload(); + + CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.set((new Vector3f(LIGHT0_DIRECTION)).mulTranspose(normal)); + CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.set((new Vector3f(LIGHT1_DIRECTION)).mulTranspose(normal)); + CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.upload(); + CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.upload(); + } + + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + Matrix3f normal = new Matrix3f(pose); + + pose.transpose(); + pose.mulLocal(CURRENT_POSE); + + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + + pose.invert(); + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX_INVERSE, false, BUF_FLOAT_16); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } + + public void bindArrayBufferViewModel(List gltfRenderData, BufferViewModel bufferViewModel) { + Integer glBufferView = bufferViewModelToGlBufferView.get(bufferViewModel); + if (glBufferView == null) { + Integer glBufferViewNew = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferViewNew)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferViewNew); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, bufferViewModel.getBufferViewData(), GL15.GL_STATIC_DRAW); + bufferViewModelToGlBufferView.put(bufferViewModel, glBufferViewNew); + } else GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + } + + public int obtainElementArrayBuffer(List gltfRenderData, BufferViewModel bufferViewModel) { + Integer glBufferView = bufferViewModelToGlBufferView.get(bufferViewModel); + if (glBufferView == null) { + Integer glBufferViewNew = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferViewNew)); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glBufferViewNew); + GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, bufferViewModel.getBufferViewData(), GL15.GL_STATIC_DRAW); + bufferViewModelToGlBufferView.put(bufferViewModel, glBufferViewNew); + return glBufferViewNew; + } else { + return glBufferView; + } + } + + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if (material == null) { + Object extras = materialModel.getExtras(); + if (extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), Material.class); + } else material = new Material(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } + + public int obtainGlTexture(List gltfRenderData, TextureModel textureModel) { + Integer glTexture = textureModelToGlTexture.get(textureModel); + if (glTexture == null) { + PixelData pixelData = PixelDatas.create(textureModel.getImageModel().getImageData()); + if (pixelData == null) { + MCglTF.logger.warn("Could not extract pixel data from image"); + pixelData = PixelDatas.createErrorPixelData(); + } + + Integer glTextureNew = GL11.glGenTextures(); + gltfRenderData.add(() -> GL11.glDeleteTextures(glTextureNew)); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, glTextureNew); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, pixelData.getWidth(), pixelData.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixelData.getPixelsRGBA()); + + int minFilter = Optionals.of( + textureModel.getMinFilter(), + GL11.GL_NEAREST_MIPMAP_LINEAR); + int magFilter = Optionals.of( + textureModel.getMagFilter(), + GL11.GL_LINEAR); + int wrapS = Optionals.of( + textureModel.getWrapS(), + GL11.GL_REPEAT); + int wrapT = Optionals.of( + textureModel.getWrapT(), + GL11.GL_REPEAT); + + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, minFilter); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, magFilter); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrapS); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrapT); + + textureModelToGlTexture.put(textureModel, glTextureNew); + + return glTextureNew; + } else { + return glTexture; + } + } + + public AccessorModel obtainNormalsAccessorModel(AccessorModel positionsAccessorModel) { + AccessorModel normalsAccessorModel = positionsAccessorModelToNormalsAccessorModel.get(positionsAccessorModel); + if (normalsAccessorModel == null) { + int count = positionsAccessorModel.getCount(); + int numTriangles = count / 3; + normalsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, ""); + positionsAccessorModelToNormalsAccessorModel.put(positionsAccessorModel, normalsAccessorModel); + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + float vertex0[] = new float[3]; + float vertex1[] = new float[3]; + float vertex2[] = new float[3]; + float edge01[] = new float[3]; + float edge02[] = new float[3]; + float cross[] = new float[3]; + float normal[] = new float[3]; + for (int i = 0; i < numTriangles; i++) { + int index0 = i * 3; + int index1 = index0 + 1; + int index2 = index0 + 2; + + vertex0[0] = positionsAccessorData.get(index0, 0); + vertex0[1] = positionsAccessorData.get(index0, 1); + vertex0[2] = positionsAccessorData.get(index0, 2); + + vertex1[0] = positionsAccessorData.get(index1, 0); + vertex1[1] = positionsAccessorData.get(index1, 1); + vertex1[2] = positionsAccessorData.get(index1, 2); + + vertex2[0] = positionsAccessorData.get(index2, 0); + vertex2[1] = positionsAccessorData.get(index2, 1); + vertex2[2] = positionsAccessorData.get(index2, 2); + + MathUtils.subtract(vertex1, vertex0, edge01); + MathUtils.subtract(vertex2, vertex0, edge02); + MathUtils.cross(edge01, edge02, cross); + MathUtils.normalize(cross, normal); + + normalsAccessorData.set(index0, 0, normal[0]); + normalsAccessorData.set(index0, 1, normal[1]); + normalsAccessorData.set(index0, 2, normal[2]); + + normalsAccessorData.set(index1, 0, normal[0]); + normalsAccessorData.set(index1, 1, normal[1]); + normalsAccessorData.set(index1, 2, normal[2]); + + normalsAccessorData.set(index2, 0, normal[0]); + normalsAccessorData.set(index2, 1, normal[1]); + normalsAccessorData.set(index2, 2, normal[2]); + } + } + return normalsAccessorModel; + } + + /** + * Found this simple normals to tangent algorithm here:
+ * How to find a randomic Vector orthogonal to a given Vector + */ + public AccessorModel obtainTangentsAccessorModel(AccessorModel normalsAccessorModel) { + AccessorModel tangentsAccessorModel = normalsAccessorModelToTangentsAccessorModel.get(normalsAccessorModel); + if (tangentsAccessorModel == null) { + int count = normalsAccessorModel.getCount(); + tangentsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); + normalsAccessorModelToTangentsAccessorModel.put(normalsAccessorModel, tangentsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + float[] normal0 = new float[3]; + float[] normal1 = new float[3]; + float[] cross = new float[3]; + float[] tangent = new float[3]; + + for (int i = 0; i < count; i++) { + normal0[0] = normalsAccessorData.get(i, 0); + normal0[1] = normalsAccessorData.get(i, 1); + normal0[2] = normalsAccessorData.get(i, 2); + + normal1[0] = -normal0[2]; + normal1[1] = normal0[0]; + normal1[2] = normal0[1]; + + MathUtils.cross(normal0, normal1, cross); + MathUtils.normalize(cross, tangent); + + tangentsAccessorData.set(i, 0, tangent[0]); + tangentsAccessorData.set(i, 1, tangent[1]); + tangentsAccessorData.set(i, 2, tangent[2]); + tangentsAccessorData.set(i, 3, 1.0F); + } + } + return tangentsAccessorModel; + } + + public AccessorModel obtainTangentsAccessorModel(MeshPrimitiveModel meshPrimitiveModel, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel) { + AccessorModel tangentsAccessorModel = meshPrimitiveModelToTangentsAccessorModel.get(meshPrimitiveModel); + if (tangentsAccessorModel == null) { + int count = positionsAccessorModel.getCount(); + int numFaces = count / 3; + tangentsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); + meshPrimitiveModelToTangentsAccessorModel.put(meshPrimitiveModel, tangentsAccessorModel); + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0]); + tangentsAccessorData.set(index, 1, tangent[1]); + tangentsAccessorData.set(index, 2, tangent[2]); + tangentsAccessorData.set(index, 3, -sign); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + return tangentsAccessorModel; + } + + public AccessorModel obtainVec4ColorsAccessorModel(AccessorModel colorsAccessorModel) { + if (colorsAccessorModel.getElementType() == ElementType.VEC3) { + AccessorModel colorsVec4AccessorModel = colorsAccessorModelVec3ToVec4.get(colorsAccessorModel); + if (colorsVec4AccessorModel == null) { + int count = colorsAccessorModel.getCount(); + colorsVec4AccessorModel = AccessorModelCreation.createAccessorModel(colorsAccessorModel.getComponentType(), count, ElementType.VEC4, ""); + colorsAccessorModelVec3ToVec4.put(colorsAccessorModel, colorsVec4AccessorModel); + AccessorData accessorData = AccessorDatas.create(colorsVec4AccessorModel); + if (accessorData instanceof AccessorByteData) { + AccessorByteData colorsVec4AccessorData = (AccessorByteData) accessorData; + AccessorByteData colorsAccessorData = AccessorDatas.createByte(colorsAccessorModel); + if (colorsAccessorData.isUnsigned()) { + for (int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, (byte) -1); + } + } else { + for (int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, Byte.MAX_VALUE); + } + } + } else if (accessorData instanceof AccessorShortData) { + AccessorShortData colorsVec4AccessorData = (AccessorShortData) accessorData; + AccessorShortData colorsAccessorData = AccessorDatas.createShort(colorsAccessorModel); + if (colorsAccessorData.isUnsigned()) { + for (int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, (short) -1); + } + } else { + for (int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, Short.MAX_VALUE); + } + } + } else if (accessorData instanceof AccessorFloatData) { + AccessorFloatData colorsVec4AccessorData = (AccessorFloatData) accessorData; + AccessorFloatData colorsAccessorData = AccessorDatas.createFloat(colorsAccessorModel); + for (int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, 1.0F); + } + } + } + return colorsVec4AccessorModel; + } + return colorsAccessorModel; + } + + public AccessorModel obtainUnsignedJointsModel(AccessorModel accessorModel) { + AccessorModel unsignedAccessorModel = jointsAccessorModelUnsignedLookup.get(accessorModel); + if (unsignedAccessorModel == null) { + int count = accessorModel.getCount(); + unsignedAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_INT, count, ElementType.VEC4, ""); + AccessorIntData unsignedAccessorData = AccessorDatas.createInt(unsignedAccessorModel); + if (accessorModel.getComponentDataType() == short.class) { + AccessorShortData accessorData = AccessorDatas.createShort(accessorModel); + for (int i = 0; i < count; i++) { + unsignedAccessorData.set(i, 0, Short.toUnsignedInt(accessorData.get(i, 0))); + unsignedAccessorData.set(i, 1, Short.toUnsignedInt(accessorData.get(i, 1))); + unsignedAccessorData.set(i, 2, Short.toUnsignedInt(accessorData.get(i, 2))); + unsignedAccessorData.set(i, 3, Short.toUnsignedInt(accessorData.get(i, 3))); + } + } else { + AccessorByteData accessorData = AccessorDatas.createByte(accessorModel); + for (int i = 0; i < count; i++) { + unsignedAccessorData.set(i, 0, Byte.toUnsignedInt(accessorData.get(i, 0))); + unsignedAccessorData.set(i, 1, Byte.toUnsignedInt(accessorData.get(i, 1))); + unsignedAccessorData.set(i, 2, Byte.toUnsignedInt(accessorData.get(i, 2))); + unsignedAccessorData.set(i, 3, Byte.toUnsignedInt(accessorData.get(i, 3))); + } + } + jointsAccessorModelUnsignedLookup.put(accessorModel, unsignedAccessorModel); + } + return unsignedAccessorModel; + } + + public AccessorModel obtainDequantizedWeightsModel(AccessorModel accessorModel) { + AccessorModel dequantizedAccessorModel = weightsAccessorModelDequantizedLookup.get(accessorModel); + if (dequantizedAccessorModel == null) { + if (accessorModel.getComponentDataType() != float.class) { + AccessorData accessorData = AccessorDatas.create(accessorModel); + int count = accessorModel.getCount(); + dequantizedAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); + AccessorFloatData dequantizedAccessorData = AccessorDatas.createFloat(dequantizedAccessorModel); + for (int i = 0; i < count; i++) { + dequantizedAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + dequantizedAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + dequantizedAccessorData.set(i, 2, accessorData.getFloat(i, 2)); + dequantizedAccessorData.set(i, 3, accessorData.getFloat(i, 3)); + } + weightsAccessorModelDequantizedLookup.put(accessorModel, dequantizedAccessorModel); + } else { + return accessorModel; + } + } + return dequantizedAccessorModel; + } + + public AccessorModel obtainVec3FloatMorphedModel(NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + AccessorFloatData baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + AccessorFloatData morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + + float weights[] = new float[targetAccessorDatas.size()]; + int numComponents = 3; + int numElements = morphedAccessorData.getNumElements(); + + List morphingCommands = new ArrayList(numElements * numComponents); + for (int element = 0; element < numElements; element++) { + for (int component = 0; component < numComponents; component++) { + int e = element; + int c = component; + morphingCommands.add(() -> { + float r = baseAccessorData.get(e, c); + for (int i = 0; i < weights.length; i++) { + AccessorFloatData target = targetAccessorDatas.get(i); + if (target != null) { + r += weights[i] * target.get(e, c); + } + } + morphedAccessorData.set(e, c, r); + }); + } + } + + command.add(() -> { + if (nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); + else if (meshModel.getWeights() != null) + System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); + + morphingCommands.parallelStream().forEach(Runnable::run); + }); + return morphedAccessorModel; + } + + public Pair, List>> obtainUnindexed(MeshPrimitiveModel meshPrimitiveModel) { + Pair, List>> unindexed; + AccessorModel indicesAccessorModel = meshPrimitiveModel.getIndices(); + if (indicesAccessorModel != null) { + unindexed = meshPrimitiveModelToUnindexed.get(meshPrimitiveModel); + if (unindexed == null) { + int indices[] = AccessorDataUtils.readInts(AccessorDatas.create(indicesAccessorModel)); + Map attributes = meshPrimitiveModel.getAttributes(); + Map attributesUnindexed = new LinkedHashMap(attributes.size()); + attributes.forEach((name, attribute) -> { + ElementType elementType = attribute.getElementType(); + int size = elementType.getNumComponents(); + AccessorModel accessorModel = AccessorModelCreation.createAccessorModel(attribute.getComponentType(), indices.length, elementType, ""); + attributesUnindexed.put(name, accessorModel); + AccessorData accessorData = AccessorDatas.create(accessorModel); + if (accessorData instanceof AccessorByteData) { + AccessorByteData accessorDataUnindexed = (AccessorByteData) accessorData; + AccessorByteData accessorDataIndexed = AccessorDatas.createByte(attribute); + for (int i = 0; i < indices.length; i++) { + int index = indices[i]; + for (int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } else if (accessorData instanceof AccessorShortData) { + AccessorShortData accessorDataUnindexed = (AccessorShortData) accessorData; + AccessorShortData accessorDataIndexed = AccessorDatas.createShort(attribute); + for (int i = 0; i < indices.length; i++) { + int index = indices[i]; + for (int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } else if (accessorData instanceof AccessorIntData) { + AccessorIntData accessorDataUnindexed = (AccessorIntData) accessorData; + AccessorIntData accessorDataIndexed = AccessorDatas.createInt(attribute); + for (int i = 0; i < indices.length; i++) { + int index = indices[i]; + for (int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } else if (accessorData instanceof AccessorFloatData) { + AccessorFloatData accessorDataUnindexed = (AccessorFloatData) accessorData; + AccessorFloatData accessorDataIndexed = AccessorDatas.createFloat(attribute); + for (int i = 0; i < indices.length; i++) { + int index = indices[i]; + for (int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + }); + + List> targets = meshPrimitiveModel.getTargets(); + List> targetsUnindexed = new ArrayList>(targets.size()); + targets.forEach((target) -> { + Map targetUnindexed = new LinkedHashMap(target.size()); + targetsUnindexed.add(targetUnindexed); + target.forEach((name, attribute) -> { + ElementType elementType = attribute.getElementType(); + int size = elementType.getNumComponents(); + AccessorModel accessorModel = AccessorModelCreation.createAccessorModel(attribute.getComponentType(), indices.length, elementType, ""); + targetUnindexed.put(name, accessorModel); + AccessorData accessorData = AccessorDatas.create(accessorModel); + if (accessorData instanceof AccessorByteData) { + AccessorByteData accessorDataUnindexed = (AccessorByteData) accessorData; + AccessorByteData accessorDataIndexed = AccessorDatas.createByte(attribute); + for (int i = 0; i < indices.length; i++) { + int index = indices[i]; + for (int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } else if (accessorData instanceof AccessorShortData) { + AccessorShortData accessorDataUnindexed = (AccessorShortData) accessorData; + AccessorShortData accessorDataIndexed = AccessorDatas.createShort(attribute); + for (int i = 0; i < indices.length; i++) { + int index = indices[i]; + for (int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } else if (accessorData instanceof AccessorIntData) { + AccessorIntData accessorDataUnindexed = (AccessorIntData) accessorData; + AccessorIntData accessorDataIndexed = AccessorDatas.createInt(attribute); + for (int i = 0; i < indices.length; i++) { + int index = indices[i]; + for (int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } else if (accessorData instanceof AccessorFloatData) { + AccessorFloatData accessorDataUnindexed = (AccessorFloatData) accessorData; + AccessorFloatData accessorDataIndexed = AccessorDatas.createFloat(attribute); + for (int i = 0; i < indices.length; i++) { + int index = indices[i]; + for (int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + }); + }); + unindexed = Pair.of(attributesUnindexed, targetsUnindexed); + meshPrimitiveModelToUnindexed.put(meshPrimitiveModel, unindexed); + } + } else unindexed = Pair.of(meshPrimitiveModel.getAttributes(), meshPrimitiveModel.getTargets()); + return unindexed; + } + + public List createSoftwareSkinningCommands(int pointCount, float[][] jointMatrices, Map attributes, AccessorFloatData inputPositionsAccessorData, AccessorFloatData inputNormalsAccessorData, AccessorFloatData inputTangentsAccessorData, AccessorFloatData outputPositionsAccessorData, AccessorFloatData outputNormalsAccessorData, AccessorFloatData outputTangentsAccessorData) { + int skinningAttributeCount = 0; + for (String name : attributes.keySet()) { + if (name.startsWith("JOINTS_")) { + skinningAttributeCount += 1; + } + } + AccessorIntData[] jointsAccessorDatas = new AccessorIntData[skinningAttributeCount]; + AccessorFloatData[] weightsAccessorDatas = new AccessorFloatData[skinningAttributeCount]; + attributes.forEach((name, attribute) -> { + if (name.startsWith("JOINTS_")) + jointsAccessorDatas[Integer.parseInt(name.substring("JOINTS_".length()))] = AccessorDatas.createInt(obtainUnsignedJointsModel(attribute)); + else if (name.startsWith("WEIGHTS_")) + weightsAccessorDatas[Integer.parseInt(name.substring("WEIGHTS_".length()))] = AccessorDatas.createFloat(obtainDequantizedWeightsModel(attribute)); + }); + + List commands = new ArrayList(pointCount); + for (int point = 0; point < pointCount; point++) { + int p = point; + commands.add(() -> { + float sm00 = 0; + float sm01 = 0; + float sm02 = 0; + float sm03 = 0; + float sm10 = 0; + float sm11 = 0; + float sm12 = 0; + float sm13 = 0; + float sm20 = 0; + float sm21 = 0; + float sm22 = 0; + float sm23 = 0; + + for (int i = 0; i < jointsAccessorDatas.length; i++) { + AccessorIntData jointsAccessorData = jointsAccessorDatas[i]; + float[] jmx = jointMatrices[jointsAccessorData.get(p, 0)]; + float[] jmy = jointMatrices[jointsAccessorData.get(p, 1)]; + float[] jmz = jointMatrices[jointsAccessorData.get(p, 2)]; + float[] jmw = jointMatrices[jointsAccessorData.get(p, 3)]; + + AccessorFloatData weightsAccessorData = weightsAccessorDatas[i]; + float wx = weightsAccessorData.get(p, 0); + float wy = weightsAccessorData.get(p, 1); + float wz = weightsAccessorData.get(p, 2); + float ww = weightsAccessorData.get(p, 3); + + sm00 += wx * jmx[0] + wy * jmy[0] + wz * jmz[0] + ww * jmw[0]; + sm01 += wx * jmx[4] + wy * jmy[4] + wz * jmz[4] + ww * jmw[4]; + sm02 += wx * jmx[8] + wy * jmy[8] + wz * jmz[8] + ww * jmw[8]; + sm03 += wx * jmx[12] + wy * jmy[12] + wz * jmz[12] + ww * jmw[12]; + sm10 += wx * jmx[1] + wy * jmy[1] + wz * jmz[1] + ww * jmw[1]; + sm11 += wx * jmx[5] + wy * jmy[5] + wz * jmz[5] + ww * jmw[5]; + sm12 += wx * jmx[9] + wy * jmy[9] + wz * jmz[9] + ww * jmw[9]; + sm13 += wx * jmx[13] + wy * jmy[13] + wz * jmz[13] + ww * jmw[13]; + sm20 += wx * jmx[2] + wy * jmy[2] + wz * jmz[2] + ww * jmw[2]; + sm21 += wx * jmx[6] + wy * jmy[6] + wz * jmz[6] + ww * jmw[6]; + sm22 += wx * jmx[10] + wy * jmy[10] + wz * jmz[10] + ww * jmw[10]; + sm23 += wx * jmx[14] + wy * jmy[14] + wz * jmz[14] + ww * jmw[14]; + } + + float px = inputPositionsAccessorData.get(p, 0); + float py = inputPositionsAccessorData.get(p, 1); + float pz = inputPositionsAccessorData.get(p, 2); + + outputPositionsAccessorData.set(p, 0, sm00 * px + sm01 * py + sm02 * pz + sm03); + outputPositionsAccessorData.set(p, 1, sm10 * px + sm11 * py + sm12 * pz + sm13); + outputPositionsAccessorData.set(p, 2, sm20 * px + sm21 * py + sm22 * pz + sm23); + + float nx = inputNormalsAccessorData.get(p, 0); + float ny = inputNormalsAccessorData.get(p, 1); + float nz = inputNormalsAccessorData.get(p, 2); + + outputNormalsAccessorData.set(p, 0, sm00 * nx + sm01 * ny + sm02 * nz); + outputNormalsAccessorData.set(p, 1, sm10 * nx + sm11 * ny + sm12 * nz); + outputNormalsAccessorData.set(p, 2, sm20 * nx + sm21 * ny + sm22 * nz); + + float tx = inputTangentsAccessorData.get(p, 0); + float ty = inputTangentsAccessorData.get(p, 1); + float tz = inputTangentsAccessorData.get(p, 2); + + outputTangentsAccessorData.set(p, 0, sm00 * tx + sm01 * ty + sm02 * tz); + outputTangentsAccessorData.set(p, 1, sm10 * tx + sm11 * ty + sm12 * tz); + outputTangentsAccessorData.set(p, 2, sm20 * tx + sm21 * ty + sm22 * tz); + }); + } + return commands; + } + + public boolean createMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { + boolean isMorphableAttribute = false; + for (Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get(attributeName); + if (accessorModel != null) { + isMorphableAttribute = true; + targetAccessorDatas.add(AccessorDatas.createFloat(accessorModel)); + } else targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public boolean createPositionNormalMorphTarget(List> morphTargets, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, List positionTargetAccessorDatas, List normalTargetAccessorDatas) { + boolean isMorphableAttribute = false; + int count = positionsAccessorModel.getCount(); + int numTriangles = count / 3; + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + for (Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get("POSITION"); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); + positionTargetAccessorDatas.add(deltaPositionsAccessorData); + AccessorFloatData normalTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + normalTargetAccessorDatas.add(normalTargetAccessorData); + float[] vertex0 = new float[3]; + float[] vertex1 = new float[3]; + float[] vertex2 = new float[3]; + float[] edge01 = new float[3]; + float[] edge02 = new float[3]; + float[] cross = new float[3]; + float[] normal0 = new float[3]; + float[] normal1 = new float[3]; + for (int i = 0; i < numTriangles; i++) { + int index0 = i * 3; + int index1 = index0 + 1; + int index2 = index0 + 2; + + vertex0[0] = positionsAccessorData.get(index0, 0) + deltaPositionsAccessorData.get(index0, 0); + vertex0[1] = positionsAccessorData.get(index0, 1) + deltaPositionsAccessorData.get(index0, 1); + vertex0[2] = positionsAccessorData.get(index0, 2) + deltaPositionsAccessorData.get(index0, 2); + + vertex1[0] = positionsAccessorData.get(index1, 0) + deltaPositionsAccessorData.get(index1, 0); + vertex1[1] = positionsAccessorData.get(index1, 1) + deltaPositionsAccessorData.get(index1, 1); + vertex1[2] = positionsAccessorData.get(index1, 2) + deltaPositionsAccessorData.get(index1, 2); + + vertex2[0] = positionsAccessorData.get(index2, 0) + deltaPositionsAccessorData.get(index2, 0); + vertex2[1] = positionsAccessorData.get(index2, 1) + deltaPositionsAccessorData.get(index2, 1); + vertex2[2] = positionsAccessorData.get(index2, 2) + deltaPositionsAccessorData.get(index2, 2); + + normal0[0] = normalsAccessorData.get(index0, 0); + normal0[1] = normalsAccessorData.get(index0, 1); + normal0[2] = normalsAccessorData.get(index0, 2); + + MathUtils.subtract(vertex1, vertex0, edge01); + MathUtils.subtract(vertex2, vertex0, edge02); + MathUtils.cross(edge01, edge02, cross); + MathUtils.normalize(cross, normal1); + + MathUtils.subtract(normal1, normal0, normal1); + + normalTargetAccessorData.set(index0, 0, normal1[0]); + normalTargetAccessorData.set(index0, 1, normal1[1]); + normalTargetAccessorData.set(index0, 2, normal1[2]); + + normalTargetAccessorData.set(index1, 0, normal1[0]); + normalTargetAccessorData.set(index1, 1, normal1[1]); + normalTargetAccessorData.set(index1, 2, normal1[2]); + + normalTargetAccessorData.set(index2, 0, normal1[0]); + normalTargetAccessorData.set(index2, 1, normal1[1]); + normalTargetAccessorData.set(index2, 2, normal1[2]); + } + } else { + positionTargetAccessorDatas.add(null); + normalTargetAccessorDatas.add(null); + } + } + return isMorphableAttribute; + } + + public boolean createPositionNormalTangentMorphTarget(List> morphTargets, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel, List positionTargetAccessorDatas, List normalTargetAccessorDatas, List tangentTargetAccessorDatas) { + boolean isMorphableAttribute = false; + int count = positionsAccessorModel.getCount(); + int numTriangles = count / 3; + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + for (Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get("POSITION"); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); + positionTargetAccessorDatas.add(deltaPositionsAccessorData); + AccessorFloatData normalTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + normalTargetAccessorDatas.add(normalTargetAccessorData); + AccessorFloatData tangentTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + tangentTargetAccessorDatas.add(tangentTargetAccessorData); + float[] vertex0 = new float[3]; + float[] vertex1 = new float[3]; + float[] vertex2 = new float[3]; + float[] edge01 = new float[3]; + float[] edge02 = new float[3]; + float[] cross = new float[3]; + float[] normal0 = new float[3]; + float[] normal1 = new float[3]; + float[] normal2 = new float[3]; + float[] tangent0 = new float[3]; + float[] tangent1 = new float[3]; + for (int i = 0; i < numTriangles; i++) { + int index0 = i * 3; + int index1 = index0 + 1; + int index2 = index0 + 2; + + vertex0[0] = positionsAccessorData.get(index0, 0) + deltaPositionsAccessorData.get(index0, 0); + vertex0[1] = positionsAccessorData.get(index0, 1) + deltaPositionsAccessorData.get(index0, 1); + vertex0[2] = positionsAccessorData.get(index0, 2) + deltaPositionsAccessorData.get(index0, 2); + + vertex1[0] = positionsAccessorData.get(index1, 0) + deltaPositionsAccessorData.get(index1, 0); + vertex1[1] = positionsAccessorData.get(index1, 1) + deltaPositionsAccessorData.get(index1, 1); + vertex1[2] = positionsAccessorData.get(index1, 2) + deltaPositionsAccessorData.get(index1, 2); + + vertex2[0] = positionsAccessorData.get(index2, 0) + deltaPositionsAccessorData.get(index2, 0); + vertex2[1] = positionsAccessorData.get(index2, 1) + deltaPositionsAccessorData.get(index2, 1); + vertex2[2] = positionsAccessorData.get(index2, 2) + deltaPositionsAccessorData.get(index2, 2); + + normal0[0] = normalsAccessorData.get(index0, 0); + normal0[1] = normalsAccessorData.get(index0, 1); + normal0[2] = normalsAccessorData.get(index0, 2); + + tangent0[0] = tangentsAccessorData.get(index0, 0); + tangent0[1] = tangentsAccessorData.get(index0, 1); + tangent0[2] = tangentsAccessorData.get(index0, 2); + + MathUtils.subtract(vertex1, vertex0, edge01); + MathUtils.subtract(vertex2, vertex0, edge02); + MathUtils.cross(edge01, edge02, cross); + MathUtils.normalize(cross, normal1); + + normal2[0] = -normal1[2]; + normal2[1] = normal1[0]; + normal2[2] = normal1[1]; + + MathUtils.cross(normal1, normal2, cross); + MathUtils.normalize(cross, tangent1); + + MathUtils.subtract(normal1, normal0, normal1); + MathUtils.subtract(tangent1, tangent0, tangent1); + + normalTargetAccessorData.set(index0, 0, normal1[0]); + normalTargetAccessorData.set(index0, 1, normal1[1]); + normalTargetAccessorData.set(index0, 2, normal1[2]); + + tangentTargetAccessorData.set(index0, 0, tangent1[0]); + tangentTargetAccessorData.set(index0, 1, tangent1[1]); + tangentTargetAccessorData.set(index0, 2, tangent1[2]); + + normalTargetAccessorData.set(index1, 0, normal1[0]); + normalTargetAccessorData.set(index1, 1, normal1[1]); + normalTargetAccessorData.set(index1, 2, normal1[2]); + + tangentTargetAccessorData.set(index1, 0, tangent1[0]); + tangentTargetAccessorData.set(index1, 1, tangent1[1]); + tangentTargetAccessorData.set(index1, 2, tangent1[2]); + + normalTargetAccessorData.set(index2, 0, normal1[0]); + normalTargetAccessorData.set(index2, 1, normal1[1]); + normalTargetAccessorData.set(index2, 2, normal1[2]); + + tangentTargetAccessorData.set(index2, 0, tangent1[0]); + tangentTargetAccessorData.set(index2, 1, tangent1[1]); + tangentTargetAccessorData.set(index2, 2, tangent1[2]); + } + } else { + positionTargetAccessorDatas.add(null); + normalTargetAccessorDatas.add(null); + tangentTargetAccessorDatas.add(null); + } + } + return isMorphableAttribute; + } + + public boolean createNormalTangentMorphTarget(List> morphTargets, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel, List normalTargetAccessorDatas, List tangentTargetAccessorDatas) { + boolean isMorphableAttribute = false; + int count = normalsAccessorModel.getCount(); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + for (Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get("NORMAL"); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); + normalTargetAccessorDatas.add(deltaNormalsAccessorData); + AccessorFloatData tangentTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + tangentTargetAccessorDatas.add(tangentTargetAccessorData); + float[] normal0 = new float[3]; + float[] normal1 = new float[3]; + float[] cross = new float[3]; + float[] tangent = new float[3]; + + for (int i = 0; i < count; i++) { + normal0[0] = normalsAccessorData.get(i, 0) + deltaNormalsAccessorData.get(i, 0); + normal0[1] = normalsAccessorData.get(i, 1) + deltaNormalsAccessorData.get(i, 1); + normal0[2] = normalsAccessorData.get(i, 2) + deltaNormalsAccessorData.get(i, 2); + + normal1[0] = -normal0[2]; + normal1[1] = normal0[0]; + normal1[2] = normal0[1]; + + MathUtils.cross(normal0, normal1, cross); + MathUtils.normalize(cross, tangent); + + tangentTargetAccessorData.set(i, 0, tangent[0] - tangentsAccessorData.get(i, 0)); + tangentTargetAccessorData.set(i, 1, tangent[1] - tangentsAccessorData.get(i, 1)); + tangentTargetAccessorData.set(i, 2, tangent[2] - tangentsAccessorData.get(i, 2)); + } + } else { + normalTargetAccessorDatas.add(null); + tangentTargetAccessorDatas.add(null); + } + } + return isMorphableAttribute; + } + + public boolean createTangentMorphTarget(List> morphTargets, List targetAccessorDatas, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel, String texcoordsAccessorName, AccessorModel tangentsAccessorModel) { + boolean isMorphableAttribute = false; + int count = positionsAccessorModel.getCount(); + int numFaces = count / 3; + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); + for (Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get("POSITION"); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); + accessorModel = morphTarget.get("NORMAL"); + if (accessorModel != null) { + AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); + accessorModel = morphTarget.get(texcoordsAccessorName); + if (accessorModel != null) { + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } else { + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + } else { + accessorModel = morphTarget.get(texcoordsAccessorName); + if (accessorModel != null) { + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } else { + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + } + continue; + } + accessorModel = morphTarget.get("NORMAL"); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); + accessorModel = morphTarget.get(texcoordsAccessorName); + if (accessorModel != null) { + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } else { + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + continue; + } + accessorModel = morphTarget.get(texcoordsAccessorName); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + continue; + } + targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public boolean createTangentMorphTarget(List> morphTargets, List targetAccessorDatas, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel, String texcoordsAccessorName, AccessorModel tangentsAccessorModel, List normalTargetAccessorDatas) { + boolean isMorphableAttribute = false; + int count = positionsAccessorModel.getCount(); + int numFaces = count / 3; + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); + Iterator iterator = normalTargetAccessorDatas.iterator(); + for (Map morphTarget : morphTargets) { + AccessorFloatData deltaNormalsAccessorData = iterator.next(); + AccessorModel accessorModel = morphTarget.get("POSITION"); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); + accessorModel = morphTarget.get(texcoordsAccessorName); + if (accessorModel != null) { + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } else { + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + continue; + } + accessorModel = morphTarget.get(texcoordsAccessorName); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + continue; + } + targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public boolean createColorMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { + boolean isMorphableAttribute = false; + for (Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get(attributeName); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData morphAccessorData = colorsMorphTargetAccessorModelToAccessorData.get(accessorModel); + if (morphAccessorData == null) { + if (accessorModel.getElementType() == ElementType.VEC3) { + int count = accessorModel.getCount(); + morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, "")); + AccessorData accessorData = AccessorDatas.create(accessorModel); + for (int i = 0; i < count; i++) { + morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + morphAccessorData.set(i, 2, accessorData.getFloat(i, 2)); + morphAccessorData.set(i, 3, 0.0F); + } + } else if (accessorModel.getComponentDataType() != float.class) { + int count = accessorModel.getCount(); + morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, "")); + AccessorData accessorData = AccessorDatas.create(accessorModel); + for (int i = 0; i < count; i++) { + morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + morphAccessorData.set(i, 2, accessorData.getFloat(i, 2)); + morphAccessorData.set(i, 3, accessorData.getFloat(i, 3)); + } + } else { + morphAccessorData = AccessorDatas.createFloat(accessorModel); + } + colorsMorphTargetAccessorModelToAccessorData.put(accessorModel, morphAccessorData); + } + targetAccessorDatas.add(morphAccessorData); + } else targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public boolean createTexcoordMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { + boolean isMorphableAttribute = false; + for (Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get(attributeName); + if (accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData morphAccessorData = texcoordsMorphTargetAccessorModelToAccessorData.get(accessorModel); + if (morphAccessorData == null) { + if (accessorModel.getComponentDataType() != float.class) { + int count = accessorModel.getCount(); + morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC2, "")); + AccessorData accessorData = AccessorDatas.create(accessorModel); + for (int i = 0; i < count; i++) { + morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + } + } else { + morphAccessorData = AccessorDatas.createFloat(accessorModel); + } + texcoordsMorphTargetAccessorModelToAccessorData.put(accessorModel, morphAccessorData); + } + targetAccessorDatas.add(morphAccessorData); + } else targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public void bindVec3FloatMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + AccessorFloatData baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + AccessorFloatData morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + ByteBuffer morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + + int glBufferView = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); + + float weights[] = new float[targetAccessorDatas.size()]; + int numComponents = 3; + int numElements = morphedAccessorData.getNumElements(); + + List morphingCommands = new ArrayList(numElements * numComponents); + for (int element = 0; element < numElements; element++) { + for (int component = 0; component < numComponents; component++) { + int e = element; + int c = component; + morphingCommands.add(() -> { + float r = baseAccessorData.get(e, c); + for (int i = 0; i < weights.length; i++) { + AccessorFloatData target = targetAccessorDatas.get(i); + if (target != null) { + r += weights[i] * target.get(e, c); + } + } + morphedAccessorData.set(e, c, r); + }); + } + } + + command.add(() -> { + if (nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); + else if (meshModel.getWeights() != null) + System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); + + morphingCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); + }); + } + + public AccessorModel bindColorMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { + AccessorFloatData baseAccessorData; + AccessorFloatData morphedAccessorData; + ByteBuffer morphedBufferViewData; + + if (baseAccessorModel.getComponentDataType() != float.class) { + int count = baseAccessorModel.getCount(); + AccessorData accessorData = AccessorDatas.create(baseAccessorModel); + baseAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); + baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + for (int i = 0; i < count; i++) { + baseAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + baseAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + baseAccessorData.set(i, 2, accessorData.getFloat(i, 2)); + baseAccessorData.set(i, 3, accessorData.getFloat(i, 3)); + } + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + } else { + baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + } + + int glBufferView = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); + + float weights[] = new float[targetAccessorDatas.size()]; + int numComponents = 4; + int numElements = morphedAccessorData.getNumElements(); + + List morphingCommands = new ArrayList(numElements * numComponents); + for (int element = 0; element < numElements; element++) { + for (int component = 0; component < numComponents; component++) { + int e = element; + int c = component; + morphingCommands.add(() -> { + float r = baseAccessorData.get(e, c); + for (int i = 0; i < weights.length; i++) { + AccessorFloatData target = targetAccessorDatas.get(i); + if (target != null) { + r += weights[i] * target.get(e, c); + } + } + morphedAccessorData.set(e, c, r); + }); + } + } + + command.add(() -> { + if (nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); + else if (meshModel.getWeights() != null) + System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); + + morphingCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); + }); + return baseAccessorModel; + } + + public AccessorModel bindTexcoordMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { + AccessorFloatData baseAccessorData; + AccessorFloatData morphedAccessorData; + ByteBuffer morphedBufferViewData; + + if (baseAccessorModel.getComponentDataType() != float.class) { + int count = baseAccessorModel.getCount(); + AccessorData accessorData = AccessorDatas.create(baseAccessorModel); + baseAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC2, ""); + baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + for (int i = 0; i < count; i++) { + baseAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + baseAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + } + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + } else { + baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + } + + int glBufferView = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); + + float weights[] = new float[targetAccessorDatas.size()]; + int numComponents = 2; + int numElements = morphedAccessorData.getNumElements(); + + List morphingCommands = new ArrayList(numElements * numComponents); + for (int element = 0; element < numElements; element++) { + for (int component = 0; component < numComponents; component++) { + int e = element; + int c = component; + morphingCommands.add(() -> { + float r = baseAccessorData.get(e, c); + for (int i = 0; i < weights.length; i++) { + AccessorFloatData target = targetAccessorDatas.get(i); + if (target != null) { + r += weights[i] * target.get(e, c); + } + } + morphedAccessorData.set(e, c, r); + }); + } + } + + command.add(() -> { + if (nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); + else if (meshModel.getWeights() != null) + System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); + + morphingCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); + }); + return baseAccessorModel; + } + + public static class Material { + + public TextureInfo baseColorTexture; + public TextureInfo normalTexture; + public TextureInfo specularTexture; + public float[] baseColorFactor; + public Boolean doubleSided; + public Runnable vanillaMaterialCommand; + public Runnable shaderModMaterialCommand; + + public void initMaterialCommand(List gltfRenderData, RenderedGltfModel renderedModel, MaterialModel materialModel) { + int colorMap; + final int normalMap; + final int specularMap; + List textureModels = renderedModel.gltfModel.getTextureModels(); + if (materialModel instanceof MaterialModelV2) { + MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; + + if (baseColorTexture == null) { + TextureModel textureModel = materialModelV2.getBaseColorTexture(); + if (textureModel != null) { + colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + baseColorTexture = new TextureInfo(); + baseColorTexture.index = textureModels.indexOf(textureModel); + } else colorMap = MCglTF.getInstance().getDefaultColorMap(); + } else + colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); + + if (normalTexture == null) { + TextureModel textureModel = materialModelV2.getNormalTexture(); + if (textureModel != null) { + normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + normalTexture = new TextureInfo(); + normalTexture.index = textureModels.indexOf(textureModel); + } else normalMap = MCglTF.getInstance().getDefaultNormalMap(); + } else + normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); + + if (specularTexture == null) { + TextureModel textureModel = materialModelV2.getMetallicRoughnessTexture(); + if (textureModel != null) { + specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + specularTexture = new TextureInfo(); + specularTexture.index = textureModels.indexOf(textureModel); + } else specularMap = MCglTF.getInstance().getDefaultSpecularMap(); + } else + specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); + + if (baseColorFactor == null) baseColorFactor = materialModelV2.getBaseColorFactor(); + + if (doubleSided == null) doubleSided = materialModelV2.isDoubleSided(); + } else { + colorMap = baseColorTexture == null ? MCglTF.getInstance().getDefaultColorMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); + normalMap = normalTexture == null ? MCglTF.getInstance().getDefaultNormalMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); + specularMap = specularTexture == null ? MCglTF.getInstance().getDefaultSpecularMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); + if (baseColorFactor == null) baseColorFactor = new float[]{1.0F, 1.0F, 1.0F, 1.0F}; + if (doubleSided == null) doubleSided = false; + } + + if (doubleSided) { + vanillaMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + GL11.glDisable(GL11.GL_CULL_FACE); + }; + shaderModMaterialCommand = () -> { + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + GL11.glDisable(GL11.GL_CULL_FACE); + }; + } else { + vanillaMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + GL11.glEnable(GL11.GL_CULL_FACE); + }; + shaderModMaterialCommand = () -> { + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + GL11.glEnable(GL11.GL_CULL_FACE); + }; + } + } + + public class TextureInfo { + public int index; + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL30.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL30.java index 9d701a6..91d259b 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL30.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL30.java @@ -1,118 +1,109 @@ package com.modularmods.mcgltf; +import de.javagl.jgltf.model.*; +import org.apache.commons.lang3.tuple.Triple; + import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.tuple.Triple; +public class RenderedGltfModelGL30 extends RenderedGltfModel { -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.MathUtils; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.SceneModel; -import de.javagl.jgltf.model.SkinModel; + public RenderedGltfModelGL30(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } -public class RenderedGltfModelGL30 extends RenderedGltfModel { + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for (SceneModel sceneModel : sceneModels) { + RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL30(); + renderedGltfScenes.add(renderedGltfScene); + + for (NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if (commands == null) { + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(null, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } else { + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List vanillaRenderCommands, List shaderModRenderCommands) { + ArrayList vanillaNodeRenderCommands = new ArrayList(); + ArrayList shaderModNodeRenderCommands = new ArrayList(); + SkinModel skinModel = nodeModel.getSkinModel(); + if (skinModel != null) { + int jointCount = skinModel.getJoints().size(); + + float[][] transforms = new float[jointCount][]; + float[] invertNodeTransform = new float[16]; + float[] bindShapeMatrix = new float[16]; + + List jointMatricesTransformCommands = new ArrayList(jointCount); + for (int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + }); + } + + Runnable jointMatricesTransformCommand = () -> { + for (int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + }; + vanillaNodeRenderCommands.add(jointMatricesTransformCommand); + shaderModNodeRenderCommands.add(jointMatricesTransformCommand); + + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } else { + if (!nodeModel.getMeshModels().isEmpty()) { + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } + nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); + if (!vanillaNodeRenderCommands.isEmpty()) { + vanillaRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformVanilla(nodeModel); + + vanillaNodeRenderCommands.forEach(Runnable::run); + } + }); + shaderModRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformShaderMod(nodeModel); - public RenderedGltfModelGL30(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for(SceneModel sceneModel : sceneModels) { - RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL30(); - renderedGltfScenes.add(renderedGltfScene); - - for(NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if(commands == null) { - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(null, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } - else { - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List vanillaRenderCommands, List shaderModRenderCommands) { - ArrayList vanillaNodeRenderCommands = new ArrayList(); - ArrayList shaderModNodeRenderCommands = new ArrayList(); - SkinModel skinModel = nodeModel.getSkinModel(); - if(skinModel != null) { - int jointCount = skinModel.getJoints().size(); - - float[][] transforms = new float[jointCount][]; - float[] invertNodeTransform = new float[16]; - float[] bindShapeMatrix = new float[16]; - - List jointMatricesTransformCommands = new ArrayList(jointCount); - for(int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - }); - } - - Runnable jointMatricesTransformCommand = () -> { - for(int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - }; - vanillaNodeRenderCommands.add(jointMatricesTransformCommand); - shaderModNodeRenderCommands.add(jointMatricesTransformCommand); - - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - else { - if(!nodeModel.getMeshModels().isEmpty()) { - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } - nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); - if(!vanillaNodeRenderCommands.isEmpty()) { - vanillaRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformVanilla(nodeModel); - - vanillaNodeRenderCommands.forEach(Runnable::run); - } - }); - shaderModRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformShaderMod(nodeModel); - - shaderModNodeRenderCommands.forEach(Runnable::run); - } - }); - } - } + shaderModNodeRenderCommands.forEach(Runnable::run); + } + }); + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL33.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL33.java index c75940d..fd8a7b8 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL33.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL33.java @@ -1,9 +1,6 @@ package com.modularmods.mcgltf; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - +import de.javagl.jgltf.model.*; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import org.lwjgl.opengl.GL11; @@ -11,1156 +8,1123 @@ import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; -import de.javagl.jgltf.model.AccessorFloatData; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.SceneModel; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; public class RenderedGltfModelGL33 extends RenderedGltfModelGL40 { - public RenderedGltfModelGL33(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for(SceneModel sceneModel : sceneModels) { - RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL33(); - renderedGltfScenes.add(renderedGltfScene); - - for(NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if(commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } - else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - @Override - protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if(indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } - else { - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - } - - protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if(indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } - else { - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - } - - @Override - protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - @Override - protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if(texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - @Override - protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - if(createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - } - else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if(colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if(texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } - else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } + public RenderedGltfModelGL33(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for (SceneModel sceneModel : sceneModels) { + RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL33(); + renderedGltfScenes.add(renderedGltfScene); + + for (NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if (commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + @Override + protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if (indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } else { + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + } + + protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if (indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } else { + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + } + + @Override + protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + @Override + protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if (texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + @Override + protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + if (createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + } else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if (colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if (texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL40.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL40.java index 0e77865..f7f523b 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL40.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL40.java @@ -1,201 +1,192 @@ package com.modularmods.mcgltf; -import java.util.ArrayList; -import java.util.List; - +import de.javagl.jgltf.model.*; import org.apache.commons.lang3.tuple.Triple; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL31; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.MathUtils; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.SceneModel; -import de.javagl.jgltf.model.SkinModel; +import java.util.ArrayList; +import java.util.List; public class RenderedGltfModelGL40 extends RenderedGltfModel { - public RenderedGltfModelGL40(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for(SceneModel sceneModel : sceneModels) { - RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL40(); - renderedGltfScenes.add(renderedGltfScene); - - for(NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if(commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } - else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - @Override - protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List skinningCommands, List vanillaRenderCommands, List shaderModRenderCommands) { - ArrayList nodeSkinningCommands = new ArrayList(); - ArrayList vanillaNodeRenderCommands = new ArrayList(); - ArrayList shaderModNodeRenderCommands = new ArrayList(); - SkinModel skinModel = nodeModel.getSkinModel(); - if(skinModel != null) { - boolean canHaveHardwareSkinning; - checkHardwareSkinning: { - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - if(!meshPrimitiveModel.getAttributes().containsKey("JOINTS_1")) { - canHaveHardwareSkinning = true; - break checkHardwareSkinning; - } - } - } - canHaveHardwareSkinning = false; - } - - int jointCount = skinModel.getJoints().size(); - - float[][] transforms = new float[jointCount][]; - float[] invertNodeTransform = new float[16]; - float[] bindShapeMatrix = new float[16]; - - if(canHaveHardwareSkinning) { - int jointMatrixSize = jointCount * 16; - float[] jointMatrices = new float[jointMatrixSize]; - - int jointMatrixBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(jointMatrixBuffer)); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, jointMatrixBuffer); - GL15.glBufferData(GL31.GL_TEXTURE_BUFFER, jointMatrixSize * Float.BYTES, GL15.GL_STATIC_DRAW); - int glTexture = GL11.glGenTextures(); - gltfRenderData.add(() -> GL11.glDeleteTextures(glTexture)); - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, glTexture); - GL31.glTexBuffer(GL31.GL_TEXTURE_BUFFER, GL30.GL_RGBA32F, jointMatrixBuffer); - - List jointMatricesTransformCommands = new ArrayList(jointCount); - for(int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - System.arraycopy(transform, 0, jointMatrices, i * 16, 16); - }); - } - - nodeSkinningCommands.add(() -> { - for(int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, jointMatrixBuffer); - GL15.glBufferSubData(GL31.GL_TEXTURE_BUFFER, 0, putFloatBuffer(jointMatrices)); - - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, glTexture); - }); - - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - else { - List jointMatricesTransformCommands = new ArrayList(jointCount); - for(int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - }); - } - - Runnable jointMatricesTransformCommand = () -> { - for(int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - }; - vanillaNodeRenderCommands.add(jointMatricesTransformCommand); - shaderModNodeRenderCommands.add(jointMatricesTransformCommand); - - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } - else { - if(!nodeModel.getMeshModels().isEmpty()) { - for(MeshModel meshModel : nodeModel.getMeshModels()) { - for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } - nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); - if(!nodeSkinningCommands.isEmpty()) { - // Zero-scale meshes visibility optimization - // https://github.com/KhronosGroup/glTF/pull/2059 - skinningCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - nodeSkinningCommands.forEach(Runnable::run); - } - }); - } - if(!vanillaNodeRenderCommands.isEmpty()) { - vanillaRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformVanilla(nodeModel); - - vanillaNodeRenderCommands.forEach(Runnable::run); - } - }); - shaderModRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformShaderMod(nodeModel); - - shaderModNodeRenderCommands.forEach(Runnable::run); - } - }); - } - } + public RenderedGltfModelGL40(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for (SceneModel sceneModel : sceneModels) { + RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL40(); + renderedGltfScenes.add(renderedGltfScene); + + for (NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if (commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + @Override + protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List skinningCommands, List vanillaRenderCommands, List shaderModRenderCommands) { + ArrayList nodeSkinningCommands = new ArrayList(); + ArrayList vanillaNodeRenderCommands = new ArrayList(); + ArrayList shaderModNodeRenderCommands = new ArrayList(); + SkinModel skinModel = nodeModel.getSkinModel(); + if (skinModel != null) { + boolean canHaveHardwareSkinning; + checkHardwareSkinning: + { + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + if (!meshPrimitiveModel.getAttributes().containsKey("JOINTS_1")) { + canHaveHardwareSkinning = true; + break checkHardwareSkinning; + } + } + } + canHaveHardwareSkinning = false; + } + + int jointCount = skinModel.getJoints().size(); + + float[][] transforms = new float[jointCount][]; + float[] invertNodeTransform = new float[16]; + float[] bindShapeMatrix = new float[16]; + + if (canHaveHardwareSkinning) { + int jointMatrixSize = jointCount * 16; + float[] jointMatrices = new float[jointMatrixSize]; + + int jointMatrixBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(jointMatrixBuffer)); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, jointMatrixBuffer); + GL15.glBufferData(GL31.GL_TEXTURE_BUFFER, jointMatrixSize * Float.BYTES, GL15.GL_STATIC_DRAW); + int glTexture = GL11.glGenTextures(); + gltfRenderData.add(() -> GL11.glDeleteTextures(glTexture)); + GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, glTexture); + GL31.glTexBuffer(GL31.GL_TEXTURE_BUFFER, GL30.GL_RGBA32F, jointMatrixBuffer); + + List jointMatricesTransformCommands = new ArrayList(jointCount); + for (int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + System.arraycopy(transform, 0, jointMatrices, i * 16, 16); + }); + } + + nodeSkinningCommands.add(() -> { + for (int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, jointMatrixBuffer); + GL15.glBufferSubData(GL31.GL_TEXTURE_BUFFER, 0, putFloatBuffer(jointMatrices)); + + GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, glTexture); + }); + + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } else { + List jointMatricesTransformCommands = new ArrayList(jointCount); + for (int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + }); + } + + Runnable jointMatricesTransformCommand = () -> { + for (int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + }; + vanillaNodeRenderCommands.add(jointMatricesTransformCommand); + shaderModNodeRenderCommands.add(jointMatricesTransformCommand); + + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } else { + if (!nodeModel.getMeshModels().isEmpty()) { + for (MeshModel meshModel : nodeModel.getMeshModels()) { + for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } + nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); + if (!nodeSkinningCommands.isEmpty()) { + // Zero-scale meshes visibility optimization + // https://github.com/KhronosGroup/glTF/pull/2059 + skinningCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + nodeSkinningCommands.forEach(Runnable::run); + } + }); + } + if (!vanillaNodeRenderCommands.isEmpty()) { + vanillaRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformVanilla(nodeModel); + + vanillaNodeRenderCommands.forEach(Runnable::run); + } + }); + shaderModRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformShaderMod(nodeModel); + + shaderModNodeRenderCommands.forEach(Runnable::run); + } + }); + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfScene.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfScene.java index 15a9ca1..bd73535 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfScene.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfScene.java @@ -1,122 +1,114 @@ package com.modularmods.mcgltf; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.renderer.GameRenderer; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.opengl.*; + import java.util.ArrayList; import java.util.List; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL40; -import org.lwjgl.opengl.GL43; +public class RenderedGltfScene { -import com.mojang.blaze3d.systems.RenderSystem; + public final List skinningCommands = new ArrayList(); -import net.minecraft.client.renderer.GameRenderer; + public final List vanillaRenderCommands = new ArrayList(); -public class RenderedGltfScene { + public final List shaderModRenderCommands = new ArrayList(); + + public void renderForVanilla() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + } + + RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); + int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); + GL20.glUseProgram(entitySolidProgram); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); + + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); + + RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); + + vanillaRenderCommands.forEach(Runnable::run); + + GL20.glUseProgram(currentProgram); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); + RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); + + Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); + projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); + (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + shaderModRenderCommands.forEach(Runnable::run); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); - public final List skinningCommands = new ArrayList(); - - public final List vanillaRenderCommands = new ArrayList(); - - public final List shaderModRenderCommands = new ArrayList(); - - public void renderForVanilla() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - } - - RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); - int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); - GL20.glUseProgram(entitySolidProgram); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); - - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); - - RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); - - vanillaRenderCommands.forEach(Runnable::run); - - GL20.glUseProgram(currentProgram); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(currentProgram); - } - - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); - RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); - - Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); - projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); - (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - shaderModRenderCommands.forEach(Runnable::run); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL30.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL30.java index 87ab27e..f005fc9 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL30.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL30.java @@ -1,92 +1,90 @@ package com.modularmods.mcgltf; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.renderer.GameRenderer; import org.joml.Matrix4f; import org.joml.Vector3f; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL20; -import com.mojang.blaze3d.systems.RenderSystem; +public class RenderedGltfSceneGL30 extends RenderedGltfScene { -import net.minecraft.client.renderer.GameRenderer; + @Override + public void renderForVanilla() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); -public class RenderedGltfSceneGL30 extends RenderedGltfScene { + RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); + int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); + GL20.glUseProgram(entitySolidProgram); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); + + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); + + RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); + + vanillaRenderCommands.forEach(Runnable::run); + + GL20.glUseProgram(currentProgram); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); + RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); + + Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); + projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); + (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + shaderModRenderCommands.forEach(Runnable::run); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); - @Override - public void renderForVanilla() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); - int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); - GL20.glUseProgram(entitySolidProgram); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); - - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); - - RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); - - vanillaRenderCommands.forEach(Runnable::run); - - GL20.glUseProgram(currentProgram); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); - RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); - - Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); - projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); - (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - shaderModRenderCommands.forEach(Runnable::run); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL33.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL33.java index 71b4bf2..0109629 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL33.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL33.java @@ -1,112 +1,105 @@ package com.modularmods.mcgltf; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.renderer.GameRenderer; import org.joml.Matrix4f; import org.joml.Vector3f; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL31; +import org.lwjgl.opengl.*; -import com.mojang.blaze3d.systems.RenderSystem; +public class RenderedGltfSceneGL33 extends RenderedGltfScene { -import net.minecraft.client.renderer.GameRenderer; + @Override + public void renderForVanilla() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); -public class RenderedGltfSceneGL33 extends RenderedGltfScene { + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + } + + RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); + int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); + GL20.glUseProgram(entitySolidProgram); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); + + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); + + RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); + + vanillaRenderCommands.forEach(Runnable::run); + + GL20.glUseProgram(currentProgram); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); + RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); + + Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); + projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); + (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + shaderModRenderCommands.forEach(Runnable::run); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); - @Override - public void renderForVanilla() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - } - - RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); - int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); - GL20.glUseProgram(entitySolidProgram); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); - - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); - - RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); - - vanillaRenderCommands.forEach(Runnable::run); - - GL20.glUseProgram(currentProgram); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(currentProgram); - } - - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); - RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); - - Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); - projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); - (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - shaderModRenderCommands.forEach(Runnable::run); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL40.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL40.java index d49bb86..8982854 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL40.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL40.java @@ -1,115 +1,107 @@ package com.modularmods.mcgltf; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.renderer.GameRenderer; import org.joml.Matrix4f; import org.joml.Vector3f; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL31; -import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.*; -import com.mojang.blaze3d.systems.RenderSystem; +public class RenderedGltfSceneGL40 extends RenderedGltfScene { -import net.minecraft.client.renderer.GameRenderer; + @Override + public void renderForVanilla() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); -public class RenderedGltfSceneGL40 extends RenderedGltfScene { + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + } + + RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); + int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); + GL20.glUseProgram(entitySolidProgram); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); + + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); + + RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); + + vanillaRenderCommands.forEach(Runnable::run); + + GL20.glUseProgram(currentProgram); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); + RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); + + Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); + projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); + (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + shaderModRenderCommands.forEach(Runnable::run); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); - @Override - public void renderForVanilla() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - } - - RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); - int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); - GL20.glUseProgram(entitySolidProgram); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); - - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); - - RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); - - vanillaRenderCommands.forEach(Runnable::run); - - GL20.glUseProgram(currentProgram); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(currentProgram); - } - - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); - RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); - - Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); - projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); - (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - shaderModRenderCommands.forEach(Runnable::run); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/CubicSplineInterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/CubicSplineInterpolatedChannel.java index ab1b7b9..8c95898 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/CubicSplineInterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/CubicSplineInterpolatedChannel.java @@ -2,58 +2,56 @@ public abstract class CubicSplineInterpolatedChannel extends InterpolatedChannel { - /** - * The values. Each element of this array corresponds to one key - * frame time - */ - protected final float[][][] values; - - public CubicSplineInterpolatedChannel(float[] timesS, float[][][] values) { - super(timesS); - this.values = values; - } - - @Override - public void update(float timeS) { - float[] output = getListener(); - if(timeS <= timesS[0]) { - System.arraycopy(values[0][1], 0, output, 0, output.length); - } - else if(timeS >= timesS[timesS.length - 1]) { - System.arraycopy(values[timesS.length - 1][1], 0, output, 0, output.length); - } - else { - // Adapted from https://github.khronos.org/glTF-Tutorials/gltfTutorial/gltfTutorial_007_Animations.html#cubic-spline-interpolation - int previousIndex = computeIndex(timeS, timesS); - int nextIndex = previousIndex + 1; - - float local = timeS - timesS[previousIndex]; - float delta = timesS[nextIndex] - timesS[previousIndex]; - float alpha = local / delta; - float alpha2 = alpha * alpha; - float alpha3 = alpha2 * alpha; - - float aa = 2 * alpha3 - 3 * alpha2 + 1; - float ab = alpha3 - 2 * alpha2 + alpha; - float ac = -2 * alpha3 + 3 * alpha2; - float ad = alpha3 - alpha2; - - float[][] previous = values[previousIndex]; - float[][] next = values[nextIndex]; - - float[] previousPoint = previous[1]; - float[] nextPoint = next[1]; - float[] previousOutputTangent = previous[2]; - float[] nextInputTangent = next[0]; - - for(int i = 0; i < output.length; i++) { - float p = previousPoint[i]; - float pt = previousOutputTangent[i] * delta; - float n = nextPoint[i]; - float nt = nextInputTangent[i] * delta; - output[i] = aa * p + ab * pt + ac * n + ad * nt; - } - } - } + /** + * The values. Each element of this array corresponds to one key + * frame time + */ + protected final float[][][] values; + + public CubicSplineInterpolatedChannel(float[] timesS, float[][][] values) { + super(timesS); + this.values = values; + } + + @Override + public void update(float timeS) { + float[] output = getListener(); + if (timeS <= timesS[0]) { + System.arraycopy(values[0][1], 0, output, 0, output.length); + } else if (timeS >= timesS[timesS.length - 1]) { + System.arraycopy(values[timesS.length - 1][1], 0, output, 0, output.length); + } else { + // Adapted from https://github.khronos.org/glTF-Tutorials/gltfTutorial/gltfTutorial_007_Animations.html#cubic-spline-interpolation + int previousIndex = computeIndex(timeS, timesS); + int nextIndex = previousIndex + 1; + + float local = timeS - timesS[previousIndex]; + float delta = timesS[nextIndex] - timesS[previousIndex]; + float alpha = local / delta; + float alpha2 = alpha * alpha; + float alpha3 = alpha2 * alpha; + + float aa = 2 * alpha3 - 3 * alpha2 + 1; + float ab = alpha3 - 2 * alpha2 + alpha; + float ac = -2 * alpha3 + 3 * alpha2; + float ad = alpha3 - alpha2; + + float[][] previous = values[previousIndex]; + float[][] next = values[nextIndex]; + + float[] previousPoint = previous[1]; + float[] nextPoint = next[1]; + float[] previousOutputTangent = previous[2]; + float[] nextInputTangent = next[0]; + + for (int i = 0; i < output.length; i++) { + float p = previousPoint[i]; + float pt = previousOutputTangent[i] * delta; + float n = nextPoint[i]; + float nt = nextInputTangent[i] * delta; + output[i] = aa * p + ab * pt + ac * n + ad * nt; + } + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/GltfAnimationCreator.java b/src/main/java/com/modularmods/mcgltf/animation/GltfAnimationCreator.java index 357162f..883fe0d 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/GltfAnimationCreator.java +++ b/src/main/java/com/modularmods/mcgltf/animation/GltfAnimationCreator.java @@ -1,384 +1,376 @@ package com.modularmods.mcgltf.animation; -import java.util.ArrayList; -import java.util.List; - import com.modularmods.mcgltf.MCglTF; - -import de.javagl.jgltf.model.AccessorData; -import de.javagl.jgltf.model.AccessorFloatData; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.AnimationModel; -import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.*; import de.javagl.jgltf.model.AnimationModel.Channel; import de.javagl.jgltf.model.AnimationModel.Interpolation; import de.javagl.jgltf.model.AnimationModel.Sampler; +import java.util.ArrayList; +import java.util.List; + public final class GltfAnimationCreator { - public static List createGltfAnimation(AnimationModel animationModel) { - List channels = animationModel.getChannels(); - List interpolatedChannels = new ArrayList(channels.size()); - for(Channel channel : channels) { - Sampler sampler = channel.getSampler(); - - AccessorModel input = sampler.getInput(); - AccessorData inputData = input.getAccessorData(); - if (!(inputData instanceof AccessorFloatData)) - { - MCglTF.logger.warn("Input data is not an AccessorFloatData, but " - + inputData.getClass()); - continue; - } - AccessorFloatData inputFloatData = (AccessorFloatData)inputData; - - AccessorModel output = sampler.getOutput(); - AccessorData outputData = output.getAccessorData(); - if (!(outputData instanceof AccessorFloatData)) - { - MCglTF.logger.warn("Output data is not an AccessorFloatData, but " - + outputData.getClass()); - continue; - } - AccessorFloatData outputFloatData = (AccessorFloatData)outputData; - - int numKeyElements = inputFloatData.getNumElements(); - float[] keys = new float[numKeyElements]; - for(int e = 0; e < numKeyElements; e++) { - keys[e] = inputFloatData.get(e); - } - - int globalIndex = 0; - int numComponentsPerElement; - float[][] values; - float[][][] valuesCubic; - - NodeModel nodeModel = channel.getNodeModel(); - - String path = channel.getPath(); - Interpolation interpolation; - switch(path) { - case "translation": - numComponentsPerElement = outputData.getNumComponentsPerElement(); - interpolation = sampler.getInterpolation(); - switch(interpolation) { - case STEP: - values = new float[numKeyElements][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] translation = nodeModel.getTranslation(); - if(translation == null) { - translation = new float[numComponentsPerElement]; - nodeModel.setTranslation(translation); - } - return translation; - } - - }); - break; - case LINEAR: - values = new float[numKeyElements][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] translation = nodeModel.getTranslation(); - if(translation == null) { - translation = new float[numComponentsPerElement]; - nodeModel.setTranslation(translation); - } - return translation; - } - - }); - break; - case CUBICSPLINE: - valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[][] elements = valuesCubic[e]; - for(int i = 0; i < 3; i++) { - float[] components = elements[i]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - } - interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { - - @Override - protected float[] getListener() { - float[] translation = nodeModel.getTranslation(); - if(translation == null) { - translation = new float[numComponentsPerElement]; - nodeModel.setTranslation(translation); - } - return translation; - } - - }); - break; - default: - MCglTF.logger.warn("Interpolation type not supported: " + interpolation); - break; - } - break; - case "rotation": - numComponentsPerElement = outputData.getNumComponentsPerElement(); - interpolation = sampler.getInterpolation(); - switch(interpolation) { - case STEP: - values = new float[numKeyElements][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] rotation = nodeModel.getRotation(); - if(rotation == null) { - rotation = new float[numComponentsPerElement]; - nodeModel.setRotation(rotation); - } - return rotation; - } - - }); - break; - case LINEAR: - values = new float[numKeyElements][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new SphericalLinearInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] rotation = nodeModel.getRotation(); - if(rotation == null) { - rotation = new float[numComponentsPerElement]; - nodeModel.setRotation(rotation); - } - return rotation; - } - - }); - break; - case CUBICSPLINE: - valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[][] elements = valuesCubic[e]; - for(int i = 0; i < 3; i++) { - float[] components = elements[i]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - } - interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { - - @Override - protected float[] getListener() { - float[] rotation = nodeModel.getRotation(); - if(rotation == null) { - rotation = new float[numComponentsPerElement]; - nodeModel.setRotation(rotation); - } - return rotation; - } - - }); - break; - default: - MCglTF.logger.warn("Interpolation type not supported: " + interpolation); - break; - } - break; - case "scale": - numComponentsPerElement = outputData.getNumComponentsPerElement(); - interpolation = sampler.getInterpolation(); - switch(interpolation) { - case STEP: - values = new float[numKeyElements][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] scale = nodeModel.getScale(); - if(scale == null) { - scale = new float[numComponentsPerElement]; - nodeModel.setScale(scale); - } - return scale; - } - - }); - break; - case LINEAR: - values = new float[numKeyElements][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] scale = nodeModel.getScale(); - if(scale == null) { - scale = new float[numComponentsPerElement]; - nodeModel.setScale(scale); - } - return scale; - } - - }); - break; - case CUBICSPLINE: - valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[][] elements = valuesCubic[e]; - for(int i = 0; i < 3; i++) { - float[] components = elements[i]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - } - interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { - - @Override - protected float[] getListener() { - float[] scale = nodeModel.getScale(); - if(scale == null) { - scale = new float[numComponentsPerElement]; - nodeModel.setScale(scale); - } - return scale; - } - - }); - break; - default: - MCglTF.logger.warn("Interpolation type not supported: " + interpolation); - break; - } - break; - case "weights": - interpolation = sampler.getInterpolation(); - switch(interpolation) { - case STEP: - numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements; - values = new float[numKeyElements][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] weights = nodeModel.getWeights(); - if(weights == null) { - weights = new float[numComponentsPerElement]; - nodeModel.setWeights(weights); - } - return weights; - } - - }); - break; - case LINEAR: - numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements; - values = new float[numKeyElements][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] weights = nodeModel.getWeights(); - if(weights == null) { - weights = new float[numComponentsPerElement]; - nodeModel.setWeights(weights); - } - return weights; - } - - }); - break; - case CUBICSPLINE: - numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements / 3; - valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; - for(int e = 0; e < numKeyElements; e++) { - float[][] elements = valuesCubic[e]; - for(int i = 0; i < 3; i++) { - float[] components = elements[i]; - for(int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - } - interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { - - @Override - protected float[] getListener() { - float[] weights = nodeModel.getWeights(); - if(weights == null) { - weights = new float[numComponentsPerElement]; - nodeModel.setWeights(weights); - } - return weights; - } - - }); - break; - default: - MCglTF.logger.warn("Interpolation type not supported: " + interpolation); - break; - } - break; - default: - MCglTF.logger.warn("Animation channel target path must be " - + "\"translation\", \"rotation\", \"scale\" or \"weights\", " - + "but is " + path); - break; - } - } - return interpolatedChannels; - } + public static List createGltfAnimation(AnimationModel animationModel) { + List channels = animationModel.getChannels(); + List interpolatedChannels = new ArrayList(channels.size()); + for (Channel channel : channels) { + Sampler sampler = channel.getSampler(); + + AccessorModel input = sampler.getInput(); + AccessorData inputData = input.getAccessorData(); + if (!(inputData instanceof AccessorFloatData)) { + MCglTF.logger.warn("Input data is not an AccessorFloatData, but " + + inputData.getClass()); + continue; + } + AccessorFloatData inputFloatData = (AccessorFloatData) inputData; + AccessorModel output = sampler.getOutput(); + AccessorData outputData = output.getAccessorData(); + if (!(outputData instanceof AccessorFloatData)) { + MCglTF.logger.warn("Output data is not an AccessorFloatData, but " + + outputData.getClass()); + continue; + } + AccessorFloatData outputFloatData = (AccessorFloatData) outputData; + + int numKeyElements = inputFloatData.getNumElements(); + float[] keys = new float[numKeyElements]; + for (int e = 0; e < numKeyElements; e++) { + keys[e] = inputFloatData.get(e); + } + + int globalIndex = 0; + int numComponentsPerElement; + float[][] values; + float[][][] valuesCubic; + + NodeModel nodeModel = channel.getNodeModel(); + + String path = channel.getPath(); + Interpolation interpolation; + switch (path) { + case "translation": + numComponentsPerElement = outputData.getNumComponentsPerElement(); + interpolation = sampler.getInterpolation(); + switch (interpolation) { + case STEP: + values = new float[numKeyElements][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] translation = nodeModel.getTranslation(); + if (translation == null) { + translation = new float[numComponentsPerElement]; + nodeModel.setTranslation(translation); + } + return translation; + } + + }); + break; + case LINEAR: + values = new float[numKeyElements][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] translation = nodeModel.getTranslation(); + if (translation == null) { + translation = new float[numComponentsPerElement]; + nodeModel.setTranslation(translation); + } + return translation; + } + + }); + break; + case CUBICSPLINE: + valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[][] elements = valuesCubic[e]; + for (int i = 0; i < 3; i++) { + float[] components = elements[i]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + } + interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { + + @Override + protected float[] getListener() { + float[] translation = nodeModel.getTranslation(); + if (translation == null) { + translation = new float[numComponentsPerElement]; + nodeModel.setTranslation(translation); + } + return translation; + } + + }); + break; + default: + MCglTF.logger.warn("Interpolation type not supported: " + interpolation); + break; + } + break; + case "rotation": + numComponentsPerElement = outputData.getNumComponentsPerElement(); + interpolation = sampler.getInterpolation(); + switch (interpolation) { + case STEP: + values = new float[numKeyElements][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] rotation = nodeModel.getRotation(); + if (rotation == null) { + rotation = new float[numComponentsPerElement]; + nodeModel.setRotation(rotation); + } + return rotation; + } + + }); + break; + case LINEAR: + values = new float[numKeyElements][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new SphericalLinearInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] rotation = nodeModel.getRotation(); + if (rotation == null) { + rotation = new float[numComponentsPerElement]; + nodeModel.setRotation(rotation); + } + return rotation; + } + + }); + break; + case CUBICSPLINE: + valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[][] elements = valuesCubic[e]; + for (int i = 0; i < 3; i++) { + float[] components = elements[i]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + } + interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { + + @Override + protected float[] getListener() { + float[] rotation = nodeModel.getRotation(); + if (rotation == null) { + rotation = new float[numComponentsPerElement]; + nodeModel.setRotation(rotation); + } + return rotation; + } + + }); + break; + default: + MCglTF.logger.warn("Interpolation type not supported: " + interpolation); + break; + } + break; + case "scale": + numComponentsPerElement = outputData.getNumComponentsPerElement(); + interpolation = sampler.getInterpolation(); + switch (interpolation) { + case STEP: + values = new float[numKeyElements][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] scale = nodeModel.getScale(); + if (scale == null) { + scale = new float[numComponentsPerElement]; + nodeModel.setScale(scale); + } + return scale; + } + + }); + break; + case LINEAR: + values = new float[numKeyElements][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] scale = nodeModel.getScale(); + if (scale == null) { + scale = new float[numComponentsPerElement]; + nodeModel.setScale(scale); + } + return scale; + } + + }); + break; + case CUBICSPLINE: + valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[][] elements = valuesCubic[e]; + for (int i = 0; i < 3; i++) { + float[] components = elements[i]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + } + interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { + + @Override + protected float[] getListener() { + float[] scale = nodeModel.getScale(); + if (scale == null) { + scale = new float[numComponentsPerElement]; + nodeModel.setScale(scale); + } + return scale; + } + + }); + break; + default: + MCglTF.logger.warn("Interpolation type not supported: " + interpolation); + break; + } + break; + case "weights": + interpolation = sampler.getInterpolation(); + switch (interpolation) { + case STEP: + numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements; + values = new float[numKeyElements][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] weights = nodeModel.getWeights(); + if (weights == null) { + weights = new float[numComponentsPerElement]; + nodeModel.setWeights(weights); + } + return weights; + } + + }); + break; + case LINEAR: + numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements; + values = new float[numKeyElements][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] weights = nodeModel.getWeights(); + if (weights == null) { + weights = new float[numComponentsPerElement]; + nodeModel.setWeights(weights); + } + return weights; + } + + }); + break; + case CUBICSPLINE: + numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements / 3; + valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; + for (int e = 0; e < numKeyElements; e++) { + float[][] elements = valuesCubic[e]; + for (int i = 0; i < 3; i++) { + float[] components = elements[i]; + for (int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + } + interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { + + @Override + protected float[] getListener() { + float[] weights = nodeModel.getWeights(); + if (weights == null) { + weights = new float[numComponentsPerElement]; + nodeModel.setWeights(weights); + } + return weights; + } + + }); + break; + default: + MCglTF.logger.warn("Interpolation type not supported: " + interpolation); + break; + } + break; + default: + MCglTF.logger.warn("Animation channel target path must be " + + "\"translation\", \"rotation\", \"scale\" or \"weights\", " + + "but is " + path); + break; + } + } + return interpolatedChannels; + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/InterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/InterpolatedChannel.java index 30ab3b4..c255888 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/InterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/InterpolatedChannel.java @@ -4,41 +4,39 @@ public abstract class InterpolatedChannel { - /** - * The key frame times, in seconds - */ - protected final float[] timesS; - - public InterpolatedChannel(float[] timesS) { - this.timesS = timesS; - } - - public float[] getKeys() { - return timesS; - } - - public abstract void update(float timeS); - - protected abstract float[] getListener(); - - /** - * Compute the index of the segment that the given key belongs to. - * If the given key is smaller than the smallest or larger than - * the largest key, then 0 or keys.length-1 will be returned, - * respectively. - * - * @param key The key - * @param keys The sorted keys - * @return The index for the key - */ - public static int computeIndex(float key, float keys[]) - { - int index = Arrays.binarySearch(keys, key); - if (index >= 0) - { - return index; - } - return Math.max(0, -index - 2); - } + /** + * The key frame times, in seconds + */ + protected final float[] timesS; + + public InterpolatedChannel(float[] timesS) { + this.timesS = timesS; + } + + /** + * Compute the index of the segment that the given key belongs to. + * If the given key is smaller than the smallest or larger than + * the largest key, then 0 or keys.length-1 will be returned, + * respectively. + * + * @param key The key + * @param keys The sorted keys + * @return The index for the key + */ + public static int computeIndex(float key, float keys[]) { + int index = Arrays.binarySearch(keys, key); + if (index >= 0) { + return index; + } + return Math.max(0, -index - 2); + } + + public float[] getKeys() { + return timesS; + } + + public abstract void update(float timeS); + + protected abstract float[] getListener(); } diff --git a/src/main/java/com/modularmods/mcgltf/animation/LinearInterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/LinearInterpolatedChannel.java index f7bce13..7d5fbfd 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/LinearInterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/LinearInterpolatedChannel.java @@ -2,43 +2,41 @@ public abstract class LinearInterpolatedChannel extends InterpolatedChannel { - /** - * The values. Each element of this array corresponds to one key - * frame time - */ - protected final float[][] values; - - public LinearInterpolatedChannel(float[] timesS, float[][] values) { - super(timesS); - this.values = values; - } - - @Override - public void update(float timeS) { - float[] output = getListener(); - if(timeS <= timesS[0]) { - System.arraycopy(values[0], 0, output, 0, output.length); - } - else if(timeS >= timesS[timesS.length - 1]) { - System.arraycopy(values[timesS.length - 1], 0, output, 0, output.length); - } - else { - int previousIndex = computeIndex(timeS, timesS); - int nextIndex = previousIndex + 1; - - float local = timeS - timesS[previousIndex]; - float delta = timesS[nextIndex] - timesS[previousIndex]; - float alpha = local / delta; - - float[] previousPoint = values[previousIndex]; - float[] nextPoint = values[nextIndex]; - - for(int i = 0; i < output.length; i++) { - float p = previousPoint[i]; - float n = nextPoint[i]; - output[i] = p + alpha * (n - p); - } - } - } + /** + * The values. Each element of this array corresponds to one key + * frame time + */ + protected final float[][] values; + + public LinearInterpolatedChannel(float[] timesS, float[][] values) { + super(timesS); + this.values = values; + } + + @Override + public void update(float timeS) { + float[] output = getListener(); + if (timeS <= timesS[0]) { + System.arraycopy(values[0], 0, output, 0, output.length); + } else if (timeS >= timesS[timesS.length - 1]) { + System.arraycopy(values[timesS.length - 1], 0, output, 0, output.length); + } else { + int previousIndex = computeIndex(timeS, timesS); + int nextIndex = previousIndex + 1; + + float local = timeS - timesS[previousIndex]; + float delta = timesS[nextIndex] - timesS[previousIndex]; + float alpha = local / delta; + + float[] previousPoint = values[previousIndex]; + float[] nextPoint = values[nextIndex]; + + for (int i = 0; i < output.length; i++) { + float p = previousPoint[i]; + float n = nextPoint[i]; + output[i] = p + alpha * (n - p); + } + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/SphericalLinearInterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/SphericalLinearInterpolatedChannel.java index d220554..7ed682b 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/SphericalLinearInterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/SphericalLinearInterpolatedChannel.java @@ -2,80 +2,74 @@ public abstract class SphericalLinearInterpolatedChannel extends InterpolatedChannel { - /** - * The values. Each element of this array corresponds to one key - * frame time - */ - protected final float[][] values; - - public SphericalLinearInterpolatedChannel(float[] timesS, float[][] values) { - super(timesS); - this.values = values; - } - - @Override - public void update(float timeS) { - float[] output = getListener(); - if(timeS <= timesS[0]) { - System.arraycopy(values[0], 0, output, 0, output.length); - } - else if(timeS >= timesS[timesS.length - 1]) { - System.arraycopy(values[timesS.length - 1], 0, output, 0, output.length); - } - else { - int previousIndex = computeIndex(timeS, timesS); - int nextIndex = previousIndex + 1; - - float local = timeS - timesS[previousIndex]; - float delta = timesS[nextIndex] - timesS[previousIndex]; - float alpha = local / delta; - - float[] previousPoint = values[previousIndex]; - float[] nextPoint = values[nextIndex]; - - // Adapted from javax.vecmath.Quat4f - float ax = previousPoint[0]; - float ay = previousPoint[1]; - float az = previousPoint[2]; - float aw = previousPoint[3]; - float bx = nextPoint[0]; - float by = nextPoint[1]; - float bz = nextPoint[2]; - float bw = nextPoint[3]; + /** + * The values. Each element of this array corresponds to one key + * frame time + */ + protected final float[][] values; - float dot = ax * bx + ay * by + az * bz + aw * bw; - if (dot < 0) - { - bx = -bx; - by = -by; - bz = -bz; - bw = -bw; - dot = -dot; - } - float epsilon = 1e-6f; - float s0, s1; - if ((1.0 - dot) > epsilon) - { - float omega = (float)Math.acos(dot); - float invSinOmega = 1.0f / (float)Math.sin(omega); - s0 = (float)Math.sin((1.0 - alpha) * omega) * invSinOmega; - s1 = (float)Math.sin(alpha * omega) * invSinOmega; - } - else - { - s0 = 1.0f - alpha; - s1 = alpha; - } - float rx = s0 * ax + s1 * bx; - float ry = s0 * ay + s1 * by; - float rz = s0 * az + s1 * bz; - float rw = s0 * aw + s1 * bw; - - output[0] = rx; - output[1] = ry; - output[2] = rz; - output[3] = rw; - } - } + public SphericalLinearInterpolatedChannel(float[] timesS, float[][] values) { + super(timesS); + this.values = values; + } + + @Override + public void update(float timeS) { + float[] output = getListener(); + if (timeS <= timesS[0]) { + System.arraycopy(values[0], 0, output, 0, output.length); + } else if (timeS >= timesS[timesS.length - 1]) { + System.arraycopy(values[timesS.length - 1], 0, output, 0, output.length); + } else { + int previousIndex = computeIndex(timeS, timesS); + int nextIndex = previousIndex + 1; + + float local = timeS - timesS[previousIndex]; + float delta = timesS[nextIndex] - timesS[previousIndex]; + float alpha = local / delta; + + float[] previousPoint = values[previousIndex]; + float[] nextPoint = values[nextIndex]; + + // Adapted from javax.vecmath.Quat4f + float ax = previousPoint[0]; + float ay = previousPoint[1]; + float az = previousPoint[2]; + float aw = previousPoint[3]; + float bx = nextPoint[0]; + float by = nextPoint[1]; + float bz = nextPoint[2]; + float bw = nextPoint[3]; + + float dot = ax * bx + ay * by + az * bz + aw * bw; + if (dot < 0) { + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + dot = -dot; + } + float epsilon = 1e-6f; + float s0, s1; + if ((1.0 - dot) > epsilon) { + float omega = (float) Math.acos(dot); + float invSinOmega = 1.0f / (float) Math.sin(omega); + s0 = (float) Math.sin((1.0 - alpha) * omega) * invSinOmega; + s1 = (float) Math.sin(alpha * omega) * invSinOmega; + } else { + s0 = 1.0f - alpha; + s1 = alpha; + } + float rx = s0 * ax + s1 * bx; + float ry = s0 * ay + s1 * by; + float rz = s0 * az + s1 * bz; + float rw = s0 * aw + s1 * bw; + + output[0] = rx; + output[1] = ry; + output[2] = rz; + output[3] = rw; + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/StepInterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/StepInterpolatedChannel.java index cea61a5..cc51bb5 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/StepInterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/StepInterpolatedChannel.java @@ -2,21 +2,21 @@ public abstract class StepInterpolatedChannel extends InterpolatedChannel { - /** - * The values. Each element of this array corresponds to one key - * frame time - */ - protected final float[][] values; - - public StepInterpolatedChannel(float[] timesS, float[][] values) { - super(timesS); - this.values = values; - } - - @Override - public void update(float timeS) { - float[] output = getListener(); - System.arraycopy(values[computeIndex(timeS, timesS)], 0, output, 0, output.length); - } + /** + * The values. Each element of this array corresponds to one key + * frame time + */ + protected final float[][] values; + + public StepInterpolatedChannel(float[] timesS, float[][] values) { + super(timesS); + this.values = values; + } + + @Override + public void update(float timeS) { + float[] output = getListener(); + System.arraycopy(values[computeIndex(timeS, timesS)], 0, output, 0, output.length); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/IrisRenderingHook.java b/src/main/java/com/modularmods/mcgltf/iris/IrisRenderingHook.java index 42b5e68..2c2a777 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/IrisRenderingHook.java +++ b/src/main/java/com/modularmods/mcgltf/iris/IrisRenderingHook.java @@ -1,238 +1,170 @@ package com.modularmods.mcgltf.iris; -import java.util.EnumMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import net.irisshaders.batchedentityrendering.impl.WrappableRenderType; -import net.irisshaders.iris.Iris; -import net.irisshaders.iris.pipeline.WorldRenderingPhase; -import net.irisshaders.iris.pipeline.WorldRenderingPipeline; -import org.joml.Vector3f; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; - import com.modularmods.mcgltf.RenderedGltfModel; import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.VertexFormat; - +import net.irisshaders.batchedentityrendering.impl.WrappableRenderType; +import net.irisshaders.iris.Iris; +import net.irisshaders.iris.pipeline.WorldRenderingPhase; +import net.irisshaders.iris.pipeline.WorldRenderingPipeline; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShaderInstance; +import org.joml.Vector3f; +import org.lwjgl.opengl.*; + +import java.util.*; public class IrisRenderingHook { - private static final Map>> phaseRenderStateShardToCommands = new EnumMap>>(WorldRenderingPhase.class); - private static RenderStateShard currentRenderStateShard; - - public static void submitCommandForIrisRenderingByPhaseName(String phase, RenderType renderType, Runnable command) { - submitCommandForIrisRendering(WorldRenderingPhase.valueOf(phase), renderType, command); - } - - public static void submitCommandForIrisRendering(WorldRenderingPhase phase, RenderType renderType, Runnable command) { - Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); - if(renderStateShardToCommands == null) { - renderStateShardToCommands = new LinkedHashMap>(); - phaseRenderStateShardToCommands.put(phase, renderStateShardToCommands); - List commands = new LinkedList(); - renderStateShardToCommands.put(renderType, commands); - commands.add(command); - } - else { - List commands = renderStateShardToCommands.get(renderType); - if(commands == null) { - commands = new LinkedList(); - renderStateShardToCommands.put(renderType, commands); - } - commands.add(command); - } - } - - public static void irisHookAfterSetupRenderState(RenderStateShard renderStateShard) { - currentRenderStateShard = ((renderStateShard instanceof WrappableRenderType) ? ((WrappableRenderType)renderStateShard).unwrap() : renderStateShard); - } - - public static void irisHookBypassBufferUploaderVextexCountCheck(BufferBuilder.RenderedBuffer renderedBuffer) { - WorldRenderingPipeline pipeline = Iris.getPipelineManager().getPipelineNullable(); - if(pipeline != null) { - WorldRenderingPhase phase = pipeline.getPhase(); - Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); - if(renderStateShardToCommands != null) { - List commands = renderStateShardToCommands.remove(currentRenderStateShard); - if(commands != null) { - ShaderInstance shaderInstance = RenderedGltfModel.CURRENT_SHADER_INSTANCE = RenderSystem.getShader(); - for (int i = 0; i < 12; ++i) { - int j = RenderSystem.getShaderTexture(i); - shaderInstance.setSampler("Sampler" + i, j); - } - if (shaderInstance.MODEL_VIEW_MATRIX != null) { - shaderInstance.MODEL_VIEW_MATRIX.set(RenderSystem.getModelViewMatrix()); - } - if (shaderInstance.PROJECTION_MATRIX != null) { - shaderInstance.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - } - if (shaderInstance.INVERSE_VIEW_ROTATION_MATRIX != null) { - shaderInstance.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - } - if (shaderInstance.COLOR_MODULATOR != null) { - shaderInstance.COLOR_MODULATOR.set(RenderSystem.getShaderColor()); - } - if (shaderInstance.FOG_START != null) { - shaderInstance.FOG_START.set(RenderSystem.getShaderFogStart()); - } - if (shaderInstance.FOG_END != null) { - shaderInstance.FOG_END.set(RenderSystem.getShaderFogEnd()); - } - if (shaderInstance.FOG_COLOR != null) { - shaderInstance.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - } - if (shaderInstance.FOG_SHAPE != null) { - shaderInstance.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - } - if (shaderInstance.TEXTURE_MATRIX != null) { - shaderInstance.TEXTURE_MATRIX.set(RenderSystem.getTextureMatrix()); - } - if (shaderInstance.GAME_TIME != null) { - shaderInstance.GAME_TIME.set(RenderSystem.getShaderGameTime()); - } - if (shaderInstance.SCREEN_SIZE != null) { - Window window = Minecraft.getInstance().getWindow(); - shaderInstance.SCREEN_SIZE.set((float)window.getWidth(), (float)window.getHeight()); - } - if (shaderInstance.LINE_WIDTH != null) { - VertexFormat.Mode mode = renderedBuffer.drawState().mode(); - if(mode == VertexFormat.Mode.LINES || mode == VertexFormat.Mode.LINE_STRIP) { - shaderInstance.LINE_WIDTH.set(RenderSystem.getShaderLineWidth()); - } - } - RenderSystem.setupShaderLights(shaderInstance); - shaderInstance.apply(); - - setupAndRender(phase, shaderInstance, commands); - - shaderInstance.clear(); - } - } - } - } - - public static void irisHookAfterVertexBufferDraw() { - WorldRenderingPipeline pipeline = Iris.getPipelineManager().getPipelineNullable(); - if(pipeline != null) { - WorldRenderingPhase phase = pipeline.getPhase(); - Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); - if(renderStateShardToCommands != null) { - List commands = renderStateShardToCommands.remove(currentRenderStateShard); - if(commands != null) { - setupAndRender(phase, RenderedGltfModel.CURRENT_SHADER_INSTANCE = RenderSystem.getShader(), commands); - } - } - } - } - - private static void setupAndRender(WorldRenderingPhase phase, ShaderInstance shaderInstance, List commands) { - int currentVAO = GL11.glGetInteger(GL30.GL_VERTEX_ARRAY_BINDING); - int currentArrayBuffer = GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING); - int currentElementArrayBuffer = GL11.glGetInteger(GL15.GL_ELEMENT_ARRAY_BUFFER_BINDING); - - boolean currentCullFace = GL11.glGetBoolean(GL11.GL_CULL_FACE); - - if(phase != WorldRenderingPhase.NONE) { - int currentProgram = shaderInstance.getId(); - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "iris_ModelViewMat"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "iris_NormalMat"); - int normals = GL20.glGetUniformLocation(currentProgram, "normals"); - int specular = GL20.glGetUniformLocation(currentProgram, "specular"); - - int currentTextureColor; - - if(normals != -1) { - RenderedGltfModel.NORMAL_MAP_INDEX = GL13.GL_TEXTURE0 + GL20.glGetUniformi(currentProgram, normals); - if(specular != -1) { - RenderedGltfModel.SPECULAR_MAP_INDEX = GL13.GL_TEXTURE0 + GL20.glGetUniformi(currentProgram, specular); - - GL13.glActiveTexture(RenderedGltfModel.NORMAL_MAP_INDEX); - int currentTextureNormal = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(RenderedGltfModel.SPECULAR_MAP_INDEX); - int currentTextureSpecular = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - currentTextureColor = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - commands.forEach(Runnable::run); - - GL13.glActiveTexture(RenderedGltfModel.NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureNormal); - GL13.glActiveTexture(RenderedGltfModel.SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureSpecular); - } - else { - RenderedGltfModel.SPECULAR_MAP_INDEX = -1; - - GL13.glActiveTexture(RenderedGltfModel.NORMAL_MAP_INDEX); - int currentTextureNormal = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - currentTextureColor = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - commands.forEach(Runnable::run); - - GL13.glActiveTexture(RenderedGltfModel.NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureNormal); - } - } - else { - RenderedGltfModel.NORMAL_MAP_INDEX = -1; - if(specular != -1) { - RenderedGltfModel.SPECULAR_MAP_INDEX = GL13.GL_TEXTURE0 + GL20.glGetUniformi(currentProgram, specular); - - GL13.glActiveTexture(RenderedGltfModel.SPECULAR_MAP_INDEX); - int currentTextureSpecular = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - currentTextureColor = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - commands.forEach(Runnable::run); - - GL13.glActiveTexture(RenderedGltfModel.SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureSpecular); - } - else { - RenderedGltfModel.SPECULAR_MAP_INDEX = -1; - - GL13.glActiveTexture(GL13.GL_TEXTURE0); - currentTextureColor = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - commands.forEach(Runnable::run); - } - } - - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureColor); - } - else { - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(shaderInstance.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(shaderInstance.LIGHT1_DIRECTION.getFloatBuffer()); - - GL13.glActiveTexture(GL13.GL_TEXTURE0); - int currentTextureColor = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - commands.forEach(Runnable::run); - - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureColor); - } - - if(currentCullFace) GL11.glEnable(GL11.GL_CULL_FACE); - else GL11.glDisable(GL11.GL_CULL_FACE); - - GL30.glBindVertexArray(currentVAO); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, currentArrayBuffer); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, currentElementArrayBuffer); - } + private static final Map>> phaseRenderStateShardToCommands = new EnumMap>>(WorldRenderingPhase.class); + private static RenderStateShard currentRenderStateShard; + + public static void submitCommandForIrisRenderingByPhaseName(String phase, RenderType renderType, Runnable command) { + submitCommandForIrisRendering(WorldRenderingPhase.valueOf(phase), renderType, command); + } + + public static void submitCommandForIrisRendering(WorldRenderingPhase phase, RenderType renderType, Runnable command) { + Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); + if (renderStateShardToCommands == null) { + renderStateShardToCommands = new LinkedHashMap>(); + phaseRenderStateShardToCommands.put(phase, renderStateShardToCommands); + List commands = new LinkedList(); + renderStateShardToCommands.put(renderType, commands); + commands.add(command); + } else { + List commands = renderStateShardToCommands.get(renderType); + if (commands == null) { + commands = new LinkedList(); + renderStateShardToCommands.put(renderType, commands); + } + commands.add(command); + } + } + + public static void irisHookAfterSetupRenderState(RenderStateShard renderStateShard) { + currentRenderStateShard = ((renderStateShard instanceof WrappableRenderType) ? ((WrappableRenderType) renderStateShard).unwrap() : renderStateShard); + } + + public static void irisHookBypassBufferUploaderVextexCountCheck(BufferBuilder.RenderedBuffer renderedBuffer) { + WorldRenderingPipeline pipeline = Iris.getPipelineManager().getPipelineNullable(); + if (pipeline != null) { + WorldRenderingPhase phase = pipeline.getPhase(); + Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); + if (renderStateShardToCommands != null) { + List commands = renderStateShardToCommands.remove(currentRenderStateShard); + if (commands != null) { + ShaderInstance shaderInstance = RenderedGltfModel.CURRENT_SHADER_INSTANCE = RenderSystem.getShader(); + for (int i = 0; i < 12; ++i) { + int j = RenderSystem.getShaderTexture(i); + shaderInstance.setSampler("Sampler" + i, j); + } + if (shaderInstance.MODEL_VIEW_MATRIX != null) { + shaderInstance.MODEL_VIEW_MATRIX.set(RenderSystem.getModelViewMatrix()); + } + if (shaderInstance.PROJECTION_MATRIX != null) { + shaderInstance.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + } + if (shaderInstance.INVERSE_VIEW_ROTATION_MATRIX != null) { + shaderInstance.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + } + if (shaderInstance.COLOR_MODULATOR != null) { + shaderInstance.COLOR_MODULATOR.set(RenderSystem.getShaderColor()); + } + if (shaderInstance.FOG_START != null) { + shaderInstance.FOG_START.set(RenderSystem.getShaderFogStart()); + } + if (shaderInstance.FOG_END != null) { + shaderInstance.FOG_END.set(RenderSystem.getShaderFogEnd()); + } + if (shaderInstance.FOG_COLOR != null) { + shaderInstance.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + } + if (shaderInstance.FOG_SHAPE != null) { + shaderInstance.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + } + if (shaderInstance.TEXTURE_MATRIX != null) { + shaderInstance.TEXTURE_MATRIX.set(RenderSystem.getTextureMatrix()); + } + if (shaderInstance.GAME_TIME != null) { + shaderInstance.GAME_TIME.set(RenderSystem.getShaderGameTime()); + } + if (shaderInstance.SCREEN_SIZE != null) { + Window window = Minecraft.getInstance().getWindow(); + shaderInstance.SCREEN_SIZE.set((float) window.getWidth(), (float) window.getHeight()); + } + if (shaderInstance.LINE_WIDTH != null) { + VertexFormat.Mode mode = renderedBuffer.drawState().mode(); + if (mode == VertexFormat.Mode.LINES || mode == VertexFormat.Mode.LINE_STRIP) { + shaderInstance.LINE_WIDTH.set(RenderSystem.getShaderLineWidth()); + } + } + RenderSystem.setupShaderLights(shaderInstance); + shaderInstance.apply(); + + setupAndRender(phase, shaderInstance, commands); + + shaderInstance.clear(); + } + } + } + } + + public static void irisHookAfterVertexBufferDraw() { + WorldRenderingPipeline pipeline = Iris.getPipelineManager().getPipelineNullable(); + if (pipeline != null) { + WorldRenderingPhase phase = pipeline.getPhase(); + Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); + if (renderStateShardToCommands != null) { + List commands = renderStateShardToCommands.remove(currentRenderStateShard); + if (commands != null) { + setupAndRender(phase, RenderedGltfModel.CURRENT_SHADER_INSTANCE = RenderSystem.getShader(), commands); + } + } + } + } + + private static void setupAndRender(WorldRenderingPhase phase, ShaderInstance shaderInstance, List commands) { + int currentVAO = GL11.glGetInteger(GL30.GL_VERTEX_ARRAY_BINDING); + int currentArrayBuffer = GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING); + int currentElementArrayBuffer = GL11.glGetInteger(GL15.GL_ELEMENT_ARRAY_BUFFER_BINDING); + + boolean currentCullFace = GL11.glGetBoolean(GL11.GL_CULL_FACE); + + int currentTextureColor = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 2); + int currentTextureNormal = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); + int currentTextureSpecular = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + try { + if (phase != WorldRenderingPhase.NONE) { + int currentProgram = shaderInstance.getId(); + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "iris_ModelViewMat"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "iris_NormalMat"); + } else { + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(shaderInstance.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(shaderInstance.LIGHT1_DIRECTION.getFloatBuffer()); + } + commands.forEach(Runnable::run); + } finally { + GL20.glDisableVertexAttribArray(RenderedGltfModel.at_tangent); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureColor); + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 2); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureNormal); + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureSpecular); + } + + if (currentCullFace) GL11.glEnable(GL11.GL_CULL_FACE); + else GL11.glDisable(GL11.GL_CULL_FACE); + + GL30.glBindVertexArray(currentVAO); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, currentArrayBuffer); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, currentElementArrayBuffer); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL30Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL30Iris.java index b8aa780..4b04cc2 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL30Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL30Iris.java @@ -1,89 +1,85 @@ package com.modularmods.mcgltf.iris; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang3.tuple.Triple; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.lwjgl.opengl.GL20; - import com.google.gson.Gson; import com.modularmods.mcgltf.RenderedGltfModelGL30; - import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.NodeModel; import de.javagl.jgltf.model.SceneModel; +import org.apache.commons.lang3.tuple.Triple; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL20; + +import java.util.ArrayList; +import java.util.List; public class RenderedGltfModelGL30Iris extends RenderedGltfModelGL30 { - public RenderedGltfModelGL30Iris(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } + public RenderedGltfModelGL30Iris(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for (SceneModel sceneModel : sceneModels) { + RenderedGltfSceneGL30Iris renderedGltfScene = new RenderedGltfSceneGL30Iris(); + renderedGltfScenes.add(renderedGltfScene); + + for (NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if (commands == null) { + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(null, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } else { + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + @Override + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + + if (NORMAL_MATRIX != -1) { + Matrix3f normal = new Matrix3f(pose); + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for(SceneModel sceneModel : sceneModels) { - RenderedGltfSceneGL30Iris renderedGltfScene = new RenderedGltfSceneGL30Iris(); - renderedGltfScenes.add(renderedGltfScene); - - for(NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if(commands == null) { - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(null, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } - else { - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } + pose.transpose(); + pose.mulLocal(CURRENT_POSE); - @Override - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - - if(NORMAL_MATRIX != -1) { - Matrix3f normal = new Matrix3f(pose); - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } - - pose.transpose(); - pose.mulLocal(CURRENT_POSE); - - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - } + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + } - @Override - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if(material == null) { - Object extras = materialModel.getExtras(); - if(extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); - } - else material = new RenderedGltfModelIris.MaterialIris(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } + @Override + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if (material == null) { + Object extras = materialModel.getExtras(); + if (extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); + } else material = new RenderedGltfModelIris.MaterialIris(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL33Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL33Iris.java index fecdf36..81ca723 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL33Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL33Iris.java @@ -1,93 +1,89 @@ package com.modularmods.mcgltf.iris; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang3.tuple.Triple; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.lwjgl.opengl.GL20; - import com.google.gson.Gson; import com.modularmods.mcgltf.RenderedGltfModelGL33; - import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.NodeModel; import de.javagl.jgltf.model.SceneModel; +import org.apache.commons.lang3.tuple.Triple; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL20; + +import java.util.ArrayList; +import java.util.List; public class RenderedGltfModelGL33Iris extends RenderedGltfModelGL33 { - public RenderedGltfModelGL33Iris(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } + public RenderedGltfModelGL33Iris(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for (SceneModel sceneModel : sceneModels) { + RenderedGltfSceneGL33Iris renderedGltfScene = new RenderedGltfSceneGL33Iris(); + renderedGltfScenes.add(renderedGltfScene); + + for (NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if (commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + @Override + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + + if (NORMAL_MATRIX != -1) { + Matrix3f normal = new Matrix3f(pose); + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for(SceneModel sceneModel : sceneModels) { - RenderedGltfSceneGL33Iris renderedGltfScene = new RenderedGltfSceneGL33Iris(); - renderedGltfScenes.add(renderedGltfScene); - - for(NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if(commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } - else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } + pose.transpose(); + pose.mulLocal(CURRENT_POSE); - @Override - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - - if(NORMAL_MATRIX != -1) { - Matrix3f normal = new Matrix3f(pose); - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } - - pose.transpose(); - pose.mulLocal(CURRENT_POSE); - - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - } + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + } - @Override - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if(material == null) { - Object extras = materialModel.getExtras(); - if(extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); - } - else material = new RenderedGltfModelIris.MaterialIris(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } + @Override + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if (material == null) { + Object extras = materialModel.getExtras(); + if (extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); + } else material = new RenderedGltfModelIris.MaterialIris(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL40Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL40Iris.java index a72e0a7..5cbb597 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL40Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL40Iris.java @@ -1,93 +1,89 @@ package com.modularmods.mcgltf.iris; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang3.tuple.Triple; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.lwjgl.opengl.GL20; - import com.google.gson.Gson; import com.modularmods.mcgltf.RenderedGltfModelGL40; - import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.NodeModel; import de.javagl.jgltf.model.SceneModel; +import org.apache.commons.lang3.tuple.Triple; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL20; + +import java.util.ArrayList; +import java.util.List; public class RenderedGltfModelGL40Iris extends RenderedGltfModelGL40 { - public RenderedGltfModelGL40Iris(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } + public RenderedGltfModelGL40Iris(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for (SceneModel sceneModel : sceneModels) { + RenderedGltfSceneGL40Iris renderedGltfScene = new RenderedGltfSceneGL40Iris(); + renderedGltfScenes.add(renderedGltfScene); + + for (NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if (commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + @Override + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + + if (NORMAL_MATRIX != -1) { + Matrix3f normal = new Matrix3f(pose); + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for(SceneModel sceneModel : sceneModels) { - RenderedGltfSceneGL40Iris renderedGltfScene = new RenderedGltfSceneGL40Iris(); - renderedGltfScenes.add(renderedGltfScene); - - for(NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if(commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } - else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } + pose.transpose(); + pose.mulLocal(CURRENT_POSE); - @Override - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - - if(NORMAL_MATRIX != -1) { - Matrix3f normal = new Matrix3f(pose); - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } - - pose.transpose(); - pose.mulLocal(CURRENT_POSE); - - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - } + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + } - @Override - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if(material == null) { - Object extras = materialModel.getExtras(); - if(extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); - } - else material = new RenderedGltfModelIris.MaterialIris(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } + @Override + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if (material == null) { + Object extras = materialModel.getExtras(); + if (extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); + } else material = new RenderedGltfModelIris.MaterialIris(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelIris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelIris.java index d4507f5..bcbdf4b 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelIris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelIris.java @@ -1,8 +1,10 @@ package com.modularmods.mcgltf.iris; -import java.util.ArrayList; -import java.util.List; - +import com.google.gson.Gson; +import com.modularmods.mcgltf.MCglTF; +import com.modularmods.mcgltf.RenderedGltfModel; +import de.javagl.jgltf.model.*; +import de.javagl.jgltf.model.v2.MaterialModelV2; import org.apache.commons.lang3.tuple.Triple; import org.joml.Matrix3f; import org.joml.Matrix4f; @@ -10,191 +12,234 @@ import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL20; -import com.google.gson.Gson; -import com.modularmods.mcgltf.MCglTF; -import com.modularmods.mcgltf.RenderedGltfModel; - -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.MaterialModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.SceneModel; -import de.javagl.jgltf.model.TextureModel; -import de.javagl.jgltf.model.v2.MaterialModelV2; +import java.util.ArrayList; +import java.util.List; public class RenderedGltfModelIris extends RenderedGltfModel { - public RenderedGltfModelIris(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for(SceneModel sceneModel : sceneModels) { - RenderedGltfSceneIris renderedGltfScene = new RenderedGltfSceneIris(); - renderedGltfScenes.add(renderedGltfScene); - - for(NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if(commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } - else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - @Override - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - - if(NORMAL_MATRIX != -1) { - Matrix3f normal = new Matrix3f(pose); - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } - - pose.transpose(); - pose.mulLocal(CURRENT_POSE); - - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - } - - @Override - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if(material == null) { - Object extras = materialModel.getExtras(); - if(extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), MaterialIris.class); - } - else material = new MaterialIris(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } - - public static class MaterialIris extends Material { - - @Override - public void initMaterialCommand(List gltfRenderData, RenderedGltfModel renderedModel, MaterialModel materialModel) { - int colorMap; - int normalMap; - int specularMap; - List textureModels = renderedModel.gltfModel.getTextureModels(); - if(materialModel instanceof MaterialModelV2) { - MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; - - if(baseColorTexture == null) { - TextureModel textureModel = materialModelV2.getBaseColorTexture(); - if(textureModel != null) { - colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - baseColorTexture = new TextureInfo(); - baseColorTexture.index = textureModels.indexOf(textureModel); - } - else colorMap = MCglTF.getInstance().getDefaultColorMap(); - } - else colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); - - if(normalTexture == null) { - TextureModel textureModel = materialModelV2.getNormalTexture(); - if(textureModel != null) { - normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - normalTexture = new TextureInfo(); - normalTexture.index = textureModels.indexOf(textureModel); - } - else normalMap = MCglTF.getInstance().getDefaultNormalMap(); - } - else normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); - - if(specularTexture == null) { - TextureModel textureModel = materialModelV2.getMetallicRoughnessTexture(); - if(textureModel != null) { - specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - specularTexture = new TextureInfo(); - specularTexture.index = textureModels.indexOf(textureModel); - } - else specularMap = MCglTF.getInstance().getDefaultSpecularMap(); - } - else specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); - - if(baseColorFactor == null) baseColorFactor = materialModelV2.getBaseColorFactor(); - - if(doubleSided == null) doubleSided = materialModelV2.isDoubleSided(); - } - else { - colorMap = baseColorTexture == null ? MCglTF.getInstance().getDefaultColorMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); - normalMap = normalTexture == null ? MCglTF.getInstance().getDefaultNormalMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); - specularMap = specularTexture == null ? MCglTF.getInstance().getDefaultSpecularMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); - if(baseColorFactor == null) baseColorFactor = new float[]{1.0F, 1.0F, 1.0F, 1.0F}; - if(doubleSided == null) doubleSided = false; - } - - if(doubleSided) { - vanillaMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glDisable(GL11.GL_CULL_FACE); - }; - shaderModMaterialCommand = () -> { - GL13.glActiveTexture(COLOR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - if(NORMAL_MAP_INDEX != -1) { - GL13.glActiveTexture(NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); - } - if(SPECULAR_MAP_INDEX != -1) { - GL13.glActiveTexture(SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); - } - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glDisable(GL11.GL_CULL_FACE); - }; - } - else { - vanillaMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - shaderModMaterialCommand = () -> { - GL13.glActiveTexture(COLOR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - if(NORMAL_MAP_INDEX != -1) { - GL13.glActiveTexture(NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); - } - if(SPECULAR_MAP_INDEX != -1) { - GL13.glActiveTexture(SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); - } - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - } - } - - } + public RenderedGltfModelIris(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for (SceneModel sceneModel : sceneModels) { + RenderedGltfSceneIris renderedGltfScene = new RenderedGltfSceneIris(); + renderedGltfScenes.add(renderedGltfScene); + + for (NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if (commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + @Override + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + + if (NORMAL_MATRIX != -1) { + Matrix3f normal = new Matrix3f(pose); + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } + + pose.transpose(); + pose.mulLocal(CURRENT_POSE); + + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + } + + @Override + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if (material == null) { + Object extras = materialModel.getExtras(); + if (extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), MaterialIris.class); + } else material = new MaterialIris(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } + + public static class MaterialIris extends Material { + + @Override + public void initMaterialCommand(List gltfRenderData, RenderedGltfModel renderedModel, MaterialModel materialModel) { + int colorMap; + int normalMap; + int specularMap; + List textureModels = renderedModel.gltfModel.getTextureModels(); + if (materialModel instanceof MaterialModelV2) { + MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; + + if (baseColorTexture == null) { + TextureModel textureModel = materialModelV2.getBaseColorTexture(); + if (textureModel != null) { + colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + baseColorTexture = new TextureInfo(); + baseColorTexture.index = textureModels.indexOf(textureModel); + } else colorMap = MCglTF.getInstance().getDefaultColorMap(); + } else + colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); + + if (normalTexture == null) { + TextureModel textureModel = materialModelV2.getNormalTexture(); + if (textureModel != null) { + normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + normalTexture = new TextureInfo(); + normalTexture.index = textureModels.indexOf(textureModel); + } else normalMap = MCglTF.getInstance().getDefaultNormalMap(); + } else + normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); + + if (specularTexture == null) { + TextureModel textureModel = materialModelV2.getMetallicRoughnessTexture(); + if (textureModel != null) { + specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + specularTexture = new TextureInfo(); + specularTexture.index = textureModels.indexOf(textureModel); + } else specularMap = MCglTF.getInstance().getDefaultSpecularMap(); + } else + specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); + + if (baseColorFactor == null) baseColorFactor = materialModelV2.getBaseColorFactor(); + + if (doubleSided == null) doubleSided = materialModelV2.isDoubleSided(); + } else { + colorMap = baseColorTexture == null ? MCglTF.getInstance().getDefaultColorMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); + normalMap = normalTexture == null ? MCglTF.getInstance().getDefaultNormalMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); + specularMap = specularTexture == null ? MCglTF.getInstance().getDefaultSpecularMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); + if (baseColorFactor == null) baseColorFactor = new float[]{1.0F, 1.0F, 1.0F, 1.0F}; + if (doubleSided == null) doubleSided = false; + } + + if (doubleSided) { + vanillaMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + + // Enhanced transparency handling for vanilla rendering + if (baseColorFactor[3] < 1.0f) { + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } else { + GL11.glDisable(GL11.GL_BLEND); + } + + GL11.glDisable(GL11.GL_CULL_FACE); + }; + shaderModMaterialCommand = () -> { + GL13.glActiveTexture(COLOR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + + if (NORMAL_MAP_INDEX != -1) { + GL13.glActiveTexture(NORMAL_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); + } + if (SPECULAR_MAP_INDEX != -1) { + GL13.glActiveTexture(SPECULAR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); + } + + // Enhanced color attribute with proper alpha handling + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], + baseColorFactor[2], baseColorFactor[3]); + + // Enhanced transparency handling for Iris shader rendering + if (baseColorFactor[3] < 1.0f) { + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } else { + GL11.glDisable(GL11.GL_BLEND); + } + + // Add entityColor uniform support for shader packs like SEUS PTGI + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); + if (entityColorLocation != -1) { + GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); + } + + GL11.glDisable(GL11.GL_CULL_FACE); + }; + } else { + vanillaMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + + // Enhanced transparency handling for vanilla rendering + if (baseColorFactor[3] < 1.0f) { + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } else { + GL11.glDisable(GL11.GL_BLEND); + } + + GL11.glEnable(GL11.GL_CULL_FACE); + }; + shaderModMaterialCommand = () -> { + GL13.glActiveTexture(COLOR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + + if (NORMAL_MAP_INDEX != -1) { + GL13.glActiveTexture(NORMAL_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); + } + if (SPECULAR_MAP_INDEX != -1) { + GL13.glActiveTexture(SPECULAR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); + } + + // Enhanced color attribute with proper alpha handling + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], + baseColorFactor[2], baseColorFactor[3]); + + // Enhanced transparency handling for Iris shader rendering + if (baseColorFactor[3] < 1.0f) { + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } else { + GL11.glDisable(GL11.GL_BLEND); + } + + // Add entityColor uniform support for shader packs like SEUS PTGI + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); + if (entityColorLocation != -1) { + GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); + } + + GL11.glEnable(GL11.GL_CULL_FACE); + }; + } + } + + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL30Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL30Iris.java index 5b2d772..ea8c200 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL30Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL30Iris.java @@ -2,21 +2,25 @@ import com.modularmods.mcgltf.RenderedGltfModel; import com.modularmods.mcgltf.RenderedGltfSceneGL30; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL20; public class RenderedGltfSceneGL30Iris extends RenderedGltfSceneGL30 { - @Override - public void renderForVanilla() { - vanillaRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - shaderModRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + vanillaRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + shaderModRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL33Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL33Iris.java index cb3cb8e..ccc275c 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL33Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL33Iris.java @@ -1,47 +1,44 @@ package com.modularmods.mcgltf.iris; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL31; - import com.modularmods.mcgltf.MCglTF; import com.modularmods.mcgltf.RenderedGltfModel; import com.modularmods.mcgltf.RenderedGltfSceneGL33; +import org.lwjgl.opengl.*; public class RenderedGltfSceneGL33Iris extends RenderedGltfSceneGL33 { - @Override - public void renderForVanilla() { - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); - } - - vanillaRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); - } - - shaderModRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); + } + + vanillaRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + shaderModRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL40Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL40Iris.java index 0db3f0c..486ad29 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL40Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL40Iris.java @@ -1,50 +1,46 @@ package com.modularmods.mcgltf.iris; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL31; -import org.lwjgl.opengl.GL40; - import com.modularmods.mcgltf.MCglTF; import com.modularmods.mcgltf.RenderedGltfModel; import com.modularmods.mcgltf.RenderedGltfSceneGL40; +import org.lwjgl.opengl.*; public class RenderedGltfSceneGL40Iris extends RenderedGltfSceneGL40 { - @Override - public void renderForVanilla() { - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); - } - - vanillaRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); - } - - shaderModRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); + } + + vanillaRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + shaderModRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneIris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneIris.java index 1e74cb8..0417ffb 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneIris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneIris.java @@ -1,50 +1,46 @@ package com.modularmods.mcgltf.iris; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL40; -import org.lwjgl.opengl.GL43; - import com.modularmods.mcgltf.MCglTF; import com.modularmods.mcgltf.RenderedGltfModel; import com.modularmods.mcgltf.RenderedGltfScene; +import org.lwjgl.opengl.*; public class RenderedGltfSceneIris extends RenderedGltfScene { - @Override - public void renderForVanilla() { - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); - } - - vanillaRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - if(!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); - } - - shaderModRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); + } + + vanillaRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if (!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + shaderModRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/mixin/IrisCompatMixinPlugin.java b/src/main/java/com/modularmods/mcgltf/iris/mixin/IrisCompatMixinPlugin.java index bd5012c..23eef9b 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/mixin/IrisCompatMixinPlugin.java +++ b/src/main/java/com/modularmods/mcgltf/iris/mixin/IrisCompatMixinPlugin.java @@ -1,41 +1,44 @@ package com.modularmods.mcgltf.iris.mixin; -import java.util.List; -import java.util.Set; - +import net.fabricmc.loader.api.FabricLoader; import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; -import net.fabricmc.loader.api.FabricLoader; +import java.util.List; +import java.util.Set; public class IrisCompatMixinPlugin implements IMixinConfigPlugin { - @Override - public void onLoad(String mixinPackage) {} + @Override + public void onLoad(String mixinPackage) { + } - @Override - public String getRefMapperConfig() { - return null; - } + @Override + public String getRefMapperConfig() { + return null; + } - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - return FabricLoader.getInstance().isModLoaded("iris"); - } + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + return FabricLoader.getInstance().isModLoaded("iris"); + } - @Override - public void acceptTargets(Set myTargets, Set otherTargets) {} + @Override + public void acceptTargets(Set myTargets, Set otherTargets) { + } - @Override - public List getMixins() { - return null; - } + @Override + public List getMixins() { + return null; + } - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} + @Override + public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + } - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinBufferUploader.java b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinBufferUploader.java index 189ea18..4ab3e94 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinBufferUploader.java +++ b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinBufferUploader.java @@ -1,19 +1,18 @@ package com.modularmods.mcgltf.iris.mixin; +import com.modularmods.mcgltf.iris.IrisRenderingHook; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.BufferUploader; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.modularmods.mcgltf.iris.IrisRenderingHook; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.BufferUploader; - @Mixin(BufferUploader.class) public class MixinBufferUploader { - @Inject(method = "_drawWithShader(Lcom/mojang/blaze3d/vertex/BufferBuilder$RenderedBuffer;)V", at = @At("HEAD")) - private static void before_drawWithShader(BufferBuilder.RenderedBuffer renderedBuffer, CallbackInfo ci) { - if(renderedBuffer.isEmpty()) IrisRenderingHook.irisHookBypassBufferUploaderVextexCountCheck(renderedBuffer); - } + @Inject(method = "_drawWithShader(Lcom/mojang/blaze3d/vertex/BufferBuilder$RenderedBuffer;)V", at = @At("HEAD")) + private static void before_drawWithShader(BufferBuilder.RenderedBuffer renderedBuffer, CallbackInfo ci) { + if (renderedBuffer.isEmpty()) IrisRenderingHook.irisHookBypassBufferUploaderVextexCountCheck(renderedBuffer); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinRenderStateShard.java b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinRenderStateShard.java index 8d7f9ac..4fc5701 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinRenderStateShard.java +++ b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinRenderStateShard.java @@ -1,19 +1,17 @@ package com.modularmods.mcgltf.iris.mixin; +import com.modularmods.mcgltf.iris.IrisRenderingHook; +import net.minecraft.client.renderer.RenderStateShard; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.modularmods.mcgltf.iris.IrisRenderingHook; - -import net.minecraft.client.renderer.RenderStateShard; - @Mixin(RenderStateShard.class) public class MixinRenderStateShard { - @Inject(method = "setupRenderState()V", at = @At("TAIL")) - private void afterSetupRenderState(CallbackInfo ci) { - IrisRenderingHook.irisHookAfterSetupRenderState((RenderStateShard)(Object)this); - } + @Inject(method = "setupRenderState()V", at = @At("TAIL")) + private void afterSetupRenderState(CallbackInfo ci) { + IrisRenderingHook.irisHookAfterSetupRenderState((RenderStateShard) (Object) this); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinVertexBuffer.java b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinVertexBuffer.java index bb9ad41..bc5940b 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinVertexBuffer.java +++ b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinVertexBuffer.java @@ -1,18 +1,17 @@ package com.modularmods.mcgltf.iris.mixin; +import com.modularmods.mcgltf.iris.IrisRenderingHook; +import com.mojang.blaze3d.vertex.VertexBuffer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.modularmods.mcgltf.iris.IrisRenderingHook; -import com.mojang.blaze3d.vertex.VertexBuffer; - @Mixin(VertexBuffer.class) public class MixinVertexBuffer { - @Inject(method = "draw()V", at = @At("TAIL")) - private void afterDraw(CallbackInfo ci) { - IrisRenderingHook.irisHookAfterVertexBufferDraw(); - } + @Inject(method = "draw()V", at = @At("TAIL")) + private void afterDraw(CallbackInfo ci) { + IrisRenderingHook.irisHookAfterVertexBufferDraw(); + } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Accessor.java b/src/main/java/de/javagl/jgltf/impl/v1/Accessor.java index 94d8d6b..f4851cd 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Accessor.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Accessor.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,303 +9,315 @@ package de.javagl.jgltf.impl.v1; - /** - * A typed view into a bufferView. A bufferView contains raw binary data. - * An accessor provides a typed view into a bufferView or a subset of a - * bufferView similar to how WebGL's `vertexAttribPointer()` defines an - * attribute in a buffer. - * - * Auto-generated for accessor.schema.json - * + * A typed view into a bufferView. A bufferView contains raw binary data. + * An accessor provides a typed view into a bufferView or a subset of a + * bufferView similar to how WebGL's `vertexAttribPointer()` defines an + * attribute in a buffer. + *

+ * Auto-generated for accessor.schema.json + * */ public class Accessor - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The ID of the bufferView. (required) - * + * The ID of the bufferView. (required) + * */ private String bufferView; /** - * The offset relative to the start of the bufferView in bytes. - * (required)
- * Minimum: 0 (inclusive) - * + * The offset relative to the start of the bufferView in bytes. + * (required)
+ * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The stride, in bytes, between attributes referenced by this accessor. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive)
- * Maximum: 255 (inclusive) - * + * The stride, in bytes, between attributes referenced by this accessor. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive)
+ * Maximum: 255 (inclusive) + * */ private Integer byteStride; /** - * The datatype of components in the attribute. (required)
- * Valid values: [5120, 5121, 5122, 5123, 5126] - * + * The datatype of components in the attribute. (required)
+ * Valid values: [5120, 5121, 5122, 5123, 5126] + * */ private Integer componentType; /** - * The number of attributes referenced by this accessor. (required)
- * Minimum: 1 (inclusive) - * + * The number of attributes referenced by this accessor. (required)
+ * Minimum: 1 (inclusive) + * */ private Integer count; /** - * Specifies if the attribute is a scalar, vector, or matrix. - * (required)
- * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", - * "MAT4"] - * + * Specifies if the attribute is a scalar, vector, or matrix. + * (required)
+ * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", + * "MAT4"] + * */ private String type; /** - * Maximum value of each component in this attribute. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Maximum value of each component in this attribute. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * */ private Number[] max; /** - * Minimum value of each component in this attribute. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Minimum value of each component in this attribute. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * */ private Number[] min; /** - * The ID of the bufferView. (required) - * + * The ID of the bufferView. (required) + * + * @return The bufferView + * + */ + public String getBufferView() { + return this.bufferView; + } + + /** + * The ID of the bufferView. (required) + * * @param bufferView The bufferView to set * @throws NullPointerException If the given value is null - * + * */ public void setBufferView(String bufferView) { if (bufferView == null) { - throw new NullPointerException((("Invalid value for bufferView: "+ bufferView)+", may not be null")); + throw new NullPointerException((("Invalid value for bufferView: " + bufferView) + ", may not be null")); } this.bufferView = bufferView; } /** - * The ID of the bufferView. (required) - * - * @return The bufferView - * + * The offset relative to the start of the bufferView in bytes. + * (required)
+ * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public String getBufferView() { - return this.bufferView; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The offset relative to the start of the bufferView in bytes. - * (required)
- * Minimum: 0 (inclusive) - * + * The offset relative to the start of the bufferView in bytes. + * (required)
+ * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { - throw new NullPointerException((("Invalid value for byteOffset: "+ byteOffset)+", may not be null")); + throw new NullPointerException((("Invalid value for byteOffset: " + byteOffset) + ", may not be null")); } - if (byteOffset< 0) { + if (byteOffset < 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * The offset relative to the start of the bufferView in bytes. - * (required)
- * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * The stride, in bytes, between attributes referenced by this accessor. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive)
+ * Maximum: 255 (inclusive) + * + * @return The byteStride + * */ - public Integer getByteOffset() { - return this.byteOffset; + public Integer getByteStride() { + return this.byteStride; } /** - * The stride, in bytes, between attributes referenced by this accessor. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive)
- * Maximum: 255 (inclusive) - * + * The stride, in bytes, between attributes referenced by this accessor. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive)
+ * Maximum: 255 (inclusive) + * * @param byteStride The byteStride to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteStride(Integer byteStride) { if (byteStride == null) { this.byteStride = byteStride; - return ; + return; } if (byteStride > 255) { throw new IllegalArgumentException("byteStride > 255"); } - if (byteStride< 0) { + if (byteStride < 0) { throw new IllegalArgumentException("byteStride < 0"); } this.byteStride = byteStride; } /** - * The stride, in bytes, between attributes referenced by this accessor. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive)
- * Maximum: 255 (inclusive) - * - * @return The byteStride - * + * Returns the default value of the byteStride
+ * + * @return The default byteStride + * @see #getByteStride + * */ - public Integer getByteStride() { - return this.byteStride; + public Integer defaultByteStride() { + return 0; } /** - * Returns the default value of the byteStride
- * @see #getByteStride - * - * @return The default byteStride - * + * The datatype of components in the attribute. (required)
+ * Valid values: [5120, 5121, 5122, 5123, 5126] + * + * @return The componentType + * */ - public Integer defaultByteStride() { - return 0; + public Integer getComponentType() { + return this.componentType; } /** - * The datatype of components in the attribute. (required)
- * Valid values: [5120, 5121, 5122, 5123, 5126] - * + * The datatype of components in the attribute. (required)
+ * Valid values: [5120, 5121, 5122, 5123, 5126] + * * @param componentType The componentType to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setComponentType(Integer componentType) { if (componentType == null) { - throw new NullPointerException((("Invalid value for componentType: "+ componentType)+", may not be null")); + throw new NullPointerException((("Invalid value for componentType: " + componentType) + ", may not be null")); } - if (((((componentType!= 5120)&&(componentType!= 5121))&&(componentType!= 5122))&&(componentType!= 5123))&&(componentType!= 5126)) { - throw new IllegalArgumentException((("Invalid value for componentType: "+ componentType)+", valid: [5120, 5121, 5122, 5123, 5126]")); + if (((((componentType != 5120) && (componentType != 5121)) && (componentType != 5122)) && (componentType != 5123)) && (componentType != 5126)) { + throw new IllegalArgumentException((("Invalid value for componentType: " + componentType) + ", valid: [5120, 5121, 5122, 5123, 5126]")); } this.componentType = componentType; } /** - * The datatype of components in the attribute. (required)
- * Valid values: [5120, 5121, 5122, 5123, 5126] - * - * @return The componentType - * + * The number of attributes referenced by this accessor. (required)
+ * Minimum: 1 (inclusive) + * + * @return The count + * */ - public Integer getComponentType() { - return this.componentType; + public Integer getCount() { + return this.count; } /** - * The number of attributes referenced by this accessor. (required)
- * Minimum: 1 (inclusive) - * + * The number of attributes referenced by this accessor. (required)
+ * Minimum: 1 (inclusive) + * * @param count The count to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCount(Integer count) { if (count == null) { - throw new NullPointerException((("Invalid value for count: "+ count)+", may not be null")); + throw new NullPointerException((("Invalid value for count: " + count) + ", may not be null")); } - if (count< 1) { + if (count < 1) { throw new IllegalArgumentException("count < 1"); } this.count = count; } /** - * The number of attributes referenced by this accessor. (required)
- * Minimum: 1 (inclusive) - * - * @return The count - * + * Specifies if the attribute is a scalar, vector, or matrix. + * (required)
+ * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", + * "MAT4"] + * + * @return The type + * */ - public Integer getCount() { - return this.count; + public String getType() { + return this.type; } /** - * Specifies if the attribute is a scalar, vector, or matrix. - * (required)
- * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", - * "MAT4"] - * + * Specifies if the attribute is a scalar, vector, or matrix. + * (required)
+ * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", + * "MAT4"] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); + throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); } - if (((((((!"SCALAR".equals(type))&&(!"VEC2".equals(type)))&&(!"VEC3".equals(type)))&&(!"VEC4".equals(type)))&&(!"MAT2".equals(type)))&&(!"MAT3".equals(type)))&&(!"MAT4".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [\"SCALAR\", \"VEC2\", \"VEC3\", \"VEC4\", \"MAT2\", \"MAT3\", \"MAT4\"]")); + if (((((((!"SCALAR".equals(type)) && (!"VEC2".equals(type))) && (!"VEC3".equals(type))) && (!"VEC4".equals(type))) && (!"MAT2".equals(type))) && (!"MAT3".equals(type))) && (!"MAT4".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [\"SCALAR\", \"VEC2\", \"VEC3\", \"VEC4\", \"MAT2\", \"MAT3\", \"MAT4\"]")); } this.type = type; } /** - * Specifies if the attribute is a scalar, vector, or matrix. - * (required)
- * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", - * "MAT4"] - * - * @return The type - * + * Maximum value of each component in this attribute. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The max + * */ - public String getType() { - return this.type; + public Number[] getMax() { + return this.max; } /** - * Maximum value of each component in this attribute. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Maximum value of each component in this attribute. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * * @param max The max to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMax(Number[] max) { if (max == null) { this.max = max; - return ; + return; } - if (max.length< 1) { + if (max.length < 1) { throw new IllegalArgumentException("Number of max elements is < 1"); } if (max.length > 16) { @@ -315,37 +327,37 @@ public void setMax(Number[] max) { } /** - * Maximum value of each component in this attribute. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * - * @return The max - * + * Minimum value of each component in this attribute. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The min + * */ - public Number[] getMax() { - return this.max; + public Number[] getMin() { + return this.min; } /** - * Minimum value of each component in this attribute. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Minimum value of each component in this attribute. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * * @param min The min to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMin(Number[] min) { if (min == null) { this.min = min; - return ; + return; } - if (min.length< 1) { + if (min.length < 1) { throw new IllegalArgumentException("Number of min elements is < 1"); } if (min.length > 16) { @@ -354,18 +366,4 @@ public void setMin(Number[] min) { this.min = min; } - /** - * Minimum value of each component in this attribute. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * - * @return The min - * - */ - public Number[] getMin() { - return this.min; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Animation.java b/src/main/java/de/javagl/jgltf/impl/v1/Animation.java index 59b6b45..bc6adc2 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Animation.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Animation.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -15,83 +15,82 @@ /** - * A keyframe animation. - * - * Auto-generated for animation.schema.json - * + * A keyframe animation. + *

+ * Auto-generated for animation.schema.json + * */ public class Animation - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * An array of channels, each of which targets an animation's sampler at - * a node's property. (optional)
- * Default: []
- * Array elements:
- *   Targets an animation's sampler at a node's property. - * (optional) - * + * An array of channels, each of which targets an animation's sampler at + * a node's property. (optional)
+ * Default: []
+ * Array elements:
+ *   Targets an animation's sampler at a node's property. + * (optional) + * */ private List channels; /** - * A dictionary object of strings whose values are IDs of accessors with - * keyframe data, e.g., time, translation, rotation, etc. (optional)
- * Default: {} - * + * A dictionary object of strings whose values are IDs of accessors with + * keyframe data, e.g., time, translation, rotation, etc. (optional)
+ * Default: {} + * */ private Map parameters; /** - * A dictionary object of samplers that combines input and output - * parameters with an interpolation algorithm to define a keyframe graph - * (but not its target). (optional)
- * Default: {} - * + * A dictionary object of samplers that combines input and output + * parameters with an interpolation algorithm to define a keyframe graph + * (but not its target). (optional)
+ * Default: {} + * */ private Map samplers; /** - * An array of channels, each of which targets an animation's sampler at - * a node's property. (optional)
- * Default: []
- * Array elements:
- *   Targets an animation's sampler at a node's property. - * (optional) - * + * An array of channels, each of which targets an animation's sampler at + * a node's property. (optional)
+ * Default: []
+ * Array elements:
+ *   Targets an animation's sampler at a node's property. + * (optional) + * + * @return The channels + * + */ + public List getChannels() { + return this.channels; + } + + /** + * An array of channels, each of which targets an animation's sampler at + * a node's property. (optional)
+ * Default: []
+ * Array elements:
+ *   Targets an animation's sampler at a node's property. + * (optional) + * * @param channels The channels to set - * + * */ public void setChannels(List channels) { if (channels == null) { this.channels = channels; - return ; + return; } this.channels = channels; } /** - * An array of channels, each of which targets an animation's sampler at - * a node's property. (optional)
- * Default: []
- * Array elements:
- *   Targets an animation's sampler at a node's property. - * (optional) - * - * @return The channels - * - */ - public List getChannels() { - return this.channels; - } - - /** - * Add the given channels. The channels of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given channels. The channels of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addChannels(AnimationChannel element) { if (element == null) { @@ -99,7 +98,7 @@ public void addChannels(AnimationChannel element) { } List oldList = this.channels; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -107,15 +106,15 @@ public void addChannels(AnimationChannel element) { } /** - * Remove the given channels. The channels of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given channels. The channels of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeChannels(AnimationChannel element) { if (element == null) { @@ -123,7 +122,7 @@ public void removeChannels(AnimationChannel element) { } List oldList = this.channels; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -135,53 +134,53 @@ public void removeChannels(AnimationChannel element) { } /** - * Returns the default value of the channels
- * @see #getChannels - * + * Returns the default value of the channels
+ * * @return The default channels - * + * @see #getChannels + * */ public List defaultChannels() { return new ArrayList(); } /** - * A dictionary object of strings whose values are IDs of accessors with - * keyframe data, e.g., time, translation, rotation, etc. (optional)
- * Default: {} - * + * A dictionary object of strings whose values are IDs of accessors with + * keyframe data, e.g., time, translation, rotation, etc. (optional)
+ * Default: {} + * + * @return The parameters + * + */ + public Map getParameters() { + return this.parameters; + } + + /** + * A dictionary object of strings whose values are IDs of accessors with + * keyframe data, e.g., time, translation, rotation, etc. (optional)
+ * Default: {} + * * @param parameters The parameters to set - * + * */ public void setParameters(Map parameters) { if (parameters == null) { this.parameters = parameters; - return ; + return; } this.parameters = parameters; } /** - * A dictionary object of strings whose values are IDs of accessors with - * keyframe data, e.g., time, translation, rotation, etc. (optional)
- * Default: {} - * - * @return The parameters - * - */ - public Map getParameters() { - return this.parameters; - } - - /** - * Add the given parameters. The parameters of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given parameters. The parameters of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addParameters(String key, String value) { if (key == null) { @@ -192,7 +191,7 @@ public void addParameters(String key, String value) { } Map oldMap = this.parameters; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -200,15 +199,15 @@ public void addParameters(String key, String value) { } /** - * Remove the given parameters. The parameters of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given parameters. The parameters of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeParameters(String key) { if (key == null) { @@ -216,7 +215,7 @@ public void removeParameters(String key) { } Map oldMap = this.parameters; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -228,55 +227,55 @@ public void removeParameters(String key) { } /** - * Returns the default value of the parameters
- * @see #getParameters - * + * Returns the default value of the parameters
+ * * @return The default parameters - * + * @see #getParameters + * */ public Map defaultParameters() { return new LinkedHashMap(); } /** - * A dictionary object of samplers that combines input and output - * parameters with an interpolation algorithm to define a keyframe graph - * (but not its target). (optional)
- * Default: {} - * + * A dictionary object of samplers that combines input and output + * parameters with an interpolation algorithm to define a keyframe graph + * (but not its target). (optional)
+ * Default: {} + * + * @return The samplers + * + */ + public Map getSamplers() { + return this.samplers; + } + + /** + * A dictionary object of samplers that combines input and output + * parameters with an interpolation algorithm to define a keyframe graph + * (but not its target). (optional)
+ * Default: {} + * * @param samplers The samplers to set - * + * */ public void setSamplers(Map samplers) { if (samplers == null) { this.samplers = samplers; - return ; + return; } this.samplers = samplers; } /** - * A dictionary object of samplers that combines input and output - * parameters with an interpolation algorithm to define a keyframe graph - * (but not its target). (optional)
- * Default: {} - * - * @return The samplers - * - */ - public Map getSamplers() { - return this.samplers; - } - - /** - * Add the given samplers. The samplers of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given samplers. The samplers of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addSamplers(String key, AnimationSampler value) { if (key == null) { @@ -287,7 +286,7 @@ public void addSamplers(String key, AnimationSampler value) { } Map oldMap = this.samplers; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -295,15 +294,15 @@ public void addSamplers(String key, AnimationSampler value) { } /** - * Remove the given samplers. The samplers of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given samplers. The samplers of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeSamplers(String key) { if (key == null) { @@ -311,7 +310,7 @@ public void removeSamplers(String key) { } Map oldMap = this.samplers; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -323,11 +322,11 @@ public void removeSamplers(String key) { } /** - * Returns the default value of the samplers
- * @see #getSamplers - * + * Returns the default value of the samplers
+ * * @return The default samplers - * + * @see #getSamplers + * */ public Map defaultSamplers() { return new LinkedHashMap(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannel.java b/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannel.java index 211d301..398a141 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannel.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannel.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,77 +9,75 @@ package de.javagl.jgltf.impl.v1; - /** - * Targets an animation's sampler at a node's property. - * - * Auto-generated for animation.channel.schema.json - * + * Targets an animation's sampler at a node's property. + *

+ * Auto-generated for animation.channel.schema.json + * */ public class AnimationChannel - extends GlTFProperty -{ + extends GlTFProperty { /** - * The ID of a sampler in this animation used to compute the value for - * the target. (required) - * + * The ID of a sampler in this animation used to compute the value for + * the target. (required) + * */ private String sampler; /** - * The ID of the node and TRS property to target. (required) - * + * The ID of the node and TRS property to target. (required) + * */ private AnimationChannelTarget target; /** - * The ID of a sampler in this animation used to compute the value for - * the target. (required) - * + * The ID of a sampler in this animation used to compute the value for + * the target. (required) + * + * @return The sampler + * + */ + public String getSampler() { + return this.sampler; + } + + /** + * The ID of a sampler in this animation used to compute the value for + * the target. (required) + * * @param sampler The sampler to set * @throws NullPointerException If the given value is null - * + * */ public void setSampler(String sampler) { if (sampler == null) { - throw new NullPointerException((("Invalid value for sampler: "+ sampler)+", may not be null")); + throw new NullPointerException((("Invalid value for sampler: " + sampler) + ", may not be null")); } this.sampler = sampler; } /** - * The ID of a sampler in this animation used to compute the value for - * the target. (required) - * - * @return The sampler - * + * The ID of the node and TRS property to target. (required) + * + * @return The target + * */ - public String getSampler() { - return this.sampler; + public AnimationChannelTarget getTarget() { + return this.target; } /** - * The ID of the node and TRS property to target. (required) - * + * The ID of the node and TRS property to target. (required) + * * @param target The target to set * @throws NullPointerException If the given value is null - * + * */ public void setTarget(AnimationChannelTarget target) { if (target == null) { - throw new NullPointerException((("Invalid value for target: "+ target)+", may not be null")); + throw new NullPointerException((("Invalid value for target: " + target) + ", may not be null")); } this.target = target; } - /** - * The ID of the node and TRS property to target. (required) - * - * @return The target - * - */ - public AnimationChannelTarget getTarget() { - return this.target; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannelTarget.java b/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannelTarget.java index ae6d9db..49e4312 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannelTarget.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannelTarget.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,82 +9,80 @@ package de.javagl.jgltf.impl.v1; - /** - * The ID of the node and TRS property that an animation channel targets. - * - * Auto-generated for animation.channel.target.schema.json - * + * The ID of the node and TRS property that an animation channel targets. + *

+ * Auto-generated for animation.channel.target.schema.json + * */ public class AnimationChannelTarget - extends GlTFProperty -{ + extends GlTFProperty { /** - * The ID of the node to target. (required) - * + * The ID of the node to target. (required) + * */ private String id; /** - * The name of the node's TRS property to modify. (required)
- * Valid values: ["translation", "rotation", "scale"] - * + * The name of the node's TRS property to modify. (required)
+ * Valid values: ["translation", "rotation", "scale"] + * */ private String path; /** - * The ID of the node to target. (required) - * + * The ID of the node to target. (required) + * + * @return The id + * + */ + public String getId() { + return this.id; + } + + /** + * The ID of the node to target. (required) + * * @param id The id to set * @throws NullPointerException If the given value is null - * + * */ public void setId(String id) { if (id == null) { - throw new NullPointerException((("Invalid value for id: "+ id)+", may not be null")); + throw new NullPointerException((("Invalid value for id: " + id) + ", may not be null")); } this.id = id; } /** - * The ID of the node to target. (required) - * - * @return The id - * + * The name of the node's TRS property to modify. (required)
+ * Valid values: ["translation", "rotation", "scale"] + * + * @return The path + * */ - public String getId() { - return this.id; + public String getPath() { + return this.path; } /** - * The name of the node's TRS property to modify. (required)
- * Valid values: ["translation", "rotation", "scale"] - * + * The name of the node's TRS property to modify. (required)
+ * Valid values: ["translation", "rotation", "scale"] + * * @param path The path to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setPath(String path) { if (path == null) { - throw new NullPointerException((("Invalid value for path: "+ path)+", may not be null")); + throw new NullPointerException((("Invalid value for path: " + path) + ", may not be null")); } - if (((!"translation".equals(path))&&(!"rotation".equals(path)))&&(!"scale".equals(path))) { - throw new IllegalArgumentException((("Invalid value for path: "+ path)+", valid: [\"translation\", \"rotation\", \"scale\"]")); + if (((!"translation".equals(path)) && (!"rotation".equals(path))) && (!"scale".equals(path))) { + throw new IllegalArgumentException((("Invalid value for path: " + path) + ", valid: [\"translation\", \"rotation\", \"scale\"]")); } this.path = path; } - /** - * The name of the node's TRS property to modify. (required)
- * Valid values: ["translation", "rotation", "scale"] - * - * @return The path - * - */ - public String getPath() { - return this.path; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/AnimationSampler.java b/src/main/java/de/javagl/jgltf/impl/v1/AnimationSampler.java index 170377d..5ec23aa 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/AnimationSampler.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/AnimationSampler.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,132 +9,130 @@ package de.javagl.jgltf.impl.v1; - /** - * Combines input and output parameters with an interpolation algorithm - * to define a keyframe graph (but not its target). - * - * Auto-generated for animation.sampler.schema.json - * + * Combines input and output parameters with an interpolation algorithm + * to define a keyframe graph (but not its target). + *

+ * Auto-generated for animation.sampler.schema.json + * */ public class AnimationSampler - extends GlTFProperty -{ + extends GlTFProperty { /** - * The ID of a parameter in this animation to use as keyframe input, - * e.g., time. (required) - * + * The ID of a parameter in this animation to use as keyframe input, + * e.g., time. (required) + * */ private String input; /** - * Interpolation algorithm. (optional)
- * Default: "LINEAR"
- * Valid values: ["LINEAR", "STEP"] - * + * Interpolation algorithm. (optional)
+ * Default: "LINEAR"
+ * Valid values: ["LINEAR", "STEP"] + * */ private String interpolation; /** - * The ID of a parameter in this animation to use as keyframe output. - * (required) - * + * The ID of a parameter in this animation to use as keyframe output. + * (required) + * */ private String output; /** - * The ID of a parameter in this animation to use as keyframe input, - * e.g., time. (required) - * + * The ID of a parameter in this animation to use as keyframe input, + * e.g., time. (required) + * + * @return The input + * + */ + public String getInput() { + return this.input; + } + + /** + * The ID of a parameter in this animation to use as keyframe input, + * e.g., time. (required) + * * @param input The input to set * @throws NullPointerException If the given value is null - * + * */ public void setInput(String input) { if (input == null) { - throw new NullPointerException((("Invalid value for input: "+ input)+", may not be null")); + throw new NullPointerException((("Invalid value for input: " + input) + ", may not be null")); } this.input = input; } /** - * The ID of a parameter in this animation to use as keyframe input, - * e.g., time. (required) - * - * @return The input - * + * Interpolation algorithm. (optional)
+ * Default: "LINEAR"
+ * Valid values: ["LINEAR"] + * + * @return The interpolation + * */ - public String getInput() { - return this.input; + public String getInterpolation() { + return this.interpolation; } /** - * Interpolation algorithm. (optional)
- * Default: "LINEAR"
- * Valid values: ["LINEAR"] - * + * Interpolation algorithm. (optional)
+ * Default: "LINEAR"
+ * Valid values: ["LINEAR"] + * * @param interpolation The interpolation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setInterpolation(String interpolation) { if (interpolation == null) { this.interpolation = interpolation; - return ; + return; } - if ((!"LINEAR".equals(interpolation))&&(!"STEP".equals(interpolation))) { - throw new IllegalArgumentException((("Invalid value for interpolation: "+ interpolation)+", valid: [\"LINEAR\", \"STEP\"]")); + if ((!"LINEAR".equals(interpolation)) && (!"STEP".equals(interpolation))) { + throw new IllegalArgumentException((("Invalid value for interpolation: " + interpolation) + ", valid: [\"LINEAR\", \"STEP\"]")); } this.interpolation = interpolation; } /** - * Interpolation algorithm. (optional)
- * Default: "LINEAR"
- * Valid values: ["LINEAR"] - * - * @return The interpolation - * + * Returns the default value of the interpolation
+ * + * @return The default interpolation + * @see #getInterpolation + * */ - public String getInterpolation() { - return this.interpolation; + public String defaultInterpolation() { + return "LINEAR"; } /** - * Returns the default value of the interpolation
- * @see #getInterpolation - * - * @return The default interpolation - * + * The ID of a parameter in this animation to use as keyframe output. + * (required) + * + * @return The output + * */ - public String defaultInterpolation() { - return "LINEAR"; + public String getOutput() { + return this.output; } /** - * The ID of a parameter in this animation to use as keyframe output. - * (required) - * + * The ID of a parameter in this animation to use as keyframe output. + * (required) + * * @param output The output to set * @throws NullPointerException If the given value is null - * + * */ public void setOutput(String output) { if (output == null) { - throw new NullPointerException((("Invalid value for output: "+ output)+", may not be null")); + throw new NullPointerException((("Invalid value for output: " + output) + ", may not be null")); } this.output = output; } - /** - * The ID of a parameter in this animation to use as keyframe output. - * (required) - * - * @return The output - * - */ - public String getOutput() { - return this.output; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Asset.java b/src/main/java/de/javagl/jgltf/impl/v1/Asset.java index ea6360b..b951379 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Asset.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Asset.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,195 +9,193 @@ package de.javagl.jgltf.impl.v1; - /** - * Metadata about the glTF asset. - * - * Auto-generated for asset.schema.json - * + * Metadata about the glTF asset. + *

+ * Auto-generated for asset.schema.json + * */ public class Asset - extends GlTFProperty -{ + extends GlTFProperty { /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * */ private String copyright; /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * */ private String generator; /** - * Specifies if the shaders were generated with premultiplied alpha. - * (optional)
- * Default: false - * + * Specifies if the shaders were generated with premultiplied alpha. + * (optional)
+ * Default: false + * */ private Boolean premultipliedAlpha; /** - * The profile of this Asset (optional)
- * Default: {} - * + * The profile of this Asset (optional)
+ * Default: {} + * */ private AssetProfile profile; /** - * The glTF version. (required) - * + * The glTF version. (required) + * */ private String version; /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * + * @return The copyright + * + */ + public String getCopyright() { + return this.copyright; + } + + /** + * A copyright message suitable for display to credit the content + * creator. (optional) + * * @param copyright The copyright to set - * + * */ public void setCopyright(String copyright) { if (copyright == null) { this.copyright = copyright; - return ; + return; } this.copyright = copyright; } /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * - * @return The copyright - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * + * @return The generator + * */ - public String getCopyright() { - return this.copyright; + public String getGenerator() { + return this.generator; } /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * * @param generator The generator to set - * + * */ public void setGenerator(String generator) { if (generator == null) { this.generator = generator; - return ; + return; } this.generator = generator; } /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * - * @return The generator - * - */ - public String getGenerator() { - return this.generator; - } - - /** - * Specifies if the shaders were generated with premultiplied alpha. - * (optional)
- * Default: false - * + * Specifies if the shaders were generated with premultiplied alpha. + * (optional)
+ * Default: false + * * @param premultipliedAlpha The premultipliedAlpha to set - * + * */ public void setPremultipliedAlpha(Boolean premultipliedAlpha) { if (premultipliedAlpha == null) { this.premultipliedAlpha = premultipliedAlpha; - return ; + return; } this.premultipliedAlpha = premultipliedAlpha; } /** - * Specifies if the shaders were generated with premultiplied alpha. - * (optional)
- * Default: false - * + * Specifies if the shaders were generated with premultiplied alpha. + * (optional)
+ * Default: false + * * @return The premultipliedAlpha - * + * */ public Boolean isPremultipliedAlpha() { return this.premultipliedAlpha; } /** - * Returns the default value of the premultipliedAlpha
- * @see #isPremultipliedAlpha - * + * Returns the default value of the premultipliedAlpha
+ * * @return The default premultipliedAlpha - * + * @see #isPremultipliedAlpha + * */ public Boolean defaultPremultipliedAlpha() { return false; } /** - * The profile of this Asset (optional)
- * Default: {} - * + * The profile of this Asset (optional)
+ * Default: {} + * + * @return The profile + * + */ + public AssetProfile getProfile() { + return this.profile; + } + + /** + * The profile of this Asset (optional)
+ * Default: {} + * * @param profile The profile to set - * + * */ public void setProfile(AssetProfile profile) { if (profile == null) { this.profile = profile; - return ; + return; } this.profile = profile; } /** - * The profile of this Asset (optional)
- * Default: {} - * - * @return The profile - * + * Returns the default value of the profile
+ * + * @return The default profile + * @see #getProfile + * */ - public AssetProfile getProfile() { - return this.profile; + public AssetProfile defaultProfile() { + return new AssetProfile(); } /** - * Returns the default value of the profile
- * @see #getProfile - * - * @return The default profile - * + * The glTF version. (required) + * + * @return The version + * */ - public AssetProfile defaultProfile() { - return new AssetProfile(); + public String getVersion() { + return this.version; } /** - * The glTF version. (required) - * + * The glTF version. (required) + * * @param version The version to set * @throws NullPointerException If the given value is null - * + * */ public void setVersion(String version) { if (version == null) { - throw new NullPointerException((("Invalid value for version: "+ version)+", may not be null")); + throw new NullPointerException((("Invalid value for version: " + version) + ", may not be null")); } this.version = version; } - /** - * The glTF version. (required) - * - * @return The version - * - */ - public String getVersion() { - return this.version; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/AssetProfile.java b/src/main/java/de/javagl/jgltf/impl/v1/AssetProfile.java index 683b676..da44dcb 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/AssetProfile.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/AssetProfile.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,99 +9,97 @@ package de.javagl.jgltf.impl.v1; - /** - * Specifies the target rendering API and version, e.g., WebGL 1.0.3. - * - * Auto-generated for asset.profile.schema.json - * + * Specifies the target rendering API and version, e.g., WebGL 1.0.3. + *

+ * Auto-generated for asset.profile.schema.json + * */ public class AssetProfile - extends GlTFProperty -{ + extends GlTFProperty { /** - * Specifies the target rendering API. (optional)
- * Default: "WebGL" - * + * Specifies the target rendering API. (optional)
+ * Default: "WebGL" + * */ private String api; /** - * The API version. (optional)
- * Default: "1.0.3" - * + * The API version. (optional)
+ * Default: "1.0.3" + * */ private String version; /** - * Specifies the target rendering API. (optional)
- * Default: "WebGL" - * + * Specifies the target rendering API. (optional)
+ * Default: "WebGL" + * + * @return The api + * + */ + public String getApi() { + return this.api; + } + + /** + * Specifies the target rendering API. (optional)
+ * Default: "WebGL" + * * @param api The api to set - * + * */ public void setApi(String api) { if (api == null) { this.api = api; - return ; + return; } this.api = api; } /** - * Specifies the target rendering API. (optional)
- * Default: "WebGL" - * - * @return The api - * + * Returns the default value of the api
+ * + * @return The default api + * @see #getApi + * */ - public String getApi() { - return this.api; + public String defaultApi() { + return "WebGL"; } /** - * Returns the default value of the api
- * @see #getApi - * - * @return The default api - * + * The API version. (optional)
+ * Default: "1.0.3" + * + * @return The version + * */ - public String defaultApi() { - return "WebGL"; + public String getVersion() { + return this.version; } /** - * The API version. (optional)
- * Default: "1.0.3" - * + * The API version. (optional)
+ * Default: "1.0.3" + * * @param version The version to set - * + * */ public void setVersion(String version) { if (version == null) { this.version = version; - return ; + return; } this.version = version; } /** - * The API version. (optional)
- * Default: "1.0.3" - * - * @return The version - * - */ - public String getVersion() { - return this.version; - } - - /** - * Returns the default value of the version
- * @see #getVersion - * + * Returns the default value of the version
+ * * @return The default version - * + * @see #getVersion + * */ public String defaultVersion() { return "1.0.3"; diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Buffer.java b/src/main/java/de/javagl/jgltf/impl/v1/Buffer.java index 22ac00c..8227e7b 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Buffer.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Buffer.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,144 +9,142 @@ package de.javagl.jgltf.impl.v1; - /** - * A buffer points to binary geometry, animation, or skins. - * - * Auto-generated for buffer.schema.json - * + * A buffer points to binary geometry, animation, or skins. + *

+ * Auto-generated for buffer.schema.json + * */ public class Buffer - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The uri of the buffer. (required) - * + * The uri of the buffer. (required) + * */ private String uri; /** - * The length of the buffer in bytes. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The length of the buffer in bytes. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * */ private Integer byteLength; /** - * XMLHttpRequest `responseType`. (optional)
- * Default: "arraybuffer"
- * Valid values: ["arraybuffer", "text"] - * + * XMLHttpRequest `responseType`. (optional)
+ * Default: "arraybuffer"
+ * Valid values: ["arraybuffer", "text"] + * */ private String type; /** - * The uri of the buffer. (required) - * + * The uri of the buffer. (required) + * + * @return The uri + * + */ + public String getUri() { + return this.uri; + } + + /** + * The uri of the buffer. (required) + * * @param uri The uri to set * @throws NullPointerException If the given value is null - * + * */ public void setUri(String uri) { if (uri == null) { - throw new NullPointerException((("Invalid value for uri: "+ uri)+", may not be null")); + throw new NullPointerException((("Invalid value for uri: " + uri) + ", may not be null")); } this.uri = uri; } /** - * The uri of the buffer. (required) - * - * @return The uri - * + * The length of the buffer in bytes. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * + * @return The byteLength + * */ - public String getUri() { - return this.uri; + public Integer getByteLength() { + return this.byteLength; } /** - * The length of the buffer in bytes. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The length of the buffer in bytes. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * * @param byteLength The byteLength to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteLength(Integer byteLength) { if (byteLength == null) { this.byteLength = byteLength; - return ; + return; } - if (byteLength< 0) { + if (byteLength < 0) { throw new IllegalArgumentException("byteLength < 0"); } this.byteLength = byteLength; } /** - * The length of the buffer in bytes. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * - * @return The byteLength - * + * Returns the default value of the byteLength
+ * + * @return The default byteLength + * @see #getByteLength + * */ - public Integer getByteLength() { - return this.byteLength; + public Integer defaultByteLength() { + return 0; } /** - * Returns the default value of the byteLength
- * @see #getByteLength - * - * @return The default byteLength - * + * XMLHttpRequest `responseType`. (optional)
+ * Default: "arraybuffer"
+ * Valid values: ["arraybuffer", "text"] + * + * @return The type + * */ - public Integer defaultByteLength() { - return 0; + public String getType() { + return this.type; } /** - * XMLHttpRequest `responseType`. (optional)
- * Default: "arraybuffer"
- * Valid values: ["arraybuffer", "text"] - * + * XMLHttpRequest `responseType`. (optional)
+ * Default: "arraybuffer"
+ * Valid values: ["arraybuffer", "text"] + * * @param type The type to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { this.type = type; - return ; + return; } - if ((!"arraybuffer".equals(type))&&(!"text".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [\"arraybuffer\", \"text\"]")); + if ((!"arraybuffer".equals(type)) && (!"text".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [\"arraybuffer\", \"text\"]")); } this.type = type; } /** - * XMLHttpRequest `responseType`. (optional)
- * Default: "arraybuffer"
- * Valid values: ["arraybuffer", "text"] - * - * @return The type - * - */ - public String getType() { - return this.type; - } - - /** - * Returns the default value of the type
- * @see #getType - * + * Returns the default value of the type
+ * * @return The default type - * + * @see #getType + * */ public String defaultType() { return "arraybuffer"; diff --git a/src/main/java/de/javagl/jgltf/impl/v1/BufferView.java b/src/main/java/de/javagl/jgltf/impl/v1/BufferView.java index 4747a1d..446e796 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/BufferView.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/BufferView.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,170 +9,168 @@ package de.javagl.jgltf.impl.v1; - /** - * A view into a buffer generally representing a subset of the buffer. - * - * Auto-generated for bufferView.schema.json - * + * A view into a buffer generally representing a subset of the buffer. + *

+ * Auto-generated for bufferView.schema.json + * */ public class BufferView - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The ID of the buffer. (required) - * + * The ID of the buffer. (required) + * */ private String buffer; /** - * The offset into the buffer in bytes. (required)
- * Minimum: 0 (inclusive) - * + * The offset into the buffer in bytes. (required)
+ * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The length of the bufferView in bytes. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The length of the bufferView in bytes. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * */ private Integer byteLength; /** - * The target that the WebGL buffer should be bound to. (optional)
- * Valid values: [34962, 34963] - * + * The target that the WebGL buffer should be bound to. (optional)
+ * Valid values: [34962, 34963] + * */ private Integer target; /** - * The ID of the buffer. (required) - * + * The ID of the buffer. (required) + * + * @return The buffer + * + */ + public String getBuffer() { + return this.buffer; + } + + /** + * The ID of the buffer. (required) + * * @param buffer The buffer to set * @throws NullPointerException If the given value is null - * + * */ public void setBuffer(String buffer) { if (buffer == null) { - throw new NullPointerException((("Invalid value for buffer: "+ buffer)+", may not be null")); + throw new NullPointerException((("Invalid value for buffer: " + buffer) + ", may not be null")); } this.buffer = buffer; } /** - * The ID of the buffer. (required) - * - * @return The buffer - * + * The offset into the buffer in bytes. (required)
+ * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public String getBuffer() { - return this.buffer; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The offset into the buffer in bytes. (required)
- * Minimum: 0 (inclusive) - * + * The offset into the buffer in bytes. (required)
+ * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { - throw new NullPointerException((("Invalid value for byteOffset: "+ byteOffset)+", may not be null")); + throw new NullPointerException((("Invalid value for byteOffset: " + byteOffset) + ", may not be null")); } - if (byteOffset< 0) { + if (byteOffset < 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * The offset into the buffer in bytes. (required)
- * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * The length of the bufferView in bytes. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * + * @return The byteLength + * */ - public Integer getByteOffset() { - return this.byteOffset; + public Integer getByteLength() { + return this.byteLength; } /** - * The length of the bufferView in bytes. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The length of the bufferView in bytes. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * * @param byteLength The byteLength to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteLength(Integer byteLength) { if (byteLength == null) { this.byteLength = byteLength; - return ; + return; } - if (byteLength< 0) { + if (byteLength < 0) { throw new IllegalArgumentException("byteLength < 0"); } this.byteLength = byteLength; } /** - * The length of the bufferView in bytes. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * - * @return The byteLength - * + * Returns the default value of the byteLength
+ * + * @return The default byteLength + * @see #getByteLength + * */ - public Integer getByteLength() { - return this.byteLength; + public Integer defaultByteLength() { + return 0; } /** - * Returns the default value of the byteLength
- * @see #getByteLength - * - * @return The default byteLength - * + * The target that the WebGL buffer should be bound to. (optional)
+ * Valid values: [34962, 34963] + * + * @return The target + * */ - public Integer defaultByteLength() { - return 0; + public Integer getTarget() { + return this.target; } /** - * The target that the WebGL buffer should be bound to. (optional)
- * Valid values: [34962, 34963] - * + * The target that the WebGL buffer should be bound to. (optional)
+ * Valid values: [34962, 34963] + * * @param target The target to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTarget(Integer target) { if (target == null) { this.target = target; - return ; + return; } - if ((target!= 34962)&&(target!= 34963)) { - throw new IllegalArgumentException((("Invalid value for target: "+ target)+", valid: [34962, 34963]")); + if ((target != 34962) && (target != 34963)) { + throw new IllegalArgumentException((("Invalid value for target: " + target) + ", valid: [34962, 34963]")); } this.target = target; } - /** - * The target that the WebGL buffer should be bound to. (optional)
- * Valid values: [34962, 34963] - * - * @return The target - * - */ - public Integer getTarget() { - return this.target; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Camera.java b/src/main/java/de/javagl/jgltf/impl/v1/Camera.java index c3ce0a7..f905c0d 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Camera.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Camera.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,121 +9,119 @@ package de.javagl.jgltf.impl.v1; - /** - * A camera's projection. A node can reference a camera ID to apply a - * transform to place the camera in the scene. - * - * Auto-generated for camera.schema.json - * + * A camera's projection. A node can reference a camera ID to apply a + * transform to place the camera in the scene. + *

+ * Auto-generated for camera.schema.json + * */ public class Camera - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. (optional) - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. (optional) + * */ private CameraOrthographic orthographic; /** - * A perspective camera containing properties to create a perspective - * projection matrix. (optional) - * + * A perspective camera containing properties to create a perspective + * projection matrix. (optional) + * */ private CameraPerspective perspective; /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
- * Valid values: ["perspective", "orthographic"] - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
+ * Valid values: ["perspective", "orthographic"] + * */ private String type; /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. (optional) - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. (optional) + * + * @return The orthographic + * + */ + public CameraOrthographic getOrthographic() { + return this.orthographic; + } + + /** + * An orthographic camera containing properties to create an orthographic + * projection matrix. (optional) + * * @param orthographic The orthographic to set - * + * */ public void setOrthographic(CameraOrthographic orthographic) { if (orthographic == null) { this.orthographic = orthographic; - return ; + return; } this.orthographic = orthographic; } /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. (optional) - * - * @return The orthographic - * + * A perspective camera containing properties to create a perspective + * projection matrix. (optional) + * + * @return The perspective + * */ - public CameraOrthographic getOrthographic() { - return this.orthographic; + public CameraPerspective getPerspective() { + return this.perspective; } /** - * A perspective camera containing properties to create a perspective - * projection matrix. (optional) - * + * A perspective camera containing properties to create a perspective + * projection matrix. (optional) + * * @param perspective The perspective to set - * + * */ public void setPerspective(CameraPerspective perspective) { if (perspective == null) { this.perspective = perspective; - return ; + return; } this.perspective = perspective; } /** - * A perspective camera containing properties to create a perspective - * projection matrix. (optional) - * - * @return The perspective - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
+ * Valid values: ["perspective", "orthographic"] + * + * @return The type + * */ - public CameraPerspective getPerspective() { - return this.perspective; + public String getType() { + return this.type; } /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
- * Valid values: ["perspective", "orthographic"] - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
+ * Valid values: ["perspective", "orthographic"] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); + throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); } - if ((!"perspective".equals(type))&&(!"orthographic".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [\"perspective\", \"orthographic\"]")); + if ((!"perspective".equals(type)) && (!"orthographic".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [\"perspective\", \"orthographic\"]")); } this.type = type; } - /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
- * Valid values: ["perspective", "orthographic"] - * - * @return The type - * - */ - public String getType() { - return this.type; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/CameraOrthographic.java b/src/main/java/de/javagl/jgltf/impl/v1/CameraOrthographic.java index 6287ffc..2fcec36 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/CameraOrthographic.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/CameraOrthographic.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,149 +9,147 @@ package de.javagl.jgltf.impl.v1; - /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. - * - * Auto-generated for camera.orthographic.schema.json - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. + *

+ * Auto-generated for camera.orthographic.schema.json + * */ public class CameraOrthographic - extends GlTFProperty -{ + extends GlTFProperty { /** - * The floating-point horizontal magnification of the view. (required) - * + * The floating-point horizontal magnification of the view. (required) + * */ private Float xmag; /** - * The floating-point vertical magnification of the view. (required) - * + * The floating-point vertical magnification of the view. (required) + * */ private Float ymag; /** - * The floating-point distance to the far clipping plane. (required)
- * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the far clipping plane. (required)
+ * Minimum: 0.0 (inclusive) + * */ private Float zfar; /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (inclusive) + * */ private Float znear; /** - * The floating-point horizontal magnification of the view. (required) - * + * The floating-point horizontal magnification of the view. (required) + * + * @return The xmag + * + */ + public Float getXmag() { + return this.xmag; + } + + /** + * The floating-point horizontal magnification of the view. (required) + * * @param xmag The xmag to set * @throws NullPointerException If the given value is null - * + * */ public void setXmag(Float xmag) { if (xmag == null) { - throw new NullPointerException((("Invalid value for xmag: "+ xmag)+", may not be null")); + throw new NullPointerException((("Invalid value for xmag: " + xmag) + ", may not be null")); } this.xmag = xmag; } /** - * The floating-point horizontal magnification of the view. (required) - * - * @return The xmag - * + * The floating-point vertical magnification of the view. (required) + * + * @return The ymag + * */ - public Float getXmag() { - return this.xmag; + public Float getYmag() { + return this.ymag; } /** - * The floating-point vertical magnification of the view. (required) - * + * The floating-point vertical magnification of the view. (required) + * * @param ymag The ymag to set * @throws NullPointerException If the given value is null - * + * */ public void setYmag(Float ymag) { if (ymag == null) { - throw new NullPointerException((("Invalid value for ymag: "+ ymag)+", may not be null")); + throw new NullPointerException((("Invalid value for ymag: " + ymag) + ", may not be null")); } this.ymag = ymag; } /** - * The floating-point vertical magnification of the view. (required) - * - * @return The ymag - * + * The floating-point distance to the far clipping plane. (required)
+ * Minimum: 0.0 (inclusive) + * + * @return The zfar + * */ - public Float getYmag() { - return this.ymag; + public Float getZfar() { + return this.zfar; } /** - * The floating-point distance to the far clipping plane. (required)
- * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the far clipping plane. (required)
+ * Minimum: 0.0 (inclusive) + * * @param zfar The zfar to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZfar(Float zfar) { if (zfar == null) { - throw new NullPointerException((("Invalid value for zfar: "+ zfar)+", may not be null")); + throw new NullPointerException((("Invalid value for zfar: " + zfar) + ", may not be null")); } - if (zfar< 0.0D) { + if (zfar < 0.0D) { throw new IllegalArgumentException("zfar < 0.0"); } this.zfar = zfar; } /** - * The floating-point distance to the far clipping plane. (required)
- * Minimum: 0.0 (inclusive) - * - * @return The zfar - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (inclusive) + * + * @return The znear + * */ - public Float getZfar() { - return this.zfar; + public Float getZnear() { + return this.znear; } /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (inclusive) + * * @param znear The znear to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZnear(Float znear) { if (znear == null) { - throw new NullPointerException((("Invalid value for znear: "+ znear)+", may not be null")); + throw new NullPointerException((("Invalid value for znear: " + znear) + ", may not be null")); } - if (znear< 0.0D) { + if (znear < 0.0D) { throw new IllegalArgumentException("znear < 0.0"); } this.znear = znear; } - /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (inclusive) - * - * @return The znear - * - */ - public Float getZnear() { - return this.znear; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/CameraPerspective.java b/src/main/java/de/javagl/jgltf/impl/v1/CameraPerspective.java index 33deae6..7c3f192 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/CameraPerspective.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/CameraPerspective.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,165 +9,163 @@ package de.javagl.jgltf.impl.v1; - /** - * A perspective camera containing properties to create a perspective - * projection matrix. - * - * Auto-generated for camera.perspective.schema.json - * + * A perspective camera containing properties to create a perspective + * projection matrix. + *

+ * Auto-generated for camera.perspective.schema.json + * */ public class CameraPerspective - extends GlTFProperty -{ + extends GlTFProperty { /** - * The floating-point aspect ratio of the field of view. (optional)
- * Minimum: 0.0 (inclusive) - * + * The floating-point aspect ratio of the field of view. (optional)
+ * Minimum: 0.0 (inclusive) + * */ private Float aspectRatio; /** - * The floating-point vertical field of view in radians. (required)
- * Minimum: 0.0 (inclusive) - * + * The floating-point vertical field of view in radians. (required)
+ * Minimum: 0.0 (inclusive) + * */ private Float yfov; /** - * The floating-point distance to the far clipping plane. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. (required)
+ * Minimum: 0.0 (exclusive) + * */ private Float zfar; /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (exclusive) + * */ private Float znear; /** - * The floating-point aspect ratio of the field of view. (optional)
- * Minimum: 0.0 (inclusive) - * + * The floating-point aspect ratio of the field of view. (optional)
+ * Minimum: 0.0 (inclusive) + * + * @return The aspectRatio + * + */ + public Float getAspectRatio() { + return this.aspectRatio; + } + + /** + * The floating-point aspect ratio of the field of view. (optional)
+ * Minimum: 0.0 (inclusive) + * * @param aspectRatio The aspectRatio to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAspectRatio(Float aspectRatio) { if (aspectRatio == null) { this.aspectRatio = aspectRatio; - return ; + return; } - if (aspectRatio< 0.0D) { + if (aspectRatio < 0.0D) { throw new IllegalArgumentException("aspectRatio < 0.0"); } this.aspectRatio = aspectRatio; } /** - * The floating-point aspect ratio of the field of view. (optional)
- * Minimum: 0.0 (inclusive) - * - * @return The aspectRatio - * + * The floating-point vertical field of view in radians. (required)
+ * Minimum: 0.0 (inclusive) + * + * @return The yfov + * */ - public Float getAspectRatio() { - return this.aspectRatio; + public Float getYfov() { + return this.yfov; } /** - * The floating-point vertical field of view in radians. (required)
- * Minimum: 0.0 (inclusive) - * + * The floating-point vertical field of view in radians. (required)
+ * Minimum: 0.0 (inclusive) + * * @param yfov The yfov to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setYfov(Float yfov) { if (yfov == null) { - throw new NullPointerException((("Invalid value for yfov: "+ yfov)+", may not be null")); + throw new NullPointerException((("Invalid value for yfov: " + yfov) + ", may not be null")); } - if (yfov< 0.0D) { + if (yfov < 0.0D) { throw new IllegalArgumentException("yfov < 0.0"); } this.yfov = yfov; } /** - * The floating-point vertical field of view in radians. (required)
- * Minimum: 0.0 (inclusive) - * - * @return The yfov - * + * The floating-point distance to the far clipping plane. (required)
+ * Minimum: 0.0 (exclusive) + * + * @return The zfar + * */ - public Float getYfov() { - return this.yfov; + public Float getZfar() { + return this.zfar; } /** - * The floating-point distance to the far clipping plane. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. (required)
+ * Minimum: 0.0 (exclusive) + * * @param zfar The zfar to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZfar(Float zfar) { if (zfar == null) { - throw new NullPointerException((("Invalid value for zfar: "+ zfar)+", may not be null")); + throw new NullPointerException((("Invalid value for zfar: " + zfar) + ", may not be null")); } - if (zfar<= 0.0D) { + if (zfar <= 0.0D) { throw new IllegalArgumentException("zfar <= 0.0"); } this.zfar = zfar; } /** - * The floating-point distance to the far clipping plane. (required)
- * Minimum: 0.0 (exclusive) - * - * @return The zfar - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (exclusive) + * + * @return The znear + * */ - public Float getZfar() { - return this.zfar; + public Float getZnear() { + return this.znear; } /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (exclusive) + * * @param znear The znear to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZnear(Float znear) { if (znear == null) { - throw new NullPointerException((("Invalid value for znear: "+ znear)+", may not be null")); + throw new NullPointerException((("Invalid value for znear: " + znear) + ", may not be null")); } - if (znear<= 0.0D) { + if (znear <= 0.0D) { throw new IllegalArgumentException("znear <= 0.0"); } this.znear = znear; } - /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (exclusive) - * - * @return The znear - * - */ - public Float getZnear() { - return this.znear; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/GlTF.java b/src/main/java/de/javagl/jgltf/impl/v1/GlTF.java index dfc5831..d7b0a1f 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/GlTF.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/GlTF.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -15,169 +15,168 @@ /** - * The root object for a glTF asset. - * - * Auto-generated for glTF.schema.json - * + * The root object for a glTF asset. + *

+ * Auto-generated for glTF.schema.json + * */ public class GlTF - extends GlTFProperty -{ + extends GlTFProperty { /** - * Names of extensions used somewhere in this asset. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * + * Names of extensions used somewhere in this asset. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List extensionsUsed; /** - * A dictionary object of accessors. (optional)
- * Default: {} - * + * A dictionary object of accessors. (optional)
+ * Default: {} + * */ private Map accessors; /** - * A dictionary object of keyframe animations. (optional)
- * Default: {} - * + * A dictionary object of keyframe animations. (optional)
+ * Default: {} + * */ private Map animations; /** - * Metadata about the glTF asset. (optional)
- * Default: {} - * + * Metadata about the glTF asset. (optional)
+ * Default: {} + * */ private Asset asset; /** - * A dictionary object of buffers. (optional)
- * Default: {} - * + * A dictionary object of buffers. (optional)
+ * Default: {} + * */ private Map buffers; /** - * A dictionary object of bufferViews. (optional)
- * Default: {} - * + * A dictionary object of bufferViews. (optional)
+ * Default: {} + * */ private Map bufferViews; /** - * A dictionary object of cameras. (optional)
- * Default: {} - * + * A dictionary object of cameras. (optional)
+ * Default: {} + * */ private Map cameras; /** - * A dictionary object of images. (optional)
- * Default: {} - * + * A dictionary object of images. (optional)
+ * Default: {} + * */ private Map images; /** - * A dictionary object of materials. (optional)
- * Default: {} - * + * A dictionary object of materials. (optional)
+ * Default: {} + * */ private Map materials; /** - * A dictionary object of meshes. (optional)
- * Default: {} - * + * A dictionary object of meshes. (optional)
+ * Default: {} + * */ private Map meshes; /** - * A dictionary object of nodes. (optional)
- * Default: {} - * + * A dictionary object of nodes. (optional)
+ * Default: {} + * */ private Map nodes; /** - * A dictionary object of programs. (optional)
- * Default: {} - * + * A dictionary object of programs. (optional)
+ * Default: {} + * */ private Map programs; /** - * A dictionary object of samplers. (optional)
- * Default: {} - * + * A dictionary object of samplers. (optional)
+ * Default: {} + * */ private Map samplers; /** - * The ID of the default scene. (optional) - * + * The ID of the default scene. (optional) + * */ private String scene; /** - * A dictionary object of scenes. (optional)
- * Default: {} - * + * A dictionary object of scenes. (optional)
+ * Default: {} + * */ private Map scenes; /** - * A dictionary object of shaders. (optional)
- * Default: {} - * + * A dictionary object of shaders. (optional)
+ * Default: {} + * */ private Map shaders; /** - * A dictionary object of skins. (optional)
- * Default: {} - * + * A dictionary object of skins. (optional)
+ * Default: {} + * */ private Map skins; /** - * A dictionary object of techniques. (optional)
- * Default: {} - * + * A dictionary object of techniques. (optional)
+ * Default: {} + * */ private Map techniques; /** - * A dictionary object of textures. (optional)
- * Default: {} - * + * A dictionary object of textures. (optional)
+ * Default: {} + * */ private Map textures; /** - * Names of extensions used somewhere in this asset. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * + * Names of extensions used somewhere in this asset. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The extensionsUsed + * + */ + public List getExtensionsUsed() { + return this.extensionsUsed; + } + + /** + * Names of extensions used somewhere in this asset. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * * @param extensionsUsed The extensionsUsed to set - * + * */ public void setExtensionsUsed(List extensionsUsed) { if (extensionsUsed == null) { this.extensionsUsed = extensionsUsed; - return ; + return; } this.extensionsUsed = extensionsUsed; } /** - * Names of extensions used somewhere in this asset. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * - * @return The extensionsUsed - * - */ - public List getExtensionsUsed() { - return this.extensionsUsed; - } - - /** - * Add the given extensionsUsed. The extensionsUsed of this instance will - * be replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given extensionsUsed. The extensionsUsed of this instance will + * be replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addExtensionsUsed(String element) { if (element == null) { @@ -185,7 +184,7 @@ public void addExtensionsUsed(String element) { } List oldList = this.extensionsUsed; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -193,15 +192,15 @@ public void addExtensionsUsed(String element) { } /** - * Remove the given extensionsUsed. The extensionsUsed of this instance - * will be replaced with a list that contains all previous elements, - * except for the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given extensionsUsed. The extensionsUsed of this instance + * will be replaced with a list that contains all previous elements, + * except for the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeExtensionsUsed(String element) { if (element == null) { @@ -209,7 +208,7 @@ public void removeExtensionsUsed(String element) { } List oldList = this.extensionsUsed; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -221,51 +220,51 @@ public void removeExtensionsUsed(String element) { } /** - * Returns the default value of the extensionsUsed
- * @see #getExtensionsUsed - * + * Returns the default value of the extensionsUsed
+ * * @return The default extensionsUsed - * + * @see #getExtensionsUsed + * */ public List defaultExtensionsUsed() { return new ArrayList(); } /** - * A dictionary object of accessors. (optional)
- * Default: {} - * + * A dictionary object of accessors. (optional)
+ * Default: {} + * + * @return The accessors + * + */ + public Map getAccessors() { + return this.accessors; + } + + /** + * A dictionary object of accessors. (optional)
+ * Default: {} + * * @param accessors The accessors to set - * + * */ public void setAccessors(Map accessors) { if (accessors == null) { this.accessors = accessors; - return ; + return; } this.accessors = accessors; } /** - * A dictionary object of accessors. (optional)
- * Default: {} - * - * @return The accessors - * - */ - public Map getAccessors() { - return this.accessors; - } - - /** - * Add the given accessors. The accessors of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given accessors. The accessors of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAccessors(String key, Accessor value) { if (key == null) { @@ -276,7 +275,7 @@ public void addAccessors(String key, Accessor value) { } Map oldMap = this.accessors; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -284,15 +283,15 @@ public void addAccessors(String key, Accessor value) { } /** - * Remove the given accessors. The accessors of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given accessors. The accessors of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAccessors(String key) { if (key == null) { @@ -300,7 +299,7 @@ public void removeAccessors(String key) { } Map oldMap = this.accessors; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -312,51 +311,51 @@ public void removeAccessors(String key) { } /** - * Returns the default value of the accessors
- * @see #getAccessors - * + * Returns the default value of the accessors
+ * * @return The default accessors - * + * @see #getAccessors + * */ public Map defaultAccessors() { return new LinkedHashMap(); } /** - * A dictionary object of keyframe animations. (optional)
- * Default: {} - * + * A dictionary object of keyframe animations. (optional)
+ * Default: {} + * + * @return The animations + * + */ + public Map getAnimations() { + return this.animations; + } + + /** + * A dictionary object of keyframe animations. (optional)
+ * Default: {} + * * @param animations The animations to set - * + * */ public void setAnimations(Map animations) { if (animations == null) { this.animations = animations; - return ; + return; } this.animations = animations; } /** - * A dictionary object of keyframe animations. (optional)
- * Default: {} - * - * @return The animations - * - */ - public Map getAnimations() { - return this.animations; - } - - /** - * Add the given animations. The animations of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given animations. The animations of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAnimations(String key, Animation value) { if (key == null) { @@ -367,7 +366,7 @@ public void addAnimations(String key, Animation value) { } Map oldMap = this.animations; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -375,15 +374,15 @@ public void addAnimations(String key, Animation value) { } /** - * Remove the given animations. The animations of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given animations. The animations of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAnimations(String key) { if (key == null) { @@ -391,7 +390,7 @@ public void removeAnimations(String key) { } Map oldMap = this.animations; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -403,88 +402,88 @@ public void removeAnimations(String key) { } /** - * Returns the default value of the animations
- * @see #getAnimations - * + * Returns the default value of the animations
+ * * @return The default animations - * + * @see #getAnimations + * */ public Map defaultAnimations() { return new LinkedHashMap(); } /** - * Metadata about the glTF asset. (optional)
- * Default: {} - * + * Metadata about the glTF asset. (optional)
+ * Default: {} + * + * @return The asset + * + */ + public Asset getAsset() { + return this.asset; + } + + /** + * Metadata about the glTF asset. (optional)
+ * Default: {} + * * @param asset The asset to set - * + * */ public void setAsset(Asset asset) { if (asset == null) { this.asset = asset; - return ; + return; } this.asset = asset; } /** - * Metadata about the glTF asset. (optional)
- * Default: {} - * - * @return The asset - * + * Returns the default value of the asset
+ * + * @return The default asset + * @see #getAsset + * */ - public Asset getAsset() { - return this.asset; + public Asset defaultAsset() { + return new Asset(); } /** - * Returns the default value of the asset
- * @see #getAsset - * - * @return The default asset - * + * A dictionary object of buffers. (optional)
+ * Default: {} + * + * @return The buffers + * */ - public Asset defaultAsset() { - return new Asset(); + public Map getBuffers() { + return this.buffers; } /** - * A dictionary object of buffers. (optional)
- * Default: {} - * + * A dictionary object of buffers. (optional)
+ * Default: {} + * * @param buffers The buffers to set - * + * */ public void setBuffers(Map buffers) { if (buffers == null) { this.buffers = buffers; - return ; + return; } this.buffers = buffers; } /** - * A dictionary object of buffers. (optional)
- * Default: {} - * - * @return The buffers - * - */ - public Map getBuffers() { - return this.buffers; - } - - /** - * Add the given buffers. The buffers of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given buffers. The buffers of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addBuffers(String key, Buffer value) { if (key == null) { @@ -495,7 +494,7 @@ public void addBuffers(String key, Buffer value) { } Map oldMap = this.buffers; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -503,15 +502,15 @@ public void addBuffers(String key, Buffer value) { } /** - * Remove the given buffers. The buffers of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given buffers. The buffers of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeBuffers(String key) { if (key == null) { @@ -519,7 +518,7 @@ public void removeBuffers(String key) { } Map oldMap = this.buffers; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -531,51 +530,51 @@ public void removeBuffers(String key) { } /** - * Returns the default value of the buffers
- * @see #getBuffers - * + * Returns the default value of the buffers
+ * * @return The default buffers - * + * @see #getBuffers + * */ public Map defaultBuffers() { return new LinkedHashMap(); } /** - * A dictionary object of bufferViews. (optional)
- * Default: {} - * + * A dictionary object of bufferViews. (optional)
+ * Default: {} + * + * @return The bufferViews + * + */ + public Map getBufferViews() { + return this.bufferViews; + } + + /** + * A dictionary object of bufferViews. (optional)
+ * Default: {} + * * @param bufferViews The bufferViews to set - * + * */ public void setBufferViews(Map bufferViews) { if (bufferViews == null) { this.bufferViews = bufferViews; - return ; + return; } this.bufferViews = bufferViews; } /** - * A dictionary object of bufferViews. (optional)
- * Default: {} - * - * @return The bufferViews - * - */ - public Map getBufferViews() { - return this.bufferViews; - } - - /** - * Add the given bufferViews. The bufferViews of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given bufferViews. The bufferViews of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addBufferViews(String key, BufferView value) { if (key == null) { @@ -586,7 +585,7 @@ public void addBufferViews(String key, BufferView value) { } Map oldMap = this.bufferViews; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -594,15 +593,15 @@ public void addBufferViews(String key, BufferView value) { } /** - * Remove the given bufferViews. The bufferViews of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given bufferViews. The bufferViews of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeBufferViews(String key) { if (key == null) { @@ -610,7 +609,7 @@ public void removeBufferViews(String key) { } Map oldMap = this.bufferViews; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -622,51 +621,51 @@ public void removeBufferViews(String key) { } /** - * Returns the default value of the bufferViews
- * @see #getBufferViews - * + * Returns the default value of the bufferViews
+ * * @return The default bufferViews - * + * @see #getBufferViews + * */ public Map defaultBufferViews() { return new LinkedHashMap(); } /** - * A dictionary object of cameras. (optional)
- * Default: {} - * + * A dictionary object of cameras. (optional)
+ * Default: {} + * + * @return The cameras + * + */ + public Map getCameras() { + return this.cameras; + } + + /** + * A dictionary object of cameras. (optional)
+ * Default: {} + * * @param cameras The cameras to set - * + * */ public void setCameras(Map cameras) { if (cameras == null) { this.cameras = cameras; - return ; + return; } this.cameras = cameras; } /** - * A dictionary object of cameras. (optional)
- * Default: {} - * - * @return The cameras - * - */ - public Map getCameras() { - return this.cameras; - } - - /** - * Add the given cameras. The cameras of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given cameras. The cameras of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addCameras(String key, Camera value) { if (key == null) { @@ -677,7 +676,7 @@ public void addCameras(String key, Camera value) { } Map oldMap = this.cameras; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -685,15 +684,15 @@ public void addCameras(String key, Camera value) { } /** - * Remove the given cameras. The cameras of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given cameras. The cameras of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeCameras(String key) { if (key == null) { @@ -701,7 +700,7 @@ public void removeCameras(String key) { } Map oldMap = this.cameras; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -713,51 +712,51 @@ public void removeCameras(String key) { } /** - * Returns the default value of the cameras
- * @see #getCameras - * + * Returns the default value of the cameras
+ * * @return The default cameras - * + * @see #getCameras + * */ public Map defaultCameras() { return new LinkedHashMap(); } /** - * A dictionary object of images. (optional)
- * Default: {} - * + * A dictionary object of images. (optional)
+ * Default: {} + * + * @return The images + * + */ + public Map getImages() { + return this.images; + } + + /** + * A dictionary object of images. (optional)
+ * Default: {} + * * @param images The images to set - * + * */ public void setImages(Map images) { if (images == null) { this.images = images; - return ; + return; } this.images = images; } /** - * A dictionary object of images. (optional)
- * Default: {} - * - * @return The images - * - */ - public Map getImages() { - return this.images; - } - - /** - * Add the given images. The images of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given images. The images of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addImages(String key, Image value) { if (key == null) { @@ -768,7 +767,7 @@ public void addImages(String key, Image value) { } Map oldMap = this.images; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -776,15 +775,15 @@ public void addImages(String key, Image value) { } /** - * Remove the given images. The images of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given images. The images of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeImages(String key) { if (key == null) { @@ -792,7 +791,7 @@ public void removeImages(String key) { } Map oldMap = this.images; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -804,51 +803,51 @@ public void removeImages(String key) { } /** - * Returns the default value of the images
- * @see #getImages - * + * Returns the default value of the images
+ * * @return The default images - * + * @see #getImages + * */ public Map defaultImages() { return new LinkedHashMap(); } /** - * A dictionary object of materials. (optional)
- * Default: {} - * + * A dictionary object of materials. (optional)
+ * Default: {} + * + * @return The materials + * + */ + public Map getMaterials() { + return this.materials; + } + + /** + * A dictionary object of materials. (optional)
+ * Default: {} + * * @param materials The materials to set - * + * */ public void setMaterials(Map materials) { if (materials == null) { this.materials = materials; - return ; + return; } this.materials = materials; } /** - * A dictionary object of materials. (optional)
- * Default: {} - * - * @return The materials - * - */ - public Map getMaterials() { - return this.materials; - } - - /** - * Add the given materials. The materials of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given materials. The materials of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addMaterials(String key, Material value) { if (key == null) { @@ -859,7 +858,7 @@ public void addMaterials(String key, Material value) { } Map oldMap = this.materials; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -867,15 +866,15 @@ public void addMaterials(String key, Material value) { } /** - * Remove the given materials. The materials of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given materials. The materials of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeMaterials(String key) { if (key == null) { @@ -883,7 +882,7 @@ public void removeMaterials(String key) { } Map oldMap = this.materials; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -895,51 +894,51 @@ public void removeMaterials(String key) { } /** - * Returns the default value of the materials
- * @see #getMaterials - * + * Returns the default value of the materials
+ * * @return The default materials - * + * @see #getMaterials + * */ public Map defaultMaterials() { return new LinkedHashMap(); } /** - * A dictionary object of meshes. (optional)
- * Default: {} - * + * A dictionary object of meshes. (optional)
+ * Default: {} + * + * @return The meshes + * + */ + public Map getMeshes() { + return this.meshes; + } + + /** + * A dictionary object of meshes. (optional)
+ * Default: {} + * * @param meshes The meshes to set - * + * */ public void setMeshes(Map meshes) { if (meshes == null) { this.meshes = meshes; - return ; + return; } this.meshes = meshes; } /** - * A dictionary object of meshes. (optional)
- * Default: {} - * - * @return The meshes - * - */ - public Map getMeshes() { - return this.meshes; - } - - /** - * Add the given meshes. The meshes of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given meshes. The meshes of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addMeshes(String key, Mesh value) { if (key == null) { @@ -950,7 +949,7 @@ public void addMeshes(String key, Mesh value) { } Map oldMap = this.meshes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -958,15 +957,15 @@ public void addMeshes(String key, Mesh value) { } /** - * Remove the given meshes. The meshes of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given meshes. The meshes of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeMeshes(String key) { if (key == null) { @@ -974,7 +973,7 @@ public void removeMeshes(String key) { } Map oldMap = this.meshes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -986,51 +985,51 @@ public void removeMeshes(String key) { } /** - * Returns the default value of the meshes
- * @see #getMeshes - * + * Returns the default value of the meshes
+ * * @return The default meshes - * + * @see #getMeshes + * */ public Map defaultMeshes() { return new LinkedHashMap(); } /** - * A dictionary object of nodes. (optional)
- * Default: {} - * + * A dictionary object of nodes. (optional)
+ * Default: {} + * + * @return The nodes + * + */ + public Map getNodes() { + return this.nodes; + } + + /** + * A dictionary object of nodes. (optional)
+ * Default: {} + * * @param nodes The nodes to set - * + * */ public void setNodes(Map nodes) { if (nodes == null) { this.nodes = nodes; - return ; + return; } this.nodes = nodes; } /** - * A dictionary object of nodes. (optional)
- * Default: {} - * - * @return The nodes - * - */ - public Map getNodes() { - return this.nodes; - } - - /** - * Add the given nodes. The nodes of this instance will be replaced with - * a map that contains all previous mappings, and additionally the new - * mapping. - * - * @param key The key + * Add the given nodes. The nodes of this instance will be replaced with + * a map that contains all previous mappings, and additionally the new + * mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addNodes(String key, Node value) { if (key == null) { @@ -1041,7 +1040,7 @@ public void addNodes(String key, Node value) { } Map oldMap = this.nodes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1049,15 +1048,15 @@ public void addNodes(String key, Node value) { } /** - * Remove the given nodes. The nodes of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given nodes. The nodes of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeNodes(String key) { if (key == null) { @@ -1065,7 +1064,7 @@ public void removeNodes(String key) { } Map oldMap = this.nodes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1077,51 +1076,51 @@ public void removeNodes(String key) { } /** - * Returns the default value of the nodes
- * @see #getNodes - * + * Returns the default value of the nodes
+ * * @return The default nodes - * + * @see #getNodes + * */ public Map defaultNodes() { return new LinkedHashMap(); } /** - * A dictionary object of programs. (optional)
- * Default: {} - * + * A dictionary object of programs. (optional)
+ * Default: {} + * + * @return The programs + * + */ + public Map getPrograms() { + return this.programs; + } + + /** + * A dictionary object of programs. (optional)
+ * Default: {} + * * @param programs The programs to set - * + * */ public void setPrograms(Map programs) { if (programs == null) { this.programs = programs; - return ; + return; } this.programs = programs; } /** - * A dictionary object of programs. (optional)
- * Default: {} - * - * @return The programs - * - */ - public Map getPrograms() { - return this.programs; - } - - /** - * Add the given programs. The programs of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given programs. The programs of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addPrograms(String key, Program value) { if (key == null) { @@ -1132,7 +1131,7 @@ public void addPrograms(String key, Program value) { } Map oldMap = this.programs; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1140,15 +1139,15 @@ public void addPrograms(String key, Program value) { } /** - * Remove the given programs. The programs of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given programs. The programs of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removePrograms(String key) { if (key == null) { @@ -1156,7 +1155,7 @@ public void removePrograms(String key) { } Map oldMap = this.programs; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1168,51 +1167,51 @@ public void removePrograms(String key) { } /** - * Returns the default value of the programs
- * @see #getPrograms - * + * Returns the default value of the programs
+ * * @return The default programs - * + * @see #getPrograms + * */ public Map defaultPrograms() { return new LinkedHashMap(); } /** - * A dictionary object of samplers. (optional)
- * Default: {} - * + * A dictionary object of samplers. (optional)
+ * Default: {} + * + * @return The samplers + * + */ + public Map getSamplers() { + return this.samplers; + } + + /** + * A dictionary object of samplers. (optional)
+ * Default: {} + * * @param samplers The samplers to set - * + * */ public void setSamplers(Map samplers) { if (samplers == null) { this.samplers = samplers; - return ; + return; } this.samplers = samplers; } /** - * A dictionary object of samplers. (optional)
- * Default: {} - * - * @return The samplers - * - */ - public Map getSamplers() { - return this.samplers; - } - - /** - * Add the given samplers. The samplers of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given samplers. The samplers of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addSamplers(String key, Sampler value) { if (key == null) { @@ -1223,7 +1222,7 @@ public void addSamplers(String key, Sampler value) { } Map oldMap = this.samplers; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1231,15 +1230,15 @@ public void addSamplers(String key, Sampler value) { } /** - * Remove the given samplers. The samplers of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given samplers. The samplers of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeSamplers(String key) { if (key == null) { @@ -1247,7 +1246,7 @@ public void removeSamplers(String key) { } Map oldMap = this.samplers; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1259,75 +1258,75 @@ public void removeSamplers(String key) { } /** - * Returns the default value of the samplers
- * @see #getSamplers - * + * Returns the default value of the samplers
+ * * @return The default samplers - * + * @see #getSamplers + * */ public Map defaultSamplers() { return new LinkedHashMap(); } /** - * The ID of the default scene. (optional) - * + * The ID of the default scene. (optional) + * + * @return The scene + * + */ + public String getScene() { + return this.scene; + } + + /** + * The ID of the default scene. (optional) + * * @param scene The scene to set - * + * */ public void setScene(String scene) { if (scene == null) { this.scene = scene; - return ; + return; } this.scene = scene; } /** - * The ID of the default scene. (optional) - * - * @return The scene - * + * A dictionary object of scenes. (optional)
+ * Default: {} + * + * @return The scenes + * */ - public String getScene() { - return this.scene; + public Map getScenes() { + return this.scenes; } /** - * A dictionary object of scenes. (optional)
- * Default: {} - * + * A dictionary object of scenes. (optional)
+ * Default: {} + * * @param scenes The scenes to set - * + * */ public void setScenes(Map scenes) { if (scenes == null) { this.scenes = scenes; - return ; + return; } this.scenes = scenes; } /** - * A dictionary object of scenes. (optional)
- * Default: {} - * - * @return The scenes - * - */ - public Map getScenes() { - return this.scenes; - } - - /** - * Add the given scenes. The scenes of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given scenes. The scenes of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addScenes(String key, Scene value) { if (key == null) { @@ -1338,7 +1337,7 @@ public void addScenes(String key, Scene value) { } Map oldMap = this.scenes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1346,15 +1345,15 @@ public void addScenes(String key, Scene value) { } /** - * Remove the given scenes. The scenes of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given scenes. The scenes of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeScenes(String key) { if (key == null) { @@ -1362,7 +1361,7 @@ public void removeScenes(String key) { } Map oldMap = this.scenes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1374,51 +1373,51 @@ public void removeScenes(String key) { } /** - * Returns the default value of the scenes
- * @see #getScenes - * + * Returns the default value of the scenes
+ * * @return The default scenes - * + * @see #getScenes + * */ public Map defaultScenes() { return new LinkedHashMap(); } /** - * A dictionary object of shaders. (optional)
- * Default: {} - * + * A dictionary object of shaders. (optional)
+ * Default: {} + * + * @return The shaders + * + */ + public Map getShaders() { + return this.shaders; + } + + /** + * A dictionary object of shaders. (optional)
+ * Default: {} + * * @param shaders The shaders to set - * + * */ public void setShaders(Map shaders) { if (shaders == null) { this.shaders = shaders; - return ; + return; } this.shaders = shaders; } /** - * A dictionary object of shaders. (optional)
- * Default: {} - * - * @return The shaders - * - */ - public Map getShaders() { - return this.shaders; - } - - /** - * Add the given shaders. The shaders of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given shaders. The shaders of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addShaders(String key, Shader value) { if (key == null) { @@ -1429,7 +1428,7 @@ public void addShaders(String key, Shader value) { } Map oldMap = this.shaders; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1437,15 +1436,15 @@ public void addShaders(String key, Shader value) { } /** - * Remove the given shaders. The shaders of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given shaders. The shaders of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeShaders(String key) { if (key == null) { @@ -1453,7 +1452,7 @@ public void removeShaders(String key) { } Map oldMap = this.shaders; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1465,51 +1464,51 @@ public void removeShaders(String key) { } /** - * Returns the default value of the shaders
- * @see #getShaders - * + * Returns the default value of the shaders
+ * * @return The default shaders - * + * @see #getShaders + * */ public Map defaultShaders() { return new LinkedHashMap(); } /** - * A dictionary object of skins. (optional)
- * Default: {} - * + * A dictionary object of skins. (optional)
+ * Default: {} + * + * @return The skins + * + */ + public Map getSkins() { + return this.skins; + } + + /** + * A dictionary object of skins. (optional)
+ * Default: {} + * * @param skins The skins to set - * + * */ public void setSkins(Map skins) { if (skins == null) { this.skins = skins; - return ; + return; } this.skins = skins; } /** - * A dictionary object of skins. (optional)
- * Default: {} - * - * @return The skins - * - */ - public Map getSkins() { - return this.skins; - } - - /** - * Add the given skins. The skins of this instance will be replaced with - * a map that contains all previous mappings, and additionally the new - * mapping. - * - * @param key The key + * Add the given skins. The skins of this instance will be replaced with + * a map that contains all previous mappings, and additionally the new + * mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addSkins(String key, Skin value) { if (key == null) { @@ -1520,7 +1519,7 @@ public void addSkins(String key, Skin value) { } Map oldMap = this.skins; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1528,15 +1527,15 @@ public void addSkins(String key, Skin value) { } /** - * Remove the given skins. The skins of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given skins. The skins of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeSkins(String key) { if (key == null) { @@ -1544,7 +1543,7 @@ public void removeSkins(String key) { } Map oldMap = this.skins; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1556,51 +1555,51 @@ public void removeSkins(String key) { } /** - * Returns the default value of the skins
- * @see #getSkins - * + * Returns the default value of the skins
+ * * @return The default skins - * + * @see #getSkins + * */ public Map defaultSkins() { return new LinkedHashMap(); } /** - * A dictionary object of techniques. (optional)
- * Default: {} - * + * A dictionary object of techniques. (optional)
+ * Default: {} + * + * @return The techniques + * + */ + public Map getTechniques() { + return this.techniques; + } + + /** + * A dictionary object of techniques. (optional)
+ * Default: {} + * * @param techniques The techniques to set - * + * */ public void setTechniques(Map techniques) { if (techniques == null) { this.techniques = techniques; - return ; + return; } this.techniques = techniques; } /** - * A dictionary object of techniques. (optional)
- * Default: {} - * - * @return The techniques - * - */ - public Map getTechniques() { - return this.techniques; - } - - /** - * Add the given techniques. The techniques of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given techniques. The techniques of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addTechniques(String key, Technique value) { if (key == null) { @@ -1611,7 +1610,7 @@ public void addTechniques(String key, Technique value) { } Map oldMap = this.techniques; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1619,15 +1618,15 @@ public void addTechniques(String key, Technique value) { } /** - * Remove the given techniques. The techniques of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given techniques. The techniques of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeTechniques(String key) { if (key == null) { @@ -1635,7 +1634,7 @@ public void removeTechniques(String key) { } Map oldMap = this.techniques; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1647,51 +1646,51 @@ public void removeTechniques(String key) { } /** - * Returns the default value of the techniques
- * @see #getTechniques - * + * Returns the default value of the techniques
+ * * @return The default techniques - * + * @see #getTechniques + * */ public Map defaultTechniques() { return new LinkedHashMap(); } /** - * A dictionary object of textures. (optional)
- * Default: {} - * + * A dictionary object of textures. (optional)
+ * Default: {} + * + * @return The textures + * + */ + public Map getTextures() { + return this.textures; + } + + /** + * A dictionary object of textures. (optional)
+ * Default: {} + * * @param textures The textures to set - * + * */ public void setTextures(Map textures) { if (textures == null) { this.textures = textures; - return ; + return; } this.textures = textures; } /** - * A dictionary object of textures. (optional)
- * Default: {} - * - * @return The textures - * - */ - public Map getTextures() { - return this.textures; - } - - /** - * Add the given textures. The textures of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given textures. The textures of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addTextures(String key, Texture value) { if (key == null) { @@ -1702,7 +1701,7 @@ public void addTextures(String key, Texture value) { } Map oldMap = this.textures; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1710,15 +1709,15 @@ public void addTextures(String key, Texture value) { } /** - * Remove the given textures. The textures of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given textures. The textures of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeTextures(String key) { if (key == null) { @@ -1726,7 +1725,7 @@ public void removeTextures(String key) { } Map oldMap = this.textures; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1738,11 +1737,11 @@ public void removeTextures(String key) { } /** - * Returns the default value of the textures
- * @see #getTextures - * + * Returns the default value of the textures
+ * * @return The default textures - * + * @see #getTextures + * */ public Map defaultTextures() { return new LinkedHashMap(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/GlTFChildOfRootProperty.java b/src/main/java/de/javagl/jgltf/impl/v1/GlTFChildOfRootProperty.java index f9f4351..c266f72 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/GlTFChildOfRootProperty.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/GlTFChildOfRootProperty.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,43 +9,41 @@ package de.javagl.jgltf.impl.v1; - /** - * Auto-generated for glTFChildOfRootProperty.schema.json - * + * Auto-generated for glTFChildOfRootProperty.schema.json + * */ public class GlTFChildOfRootProperty - extends GlTFProperty -{ + extends GlTFProperty { /** - * The user-defined name of this object. (optional) - * + * The user-defined name of this object. (optional) + * */ private String name; /** - * The user-defined name of this object. (optional) - * + * The user-defined name of this object. (optional) + * + * @return The name + * + */ + public String getName() { + return this.name; + } + + /** + * The user-defined name of this object. (optional) + * * @param name The name to set - * + * */ public void setName(String name) { if (name == null) { this.name = name; - return ; + return; } this.name = name; } - /** - * The user-defined name of this object. (optional) - * - * @return The name - * - */ - public String getName() { - return this.name; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/GlTFProperty.java b/src/main/java/de/javagl/jgltf/impl/v1/GlTFProperty.java index b9ba2b7..44998de 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/GlTFProperty.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/GlTFProperty.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,55 +13,55 @@ /** - * Auto-generated for glTFProperty.schema.json - * + * Auto-generated for glTFProperty.schema.json + * */ public class GlTFProperty { /** - * Dictionary object with extension-specific objects. (optional) - * + * Dictionary object with extension-specific objects. (optional) + * */ private Map extensions; /** - * Application-specific data. (optional) - * + * Application-specific data. (optional) + * */ private Object extras; /** - * Dictionary object with extension-specific objects. (optional) - * + * Dictionary object with extension-specific objects. (optional) + * + * @return The extensions + * + */ + public Map getExtensions() { + return this.extensions; + } + + /** + * Dictionary object with extension-specific objects. (optional) + * * @param extensions The extensions to set - * + * */ public void setExtensions(Map extensions) { if (extensions == null) { this.extensions = extensions; - return ; + return; } this.extensions = extensions; } /** - * Dictionary object with extension-specific objects. (optional) - * - * @return The extensions - * - */ - public Map getExtensions() { - return this.extensions; - } - - /** - * Add the given extensions. The extensions of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given extensions. The extensions of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addExtensions(String key, Object value) { if (key == null) { @@ -72,7 +72,7 @@ public void addExtensions(String key, Object value) { } Map oldMap = this.extensions; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -80,15 +80,15 @@ public void addExtensions(String key, Object value) { } /** - * Remove the given extensions. The extensions of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given extensions. The extensions of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeExtensions(String key) { if (key == null) { @@ -96,7 +96,7 @@ public void removeExtensions(String key) { } Map oldMap = this.extensions; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -108,27 +108,27 @@ public void removeExtensions(String key) { } /** - * Application-specific data. (optional) - * + * Application-specific data. (optional) + * + * @return The extras + * + */ + public Object getExtras() { + return this.extras; + } + + /** + * Application-specific data. (optional) + * * @param extras The extras to set - * + * */ public void setExtras(Object extras) { if (extras == null) { this.extras = extras; - return ; + return; } this.extras = extras; } - /** - * Application-specific data. (optional) - * - * @return The extras - * - */ - public Object getExtras() { - return this.extras; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Image.java b/src/main/java/de/javagl/jgltf/impl/v1/Image.java index f83aa2d..8a1b729 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Image.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Image.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,45 +9,43 @@ package de.javagl.jgltf.impl.v1; - /** - * Image data used to create a texture. - * - * Auto-generated for image.schema.json - * + * Image data used to create a texture. + *

+ * Auto-generated for image.schema.json + * */ public class Image - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The uri of the image. (required) - * + * The uri of the image. (required) + * */ private String uri; /** - * The uri of the image. (required) - * + * The uri of the image. (required) + * + * @return The uri + * + */ + public String getUri() { + return this.uri; + } + + /** + * The uri of the image. (required) + * * @param uri The uri to set * @throws NullPointerException If the given value is null - * + * */ public void setUri(String uri) { if (uri == null) { - throw new NullPointerException((("Invalid value for uri: "+ uri)+", may not be null")); + throw new NullPointerException((("Invalid value for uri: " + uri) + ", may not be null")); } this.uri = uri; } - /** - * The uri of the image. (required) - * - * @return The uri - * - */ - public String getUri() { - return this.uri; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Material.java b/src/main/java/de/javagl/jgltf/impl/v1/Material.java index ae40cd0..677d37f 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Material.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Material.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,86 +13,85 @@ /** - * The material appearance of a primitive. - * - * Auto-generated for material.schema.json - * + * The material appearance of a primitive. + *

+ * Auto-generated for material.schema.json + * */ public class Material - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The ID of the technique. (optional) - * + * The ID of the technique. (optional) + * */ private String technique; /** - * A dictionary object of parameter values. (optional)
- * Default: {} - * + * A dictionary object of parameter values. (optional)
+ * Default: {} + * */ private Map values; /** - * The ID of the technique. (optional) - * + * The ID of the technique. (optional) + * + * @return The technique + * + */ + public String getTechnique() { + return this.technique; + } + + /** + * The ID of the technique. (optional) + * * @param technique The technique to set - * + * */ public void setTechnique(String technique) { if (technique == null) { this.technique = technique; - return ; + return; } this.technique = technique; } /** - * The ID of the technique. (optional) - * - * @return The technique - * + * A dictionary object of parameter values. (optional)
+ * Default: {} + * + * @return The values + * */ - public String getTechnique() { - return this.technique; + public Map getValues() { + return this.values; } /** - * A dictionary object of parameter values. (optional)
- * Default: {} - * + * A dictionary object of parameter values. (optional)
+ * Default: {} + * * @param values The values to set - * + * */ public void setValues(Map values) { if (values == null) { this.values = values; - return ; + return; } this.values = values; } /** - * A dictionary object of parameter values. (optional)
- * Default: {} - * - * @return The values - * - */ - public Map getValues() { - return this.values; - } - - /** - * Add the given values. The values of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given values. The values of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addValues(String key, Object value) { if (key == null) { @@ -103,7 +102,7 @@ public void addValues(String key, Object value) { } Map oldMap = this.values; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -111,15 +110,15 @@ public void addValues(String key, Object value) { } /** - * Remove the given values. The values of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given values. The values of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeValues(String key) { if (key == null) { @@ -127,7 +126,7 @@ public void removeValues(String key) { } Map oldMap = this.values; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -139,11 +138,11 @@ public void removeValues(String key) { } /** - * Returns the default value of the values
- * @see #getValues - * + * Returns the default value of the values
+ * * @return The default values - * + * @see #getValues + * */ public Map defaultValues() { return new LinkedHashMap(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Mesh.java b/src/main/java/de/javagl/jgltf/impl/v1/Mesh.java index 4fde1ea..8034308 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Mesh.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Mesh.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,69 +13,68 @@ /** - * A set of primitives to be rendered. A node can contain one or more - * meshes. A node's transform places the mesh in the scene. - * - * Auto-generated for mesh.schema.json - * + * A set of primitives to be rendered. A node can contain one or more + * meshes. A node's transform places the mesh in the scene. + *

+ * Auto-generated for mesh.schema.json + * */ public class Mesh - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * An array of primitives, each defining geometry to be rendered with a - * material. (optional)
- * Default: []
- * Array elements:
- *   Geometry to be rendered with the given material. - * (optional) - * + * An array of primitives, each defining geometry to be rendered with a + * material. (optional)
+ * Default: []
+ * Array elements:
+ *   Geometry to be rendered with the given material. + * (optional) + * */ private List primitives; /** - * An array of primitives, each defining geometry to be rendered with a - * material. (optional)
- * Default: []
- * Array elements:
- *   Geometry to be rendered with the given material. - * (optional) - * + * An array of primitives, each defining geometry to be rendered with a + * material. (optional)
+ * Default: []
+ * Array elements:
+ *   Geometry to be rendered with the given material. + * (optional) + * + * @return The primitives + * + */ + public List getPrimitives() { + return this.primitives; + } + + /** + * An array of primitives, each defining geometry to be rendered with a + * material. (optional)
+ * Default: []
+ * Array elements:
+ *   Geometry to be rendered with the given material. + * (optional) + * * @param primitives The primitives to set - * + * */ public void setPrimitives(List primitives) { if (primitives == null) { this.primitives = primitives; - return ; + return; } this.primitives = primitives; } /** - * An array of primitives, each defining geometry to be rendered with a - * material. (optional)
- * Default: []
- * Array elements:
- *   Geometry to be rendered with the given material. - * (optional) - * - * @return The primitives - * - */ - public List getPrimitives() { - return this.primitives; - } - - /** - * Add the given primitives. The primitives of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given primitives. The primitives of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addPrimitives(MeshPrimitive element) { if (element == null) { @@ -83,7 +82,7 @@ public void addPrimitives(MeshPrimitive element) { } List oldList = this.primitives; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -91,15 +90,15 @@ public void addPrimitives(MeshPrimitive element) { } /** - * Remove the given primitives. The primitives of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given primitives. The primitives of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removePrimitives(MeshPrimitive element) { if (element == null) { @@ -107,7 +106,7 @@ public void removePrimitives(MeshPrimitive element) { } List oldList = this.primitives; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -119,11 +118,11 @@ public void removePrimitives(MeshPrimitive element) { } /** - * Returns the default value of the primitives
- * @see #getPrimitives - * + * Returns the default value of the primitives
+ * * @return The default primitives - * + * @see #getPrimitives + * */ public List defaultPrimitives() { return new ArrayList(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/MeshPrimitive.java b/src/main/java/de/javagl/jgltf/impl/v1/MeshPrimitive.java index 43499c3..f17c41f 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/MeshPrimitive.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/MeshPrimitive.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,78 +13,77 @@ /** - * Geometry to be rendered with the given material. - * - * Auto-generated for mesh.primitive.schema.json - * + * Geometry to be rendered with the given material. + *

+ * Auto-generated for mesh.primitive.schema.json + * */ public class MeshPrimitive - extends GlTFProperty -{ + extends GlTFProperty { /** - * A dictionary object of strings, where each string is the ID of the - * accessor containing an attribute. (optional)
- * Default: {} - * + * A dictionary object of strings, where each string is the ID of the + * accessor containing an attribute. (optional)
+ * Default: {} + * */ private Map attributes; /** - * The ID of the accessor that contains the indices. (optional) - * + * The ID of the accessor that contains the indices. (optional) + * */ private String indices; /** - * The ID of the material to apply to this primitive when rendering. - * (required) - * + * The ID of the material to apply to this primitive when rendering. + * (required) + * */ private String material; /** - * The type of primitives to render. (optional)
- * Default: 4
- * Valid values: [0, 1, 2, 3, 4, 5, 6] - * + * The type of primitives to render. (optional)
+ * Default: 4
+ * Valid values: [0, 1, 2, 3, 4, 5, 6] + * */ private Integer mode; /** - * A dictionary object of strings, where each string is the ID of the - * accessor containing an attribute. (optional)
- * Default: {} - * + * A dictionary object of strings, where each string is the ID of the + * accessor containing an attribute. (optional)
+ * Default: {} + * + * @return The attributes + * + */ + public Map getAttributes() { + return this.attributes; + } + + /** + * A dictionary object of strings, where each string is the ID of the + * accessor containing an attribute. (optional)
+ * Default: {} + * * @param attributes The attributes to set - * + * */ public void setAttributes(Map attributes) { if (attributes == null) { this.attributes = attributes; - return ; + return; } this.attributes = attributes; } /** - * A dictionary object of strings, where each string is the ID of the - * accessor containing an attribute. (optional)
- * Default: {} - * - * @return The attributes - * - */ - public Map getAttributes() { - return this.attributes; - } - - /** - * Add the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAttributes(String key, String value) { if (key == null) { @@ -95,7 +94,7 @@ public void addAttributes(String key, String value) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -103,15 +102,15 @@ public void addAttributes(String key, String value) { } /** - * Remove the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAttributes(String key) { if (key == null) { @@ -119,7 +118,7 @@ public void removeAttributes(String key) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -131,108 +130,108 @@ public void removeAttributes(String key) { } /** - * Returns the default value of the attributes
- * @see #getAttributes - * + * Returns the default value of the attributes
+ * * @return The default attributes - * + * @see #getAttributes + * */ public Map defaultAttributes() { return new LinkedHashMap(); } /** - * The ID of the accessor that contains the indices. (optional) - * + * The ID of the accessor that contains the indices. (optional) + * + * @return The indices + * + */ + public String getIndices() { + return this.indices; + } + + /** + * The ID of the accessor that contains the indices. (optional) + * * @param indices The indices to set - * + * */ public void setIndices(String indices) { if (indices == null) { this.indices = indices; - return ; + return; } this.indices = indices; } /** - * The ID of the accessor that contains the indices. (optional) - * - * @return The indices - * + * The ID of the material to apply to this primitive when rendering. + * (required) + * + * @return The material + * */ - public String getIndices() { - return this.indices; + public String getMaterial() { + return this.material; } /** - * The ID of the material to apply to this primitive when rendering. - * (required) - * + * The ID of the material to apply to this primitive when rendering. + * (required) + * * @param material The material to set * @throws NullPointerException If the given value is null - * + * */ public void setMaterial(String material) { if (material == null) { - throw new NullPointerException((("Invalid value for material: "+ material)+", may not be null")); + throw new NullPointerException((("Invalid value for material: " + material) + ", may not be null")); } this.material = material; } /** - * The ID of the material to apply to this primitive when rendering. - * (required) - * - * @return The material - * + * The type of primitives to render. (optional)
+ * Default: 4
+ * Valid values: [0, 1, 2, 3, 4, 5, 6] + * + * @return The mode + * */ - public String getMaterial() { - return this.material; + public Integer getMode() { + return this.mode; } /** - * The type of primitives to render. (optional)
- * Default: 4
- * Valid values: [0, 1, 2, 3, 4, 5, 6] - * + * The type of primitives to render. (optional)
+ * Default: 4
+ * Valid values: [0, 1, 2, 3, 4, 5, 6] + * * @param mode The mode to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMode(Integer mode) { if (mode == null) { this.mode = mode; - return ; + return; } - if (((((((mode!= 0)&&(mode!= 1))&&(mode!= 2))&&(mode!= 3))&&(mode!= 4))&&(mode!= 5))&&(mode!= 6)) { - throw new IllegalArgumentException((("Invalid value for mode: "+ mode)+", valid: [0, 1, 2, 3, 4, 5, 6]")); + if (((((((mode != 0) && (mode != 1)) && (mode != 2)) && (mode != 3)) && (mode != 4)) && (mode != 5)) && (mode != 6)) { + throw new IllegalArgumentException((("Invalid value for mode: " + mode) + ", valid: [0, 1, 2, 3, 4, 5, 6]")); } this.mode = mode; } /** - * The type of primitives to render. (optional)
- * Default: 4
- * Valid values: [0, 1, 2, 3, 4, 5, 6] - * - * @return The mode - * - */ - public Integer getMode() { - return this.mode; - } - - /** - * Returns the default value of the mode
- * @see #getMode - * + * Returns the default value of the mode
+ * * @return The default mode - * + * @see #getMode + * */ public Integer defaultMode() { - return 4; + return 4; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Node.java b/src/main/java/de/javagl/jgltf/impl/v1/Node.java index 7e268f2..71eba3d 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Node.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Node.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,167 +13,166 @@ /** - * A node in the node hierarchy. A node can have either the `camera`, - * `meshes`, or `skeletons`/`skin`/`meshes` properties defined. In the - * later case, all `primitives` in the referenced `meshes` contain - * `JOINT` and `WEIGHT` attributes and the referenced - * `material`/`technique` from each `primitive` has parameters with - * `JOINT` and `WEIGHT` semantics. A node can have either a `matrix` or - * any combination of `translation`/`rotation`/`scale` (TRS) properties. - * TRS properties are converted to matrices and postmultiplied in the `T - * * R * S` order to compose the transformation matrix; first the scale - * is applied to the vertices, then the rotation, and then the - * translation. If none are provided, the transform is the identity. When - * a node is targeted for animation (referenced by an - * animation.channel.target), only TRS properties may be present; - * `matrix` will not be present. - * - * Auto-generated for node.schema.json - * + * A node in the node hierarchy. A node can have either the `camera`, + * `meshes`, or `skeletons`/`skin`/`meshes` properties defined. In the + * later case, all `primitives` in the referenced `meshes` contain + * `JOINT` and `WEIGHT` attributes and the referenced + * `material`/`technique` from each `primitive` has parameters with + * `JOINT` and `WEIGHT` semantics. A node can have either a `matrix` or + * any combination of `translation`/`rotation`/`scale` (TRS) properties. + * TRS properties are converted to matrices and postmultiplied in the `T + * * R * S` order to compose the transformation matrix; first the scale + * is applied to the vertices, then the rotation, and then the + * translation. If none are provided, the transform is the identity. When + * a node is targeted for animation (referenced by an + * animation.channel.target), only TRS properties may be present; + * `matrix` will not be present. + *

+ * Auto-generated for node.schema.json + * */ public class Node - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The ID of the camera referenced by this node. (optional) - * + * The ID of the camera referenced by this node. (optional) + * */ private String camera; /** - * The IDs of this node's children. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * + * The IDs of this node's children. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List children; /** - * The ID of skeleton nodes. (optional)
- * Array elements:
- *   The elements of this array (optional) - * + * The ID of skeleton nodes. (optional)
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List skeletons; /** - * The ID of the skin referenced by this node. (optional) - * + * The ID of the skin referenced by this node. (optional) + * */ private String skin; /** - * Name used when this node is a joint in a skin. (optional) - * + * Name used when this node is a joint in a skin. (optional) + * */ private String jointName; /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
- * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
- * Number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
+ * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+ * Number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] matrix; /** - * The IDs of the meshes in this node. (optional)
- * Array elements:
- *   The elements of this array (optional) - * + * The IDs of the meshes in this node. (optional)
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List meshes; /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
- * Default: [0.0,0.0,0.0,1.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
+ * Default: [0.0,0.0,0.0,1.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] rotation; /** - * The node's non-uniform scale. (optional)
- * Default: [1.0,1.0,1.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * + * The node's non-uniform scale. (optional)
+ * Default: [1.0,1.0,1.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] scale; /** - * The node's translation. (optional)
- * Default: [0.0,0.0,0.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * + * The node's translation. (optional)
+ * Default: [0.0,0.0,0.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] translation; /** - * The ID of the camera referenced by this node. (optional) - * + * The ID of the camera referenced by this node. (optional) + * + * @return The camera + * + */ + public String getCamera() { + return this.camera; + } + + /** + * The ID of the camera referenced by this node. (optional) + * * @param camera The camera to set - * + * */ public void setCamera(String camera) { if (camera == null) { this.camera = camera; - return ; + return; } this.camera = camera; } /** - * The ID of the camera referenced by this node. (optional) - * - * @return The camera - * + * The IDs of this node's children. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The children + * */ - public String getCamera() { - return this.camera; + public List getChildren() { + return this.children; } /** - * The IDs of this node's children. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * + * The IDs of this node's children. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * * @param children The children to set - * + * */ public void setChildren(List children) { if (children == null) { this.children = children; - return ; + return; } this.children = children; } /** - * The IDs of this node's children. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * - * @return The children - * - */ - public List getChildren() { - return this.children; - } - - /** - * Add the given children. The children of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given children. The children of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addChildren(String element) { if (element == null) { @@ -181,7 +180,7 @@ public void addChildren(String element) { } List oldList = this.children; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -189,15 +188,15 @@ public void addChildren(String element) { } /** - * Remove the given children. The children of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given children. The children of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeChildren(String element) { if (element == null) { @@ -205,7 +204,7 @@ public void removeChildren(String element) { } List oldList = this.children; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -217,52 +216,52 @@ public void removeChildren(String element) { } /** - * Returns the default value of the children
- * @see #getChildren - * + * Returns the default value of the children
+ * * @return The default children - * + * @see #getChildren + * */ public List defaultChildren() { return new ArrayList(); } /** - * The ID of skeleton nodes. (optional)
- * Array elements:
- *   The elements of this array (optional) - * + * The ID of skeleton nodes. (optional)
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The skeletons + * + */ + public List getSkeletons() { + return this.skeletons; + } + + /** + * The ID of skeleton nodes. (optional)
+ * Array elements:
+ *   The elements of this array (optional) + * * @param skeletons The skeletons to set - * + * */ public void setSkeletons(List skeletons) { if (skeletons == null) { this.skeletons = skeletons; - return ; + return; } this.skeletons = skeletons; } /** - * The ID of skeleton nodes. (optional)
- * Array elements:
- *   The elements of this array (optional) - * - * @return The skeletons - * - */ - public List getSkeletons() { - return this.skeletons; - } - - /** - * Add the given skeletons. The skeletons of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given skeletons. The skeletons of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addSkeletons(String element) { if (element == null) { @@ -270,7 +269,7 @@ public void addSkeletons(String element) { } List oldList = this.skeletons; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -278,15 +277,15 @@ public void addSkeletons(String element) { } /** - * Remove the given skeletons. The skeletons of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given skeletons. The skeletons of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeSkeletons(String element) { if (element == null) { @@ -294,7 +293,7 @@ public void removeSkeletons(String element) { } List oldList = this.skeletons; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -306,73 +305,89 @@ public void removeSkeletons(String element) { } /** - * The ID of the skin referenced by this node. (optional) - * + * The ID of the skin referenced by this node. (optional) + * + * @return The skin + * + */ + public String getSkin() { + return this.skin; + } + + /** + * The ID of the skin referenced by this node. (optional) + * * @param skin The skin to set - * + * */ public void setSkin(String skin) { if (skin == null) { this.skin = skin; - return ; + return; } this.skin = skin; } /** - * The ID of the skin referenced by this node. (optional) - * - * @return The skin - * + * Name used when this node is a joint in a skin. (optional) + * + * @return The jointName + * */ - public String getSkin() { - return this.skin; + public String getJointName() { + return this.jointName; } /** - * Name used when this node is a joint in a skin. (optional) - * + * Name used when this node is a joint in a skin. (optional) + * * @param jointName The jointName to set - * + * */ public void setJointName(String jointName) { if (jointName == null) { this.jointName = jointName; - return ; + return; } this.jointName = jointName; } /** - * Name used when this node is a joint in a skin. (optional) - * - * @return The jointName - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
+ * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+ * Number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The matrix + * */ - public String getJointName() { - return this.jointName; + public float[] getMatrix() { + return this.matrix; } /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
- * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
- * Number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
+ * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+ * Number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * * @param matrix The matrix to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMatrix(float[] matrix) { if (matrix == null) { this.matrix = matrix; - return ; + return; } - if (matrix.length< 16) { + if (matrix.length < 16) { throw new IllegalArgumentException("Number of matrix elements is < 16"); } if (matrix.length > 16) { @@ -382,68 +397,52 @@ public void setMatrix(float[] matrix) { } /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
- * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
- * Number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * - * @return The matrix - * + * Returns the default value of the matrix
+ * + * @return The default matrix + * @see #getMatrix + * */ - public float[] getMatrix() { - return this.matrix; + public float[] defaultMatrix() { + return new float[]{1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F}; } /** - * Returns the default value of the matrix
- * @see #getMatrix - * - * @return The default matrix - * + * The IDs of the meshes in this node. (optional)
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The meshes + * */ - public float[] defaultMatrix() { - return new float[] { 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F }; + public List getMeshes() { + return this.meshes; } /** - * The IDs of the meshes in this node. (optional)
- * Array elements:
- *   The elements of this array (optional) - * + * The IDs of the meshes in this node. (optional)
+ * Array elements:
+ *   The elements of this array (optional) + * * @param meshes The meshes to set - * + * */ public void setMeshes(List meshes) { if (meshes == null) { this.meshes = meshes; - return ; + return; } this.meshes = meshes; } /** - * The IDs of the meshes in this node. (optional)
- * Array elements:
- *   The elements of this array (optional) - * - * @return The meshes - * - */ - public List getMeshes() { - return this.meshes; - } - - /** - * Add the given meshes. The meshes of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given meshes. The meshes of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addMeshes(String element) { if (element == null) { @@ -451,7 +450,7 @@ public void addMeshes(String element) { } List oldList = this.meshes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -459,15 +458,15 @@ public void addMeshes(String element) { } /** - * Remove the given meshes. The meshes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given meshes. The meshes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeMeshes(String element) { if (element == null) { @@ -475,7 +474,7 @@ public void removeMeshes(String element) { } List oldList = this.meshes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -487,24 +486,39 @@ public void removeMeshes(String element) { } /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
- * Default: [0.0,0.0,0.0,1.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
+ * Default: [0.0,0.0,0.0,1.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The rotation + * + */ + public float[] getRotation() { + return this.rotation; + } + + /** + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
+ * Default: [0.0,0.0,0.0,1.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * * @param rotation The rotation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setRotation(float[] rotation) { if (rotation == null) { this.rotation = rotation; - return ; + return; } - if (rotation.length< 4) { + if (rotation.length < 4) { throw new IllegalArgumentException("Number of rotation elements is < 4"); } if (rotation.length > 4) { @@ -514,49 +528,48 @@ public void setRotation(float[] rotation) { } /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
- * Default: [0.0,0.0,0.0,1.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * - * @return The rotation - * + * Returns the default value of the rotation
+ * + * @return The default rotation + * @see #getRotation + * */ - public float[] getRotation() { - return this.rotation; + public float[] defaultRotation() { + return new float[]{0.0F, 0.0F, 0.0F, 1.0F}; } /** - * Returns the default value of the rotation
- * @see #getRotation - * - * @return The default rotation - * + * The node's non-uniform scale. (optional)
+ * Default: [1.0,1.0,1.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The scale + * */ - public float[] defaultRotation() { - return new float[] { 0.0F, 0.0F, 0.0F, 1.0F }; + public float[] getScale() { + return this.scale; } /** - * The node's non-uniform scale. (optional)
- * Default: [1.0,1.0,1.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * + * The node's non-uniform scale. (optional)
+ * Default: [1.0,1.0,1.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * * @param scale The scale to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setScale(float[] scale) { if (scale == null) { this.scale = scale; - return ; + return; } - if (scale.length< 3) { + if (scale.length < 3) { throw new IllegalArgumentException("Number of scale elements is < 3"); } if (scale.length > 3) { @@ -566,48 +579,48 @@ public void setScale(float[] scale) { } /** - * The node's non-uniform scale. (optional)
- * Default: [1.0,1.0,1.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * - * @return The scale - * + * Returns the default value of the scale
+ * + * @return The default scale + * @see #getScale + * */ - public float[] getScale() { - return this.scale; + public float[] defaultScale() { + return new float[]{1.0F, 1.0F, 1.0F}; } /** - * Returns the default value of the scale
- * @see #getScale - * - * @return The default scale - * + * The node's translation. (optional)
+ * Default: [0.0,0.0,0.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The translation + * */ - public float[] defaultScale() { - return new float[] { 1.0F, 1.0F, 1.0F }; + public float[] getTranslation() { + return this.translation; } /** - * The node's translation. (optional)
- * Default: [0.0,0.0,0.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * + * The node's translation. (optional)
+ * Default: [0.0,0.0,0.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * * @param translation The translation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTranslation(float[] translation) { if (translation == null) { this.translation = translation; - return ; + return; } - if (translation.length< 3) { + if (translation.length < 3) { throw new IllegalArgumentException("Number of translation elements is < 3"); } if (translation.length > 3) { @@ -617,28 +630,14 @@ public void setTranslation(float[] translation) { } /** - * The node's translation. (optional)
- * Default: [0.0,0.0,0.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * - * @return The translation - * - */ - public float[] getTranslation() { - return this.translation; - } - - /** - * Returns the default value of the translation
- * @see #getTranslation - * + * Returns the default value of the translation
+ * * @return The default translation - * + * @see #getTranslation + * */ public float[] defaultTranslation() { - return new float[] { 0.0F, 0.0F, 0.0F }; + return new float[]{0.0F, 0.0F, 0.0F}; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Program.java b/src/main/java/de/javagl/jgltf/impl/v1/Program.java index 7ae7762..014bb9b 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Program.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Program.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,73 +13,72 @@ /** - * A shader program, including its vertex and fragment shader, and names - * of vertex shader attributes. - * - * Auto-generated for program.schema.json - * + * A shader program, including its vertex and fragment shader, and names + * of vertex shader attributes. + *

+ * Auto-generated for program.schema.json + * */ public class Program - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * Names of GLSL vertex shader attributes. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * + * Names of GLSL vertex shader attributes. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List attributes; /** - * The ID of the fragment shader. (required) - * + * The ID of the fragment shader. (required) + * */ private String fragmentShader; /** - * The ID of the vertex shader. (required) - * + * The ID of the vertex shader. (required) + * */ private String vertexShader; /** - * Names of GLSL vertex shader attributes. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * + * Names of GLSL vertex shader attributes. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The attributes + * + */ + public List getAttributes() { + return this.attributes; + } + + /** + * Names of GLSL vertex shader attributes. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * * @param attributes The attributes to set - * + * */ public void setAttributes(List attributes) { if (attributes == null) { this.attributes = attributes; - return ; + return; } this.attributes = attributes; } /** - * Names of GLSL vertex shader attributes. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * - * @return The attributes - * - */ - public List getAttributes() { - return this.attributes; - } - - /** - * Add the given attributes. The attributes of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given attributes. The attributes of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addAttributes(String element) { if (element == null) { @@ -87,7 +86,7 @@ public void addAttributes(String element) { } List oldList = this.attributes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -95,15 +94,15 @@ public void addAttributes(String element) { } /** - * Remove the given attributes. The attributes of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given attributes. The attributes of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeAttributes(String element) { if (element == null) { @@ -111,7 +110,7 @@ public void removeAttributes(String element) { } List oldList = this.attributes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -123,62 +122,62 @@ public void removeAttributes(String element) { } /** - * Returns the default value of the attributes
- * @see #getAttributes - * + * Returns the default value of the attributes
+ * * @return The default attributes - * + * @see #getAttributes + * */ public List defaultAttributes() { return new ArrayList(); } /** - * The ID of the fragment shader. (required) - * + * The ID of the fragment shader. (required) + * + * @return The fragmentShader + * + */ + public String getFragmentShader() { + return this.fragmentShader; + } + + /** + * The ID of the fragment shader. (required) + * * @param fragmentShader The fragmentShader to set * @throws NullPointerException If the given value is null - * + * */ public void setFragmentShader(String fragmentShader) { if (fragmentShader == null) { - throw new NullPointerException((("Invalid value for fragmentShader: "+ fragmentShader)+", may not be null")); + throw new NullPointerException((("Invalid value for fragmentShader: " + fragmentShader) + ", may not be null")); } this.fragmentShader = fragmentShader; } /** - * The ID of the fragment shader. (required) - * - * @return The fragmentShader - * + * The ID of the vertex shader. (required) + * + * @return The vertexShader + * */ - public String getFragmentShader() { - return this.fragmentShader; + public String getVertexShader() { + return this.vertexShader; } /** - * The ID of the vertex shader. (required) - * + * The ID of the vertex shader. (required) + * * @param vertexShader The vertexShader to set * @throws NullPointerException If the given value is null - * + * */ public void setVertexShader(String vertexShader) { if (vertexShader == null) { - throw new NullPointerException((("Invalid value for vertexShader: "+ vertexShader)+", may not be null")); + throw new NullPointerException((("Invalid value for vertexShader: " + vertexShader) + ", may not be null")); } this.vertexShader = vertexShader; } - /** - * The ID of the vertex shader. (required) - * - * @return The vertexShader - * - */ - public String getVertexShader() { - return this.vertexShader; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Sampler.java b/src/main/java/de/javagl/jgltf/impl/v1/Sampler.java index 4126cab..63f4749 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Sampler.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Sampler.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,220 +9,218 @@ package de.javagl.jgltf.impl.v1; - /** - * Texture sampler properties for filtering and wrapping modes. - * - * Auto-generated for sampler.schema.json - * + * Texture sampler properties for filtering and wrapping modes. + *

+ * Auto-generated for sampler.schema.json + * */ public class Sampler - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * Magnification filter. (optional)
- * Default: 9729
- * Valid values: [9728, 9729] - * + * Magnification filter. (optional)
+ * Default: 9729
+ * Valid values: [9728, 9729] + * */ private Integer magFilter; /** - * Minification filter. (optional)
- * Default: 9986
- * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * + * Minification filter. (optional)
+ * Default: 9986
+ * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * */ private Integer minFilter; /** - * s wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * + * s wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * */ private Integer wrapS; /** - * t wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * + * t wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * */ private Integer wrapT; /** - * Magnification filter. (optional)
- * Default: 9729
- * Valid values: [9728, 9729] - * + * Magnification filter. (optional)
+ * Default: 9729
+ * Valid values: [9728, 9729] + * + * @return The magFilter + * + */ + public Integer getMagFilter() { + return this.magFilter; + } + + /** + * Magnification filter. (optional)
+ * Default: 9729
+ * Valid values: [9728, 9729] + * * @param magFilter The magFilter to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMagFilter(Integer magFilter) { if (magFilter == null) { this.magFilter = magFilter; - return ; + return; } - if ((magFilter!= 9728)&&(magFilter!= 9729)) { - throw new IllegalArgumentException((("Invalid value for magFilter: "+ magFilter)+", valid: [9728, 9729]")); + if ((magFilter != 9728) && (magFilter != 9729)) { + throw new IllegalArgumentException((("Invalid value for magFilter: " + magFilter) + ", valid: [9728, 9729]")); } this.magFilter = magFilter; } /** - * Magnification filter. (optional)
- * Default: 9729
- * Valid values: [9728, 9729] - * - * @return The magFilter - * + * Returns the default value of the magFilter
+ * + * @return The default magFilter + * @see #getMagFilter + * */ - public Integer getMagFilter() { - return this.magFilter; + public Integer defaultMagFilter() { + return 9729; } /** - * Returns the default value of the magFilter
- * @see #getMagFilter - * - * @return The default magFilter - * + * Minification filter. (optional)
+ * Default: 9986
+ * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * + * @return The minFilter + * */ - public Integer defaultMagFilter() { - return 9729; + public Integer getMinFilter() { + return this.minFilter; } /** - * Minification filter. (optional)
- * Default: 9986
- * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * + * Minification filter. (optional)
+ * Default: 9986
+ * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * * @param minFilter The minFilter to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMinFilter(Integer minFilter) { if (minFilter == null) { this.minFilter = minFilter; - return ; + return; } - if ((((((minFilter!= 9728)&&(minFilter!= 9729))&&(minFilter!= 9984))&&(minFilter!= 9985))&&(minFilter!= 9986))&&(minFilter!= 9987)) { - throw new IllegalArgumentException((("Invalid value for minFilter: "+ minFilter)+", valid: [9728, 9729, 9984, 9985, 9986, 9987]")); + if ((((((minFilter != 9728) && (minFilter != 9729)) && (minFilter != 9984)) && (minFilter != 9985)) && (minFilter != 9986)) && (minFilter != 9987)) { + throw new IllegalArgumentException((("Invalid value for minFilter: " + minFilter) + ", valid: [9728, 9729, 9984, 9985, 9986, 9987]")); } this.minFilter = minFilter; } /** - * Minification filter. (optional)
- * Default: 9986
- * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * - * @return The minFilter - * + * Returns the default value of the minFilter
+ * + * @return The default minFilter + * @see #getMinFilter + * */ - public Integer getMinFilter() { - return this.minFilter; + public Integer defaultMinFilter() { + return 9986; } /** - * Returns the default value of the minFilter
- * @see #getMinFilter - * - * @return The default minFilter - * + * s wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * + * @return The wrapS + * */ - public Integer defaultMinFilter() { - return 9986; + public Integer getWrapS() { + return this.wrapS; } /** - * s wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * + * s wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * * @param wrapS The wrapS to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWrapS(Integer wrapS) { if (wrapS == null) { this.wrapS = wrapS; - return ; + return; } - if (((wrapS!= 33071)&&(wrapS!= 33648))&&(wrapS!= 10497)) { - throw new IllegalArgumentException((("Invalid value for wrapS: "+ wrapS)+", valid: [33071, 33648, 10497]")); + if (((wrapS != 33071) && (wrapS != 33648)) && (wrapS != 10497)) { + throw new IllegalArgumentException((("Invalid value for wrapS: " + wrapS) + ", valid: [33071, 33648, 10497]")); } this.wrapS = wrapS; } /** - * s wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * - * @return The wrapS - * + * Returns the default value of the wrapS
+ * + * @return The default wrapS + * @see #getWrapS + * */ - public Integer getWrapS() { - return this.wrapS; + public Integer defaultWrapS() { + return 10497; } /** - * Returns the default value of the wrapS
- * @see #getWrapS - * - * @return The default wrapS - * + * t wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * + * @return The wrapT + * */ - public Integer defaultWrapS() { - return 10497; + public Integer getWrapT() { + return this.wrapT; } /** - * t wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * + * t wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * * @param wrapT The wrapT to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWrapT(Integer wrapT) { if (wrapT == null) { this.wrapT = wrapT; - return ; + return; } - if (((wrapT!= 33071)&&(wrapT!= 33648))&&(wrapT!= 10497)) { - throw new IllegalArgumentException((("Invalid value for wrapT: "+ wrapT)+", valid: [33071, 33648, 10497]")); + if (((wrapT != 33071) && (wrapT != 33648)) && (wrapT != 10497)) { + throw new IllegalArgumentException((("Invalid value for wrapT: " + wrapT) + ", valid: [33071, 33648, 10497]")); } this.wrapT = wrapT; } /** - * t wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * - * @return The wrapT - * - */ - public Integer getWrapT() { - return this.wrapT; - } - - /** - * Returns the default value of the wrapT
- * @see #getWrapT - * + * Returns the default value of the wrapT
+ * * @return The default wrapT - * + * @see #getWrapT + * */ public Integer defaultWrapT() { - return 10497; + return 10497; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Scene.java b/src/main/java/de/javagl/jgltf/impl/v1/Scene.java index 07e8e83..323ce8f 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Scene.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Scene.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,62 +13,61 @@ /** - * The root nodes of a scene. - * - * Auto-generated for scene.schema.json - * + * The root nodes of a scene. + *

+ * Auto-generated for scene.schema.json + * */ public class Scene - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The IDs of each root node. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * + * The IDs of each root node. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List nodes; /** - * The IDs of each root node. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * + * The IDs of each root node. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The nodes + * + */ + public List getNodes() { + return this.nodes; + } + + /** + * The IDs of each root node. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional) + * * @param nodes The nodes to set - * + * */ public void setNodes(List nodes) { if (nodes == null) { this.nodes = nodes; - return ; + return; } this.nodes = nodes; } /** - * The IDs of each root node. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional) - * - * @return The nodes - * - */ - public List getNodes() { - return this.nodes; - } - - /** - * Add the given nodes. The nodes of this instance will be replaced with - * a list that contains all previous elements, and additionally the new - * element. - * + * Add the given nodes. The nodes of this instance will be replaced with + * a list that contains all previous elements, and additionally the new + * element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addNodes(String element) { if (element == null) { @@ -76,7 +75,7 @@ public void addNodes(String element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -84,15 +83,15 @@ public void addNodes(String element) { } /** - * Remove the given nodes. The nodes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given nodes. The nodes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeNodes(String element) { if (element == null) { @@ -100,7 +99,7 @@ public void removeNodes(String element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -112,11 +111,11 @@ public void removeNodes(String element) { } /** - * Returns the default value of the nodes
- * @see #getNodes - * + * Returns the default value of the nodes
+ * * @return The default nodes - * + * @see #getNodes + * */ public List defaultNodes() { return new ArrayList(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Shader.java b/src/main/java/de/javagl/jgltf/impl/v1/Shader.java index b644917..ee9ac33 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Shader.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Shader.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,82 +9,80 @@ package de.javagl.jgltf.impl.v1; - /** - * A vertex or fragment shader. - * - * Auto-generated for shader.schema.json - * + * A vertex or fragment shader. + *

+ * Auto-generated for shader.schema.json + * */ public class Shader - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The uri of the GLSL source. (required) - * + * The uri of the GLSL source. (required) + * */ private String uri; /** - * The shader stage. (required)
- * Valid values: [35632, 35633] - * + * The shader stage. (required)
+ * Valid values: [35632, 35633] + * */ private Integer type; /** - * The uri of the GLSL source. (required) - * + * The uri of the GLSL source. (required) + * + * @return The uri + * + */ + public String getUri() { + return this.uri; + } + + /** + * The uri of the GLSL source. (required) + * * @param uri The uri to set * @throws NullPointerException If the given value is null - * + * */ public void setUri(String uri) { if (uri == null) { - throw new NullPointerException((("Invalid value for uri: "+ uri)+", may not be null")); + throw new NullPointerException((("Invalid value for uri: " + uri) + ", may not be null")); } this.uri = uri; } /** - * The uri of the GLSL source. (required) - * - * @return The uri - * + * The shader stage. (required)
+ * Valid values: [35632, 35633] + * + * @return The type + * */ - public String getUri() { - return this.uri; + public Integer getType() { + return this.type; } /** - * The shader stage. (required)
- * Valid values: [35632, 35633] - * + * The shader stage. (required)
+ * Valid values: [35632, 35633] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(Integer type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); + throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); } - if ((type!= 35632)&&(type!= 35633)) { - throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [35632, 35633]")); + if ((type != 35632) && (type != 35633)) { + throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [35632, 35633]")); } this.type = type; } - /** - * The shader stage. (required)
- * Valid values: [35632, 35633] - * - * @return The type - * - */ - public Integer getType() { - return this.type; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Skin.java b/src/main/java/de/javagl/jgltf/impl/v1/Skin.java index 10895a1..2b431fc 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Skin.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Skin.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,61 +13,76 @@ /** - * Joints and matrices defining a skin. - * - * Auto-generated for skin.schema.json - * + * Joints and matrices defining a skin. + *

+ * Auto-generated for skin.schema.json + * */ public class Skin - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * Floating-point 4x4 transformation matrix stored in column-major order. - * (optional)
- * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
- * Number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point 4x4 transformation matrix stored in column-major order. + * (optional)
+ * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+ * Number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] bindShapeMatrix; /** - * The ID of the accessor containing the floating-point 4x4 inverse-bind - * matrices. (required) - * + * The ID of the accessor containing the floating-point 4x4 inverse-bind + * matrices. (required) + * */ private String inverseBindMatrices; /** - * Joint names of the joints (nodes with a `jointName` property) in this - * skin. (required)
- * Array elements:
- *   The elements of this array (optional) - * + * Joint names of the joints (nodes with a `jointName` property) in this + * skin. (required)
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List jointNames; /** - * Floating-point 4x4 transformation matrix stored in column-major order. - * (optional)
- * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
- * Number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point 4x4 transformation matrix stored in column-major order. + * (optional)
+ * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+ * Number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The bindShapeMatrix + * + */ + public float[] getBindShapeMatrix() { + return this.bindShapeMatrix; + } + + /** + * Floating-point 4x4 transformation matrix stored in column-major order. + * (optional)
+ * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+ * Number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * * @param bindShapeMatrix The bindShapeMatrix to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBindShapeMatrix(float[] bindShapeMatrix) { if (bindShapeMatrix == null) { this.bindShapeMatrix = bindShapeMatrix; - return ; + return; } - if (bindShapeMatrix.length< 16) { + if (bindShapeMatrix.length < 16) { throw new IllegalArgumentException("Number of bindShapeMatrix elements is < 16"); } if (bindShapeMatrix.length > 16) { @@ -77,96 +92,80 @@ public void setBindShapeMatrix(float[] bindShapeMatrix) { } /** - * Floating-point 4x4 transformation matrix stored in column-major order. - * (optional)
- * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
- * Number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * - * @return The bindShapeMatrix - * + * Returns the default value of the bindShapeMatrix
+ * + * @return The default bindShapeMatrix + * @see #getBindShapeMatrix + * */ - public float[] getBindShapeMatrix() { - return this.bindShapeMatrix; + public float[] defaultBindShapeMatrix() { + return new float[]{1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F}; } /** - * Returns the default value of the bindShapeMatrix
- * @see #getBindShapeMatrix - * - * @return The default bindShapeMatrix - * + * The ID of the accessor containing the floating-point 4x4 inverse-bind + * matrices. (required) + * + * @return The inverseBindMatrices + * */ - public float[] defaultBindShapeMatrix() { - return new float[] { 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F }; + public String getInverseBindMatrices() { + return this.inverseBindMatrices; } /** - * The ID of the accessor containing the floating-point 4x4 inverse-bind - * matrices. (required) - * + * The ID of the accessor containing the floating-point 4x4 inverse-bind + * matrices. (required) + * * @param inverseBindMatrices The inverseBindMatrices to set * @throws NullPointerException If the given value is null - * + * */ public void setInverseBindMatrices(String inverseBindMatrices) { if (inverseBindMatrices == null) { - throw new NullPointerException((("Invalid value for inverseBindMatrices: "+ inverseBindMatrices)+", may not be null")); + throw new NullPointerException((("Invalid value for inverseBindMatrices: " + inverseBindMatrices) + ", may not be null")); } this.inverseBindMatrices = inverseBindMatrices; } /** - * The ID of the accessor containing the floating-point 4x4 inverse-bind - * matrices. (required) - * - * @return The inverseBindMatrices - * + * Joint names of the joints (nodes with a `jointName` property) in this + * skin. (required)
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The jointNames + * */ - public String getInverseBindMatrices() { - return this.inverseBindMatrices; + public List getJointNames() { + return this.jointNames; } /** - * Joint names of the joints (nodes with a `jointName` property) in this - * skin. (required)
- * Array elements:
- *   The elements of this array (optional) - * + * Joint names of the joints (nodes with a `jointName` property) in this + * skin. (required)
+ * Array elements:
+ *   The elements of this array (optional) + * * @param jointNames The jointNames to set * @throws NullPointerException If the given value is null - * + * */ public void setJointNames(List jointNames) { if (jointNames == null) { - throw new NullPointerException((("Invalid value for jointNames: "+ jointNames)+", may not be null")); + throw new NullPointerException((("Invalid value for jointNames: " + jointNames) + ", may not be null")); } this.jointNames = jointNames; } /** - * Joint names of the joints (nodes with a `jointName` property) in this - * skin. (required)
- * Array elements:
- *   The elements of this array (optional) - * - * @return The jointNames - * - */ - public List getJointNames() { - return this.jointNames; - } - - /** - * Add the given jointNames. The jointNames of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given jointNames. The jointNames of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addJointNames(String element) { if (element == null) { @@ -174,7 +173,7 @@ public void addJointNames(String element) { } List oldList = this.jointNames; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -182,13 +181,13 @@ public void addJointNames(String element) { } /** - * Remove the given jointNames. The jointNames of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one. - * + * Remove the given jointNames. The jointNames of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeJointNames(String element) { if (element == null) { @@ -196,7 +195,7 @@ public void removeJointNames(String element) { } List oldList = this.jointNames; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Technique.java b/src/main/java/de/javagl/jgltf/impl/v1/Technique.java index b2469bb..4d20d78 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Technique.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Technique.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,82 +13,81 @@ /** - * A template for material appearances. - * - * Auto-generated for technique.schema.json - * + * A template for material appearances. + *

+ * Auto-generated for technique.schema.json + * */ public class Technique - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * A dictionary object of technique.parameters objects. (optional)
- * Default: {} - * + * A dictionary object of technique.parameters objects. (optional)
+ * Default: {} + * */ private Map parameters; /** - * A dictionary object of strings that maps GLSL attribute names to - * technique parameter IDs. (optional)
- * Default: {} - * + * A dictionary object of strings that maps GLSL attribute names to + * technique parameter IDs. (optional)
+ * Default: {} + * */ private Map attributes; /** - * The ID of the program. (required) - * + * The ID of the program. (required) + * */ private String program; /** - * A dictionary object of strings that maps GLSL uniform names to - * technique parameter IDs. (optional)
- * Default: {} - * + * A dictionary object of strings that maps GLSL uniform names to + * technique parameter IDs. (optional)
+ * Default: {} + * */ private Map uniforms; /** - * Fixed-function rendering states. (optional)
- * Default: {} - * + * Fixed-function rendering states. (optional)
+ * Default: {} + * */ private TechniqueStates states; /** - * A dictionary object of technique.parameters objects. (optional)
- * Default: {} - * + * A dictionary object of technique.parameters objects. (optional)
+ * Default: {} + * + * @return The parameters + * + */ + public Map getParameters() { + return this.parameters; + } + + /** + * A dictionary object of technique.parameters objects. (optional)
+ * Default: {} + * * @param parameters The parameters to set - * + * */ public void setParameters(Map parameters) { if (parameters == null) { this.parameters = parameters; - return ; + return; } this.parameters = parameters; } /** - * A dictionary object of technique.parameters objects. (optional)
- * Default: {} - * - * @return The parameters - * - */ - public Map getParameters() { - return this.parameters; - } - - /** - * Add the given parameters. The parameters of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given parameters. The parameters of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addParameters(String key, TechniqueParameters value) { if (key == null) { @@ -99,7 +98,7 @@ public void addParameters(String key, TechniqueParameters value) { } Map oldMap = this.parameters; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -107,15 +106,15 @@ public void addParameters(String key, TechniqueParameters value) { } /** - * Remove the given parameters. The parameters of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given parameters. The parameters of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeParameters(String key) { if (key == null) { @@ -123,7 +122,7 @@ public void removeParameters(String key) { } Map oldMap = this.parameters; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -135,53 +134,53 @@ public void removeParameters(String key) { } /** - * Returns the default value of the parameters
- * @see #getParameters - * + * Returns the default value of the parameters
+ * * @return The default parameters - * + * @see #getParameters + * */ public Map defaultParameters() { return new LinkedHashMap(); } /** - * A dictionary object of strings that maps GLSL attribute names to - * technique parameter IDs. (optional)
- * Default: {} - * + * A dictionary object of strings that maps GLSL attribute names to + * technique parameter IDs. (optional)
+ * Default: {} + * + * @return The attributes + * + */ + public Map getAttributes() { + return this.attributes; + } + + /** + * A dictionary object of strings that maps GLSL attribute names to + * technique parameter IDs. (optional)
+ * Default: {} + * * @param attributes The attributes to set - * + * */ public void setAttributes(Map attributes) { if (attributes == null) { this.attributes = attributes; - return ; + return; } this.attributes = attributes; } /** - * A dictionary object of strings that maps GLSL attribute names to - * technique parameter IDs. (optional)
- * Default: {} - * - * @return The attributes - * - */ - public Map getAttributes() { - return this.attributes; - } - - /** - * Add the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAttributes(String key, String value) { if (key == null) { @@ -192,7 +191,7 @@ public void addAttributes(String key, String value) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -200,15 +199,15 @@ public void addAttributes(String key, String value) { } /** - * Remove the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAttributes(String key) { if (key == null) { @@ -216,7 +215,7 @@ public void removeAttributes(String key) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -228,77 +227,77 @@ public void removeAttributes(String key) { } /** - * Returns the default value of the attributes
- * @see #getAttributes - * + * Returns the default value of the attributes
+ * * @return The default attributes - * + * @see #getAttributes + * */ public Map defaultAttributes() { return new LinkedHashMap(); } /** - * The ID of the program. (required) - * + * The ID of the program. (required) + * + * @return The program + * + */ + public String getProgram() { + return this.program; + } + + /** + * The ID of the program. (required) + * * @param program The program to set * @throws NullPointerException If the given value is null - * + * */ public void setProgram(String program) { if (program == null) { - throw new NullPointerException((("Invalid value for program: "+ program)+", may not be null")); + throw new NullPointerException((("Invalid value for program: " + program) + ", may not be null")); } this.program = program; } /** - * The ID of the program. (required) - * - * @return The program - * + * A dictionary object of strings that maps GLSL uniform names to + * technique parameter IDs. (optional)
+ * Default: {} + * + * @return The uniforms + * */ - public String getProgram() { - return this.program; + public Map getUniforms() { + return this.uniforms; } /** - * A dictionary object of strings that maps GLSL uniform names to - * technique parameter IDs. (optional)
- * Default: {} - * + * A dictionary object of strings that maps GLSL uniform names to + * technique parameter IDs. (optional)
+ * Default: {} + * * @param uniforms The uniforms to set - * + * */ public void setUniforms(Map uniforms) { if (uniforms == null) { this.uniforms = uniforms; - return ; + return; } this.uniforms = uniforms; } /** - * A dictionary object of strings that maps GLSL uniform names to - * technique parameter IDs. (optional)
- * Default: {} - * - * @return The uniforms - * - */ - public Map getUniforms() { - return this.uniforms; - } - - /** - * Add the given uniforms. The uniforms of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * Add the given uniforms. The uniforms of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addUniforms(String key, String value) { if (key == null) { @@ -309,7 +308,7 @@ public void addUniforms(String key, String value) { } Map oldMap = this.uniforms; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -317,15 +316,15 @@ public void addUniforms(String key, String value) { } /** - * Remove the given uniforms. The uniforms of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given uniforms. The uniforms of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeUniforms(String key) { if (key == null) { @@ -333,7 +332,7 @@ public void removeUniforms(String key) { } Map oldMap = this.uniforms; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -345,48 +344,48 @@ public void removeUniforms(String key) { } /** - * Returns the default value of the uniforms
- * @see #getUniforms - * + * Returns the default value of the uniforms
+ * * @return The default uniforms - * + * @see #getUniforms + * */ public Map defaultUniforms() { return new LinkedHashMap(); } /** - * Fixed-function rendering states. (optional)
- * Default: {} - * + * Fixed-function rendering states. (optional)
+ * Default: {} + * + * @return The states + * + */ + public TechniqueStates getStates() { + return this.states; + } + + /** + * Fixed-function rendering states. (optional)
+ * Default: {} + * * @param states The states to set - * + * */ public void setStates(TechniqueStates states) { if (states == null) { this.states = states; - return ; + return; } this.states = states; } /** - * Fixed-function rendering states. (optional)
- * Default: {} - * - * @return The states - * - */ - public TechniqueStates getStates() { - return this.states; - } - - /** - * Returns the default value of the states
- * @see #getStates - * + * Returns the default value of the states
+ * * @return The default states - * + * @see #getStates + * */ public TechniqueStates defaultStates() { return new TechniqueStates(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueParameters.java b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueParameters.java index f3f80fd..63b40a9 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueParameters.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueParameters.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,193 +9,191 @@ package de.javagl.jgltf.impl.v1; - /** - * An attribute or uniform input to a technique, and an optional semantic - * and value. - * - * Auto-generated for technique.parameters.schema.json - * + * An attribute or uniform input to a technique, and an optional semantic + * and value. + *

+ * Auto-generated for technique.parameters.schema.json + * */ public class TechniqueParameters - extends GlTFProperty -{ + extends GlTFProperty { /** - * When defined, the parameter is an array of count elements of the - * specified type. Otherwise, the parameter is not an array. - * (optional)
- * Minimum: 1 (inclusive) - * + * When defined, the parameter is an array of count elements of the + * specified type. Otherwise, the parameter is not an array. + * (optional)
+ * Minimum: 1 (inclusive) + * */ private Integer count; /** - * The id of the node whose transform is used as the parameter's value. - * (optional) - * + * The id of the node whose transform is used as the parameter's value. + * (optional) + * */ private String node; /** - * The datatype. (required)
- * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, - * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, - * 35676, 35678] - * + * The datatype. (required)
+ * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, + * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, + * 35676, 35678] + * */ private Integer type; /** - * Identifies a parameter with a well-known meaning. (optional) - * + * Identifies a parameter with a well-known meaning. (optional) + * */ private String semantic; /** - * The value of the parameter. (optional) - * + * The value of the parameter. (optional) + * */ private Object value; /** - * When defined, the parameter is an array of count elements of the - * specified type. Otherwise, the parameter is not an array. - * (optional)
- * Minimum: 1 (inclusive) - * + * When defined, the parameter is an array of count elements of the + * specified type. Otherwise, the parameter is not an array. + * (optional)
+ * Minimum: 1 (inclusive) + * + * @return The count + * + */ + public Integer getCount() { + return this.count; + } + + /** + * When defined, the parameter is an array of count elements of the + * specified type. Otherwise, the parameter is not an array. + * (optional)
+ * Minimum: 1 (inclusive) + * * @param count The count to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCount(Integer count) { if (count == null) { this.count = count; - return ; + return; } - if (count< 1) { + if (count < 1) { throw new IllegalArgumentException("count < 1"); } this.count = count; } /** - * When defined, the parameter is an array of count elements of the - * specified type. Otherwise, the parameter is not an array. - * (optional)
- * Minimum: 1 (inclusive) - * - * @return The count - * + * The id of the node whose transform is used as the parameter's value. + * (optional) + * + * @return The node + * */ - public Integer getCount() { - return this.count; + public String getNode() { + return this.node; } /** - * The id of the node whose transform is used as the parameter's value. - * (optional) - * + * The id of the node whose transform is used as the parameter's value. + * (optional) + * * @param node The node to set - * + * */ public void setNode(String node) { if (node == null) { this.node = node; - return ; + return; } this.node = node; } /** - * The id of the node whose transform is used as the parameter's value. - * (optional) - * - * @return The node - * + * The datatype. (required)
+ * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, + * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, + * 35676, 35678] + * + * @return The type + * */ - public String getNode() { - return this.node; + public Integer getType() { + return this.type; } /** - * The datatype. (required)
- * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, - * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, - * 35676, 35678] - * + * The datatype. (required)
+ * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, + * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, + * 35676, 35678] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(Integer type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); + throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); } - if (((((((((((((((((((((type!= 5120)&&(type!= 5121))&&(type!= 5122))&&(type!= 5123))&&(type!= 5124))&&(type!= 5125))&&(type!= 5126))&&(type!= 35664))&&(type!= 35665))&&(type!= 35666))&&(type!= 35667))&&(type!= 35668))&&(type!= 35669))&&(type!= 35670))&&(type!= 35671))&&(type!= 35672))&&(type!= 35673))&&(type!= 35674))&&(type!= 35675))&&(type!= 35676))&&(type!= 35678)) { - throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, 35676, 35678]")); + if (((((((((((((((((((((type != 5120) && (type != 5121)) && (type != 5122)) && (type != 5123)) && (type != 5124)) && (type != 5125)) && (type != 5126)) && (type != 35664)) && (type != 35665)) && (type != 35666)) && (type != 35667)) && (type != 35668)) && (type != 35669)) && (type != 35670)) && (type != 35671)) && (type != 35672)) && (type != 35673)) && (type != 35674)) && (type != 35675)) && (type != 35676)) && (type != 35678)) { + throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, 35676, 35678]")); } this.type = type; } /** - * The datatype. (required)
- * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, - * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, - * 35676, 35678] - * - * @return The type - * + * Identifies a parameter with a well-known meaning. (optional) + * + * @return The semantic + * */ - public Integer getType() { - return this.type; + public String getSemantic() { + return this.semantic; } /** - * Identifies a parameter with a well-known meaning. (optional) - * + * Identifies a parameter with a well-known meaning. (optional) + * * @param semantic The semantic to set - * + * */ public void setSemantic(String semantic) { if (semantic == null) { this.semantic = semantic; - return ; + return; } this.semantic = semantic; } /** - * Identifies a parameter with a well-known meaning. (optional) - * - * @return The semantic - * + * The value of the parameter. (optional) + * + * @return The value + * */ - public String getSemantic() { - return this.semantic; + public Object getValue() { + return this.value; } /** - * The value of the parameter. (optional) - * + * The value of the parameter. (optional) + * * @param value The value to set - * + * */ public void setValue(Object value) { if (value == null) { this.value = value; - return ; + return; } this.value = value; } - /** - * The value of the parameter. (optional) - * - * @return The value - * - */ - public Object getValue() { - return this.value; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStates.java b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStates.java index dc2b1ef..3ad3874 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStates.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStates.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,78 +13,77 @@ /** - * Fixed-function rendering states. - * - * Auto-generated for technique.states.schema.json - * + * Fixed-function rendering states. + *

+ * Auto-generated for technique.states.schema.json + * */ public class TechniqueStates - extends GlTFProperty -{ + extends GlTFProperty { /** - * WebGL states to enable. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] - * + * WebGL states to enable. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] + * */ private List enable; /** - * Arguments for fixed-function rendering state functions other than - * `enable()`/`disable()`. (optional) - * + * Arguments for fixed-function rendering state functions other than + * `enable()`/`disable()`. (optional) + * */ private TechniqueStatesFunctions functions; /** - * WebGL states to enable. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] - * + * WebGL states to enable. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] + * + * @return The enable + * + */ + public List getEnable() { + return this.enable; + } + + /** + * WebGL states to enable. (optional)
+ * Default: []
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] + * * @param enable The enable to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setEnable(List enable) { if (enable == null) { this.enable = enable; - return ; + return; } - for (Integer enableElement: enable) { - if ((((((enableElement!= 3042)&&(enableElement!= 2884))&&(enableElement!= 2929))&&(enableElement!= 32823))&&(enableElement!= 32926))&&(enableElement!= 3089)) { - throw new IllegalArgumentException((("Invalid value for enableElement: "+ enableElement)+", valid: [3042, 2884, 2929, 32823, 32926, 3089]")); + for (Integer enableElement : enable) { + if ((((((enableElement != 3042) && (enableElement != 2884)) && (enableElement != 2929)) && (enableElement != 32823)) && (enableElement != 32926)) && (enableElement != 3089)) { + throw new IllegalArgumentException((("Invalid value for enableElement: " + enableElement) + ", valid: [3042, 2884, 2929, 32823, 32926, 3089]")); } } this.enable = enable; } /** - * WebGL states to enable. (optional)
- * Default: []
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] - * - * @return The enable - * - */ - public List getEnable() { - return this.enable; - } - - /** - * Add the given enable. The enable of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given enable. The enable of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addEnable(Integer element) { if (element == null) { @@ -92,7 +91,7 @@ public void addEnable(Integer element) { } List oldList = this.enable; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -100,15 +99,15 @@ public void addEnable(Integer element) { } /** - * Remove the given enable. The enable of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given enable. The enable of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeEnable(Integer element) { if (element == null) { @@ -116,7 +115,7 @@ public void removeEnable(Integer element) { } List oldList = this.enable; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -128,40 +127,40 @@ public void removeEnable(Integer element) { } /** - * Returns the default value of the enable
- * @see #getEnable - * + * Returns the default value of the enable
+ * * @return The default enable - * + * @see #getEnable + * */ public List defaultEnable() { return new ArrayList(); } /** - * Arguments for fixed-function rendering state functions other than - * `enable()`/`disable()`. (optional) - * + * Arguments for fixed-function rendering state functions other than + * `enable()`/`disable()`. (optional) + * + * @return The functions + * + */ + public TechniqueStatesFunctions getFunctions() { + return this.functions; + } + + /** + * Arguments for fixed-function rendering state functions other than + * `enable()`/`disable()`. (optional) + * * @param functions The functions to set - * + * */ public void setFunctions(TechniqueStatesFunctions functions) { if (functions == null) { this.functions = functions; - return ; + return; } this.functions = functions; } - /** - * Arguments for fixed-function rendering state functions other than - * `enable()`/`disable()`. (optional) - * - * @return The functions - * - */ - public TechniqueStatesFunctions getFunctions() { - return this.functions; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStatesFunctions.java b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStatesFunctions.java index fe8c30e..9294293 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStatesFunctions.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStatesFunctions.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,158 +9,171 @@ package de.javagl.jgltf.impl.v1; - /** - * Arguments for fixed-function rendering state functions other than - * `enable()`/`disable()`. - * - * Auto-generated for technique.states.functions.schema.json - * + * Arguments for fixed-function rendering state functions other than + * `enable()`/`disable()`. + *

+ * Auto-generated for technique.states.functions.schema.json + * */ public class TechniqueStatesFunctions - extends GlTFProperty -{ + extends GlTFProperty { /** - * Floating-point values passed to `blendColor()`. [red, green, blue, - * alpha] (optional)
- * Default: [0.0,0.0,0.0,0.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point values passed to `blendColor()`. [red, green, blue, + * alpha] (optional)
+ * Default: [0.0,0.0,0.0,0.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] blendColor; /** - * Integer values passed to `blendEquationSeparate()`. (optional)
- * Default: [32774,32774]
- * Number of items: 2
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [32774, 32778, 32779] - * + * Integer values passed to `blendEquationSeparate()`. (optional)
+ * Default: [32774,32774]
+ * Number of items: 2
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [32774, 32778, 32779] + * */ private int[] blendEquationSeparate; /** - * Integer values passed to `blendFuncSeparate()`. (optional)
- * Default: [1,0,1,0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, - * 773, 32769, 32770, 32771, 32772, 776] - * + * Integer values passed to `blendFuncSeparate()`. (optional)
+ * Default: [1,0,1,0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, + * 773, 32769, 32770, 32771, 32772, 776] + * */ private int[] blendFuncSeparate; /** - * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. - * (optional)
- * Default: [true,true,true,true]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * + * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. + * (optional)
+ * Default: [true,true,true,true]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * */ private boolean[] colorMask; /** - * Integer value passed to `cullFace()`. (optional)
- * Default: [1029]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [1028, 1029, 1032] - * + * Integer value passed to `cullFace()`. (optional)
+ * Default: [1029]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [1028, 1029, 1032] + * */ private int[] cullFace; /** - * Integer values passed to `depthFunc()`. (optional)
- * Default: [513]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] - * + * Integer values passed to `depthFunc()`. (optional)
+ * Default: [513]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] + * */ private int[] depthFunc; /** - * Boolean value passed to `depthMask()`. (optional)
- * Default: [true]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * Boolean value passed to `depthMask()`. (optional)
+ * Default: [true]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * */ private boolean[] depthMask; /** - * Floating-point values passed to `depthRange()`. [zNear, zFar] - * (optional)
- * Default: [0.0,1.0]
- * Number of items: 2
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point values passed to `depthRange()`. [zNear, zFar] + * (optional)
+ * Default: [0.0,1.0]
+ * Number of items: 2
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] depthRange; /** - * Integer value passed to `frontFace()`. (optional)
- * Default: [2305]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [2304, 2305] - * + * Integer value passed to `frontFace()`. (optional)
+ * Default: [2305]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [2304, 2305] + * */ private int[] frontFace; /** - * Floating-point value passed to `lineWidth()`. (optional)
- * Default: [1.0]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0.0 (exclusive) - * + * Floating-point value passed to `lineWidth()`. (optional)
+ * Default: [1.0]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0.0 (exclusive) + * */ private float[] lineWidth; /** - * Floating-point value passed to `polygonOffset()`. [factor, units] - * (optional)
- * Default: [0.0,0.0]
- * Number of items: 2
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point value passed to `polygonOffset()`. [factor, units] + * (optional)
+ * Default: [0.0,0.0]
+ * Number of items: 2
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] polygonOffset; /** - * Floating-point value passed to `scissor()`. [x, y, width, height]. - * (optional)
- * Default: [0.0,0.0,0.0,0.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point value passed to `scissor()`. [x, y, width, height]. + * (optional)
+ * Default: [0.0,0.0,0.0,0.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] scissor; /** - * Floating-point values passed to `blendColor()`. [red, green, blue, - * alpha] (optional)
- * Default: [0.0,0.0,0.0,0.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point values passed to `blendColor()`. [red, green, blue, + * alpha] (optional)
+ * Default: [0.0,0.0,0.0,0.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The blendColor + * + */ + public float[] getBlendColor() { + return this.blendColor; + } + + /** + * Floating-point values passed to `blendColor()`. [red, green, blue, + * alpha] (optional)
+ * Default: [0.0,0.0,0.0,0.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * * @param blendColor The blendColor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBlendColor(float[] blendColor) { if (blendColor == null) { this.blendColor = blendColor; - return ; + return; } - if (blendColor.length< 4) { + if (blendColor.length < 4) { throw new IllegalArgumentException("Number of blendColor elements is < 4"); } if (blendColor.length > 4) { @@ -170,168 +183,168 @@ public void setBlendColor(float[] blendColor) { } /** - * Floating-point values passed to `blendColor()`. [red, green, blue, - * alpha] (optional)
- * Default: [0.0,0.0,0.0,0.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * - * @return The blendColor - * + * Returns the default value of the blendColor
+ * + * @return The default blendColor + * @see #getBlendColor + * */ - public float[] getBlendColor() { - return this.blendColor; + public float[] defaultBlendColor() { + return new float[]{0.0F, 0.0F, 0.0F, 0.0F}; } /** - * Returns the default value of the blendColor
- * @see #getBlendColor - * - * @return The default blendColor - * + * Integer values passed to `blendEquationSeparate()`. (optional)
+ * Default: [32774,32774]
+ * Number of items: 2
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [32774, 32778, 32779] + * + * @return The blendEquationSeparate + * */ - public float[] defaultBlendColor() { - return new float[] { 0.0F, 0.0F, 0.0F, 0.0F }; + public int[] getBlendEquationSeparate() { + return this.blendEquationSeparate; } /** - * Integer values passed to `blendEquationSeparate()`. (optional)
- * Default: [32774,32774]
- * Number of items: 2
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [32774, 32778, 32779] - * + * Integer values passed to `blendEquationSeparate()`. (optional)
+ * Default: [32774,32774]
+ * Number of items: 2
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [32774, 32778, 32779] + * * @param blendEquationSeparate The blendEquationSeparate to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBlendEquationSeparate(int[] blendEquationSeparate) { if (blendEquationSeparate == null) { this.blendEquationSeparate = blendEquationSeparate; - return ; + return; } - if (blendEquationSeparate.length< 2) { + if (blendEquationSeparate.length < 2) { throw new IllegalArgumentException("Number of blendEquationSeparate elements is < 2"); } if (blendEquationSeparate.length > 2) { throw new IllegalArgumentException("Number of blendEquationSeparate elements is > 2"); } - for (int blendEquationSeparateElement: blendEquationSeparate) { - if (((blendEquationSeparateElement!= 32774)&&(blendEquationSeparateElement!= 32778))&&(blendEquationSeparateElement!= 32779)) { - throw new IllegalArgumentException((("Invalid value for blendEquationSeparateElement: "+ blendEquationSeparateElement)+", valid: [32774, 32778, 32779]")); + for (int blendEquationSeparateElement : blendEquationSeparate) { + if (((blendEquationSeparateElement != 32774) && (blendEquationSeparateElement != 32778)) && (blendEquationSeparateElement != 32779)) { + throw new IllegalArgumentException((("Invalid value for blendEquationSeparateElement: " + blendEquationSeparateElement) + ", valid: [32774, 32778, 32779]")); } } this.blendEquationSeparate = blendEquationSeparate; } /** - * Integer values passed to `blendEquationSeparate()`. (optional)
- * Default: [32774,32774]
- * Number of items: 2
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [32774, 32778, 32779] - * - * @return The blendEquationSeparate - * + * Returns the default value of the blendEquationSeparate
+ * + * @return The default blendEquationSeparate + * @see #getBlendEquationSeparate + * */ - public int[] getBlendEquationSeparate() { - return this.blendEquationSeparate; + public int[] defaultBlendEquationSeparate() { + return new int[]{32774, 32774}; } /** - * Returns the default value of the blendEquationSeparate
- * @see #getBlendEquationSeparate - * - * @return The default blendEquationSeparate - * + * Integer values passed to `blendFuncSeparate()`. (optional)
+ * Default: [1,0,1,0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, + * 773, 32769, 32770, 32771, 32772, 776] + * + * @return The blendFuncSeparate + * */ - public int[] defaultBlendEquationSeparate() { - return new int[] { 32774, 32774 }; + public int[] getBlendFuncSeparate() { + return this.blendFuncSeparate; } /** - * Integer values passed to `blendFuncSeparate()`. (optional)
- * Default: [1,0,1,0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, - * 773, 32769, 32770, 32771, 32772, 776] - * + * Integer values passed to `blendFuncSeparate()`. (optional)
+ * Default: [1,0,1,0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, + * 773, 32769, 32770, 32771, 32772, 776] + * * @param blendFuncSeparate The blendFuncSeparate to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBlendFuncSeparate(int[] blendFuncSeparate) { if (blendFuncSeparate == null) { this.blendFuncSeparate = blendFuncSeparate; - return ; + return; } - if (blendFuncSeparate.length< 4) { + if (blendFuncSeparate.length < 4) { throw new IllegalArgumentException("Number of blendFuncSeparate elements is < 4"); } if (blendFuncSeparate.length > 4) { throw new IllegalArgumentException("Number of blendFuncSeparate elements is > 4"); } - for (int blendFuncSeparateElement: blendFuncSeparate) { - if (((((((((((((((blendFuncSeparateElement!= 0)&&(blendFuncSeparateElement!= 1))&&(blendFuncSeparateElement!= 768))&&(blendFuncSeparateElement!= 769))&&(blendFuncSeparateElement!= 774))&&(blendFuncSeparateElement!= 775))&&(blendFuncSeparateElement!= 770))&&(blendFuncSeparateElement!= 771))&&(blendFuncSeparateElement!= 772))&&(blendFuncSeparateElement!= 773))&&(blendFuncSeparateElement!= 32769))&&(blendFuncSeparateElement!= 32770))&&(blendFuncSeparateElement!= 32771))&&(blendFuncSeparateElement!= 32772))&&(blendFuncSeparateElement!= 776)) { - throw new IllegalArgumentException((("Invalid value for blendFuncSeparateElement: "+ blendFuncSeparateElement)+", valid: [0, 1, 768, 769, 774, 775, 770, 771, 772, 773, 32769, 32770, 32771, 32772, 776]")); + for (int blendFuncSeparateElement : blendFuncSeparate) { + if (((((((((((((((blendFuncSeparateElement != 0) && (blendFuncSeparateElement != 1)) && (blendFuncSeparateElement != 768)) && (blendFuncSeparateElement != 769)) && (blendFuncSeparateElement != 774)) && (blendFuncSeparateElement != 775)) && (blendFuncSeparateElement != 770)) && (blendFuncSeparateElement != 771)) && (blendFuncSeparateElement != 772)) && (blendFuncSeparateElement != 773)) && (blendFuncSeparateElement != 32769)) && (blendFuncSeparateElement != 32770)) && (blendFuncSeparateElement != 32771)) && (blendFuncSeparateElement != 32772)) && (blendFuncSeparateElement != 776)) { + throw new IllegalArgumentException((("Invalid value for blendFuncSeparateElement: " + blendFuncSeparateElement) + ", valid: [0, 1, 768, 769, 774, 775, 770, 771, 772, 773, 32769, 32770, 32771, 32772, 776]")); } } this.blendFuncSeparate = blendFuncSeparate; } /** - * Integer values passed to `blendFuncSeparate()`. (optional)
- * Default: [1,0,1,0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, - * 773, 32769, 32770, 32771, 32772, 776] - * - * @return The blendFuncSeparate - * + * Returns the default value of the blendFuncSeparate
+ * + * @return The default blendFuncSeparate + * @see #getBlendFuncSeparate + * */ - public int[] getBlendFuncSeparate() { - return this.blendFuncSeparate; + public int[] defaultBlendFuncSeparate() { + return new int[]{1, 0, 1, 0}; } /** - * Returns the default value of the blendFuncSeparate
- * @see #getBlendFuncSeparate - * - * @return The default blendFuncSeparate - * + * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. + * (optional)
+ * Default: [true,true,true,true]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The colorMask + * */ - public int[] defaultBlendFuncSeparate() { - return new int[] { 1, 0, 1, 0 }; + public boolean[] getColorMask() { + return this.colorMask; } /** - * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. - * (optional)
- * Default: [true,true,true,true]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * + * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. + * (optional)
+ * Default: [true,true,true,true]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * * @param colorMask The colorMask to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setColorMask(boolean[] colorMask) { if (colorMask == null) { this.colorMask = colorMask; - return ; + return; } - if (colorMask.length< 4) { + if (colorMask.length < 4) { throw new IllegalArgumentException("Number of colorMask elements is < 4"); } if (colorMask.length > 4) { @@ -341,165 +354,164 @@ public void setColorMask(boolean[] colorMask) { } /** - * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. - * (optional)
- * Default: [true,true,true,true]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * - * @return The colorMask - * + * Returns the default value of the colorMask
+ * + * @return The default colorMask + * @see #getColorMask + * */ - public boolean[] getColorMask() { - return this.colorMask; + public boolean[] defaultColorMask() { + return new boolean[]{true, true, true, true}; } /** - * Returns the default value of the colorMask
- * @see #getColorMask - * - * @return The default colorMask - * + * Integer value passed to `cullFace()`. (optional)
+ * Default: [1029]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [1028, 1029, 1032] + * + * @return The cullFace + * */ - public boolean[] defaultColorMask() { - return new boolean[] {true, true, true, true }; + public int[] getCullFace() { + return this.cullFace; } /** - * Integer value passed to `cullFace()`. (optional)
- * Default: [1029]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [1028, 1029, 1032] - * + * Integer value passed to `cullFace()`. (optional)
+ * Default: [1029]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [1028, 1029, 1032] + * * @param cullFace The cullFace to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCullFace(int[] cullFace) { if (cullFace == null) { this.cullFace = cullFace; - return ; + return; } - if (cullFace.length< 1) { + if (cullFace.length < 1) { throw new IllegalArgumentException("Number of cullFace elements is < 1"); } if (cullFace.length > 1) { throw new IllegalArgumentException("Number of cullFace elements is > 1"); } - for (int cullFaceElement: cullFace) { - if (((cullFaceElement!= 1028)&&(cullFaceElement!= 1029))&&(cullFaceElement!= 1032)) { - throw new IllegalArgumentException((("Invalid value for cullFaceElement: "+ cullFaceElement)+", valid: [1028, 1029, 1032]")); + for (int cullFaceElement : cullFace) { + if (((cullFaceElement != 1028) && (cullFaceElement != 1029)) && (cullFaceElement != 1032)) { + throw new IllegalArgumentException((("Invalid value for cullFaceElement: " + cullFaceElement) + ", valid: [1028, 1029, 1032]")); } } this.cullFace = cullFace; } /** - * Integer value passed to `cullFace()`. (optional)
- * Default: [1029]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [1028, 1029, 1032] - * - * @return The cullFace - * + * Returns the default value of the cullFace
+ * + * @return The default cullFace + * @see #getCullFace + * */ - public int[] getCullFace() { - return this.cullFace; + public int[] defaultCullFace() { + return new int[]{1029}; } /** - * Returns the default value of the cullFace
- * @see #getCullFace - * - * @return The default cullFace - * + * Integer values passed to `depthFunc()`. (optional)
+ * Default: [513]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] + * + * @return The depthFunc + * */ - public int[] defaultCullFace() { - return new int[] { 1029 }; + public int[] getDepthFunc() { + return this.depthFunc; } /** - * Integer values passed to `depthFunc()`. (optional)
- * Default: [513]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] - * + * Integer values passed to `depthFunc()`. (optional)
+ * Default: [513]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] + * * @param depthFunc The depthFunc to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setDepthFunc(int[] depthFunc) { if (depthFunc == null) { this.depthFunc = depthFunc; - return ; + return; } - if (depthFunc.length< 1) { + if (depthFunc.length < 1) { throw new IllegalArgumentException("Number of depthFunc elements is < 1"); } if (depthFunc.length > 1) { throw new IllegalArgumentException("Number of depthFunc elements is > 1"); } - for (int depthFuncElement: depthFunc) { - if ((((((((depthFuncElement!= 512)&&(depthFuncElement!= 513))&&(depthFuncElement!= 515))&&(depthFuncElement!= 514))&&(depthFuncElement!= 516))&&(depthFuncElement!= 517))&&(depthFuncElement!= 518))&&(depthFuncElement!= 519)) { - throw new IllegalArgumentException((("Invalid value for depthFuncElement: "+ depthFuncElement)+", valid: [512, 513, 515, 514, 516, 517, 518, 519]")); + for (int depthFuncElement : depthFunc) { + if ((((((((depthFuncElement != 512) && (depthFuncElement != 513)) && (depthFuncElement != 515)) && (depthFuncElement != 514)) && (depthFuncElement != 516)) && (depthFuncElement != 517)) && (depthFuncElement != 518)) && (depthFuncElement != 519)) { + throw new IllegalArgumentException((("Invalid value for depthFuncElement: " + depthFuncElement) + ", valid: [512, 513, 515, 514, 516, 517, 518, 519]")); } } this.depthFunc = depthFunc; } /** - * Integer values passed to `depthFunc()`. (optional)
- * Default: [513]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] - * - * @return The depthFunc - * + * Returns the default value of the depthFunc
+ * + * @return The default depthFunc + * @see #getDepthFunc + * */ - public int[] getDepthFunc() { - return this.depthFunc; + public int[] defaultDepthFunc() { + return new int[]{513}; } /** - * Returns the default value of the depthFunc
- * @see #getDepthFunc - * - * @return The default depthFunc - * + * Boolean value passed to `depthMask()`. (optional)
+ * Default: [true]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The depthMask + * */ - public int[] defaultDepthFunc() { - return new int[] { 513 }; + public boolean[] getDepthMask() { + return this.depthMask; } /** - * Boolean value passed to `depthMask()`. (optional)
- * Default: [true]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * Boolean value passed to `depthMask()`. (optional)
+ * Default: [true]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * * @param depthMask The depthMask to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setDepthMask(boolean[] depthMask) { if (depthMask == null) { this.depthMask = depthMask; - return ; + return; } - if (depthMask.length< 1) { + if (depthMask.length < 1) { throw new IllegalArgumentException("Number of depthMask elements is < 1"); } if (depthMask.length > 1) { @@ -509,49 +521,50 @@ public void setDepthMask(boolean[] depthMask) { } /** - * Boolean value passed to `depthMask()`. (optional)
- * Default: [true]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * - * @return The depthMask - * + * Returns the default value of the depthMask
+ * + * @return The default depthMask + * @see #getDepthMask + * */ - public boolean[] getDepthMask() { - return this.depthMask; + public boolean[] defaultDepthMask() { + return new boolean[]{true}; } /** - * Returns the default value of the depthMask
- * @see #getDepthMask - * - * @return The default depthMask - * + * Floating-point values passed to `depthRange()`. [zNear, zFar] + * (optional)
+ * Default: [0.0,1.0]
+ * Number of items: 2
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The depthRange + * */ - public boolean[] defaultDepthMask() { - return new boolean[] {true }; + public float[] getDepthRange() { + return this.depthRange; } /** - * Floating-point values passed to `depthRange()`. [zNear, zFar] - * (optional)
- * Default: [0.0,1.0]
- * Number of items: 2
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point values passed to `depthRange()`. [zNear, zFar] + * (optional)
+ * Default: [0.0,1.0]
+ * Number of items: 2
+ * Array elements:
+ *   The elements of this array (optional) + * * @param depthRange The depthRange to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setDepthRange(float[] depthRange) { if (depthRange == null) { this.depthRange = depthRange; - return ; + return; } - if (depthRange.length< 2) { + if (depthRange.length < 2) { throw new IllegalArgumentException("Number of depthRange elements is < 2"); } if (depthRange.length > 2) { @@ -561,115 +574,115 @@ public void setDepthRange(float[] depthRange) { } /** - * Floating-point values passed to `depthRange()`. [zNear, zFar] - * (optional)
- * Default: [0.0,1.0]
- * Number of items: 2
- * Array elements:
- *   The elements of this array (optional) - * - * @return The depthRange - * + * Returns the default value of the depthRange
+ * + * @return The default depthRange + * @see #getDepthRange + * */ - public float[] getDepthRange() { - return this.depthRange; + public float[] defaultDepthRange() { + return new float[]{0.0F, 1.0F}; } /** - * Returns the default value of the depthRange
- * @see #getDepthRange - * - * @return The default depthRange - * + * Integer value passed to `frontFace()`. (optional)
+ * Default: [2305]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [2304, 2305] + * + * @return The frontFace + * */ - public float[] defaultDepthRange() { - return new float[] { 0.0F, 1.0F }; + public int[] getFrontFace() { + return this.frontFace; } /** - * Integer value passed to `frontFace()`. (optional)
- * Default: [2305]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [2304, 2305] - * + * Integer value passed to `frontFace()`. (optional)
+ * Default: [2305]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Valid values: [2304, 2305] + * * @param frontFace The frontFace to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setFrontFace(int[] frontFace) { if (frontFace == null) { this.frontFace = frontFace; - return ; + return; } - if (frontFace.length< 1) { + if (frontFace.length < 1) { throw new IllegalArgumentException("Number of frontFace elements is < 1"); } if (frontFace.length > 1) { throw new IllegalArgumentException("Number of frontFace elements is > 1"); } - for (int frontFaceElement: frontFace) { - if ((frontFaceElement!= 2304)&&(frontFaceElement!= 2305)) { - throw new IllegalArgumentException((("Invalid value for frontFaceElement: "+ frontFaceElement)+", valid: [2304, 2305]")); + for (int frontFaceElement : frontFace) { + if ((frontFaceElement != 2304) && (frontFaceElement != 2305)) { + throw new IllegalArgumentException((("Invalid value for frontFaceElement: " + frontFaceElement) + ", valid: [2304, 2305]")); } } this.frontFace = frontFace; } /** - * Integer value passed to `frontFace()`. (optional)
- * Default: [2305]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Valid values: [2304, 2305] - * - * @return The frontFace - * + * Returns the default value of the frontFace
+ * + * @return The default frontFace + * @see #getFrontFace + * */ - public int[] getFrontFace() { - return this.frontFace; + public int[] defaultFrontFace() { + return new int[]{2305}; } /** - * Returns the default value of the frontFace
- * @see #getFrontFace - * - * @return The default frontFace - * + * Floating-point value passed to `lineWidth()`. (optional)
+ * Default: [1.0]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0.0 (exclusive) + * + * @return The lineWidth + * */ - public int[] defaultFrontFace() { - return new int[] { 2305 }; + public float[] getLineWidth() { + return this.lineWidth; } /** - * Floating-point value passed to `lineWidth()`. (optional)
- * Default: [1.0]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0.0 (exclusive) - * + * Floating-point value passed to `lineWidth()`. (optional)
+ * Default: [1.0]
+ * Number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0.0 (exclusive) + * * @param lineWidth The lineWidth to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setLineWidth(float[] lineWidth) { if (lineWidth == null) { this.lineWidth = lineWidth; - return ; + return; } - if (lineWidth.length< 1) { + if (lineWidth.length < 1) { throw new IllegalArgumentException("Number of lineWidth elements is < 1"); } if (lineWidth.length > 1) { throw new IllegalArgumentException("Number of lineWidth elements is > 1"); } - for (float lineWidthElement: lineWidth) { - if (lineWidthElement<= 0.0D) { + for (float lineWidthElement : lineWidth) { + if (lineWidthElement <= 0.0D) { throw new IllegalArgumentException("lineWidthElement <= 0.0"); } } @@ -677,50 +690,50 @@ public void setLineWidth(float[] lineWidth) { } /** - * Floating-point value passed to `lineWidth()`. (optional)
- * Default: [1.0]
- * Number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0.0 (exclusive) - * - * @return The lineWidth - * + * Returns the default value of the lineWidth
+ * + * @return The default lineWidth + * @see #getLineWidth + * */ - public float[] getLineWidth() { - return this.lineWidth; + public float[] defaultLineWidth() { + return new float[]{1.0F}; } /** - * Returns the default value of the lineWidth
- * @see #getLineWidth - * - * @return The default lineWidth - * + * Floating-point value passed to `polygonOffset()`. [factor, units] + * (optional)
+ * Default: [0.0,0.0]
+ * Number of items: 2
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The polygonOffset + * */ - public float[] defaultLineWidth() { - return new float[] { 1.0F }; + public float[] getPolygonOffset() { + return this.polygonOffset; } /** - * Floating-point value passed to `polygonOffset()`. [factor, units] - * (optional)
- * Default: [0.0,0.0]
- * Number of items: 2
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point value passed to `polygonOffset()`. [factor, units] + * (optional)
+ * Default: [0.0,0.0]
+ * Number of items: 2
+ * Array elements:
+ *   The elements of this array (optional) + * * @param polygonOffset The polygonOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setPolygonOffset(float[] polygonOffset) { if (polygonOffset == null) { this.polygonOffset = polygonOffset; - return ; + return; } - if (polygonOffset.length< 2) { + if (polygonOffset.length < 2) { throw new IllegalArgumentException("Number of polygonOffset elements is < 2"); } if (polygonOffset.length > 2) { @@ -730,50 +743,50 @@ public void setPolygonOffset(float[] polygonOffset) { } /** - * Floating-point value passed to `polygonOffset()`. [factor, units] - * (optional)
- * Default: [0.0,0.0]
- * Number of items: 2
- * Array elements:
- *   The elements of this array (optional) - * - * @return The polygonOffset - * + * Returns the default value of the polygonOffset
+ * + * @return The default polygonOffset + * @see #getPolygonOffset + * */ - public float[] getPolygonOffset() { - return this.polygonOffset; + public float[] defaultPolygonOffset() { + return new float[]{0.0F, 0.0F}; } /** - * Returns the default value of the polygonOffset
- * @see #getPolygonOffset - * - * @return The default polygonOffset - * + * Floating-point value passed to `scissor()`. [x, y, width, height]. + * (optional)
+ * Default: [0.0,0.0,0.0,0.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The scissor + * */ - public float[] defaultPolygonOffset() { - return new float[] { 0.0F, 0.0F }; + public float[] getScissor() { + return this.scissor; } /** - * Floating-point value passed to `scissor()`. [x, y, width, height]. - * (optional)
- * Default: [0.0,0.0,0.0,0.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * + * Floating-point value passed to `scissor()`. [x, y, width, height]. + * (optional)
+ * Default: [0.0,0.0,0.0,0.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional) + * * @param scissor The scissor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setScissor(float[] scissor) { if (scissor == null) { this.scissor = scissor; - return ; + return; } - if (scissor.length< 4) { + if (scissor.length < 4) { throw new IllegalArgumentException("Number of scissor elements is < 4"); } if (scissor.length > 4) { @@ -783,29 +796,14 @@ public void setScissor(float[] scissor) { } /** - * Floating-point value passed to `scissor()`. [x, y, width, height]. - * (optional)
- * Default: [0.0,0.0,0.0,0.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional) - * - * @return The scissor - * - */ - public float[] getScissor() { - return this.scissor; - } - - /** - * Returns the default value of the scissor
- * @see #getScissor - * + * Returns the default value of the scissor
+ * * @return The default scissor - * + * @see #getScissor + * */ public float[] defaultScissor() { - return new float[] { 0.0F, 0.0F, 0.0F, 0.0F }; + return new float[]{0.0F, 0.0F, 0.0F, 0.0F}; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Texture.java b/src/main/java/de/javagl/jgltf/impl/v1/Texture.java index 750a112..c617247 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Texture.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Texture.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,278 +9,276 @@ package de.javagl.jgltf.impl.v1; - /** - * A texture and its sampler. - * - * Auto-generated for texture.schema.json - * + * A texture and its sampler. + *

+ * Auto-generated for texture.schema.json + * */ public class Texture - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The texture's format. (optional)
- * Default: 6408
- * Valid values: [6406, 6407, 6408, 6409, 6410] - * + * The texture's format. (optional)
+ * Default: 6408
+ * Valid values: [6406, 6407, 6408, 6409, 6410] + * */ private Integer format; /** - * The texture's internal format. (optional)
- * Default: 6408
- * Valid values: [6406, 6407, 6408, 6409, 6410] - * + * The texture's internal format. (optional)
+ * Default: 6408
+ * Valid values: [6406, 6407, 6408, 6409, 6410] + * */ private Integer internalFormat; /** - * The ID of the sampler used by this texture. (required) - * + * The ID of the sampler used by this texture. (required) + * */ private String sampler; /** - * The ID of the image used by this texture. (required) - * + * The ID of the image used by this texture. (required) + * */ private String source; /** - * The target that the WebGL texture should be bound to. (optional)
- * Default: 3553
- * Valid values: [3553] - * + * The target that the WebGL texture should be bound to. (optional)
+ * Default: 3553
+ * Valid values: [3553] + * */ private Integer target; /** - * Texel datatype. (optional)
- * Default: 5121
- * Valid values: [5121, 33635, 32819, 32820] - * + * Texel datatype. (optional)
+ * Default: 5121
+ * Valid values: [5121, 33635, 32819, 32820] + * */ private Integer type; /** - * The texture's format. (optional)
- * Default: 6408
- * Valid values: [6406, 6407, 6408, 6409, 6410] - * + * The texture's format. (optional)
+ * Default: 6408
+ * Valid values: [6406, 6407, 6408, 6409, 6410] + * + * @return The format + * + */ + public Integer getFormat() { + return this.format; + } + + /** + * The texture's format. (optional)
+ * Default: 6408
+ * Valid values: [6406, 6407, 6408, 6409, 6410] + * * @param format The format to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setFormat(Integer format) { if (format == null) { this.format = format; - return ; + return; } - if (((((format!= 6406)&&(format!= 6407))&&(format!= 6408))&&(format!= 6409))&&(format!= 6410)) { - throw new IllegalArgumentException((("Invalid value for format: "+ format)+", valid: [6406, 6407, 6408, 6409, 6410]")); + if (((((format != 6406) && (format != 6407)) && (format != 6408)) && (format != 6409)) && (format != 6410)) { + throw new IllegalArgumentException((("Invalid value for format: " + format) + ", valid: [6406, 6407, 6408, 6409, 6410]")); } this.format = format; } /** - * The texture's format. (optional)
- * Default: 6408
- * Valid values: [6406, 6407, 6408, 6409, 6410] - * - * @return The format - * + * Returns the default value of the format
+ * + * @return The default format + * @see #getFormat + * */ - public Integer getFormat() { - return this.format; + public Integer defaultFormat() { + return 6408; } /** - * Returns the default value of the format
- * @see #getFormat - * - * @return The default format - * + * The texture's internal format. (optional)
+ * Default: 6408
+ * Valid values: [6406, 6407, 6408, 6409, 6410] + * + * @return The internalFormat + * */ - public Integer defaultFormat() { - return 6408; + public Integer getInternalFormat() { + return this.internalFormat; } /** - * The texture's internal format. (optional)
- * Default: 6408
- * Valid values: [6406, 6407, 6408, 6409, 6410] - * + * The texture's internal format. (optional)
+ * Default: 6408
+ * Valid values: [6406, 6407, 6408, 6409, 6410] + * * @param internalFormat The internalFormat to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setInternalFormat(Integer internalFormat) { if (internalFormat == null) { this.internalFormat = internalFormat; - return ; + return; } - if (((((internalFormat!= 6406)&&(internalFormat!= 6407))&&(internalFormat!= 6408))&&(internalFormat!= 6409))&&(internalFormat!= 6410)) { - throw new IllegalArgumentException((("Invalid value for internalFormat: "+ internalFormat)+", valid: [6406, 6407, 6408, 6409, 6410]")); + if (((((internalFormat != 6406) && (internalFormat != 6407)) && (internalFormat != 6408)) && (internalFormat != 6409)) && (internalFormat != 6410)) { + throw new IllegalArgumentException((("Invalid value for internalFormat: " + internalFormat) + ", valid: [6406, 6407, 6408, 6409, 6410]")); } this.internalFormat = internalFormat; } /** - * The texture's internal format. (optional)
- * Default: 6408
- * Valid values: [6406, 6407, 6408, 6409, 6410] - * - * @return The internalFormat - * + * Returns the default value of the internalFormat
+ * + * @return The default internalFormat + * @see #getInternalFormat + * */ - public Integer getInternalFormat() { - return this.internalFormat; + public Integer defaultInternalFormat() { + return 6408; } /** - * Returns the default value of the internalFormat
- * @see #getInternalFormat - * - * @return The default internalFormat - * + * The ID of the sampler used by this texture. (required) + * + * @return The sampler + * */ - public Integer defaultInternalFormat() { - return 6408; + public String getSampler() { + return this.sampler; } /** - * The ID of the sampler used by this texture. (required) - * + * The ID of the sampler used by this texture. (required) + * * @param sampler The sampler to set * @throws NullPointerException If the given value is null - * + * */ public void setSampler(String sampler) { if (sampler == null) { - throw new NullPointerException((("Invalid value for sampler: "+ sampler)+", may not be null")); + throw new NullPointerException((("Invalid value for sampler: " + sampler) + ", may not be null")); } this.sampler = sampler; } /** - * The ID of the sampler used by this texture. (required) - * - * @return The sampler - * + * The ID of the image used by this texture. (required) + * + * @return The source + * */ - public String getSampler() { - return this.sampler; + public String getSource() { + return this.source; } /** - * The ID of the image used by this texture. (required) - * + * The ID of the image used by this texture. (required) + * * @param source The source to set * @throws NullPointerException If the given value is null - * + * */ public void setSource(String source) { if (source == null) { - throw new NullPointerException((("Invalid value for source: "+ source)+", may not be null")); + throw new NullPointerException((("Invalid value for source: " + source) + ", may not be null")); } this.source = source; } /** - * The ID of the image used by this texture. (required) - * - * @return The source - * + * The target that the WebGL texture should be bound to. (optional)
+ * Default: 3553
+ * Valid values: [3553] + * + * @return The target + * */ - public String getSource() { - return this.source; + public Integer getTarget() { + return this.target; } /** - * The target that the WebGL texture should be bound to. (optional)
- * Default: 3553
- * Valid values: [3553] - * + * The target that the WebGL texture should be bound to. (optional)
+ * Default: 3553
+ * Valid values: [3553] + * * @param target The target to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTarget(Integer target) { if (target == null) { this.target = target; - return ; + return; } - if (target!= 3553) { - throw new IllegalArgumentException((("Invalid value for target: "+ target)+", valid: [3553]")); + if (target != 3553) { + throw new IllegalArgumentException((("Invalid value for target: " + target) + ", valid: [3553]")); } this.target = target; } /** - * The target that the WebGL texture should be bound to. (optional)
- * Default: 3553
- * Valid values: [3553] - * - * @return The target - * + * Returns the default value of the target
+ * + * @return The default target + * @see #getTarget + * */ - public Integer getTarget() { - return this.target; + public Integer defaultTarget() { + return 3553; } /** - * Returns the default value of the target
- * @see #getTarget - * - * @return The default target - * + * Texel datatype. (optional)
+ * Default: 5121
+ * Valid values: [5121, 33635, 32819, 32820] + * + * @return The type + * */ - public Integer defaultTarget() { - return 3553; + public Integer getType() { + return this.type; } /** - * Texel datatype. (optional)
- * Default: 5121
- * Valid values: [5121, 33635, 32819, 32820] - * + * Texel datatype. (optional)
+ * Default: 5121
+ * Valid values: [5121, 33635, 32819, 32820] + * * @param type The type to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(Integer type) { if (type == null) { this.type = type; - return ; + return; } - if ((((type!= 5121)&&(type!= 33635))&&(type!= 32819))&&(type!= 32820)) { - throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [5121, 33635, 32819, 32820]")); + if ((((type != 5121) && (type != 33635)) && (type != 32819)) && (type != 32820)) { + throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [5121, 33635, 32819, 32820]")); } this.type = type; } /** - * Texel datatype. (optional)
- * Default: 5121
- * Valid values: [5121, 33635, 32819, 32820] - * - * @return The type - * - */ - public Integer getType() { - return this.type; - } - - /** - * Returns the default value of the type
- * @see #getType - * + * Returns the default value of the type
+ * * @return The default type - * + * @see #getType + * */ public Integer defaultType() { - return 5121; + return 5121; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Accessor.java b/src/main/java/de/javagl/jgltf/impl/v2/Accessor.java index 5c4af63..ba909ed 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Accessor.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Accessor.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,303 +9,315 @@ package de.javagl.jgltf.impl.v2; - /** - * A typed view into a buffer view that contains raw binary data. - * - * Auto-generated for accessor.schema.json - * + * A typed view into a buffer view that contains raw binary data. + *

+ * Auto-generated for accessor.schema.json + * */ public class Accessor - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The index of the bufferView. (optional) - * + * The index of the bufferView. (optional) + * */ private Integer bufferView; /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The datatype of the accessor's components. (required)
- * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] - * + * The datatype of the accessor's components. (required)
+ * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] + * */ private Integer componentType; /** - * Specifies whether integer data values are normalized before usage. - * (optional)
- * Default: false - * + * Specifies whether integer data values are normalized before usage. + * (optional)
+ * Default: false + * */ private Boolean normalized; /** - * The number of elements referenced by this accessor. (required)
- * Minimum: 1 (inclusive) - * + * The number of elements referenced by this accessor. (required)
+ * Minimum: 1 (inclusive) + * */ private Integer count; /** - * Specifies if the accessor's elements are scalars, vectors, or - * matrices. (required)
- * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] - * + * Specifies if the accessor's elements are scalars, vectors, or + * matrices. (required)
+ * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] + * */ private String type; /** - * Maximum value of each component in this accessor. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Maximum value of each component in this accessor. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * */ private Number[] max; /** - * Minimum value of each component in this accessor. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Minimum value of each component in this accessor. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * */ private Number[] min; /** - * Sparse storage of elements that deviate from their initialization - * value. (optional) - * + * Sparse storage of elements that deviate from their initialization + * value. (optional) + * */ private AccessorSparse sparse; /** - * The index of the bufferView. (optional) - * + * The index of the bufferView. (optional) + * + * @return The bufferView + * + */ + public Integer getBufferView() { + return this.bufferView; + } + + /** + * The index of the bufferView. (optional) + * * @param bufferView The bufferView to set - * + * */ public void setBufferView(Integer bufferView) { if (bufferView == null) { this.bufferView = bufferView; - return ; + return; } this.bufferView = bufferView; } /** - * The index of the bufferView. (optional) - * - * @return The bufferView - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public Integer getBufferView() { - return this.bufferView; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { this.byteOffset = byteOffset; - return ; + return; } - if (byteOffset< 0) { + if (byteOffset < 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * Returns the default value of the byteOffset
+ * + * @return The default byteOffset + * @see #getByteOffset + * */ - public Integer getByteOffset() { - return this.byteOffset; + public Integer defaultByteOffset() { + return 0; } /** - * Returns the default value of the byteOffset
- * @see #getByteOffset - * - * @return The default byteOffset - * + * The datatype of the accessor's components. (required)
+ * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] + * + * @return The componentType + * */ - public Integer defaultByteOffset() { - return 0; + public Integer getComponentType() { + return this.componentType; } /** - * The datatype of the accessor's components. (required)
- * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] - * + * The datatype of the accessor's components. (required)
+ * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] + * * @param componentType The componentType to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setComponentType(Integer componentType) { if (componentType == null) { - throw new NullPointerException((("Invalid value for componentType: "+ componentType)+", may not be null")); + throw new NullPointerException((("Invalid value for componentType: " + componentType) + ", may not be null")); } - if ((((((componentType!= 5120)&&(componentType!= 5121))&&(componentType!= 5122))&&(componentType!= 5123))&&(componentType!= 5125))&&(componentType!= 5126)) { - throw new IllegalArgumentException((("Invalid value for componentType: "+ componentType)+", valid: [5120, 5121, 5122, 5123, 5125, 5126]")); + if ((((((componentType != 5120) && (componentType != 5121)) && (componentType != 5122)) && (componentType != 5123)) && (componentType != 5125)) && (componentType != 5126)) { + throw new IllegalArgumentException((("Invalid value for componentType: " + componentType) + ", valid: [5120, 5121, 5122, 5123, 5125, 5126]")); } this.componentType = componentType; } /** - * The datatype of the accessor's components. (required)
- * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] - * - * @return The componentType - * - */ - public Integer getComponentType() { - return this.componentType; - } - - /** - * Specifies whether integer data values are normalized before usage. - * (optional)
- * Default: false - * + * Specifies whether integer data values are normalized before usage. + * (optional)
+ * Default: false + * * @param normalized The normalized to set - * + * */ public void setNormalized(Boolean normalized) { if (normalized == null) { this.normalized = normalized; - return ; + return; } this.normalized = normalized; } /** - * Specifies whether integer data values are normalized before usage. - * (optional)
- * Default: false - * + * Specifies whether integer data values are normalized before usage. + * (optional)
+ * Default: false + * * @return The normalized - * + * */ public Boolean isNormalized() { return this.normalized; } /** - * Returns the default value of the normalized
- * @see #isNormalized - * + * Returns the default value of the normalized
+ * * @return The default normalized - * + * @see #isNormalized + * */ public Boolean defaultNormalized() { return false; } /** - * The number of elements referenced by this accessor. (required)
- * Minimum: 1 (inclusive) - * + * The number of elements referenced by this accessor. (required)
+ * Minimum: 1 (inclusive) + * + * @return The count + * + */ + public Integer getCount() { + return this.count; + } + + /** + * The number of elements referenced by this accessor. (required)
+ * Minimum: 1 (inclusive) + * * @param count The count to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCount(Integer count) { if (count == null) { - throw new NullPointerException((("Invalid value for count: "+ count)+", may not be null")); + throw new NullPointerException((("Invalid value for count: " + count) + ", may not be null")); } - if (count< 1) { + if (count < 1) { throw new IllegalArgumentException("count < 1"); } this.count = count; } /** - * The number of elements referenced by this accessor. (required)
- * Minimum: 1 (inclusive) - * - * @return The count - * + * Specifies if the accessor's elements are scalars, vectors, or + * matrices. (required)
+ * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] + * + * @return The type + * */ - public Integer getCount() { - return this.count; + public String getType() { + return this.type; } /** - * Specifies if the accessor's elements are scalars, vectors, or - * matrices. (required)
- * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] - * + * Specifies if the accessor's elements are scalars, vectors, or + * matrices. (required)
+ * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); + throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); } - if (((((((!"SCALAR".equals(type))&&(!"VEC2".equals(type)))&&(!"VEC3".equals(type)))&&(!"VEC4".equals(type)))&&(!"MAT2".equals(type)))&&(!"MAT3".equals(type)))&&(!"MAT4".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4]")); + if (((((((!"SCALAR".equals(type)) && (!"VEC2".equals(type))) && (!"VEC3".equals(type))) && (!"VEC4".equals(type))) && (!"MAT2".equals(type))) && (!"MAT3".equals(type))) && (!"MAT4".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4]")); } this.type = type; } /** - * Specifies if the accessor's elements are scalars, vectors, or - * matrices. (required)
- * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] - * - * @return The type - * + * Maximum value of each component in this accessor. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The max + * */ - public String getType() { - return this.type; + public Number[] getMax() { + return this.max; } /** - * Maximum value of each component in this accessor. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Maximum value of each component in this accessor. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * * @param max The max to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMax(Number[] max) { if (max == null) { this.max = max; - return ; + return; } - if (max.length< 1) { + if (max.length < 1) { throw new IllegalArgumentException("Number of max elements is < 1"); } if (max.length > 16) { @@ -315,37 +327,37 @@ public void setMax(Number[] max) { } /** - * Maximum value of each component in this accessor. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * - * @return The max - * + * Minimum value of each component in this accessor. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The min + * */ - public Number[] getMax() { - return this.max; + public Number[] getMin() { + return this.min; } /** - * Minimum value of each component in this accessor. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * Minimum value of each component in this accessor. (optional)
+ * Minimum number of items: 1
+ * Maximum number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * * @param min The min to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMin(Number[] min) { if (min == null) { this.min = min; - return ; + return; } - if (min.length< 1) { + if (min.length < 1) { throw new IllegalArgumentException("Number of min elements is < 1"); } if (min.length > 16) { @@ -355,43 +367,29 @@ public void setMin(Number[] min) { } /** - * Minimum value of each component in this accessor. (optional)
- * Minimum number of items: 1
- * Maximum number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * - * @return The min - * + * Sparse storage of elements that deviate from their initialization + * value. (optional) + * + * @return The sparse + * */ - public Number[] getMin() { - return this.min; + public AccessorSparse getSparse() { + return this.sparse; } /** - * Sparse storage of elements that deviate from their initialization - * value. (optional) - * + * Sparse storage of elements that deviate from their initialization + * value. (optional) + * * @param sparse The sparse to set - * + * */ public void setSparse(AccessorSparse sparse) { if (sparse == null) { this.sparse = sparse; - return ; + return; } this.sparse = sparse; } - /** - * Sparse storage of elements that deviate from their initialization - * value. (optional) - * - * @return The sparse - * - */ - public AccessorSparse getSparse() { - return this.sparse; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparse.java b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparse.java index 165aba7..2307c6a 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparse.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparse.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,124 +9,122 @@ package de.javagl.jgltf.impl.v2; - /** - * Sparse storage of accessor values that deviate from their - * initialization value. - * - * Auto-generated for accessor.sparse.schema.json - * + * Sparse storage of accessor values that deviate from their + * initialization value. + *

+ * Auto-generated for accessor.sparse.schema.json + * */ public class AccessorSparse - extends GlTFProperty -{ + extends GlTFProperty { /** - * Number of deviating accessor values stored in the sparse array. - * (required)
- * Minimum: 1 (inclusive) - * + * Number of deviating accessor values stored in the sparse array. + * (required)
+ * Minimum: 1 (inclusive) + * */ private Integer count; /** - * An object pointing to a buffer view containing the indices of - * deviating accessor values. The number of indices is equal to `count`. - * Indices **MUST** strictly increase. (required) - * + * An object pointing to a buffer view containing the indices of + * deviating accessor values. The number of indices is equal to `count`. + * Indices **MUST** strictly increase. (required) + * */ private AccessorSparseIndices indices; /** - * An object pointing to a buffer view containing the deviating accessor - * values. (required) - * + * An object pointing to a buffer view containing the deviating accessor + * values. (required) + * */ private AccessorSparseValues values; /** - * Number of deviating accessor values stored in the sparse array. - * (required)
- * Minimum: 1 (inclusive) - * + * Number of deviating accessor values stored in the sparse array. + * (required)
+ * Minimum: 1 (inclusive) + * + * @return The count + * + */ + public Integer getCount() { + return this.count; + } + + /** + * Number of deviating accessor values stored in the sparse array. + * (required)
+ * Minimum: 1 (inclusive) + * * @param count The count to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCount(Integer count) { if (count == null) { - throw new NullPointerException((("Invalid value for count: "+ count)+", may not be null")); + throw new NullPointerException((("Invalid value for count: " + count) + ", may not be null")); } - if (count< 1) { + if (count < 1) { throw new IllegalArgumentException("count < 1"); } this.count = count; } /** - * Number of deviating accessor values stored in the sparse array. - * (required)
- * Minimum: 1 (inclusive) - * - * @return The count - * + * An object pointing to a buffer view containing the indices of + * deviating accessor values. The number of indices is equal to `count`. + * Indices **MUST** strictly increase. (required) + * + * @return The indices + * */ - public Integer getCount() { - return this.count; + public AccessorSparseIndices getIndices() { + return this.indices; } /** - * An object pointing to a buffer view containing the indices of - * deviating accessor values. The number of indices is equal to `count`. - * Indices **MUST** strictly increase. (required) - * + * An object pointing to a buffer view containing the indices of + * deviating accessor values. The number of indices is equal to `count`. + * Indices **MUST** strictly increase. (required) + * * @param indices The indices to set * @throws NullPointerException If the given value is null - * + * */ public void setIndices(AccessorSparseIndices indices) { if (indices == null) { - throw new NullPointerException((("Invalid value for indices: "+ indices)+", may not be null")); + throw new NullPointerException((("Invalid value for indices: " + indices) + ", may not be null")); } this.indices = indices; } /** - * An object pointing to a buffer view containing the indices of - * deviating accessor values. The number of indices is equal to `count`. - * Indices **MUST** strictly increase. (required) - * - * @return The indices - * + * An object pointing to a buffer view containing the deviating accessor + * values. (required) + * + * @return The values + * */ - public AccessorSparseIndices getIndices() { - return this.indices; + public AccessorSparseValues getValues() { + return this.values; } /** - * An object pointing to a buffer view containing the deviating accessor - * values. (required) - * + * An object pointing to a buffer view containing the deviating accessor + * values. (required) + * * @param values The values to set * @throws NullPointerException If the given value is null - * + * */ public void setValues(AccessorSparseValues values) { if (values == null) { - throw new NullPointerException((("Invalid value for values: "+ values)+", may not be null")); + throw new NullPointerException((("Invalid value for values: " + values) + ", may not be null")); } this.values = values; } - /** - * An object pointing to a buffer view containing the deviating accessor - * values. (required) - * - * @return The values - * - */ - public AccessorSparseValues getValues() { - return this.values; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseIndices.java b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseIndices.java index a6b933b..e6172af 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseIndices.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseIndices.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,147 +9,145 @@ package de.javagl.jgltf.impl.v2; - /** - * An object pointing to a buffer view containing the indices of - * deviating accessor values. The number of indices is equal to - * `accessor.sparse.count`. Indices **MUST** strictly increase. - * - * Auto-generated for accessor.sparse.indices.schema.json - * + * An object pointing to a buffer view containing the indices of + * deviating accessor values. The number of indices is equal to + * `accessor.sparse.count`. Indices **MUST** strictly increase. + *

+ * Auto-generated for accessor.sparse.indices.schema.json + * */ public class AccessorSparseIndices - extends GlTFProperty -{ + extends GlTFProperty { /** - * The index of the buffer view with sparse indices. The referenced - * buffer view **MUST NOT** have its `target` or `byteStride` properties - * defined. The buffer view and the optional `byteOffset` **MUST** be - * aligned to the `componentType` byte length. (required) - * + * The index of the buffer view with sparse indices. The referenced + * buffer view **MUST NOT** have its `target` or `byteStride` properties + * defined. The buffer view and the optional `byteOffset` **MUST** be + * aligned to the `componentType` byte length. (required) + * */ private Integer bufferView; /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The indices data type. (required)
- * Valid values: [5121, 5123, 5125] - * + * The indices data type. (required)
+ * Valid values: [5121, 5123, 5125] + * */ private Integer componentType; /** - * The index of the buffer view with sparse indices. The referenced - * buffer view **MUST NOT** have its `target` or `byteStride` properties - * defined. The buffer view and the optional `byteOffset` **MUST** be - * aligned to the `componentType` byte length. (required) - * + * The index of the buffer view with sparse indices. The referenced + * buffer view **MUST NOT** have its `target` or `byteStride` properties + * defined. The buffer view and the optional `byteOffset` **MUST** be + * aligned to the `componentType` byte length. (required) + * + * @return The bufferView + * + */ + public Integer getBufferView() { + return this.bufferView; + } + + /** + * The index of the buffer view with sparse indices. The referenced + * buffer view **MUST NOT** have its `target` or `byteStride` properties + * defined. The buffer view and the optional `byteOffset` **MUST** be + * aligned to the `componentType` byte length. (required) + * * @param bufferView The bufferView to set * @throws NullPointerException If the given value is null - * + * */ public void setBufferView(Integer bufferView) { if (bufferView == null) { - throw new NullPointerException((("Invalid value for bufferView: "+ bufferView)+", may not be null")); + throw new NullPointerException((("Invalid value for bufferView: " + bufferView) + ", may not be null")); } this.bufferView = bufferView; } /** - * The index of the buffer view with sparse indices. The referenced - * buffer view **MUST NOT** have its `target` or `byteStride` properties - * defined. The buffer view and the optional `byteOffset` **MUST** be - * aligned to the `componentType` byte length. (required) - * - * @return The bufferView - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public Integer getBufferView() { - return this.bufferView; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { this.byteOffset = byteOffset; - return ; + return; } - if (byteOffset< 0) { + if (byteOffset < 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * Returns the default value of the byteOffset
+ * + * @return The default byteOffset + * @see #getByteOffset + * */ - public Integer getByteOffset() { - return this.byteOffset; + public Integer defaultByteOffset() { + return 0; } /** - * Returns the default value of the byteOffset
- * @see #getByteOffset - * - * @return The default byteOffset - * + * The indices data type. (required)
+ * Valid values: [5121, 5123, 5125] + * + * @return The componentType + * */ - public Integer defaultByteOffset() { - return 0; + public Integer getComponentType() { + return this.componentType; } /** - * The indices data type. (required)
- * Valid values: [5121, 5123, 5125] - * + * The indices data type. (required)
+ * Valid values: [5121, 5123, 5125] + * * @param componentType The componentType to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setComponentType(Integer componentType) { if (componentType == null) { - throw new NullPointerException((("Invalid value for componentType: "+ componentType)+", may not be null")); + throw new NullPointerException((("Invalid value for componentType: " + componentType) + ", may not be null")); } - if (((componentType!= 5121)&&(componentType!= 5123))&&(componentType!= 5125)) { - throw new IllegalArgumentException((("Invalid value for componentType: "+ componentType)+", valid: [5121, 5123, 5125]")); + if (((componentType != 5121) && (componentType != 5123)) && (componentType != 5125)) { + throw new IllegalArgumentException((("Invalid value for componentType: " + componentType) + ", valid: [5121, 5123, 5125]")); } this.componentType = componentType; } - /** - * The indices data type. (required)
- * Valid values: [5121, 5123, 5125] - * - * @return The componentType - * - */ - public Integer getComponentType() { - return this.componentType; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseValues.java b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseValues.java index 5437971..10e834d 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseValues.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseValues.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,109 +9,107 @@ package de.javagl.jgltf.impl.v2; - /** - * An object pointing to a buffer view containing the deviating accessor - * values. The number of elements is equal to `accessor.sparse.count` - * times number of components. The elements have the same component type - * as the base accessor. The elements are tightly packed. Data **MUST** - * be aligned following the same rules as the base accessor. - * - * Auto-generated for accessor.sparse.values.schema.json - * + * An object pointing to a buffer view containing the deviating accessor + * values. The number of elements is equal to `accessor.sparse.count` + * times number of components. The elements have the same component type + * as the base accessor. The elements are tightly packed. Data **MUST** + * be aligned following the same rules as the base accessor. + *

+ * Auto-generated for accessor.sparse.values.schema.json + * */ public class AccessorSparseValues - extends GlTFProperty -{ + extends GlTFProperty { /** - * The index of the bufferView with sparse values. The referenced buffer - * view **MUST NOT** have its `target` or `byteStride` properties - * defined. (required) - * + * The index of the bufferView with sparse values. The referenced buffer + * view **MUST NOT** have its `target` or `byteStride` properties + * defined. (required) + * */ private Integer bufferView; /** - * The offset relative to the start of the bufferView in bytes. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The offset relative to the start of the bufferView in bytes. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The index of the bufferView with sparse values. The referenced buffer - * view **MUST NOT** have its `target` or `byteStride` properties - * defined. (required) - * + * The index of the bufferView with sparse values. The referenced buffer + * view **MUST NOT** have its `target` or `byteStride` properties + * defined. (required) + * + * @return The bufferView + * + */ + public Integer getBufferView() { + return this.bufferView; + } + + /** + * The index of the bufferView with sparse values. The referenced buffer + * view **MUST NOT** have its `target` or `byteStride` properties + * defined. (required) + * * @param bufferView The bufferView to set * @throws NullPointerException If the given value is null - * + * */ public void setBufferView(Integer bufferView) { if (bufferView == null) { - throw new NullPointerException((("Invalid value for bufferView: "+ bufferView)+", may not be null")); + throw new NullPointerException((("Invalid value for bufferView: " + bufferView) + ", may not be null")); } this.bufferView = bufferView; } /** - * The index of the bufferView with sparse values. The referenced buffer - * view **MUST NOT** have its `target` or `byteStride` properties - * defined. (required) - * - * @return The bufferView - * + * The offset relative to the start of the bufferView in bytes. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public Integer getBufferView() { - return this.bufferView; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The offset relative to the start of the bufferView in bytes. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The offset relative to the start of the bufferView in bytes. + * (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { this.byteOffset = byteOffset; - return ; + return; } - if (byteOffset< 0) { + if (byteOffset < 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * The offset relative to the start of the bufferView in bytes. - * (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * - * @return The byteOffset - * - */ - public Integer getByteOffset() { - return this.byteOffset; - } - - /** - * Returns the default value of the byteOffset
- * @see #getByteOffset - * + * Returns the default value of the byteOffset
+ * * @return The default byteOffset - * + * @see #getByteOffset + * */ public Integer defaultByteOffset() { - return 0; + return 0; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Animation.java b/src/main/java/de/javagl/jgltf/impl/v2/Animation.java index 161c8f6..b8e24e0 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Animation.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Animation.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,90 +13,89 @@ /** - * A keyframe animation. - * - * Auto-generated for animation.schema.json - * + * A keyframe animation. + *

+ * Auto-generated for animation.schema.json + * */ public class Animation - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * An array of animation channels. An animation channel combines an - * animation sampler with a target property being animated. Different - * channels of the same animation **MUST NOT** have the same targets. - * (required)
- * Minimum number of items: 1
- * Array elements:
- *   An animation channel combines an animation sampler with a - * target property being animated. (optional) - * + * An array of animation channels. An animation channel combines an + * animation sampler with a target property being animated. Different + * channels of the same animation **MUST NOT** have the same targets. + * (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   An animation channel combines an animation sampler with a + * target property being animated. (optional) + * */ private List channels; /** - * An array of animation samplers. An animation sampler combines - * timestamps with a sequence of output values and defines an - * interpolation algorithm. (required)
- * Minimum number of items: 1
- * Array elements:
- *   An animation sampler combines timestamps with a sequence - * of output values and defines an interpolation algorithm. (optional) - * + * An array of animation samplers. An animation sampler combines + * timestamps with a sequence of output values and defines an + * interpolation algorithm. (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   An animation sampler combines timestamps with a sequence + * of output values and defines an interpolation algorithm. (optional) + * */ private List samplers; /** - * An array of animation channels. An animation channel combines an - * animation sampler with a target property being animated. Different - * channels of the same animation **MUST NOT** have the same targets. - * (required)
- * Minimum number of items: 1
- * Array elements:
- *   An animation channel combines an animation sampler with a - * target property being animated. (optional) - * + * An array of animation channels. An animation channel combines an + * animation sampler with a target property being animated. Different + * channels of the same animation **MUST NOT** have the same targets. + * (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   An animation channel combines an animation sampler with a + * target property being animated. (optional) + * + * @return The channels + * + */ + public List getChannels() { + return this.channels; + } + + /** + * An array of animation channels. An animation channel combines an + * animation sampler with a target property being animated. Different + * channels of the same animation **MUST NOT** have the same targets. + * (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   An animation channel combines an animation sampler with a + * target property being animated. (optional) + * * @param channels The channels to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setChannels(List channels) { if (channels == null) { - throw new NullPointerException((("Invalid value for channels: "+ channels)+", may not be null")); + throw new NullPointerException((("Invalid value for channels: " + channels) + ", may not be null")); } - if (channels.size()< 1) { + if (channels.size() < 1) { throw new IllegalArgumentException("Number of channels elements is < 1"); } this.channels = channels; } /** - * An array of animation channels. An animation channel combines an - * animation sampler with a target property being animated. Different - * channels of the same animation **MUST NOT** have the same targets. - * (required)
- * Minimum number of items: 1
- * Array elements:
- *   An animation channel combines an animation sampler with a - * target property being animated. (optional) - * - * @return The channels - * - */ - public List getChannels() { - return this.channels; - } - - /** - * Add the given channels. The channels of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given channels. The channels of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addChannels(AnimationChannel element) { if (element == null) { @@ -104,7 +103,7 @@ public void addChannels(AnimationChannel element) { } List oldList = this.channels; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -112,13 +111,13 @@ public void addChannels(AnimationChannel element) { } /** - * Remove the given channels. The channels of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one. - * + * Remove the given channels. The channels of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeChannels(AnimationChannel element) { if (element == null) { @@ -126,7 +125,7 @@ public void removeChannels(AnimationChannel element) { } List oldList = this.channels; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -134,54 +133,54 @@ public void removeChannels(AnimationChannel element) { } /** - * An array of animation samplers. An animation sampler combines - * timestamps with a sequence of output values and defines an - * interpolation algorithm. (required)
- * Minimum number of items: 1
- * Array elements:
- *   An animation sampler combines timestamps with a sequence - * of output values and defines an interpolation algorithm. (optional) - * + * An array of animation samplers. An animation sampler combines + * timestamps with a sequence of output values and defines an + * interpolation algorithm. (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   An animation sampler combines timestamps with a sequence + * of output values and defines an interpolation algorithm. (optional) + * + * @return The samplers + * + */ + public List getSamplers() { + return this.samplers; + } + + /** + * An array of animation samplers. An animation sampler combines + * timestamps with a sequence of output values and defines an + * interpolation algorithm. (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   An animation sampler combines timestamps with a sequence + * of output values and defines an interpolation algorithm. (optional) + * * @param samplers The samplers to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setSamplers(List samplers) { if (samplers == null) { - throw new NullPointerException((("Invalid value for samplers: "+ samplers)+", may not be null")); + throw new NullPointerException((("Invalid value for samplers: " + samplers) + ", may not be null")); } - if (samplers.size()< 1) { + if (samplers.size() < 1) { throw new IllegalArgumentException("Number of samplers elements is < 1"); } this.samplers = samplers; } /** - * An array of animation samplers. An animation sampler combines - * timestamps with a sequence of output values and defines an - * interpolation algorithm. (required)
- * Minimum number of items: 1
- * Array elements:
- *   An animation sampler combines timestamps with a sequence - * of output values and defines an interpolation algorithm. (optional) - * - * @return The samplers - * - */ - public List getSamplers() { - return this.samplers; - } - - /** - * Add the given samplers. The samplers of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given samplers. The samplers of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addSamplers(AnimationSampler element) { if (element == null) { @@ -189,7 +188,7 @@ public void addSamplers(AnimationSampler element) { } List oldList = this.samplers; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -197,13 +196,13 @@ public void addSamplers(AnimationSampler element) { } /** - * Remove the given samplers. The samplers of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one. - * + * Remove the given samplers. The samplers of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeSamplers(AnimationSampler element) { if (element == null) { @@ -211,7 +210,7 @@ public void removeSamplers(AnimationSampler element) { } List oldList = this.samplers; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannel.java b/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannel.java index 527a281..5fe3068 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannel.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannel.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,78 +9,76 @@ package de.javagl.jgltf.impl.v2; - /** - * An animation channel combines an animation sampler with a target - * property being animated. - * - * Auto-generated for animation.channel.schema.json - * + * An animation channel combines an animation sampler with a target + * property being animated. + *

+ * Auto-generated for animation.channel.schema.json + * */ public class AnimationChannel - extends GlTFProperty -{ + extends GlTFProperty { /** - * The index of a sampler in this animation used to compute the value for - * the target. (required) - * + * The index of a sampler in this animation used to compute the value for + * the target. (required) + * */ private Integer sampler; /** - * The descriptor of the animated property. (required) - * + * The descriptor of the animated property. (required) + * */ private AnimationChannelTarget target; /** - * The index of a sampler in this animation used to compute the value for - * the target. (required) - * + * The index of a sampler in this animation used to compute the value for + * the target. (required) + * + * @return The sampler + * + */ + public Integer getSampler() { + return this.sampler; + } + + /** + * The index of a sampler in this animation used to compute the value for + * the target. (required) + * * @param sampler The sampler to set * @throws NullPointerException If the given value is null - * + * */ public void setSampler(Integer sampler) { if (sampler == null) { - throw new NullPointerException((("Invalid value for sampler: "+ sampler)+", may not be null")); + throw new NullPointerException((("Invalid value for sampler: " + sampler) + ", may not be null")); } this.sampler = sampler; } /** - * The index of a sampler in this animation used to compute the value for - * the target. (required) - * - * @return The sampler - * + * The descriptor of the animated property. (required) + * + * @return The target + * */ - public Integer getSampler() { - return this.sampler; + public AnimationChannelTarget getTarget() { + return this.target; } /** - * The descriptor of the animated property. (required) - * + * The descriptor of the animated property. (required) + * * @param target The target to set * @throws NullPointerException If the given value is null - * + * */ public void setTarget(AnimationChannelTarget target) { if (target == null) { - throw new NullPointerException((("Invalid value for target: "+ target)+", may not be null")); + throw new NullPointerException((("Invalid value for target: " + target) + ", may not be null")); } this.target = target; } - /** - * The descriptor of the animated property. (required) - * - * @return The target - * - */ - public AnimationChannelTarget getTarget() { - return this.target; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannelTarget.java b/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannelTarget.java index a9b297b..0b5fd80 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannelTarget.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannelTarget.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,103 +9,101 @@ package de.javagl.jgltf.impl.v2; - /** - * The descriptor of the animated property. - * - * Auto-generated for animation.channel.target.schema.json - * + * The descriptor of the animated property. + *

+ * Auto-generated for animation.channel.target.schema.json + * */ public class AnimationChannelTarget - extends GlTFProperty -{ + extends GlTFProperty { /** - * The index of the node to animate. When undefined, the animated object - * **MAY** be defined by an extension. (optional) - * + * The index of the node to animate. When undefined, the animated object + * **MAY** be defined by an extension. (optional) + * */ private Integer node; /** - * The name of the node's TRS property to animate, or the `"weights"` of - * the Morph Targets it instantiates. For the `"translation"` property, - * the values that are provided by the sampler are the translation along - * the X, Y, and Z axes. For the `"rotation"` property, the values are a - * quaternion in the order (x, y, z, w), where w is the scalar. For the - * `"scale"` property, the values are the scaling factors along the X, Y, - * and Z axes. (required)
- * Valid values: [translation, rotation, scale, weights] - * + * The name of the node's TRS property to animate, or the `"weights"` of + * the Morph Targets it instantiates. For the `"translation"` property, + * the values that are provided by the sampler are the translation along + * the X, Y, and Z axes. For the `"rotation"` property, the values are a + * quaternion in the order (x, y, z, w), where w is the scalar. For the + * `"scale"` property, the values are the scaling factors along the X, Y, + * and Z axes. (required)
+ * Valid values: [translation, rotation, scale, weights] + * */ private String path; /** - * The index of the node to animate. When undefined, the animated object - * **MAY** be defined by an extension. (optional) - * + * The index of the node to animate. When undefined, the animated object + * **MAY** be defined by an extension. (optional) + * + * @return The node + * + */ + public Integer getNode() { + return this.node; + } + + /** + * The index of the node to animate. When undefined, the animated object + * **MAY** be defined by an extension. (optional) + * * @param node The node to set - * + * */ public void setNode(Integer node) { if (node == null) { this.node = node; - return ; + return; } this.node = node; } /** - * The index of the node to animate. When undefined, the animated object - * **MAY** be defined by an extension. (optional) - * - * @return The node - * + * The name of the node's TRS property to animate, or the `"weights"` of + * the Morph Targets it instantiates. For the `"translation"` property, + * the values that are provided by the sampler are the translation along + * the X, Y, and Z axes. For the `"rotation"` property, the values are a + * quaternion in the order (x, y, z, w), where w is the scalar. For the + * `"scale"` property, the values are the scaling factors along the X, Y, + * and Z axes. (required)
+ * Valid values: [translation, rotation, scale, weights] + * + * @return The path + * */ - public Integer getNode() { - return this.node; + public String getPath() { + return this.path; } /** - * The name of the node's TRS property to animate, or the `"weights"` of - * the Morph Targets it instantiates. For the `"translation"` property, - * the values that are provided by the sampler are the translation along - * the X, Y, and Z axes. For the `"rotation"` property, the values are a - * quaternion in the order (x, y, z, w), where w is the scalar. For the - * `"scale"` property, the values are the scaling factors along the X, Y, - * and Z axes. (required)
- * Valid values: [translation, rotation, scale, weights] - * + * The name of the node's TRS property to animate, or the `"weights"` of + * the Morph Targets it instantiates. For the `"translation"` property, + * the values that are provided by the sampler are the translation along + * the X, Y, and Z axes. For the `"rotation"` property, the values are a + * quaternion in the order (x, y, z, w), where w is the scalar. For the + * `"scale"` property, the values are the scaling factors along the X, Y, + * and Z axes. (required)
+ * Valid values: [translation, rotation, scale, weights] + * * @param path The path to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setPath(String path) { if (path == null) { - throw new NullPointerException((("Invalid value for path: "+ path)+", may not be null")); + throw new NullPointerException((("Invalid value for path: " + path) + ", may not be null")); } - if ((((!"translation".equals(path))&&(!"rotation".equals(path)))&&(!"scale".equals(path)))&&(!"weights".equals(path))) { - throw new IllegalArgumentException((("Invalid value for path: "+ path)+", valid: [translation, rotation, scale, weights]")); + if ((((!"translation".equals(path)) && (!"rotation".equals(path))) && (!"scale".equals(path))) && (!"weights".equals(path))) { + throw new IllegalArgumentException((("Invalid value for path: " + path) + ", valid: [translation, rotation, scale, weights]")); } this.path = path; } - /** - * The name of the node's TRS property to animate, or the `"weights"` of - * the Morph Targets it instantiates. For the `"translation"` property, - * the values that are provided by the sampler are the translation along - * the X, Y, and Z axes. For the `"rotation"` property, the values are a - * quaternion in the order (x, y, z, w), where w is the scalar. For the - * `"scale"` property, the values are the scaling factors along the X, Y, - * and Z axes. (required)
- * Valid values: [translation, rotation, scale, weights] - * - * @return The path - * - */ - public String getPath() { - return this.path; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AnimationSampler.java b/src/main/java/de/javagl/jgltf/impl/v2/AnimationSampler.java index 4b52b36..6e9c899 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AnimationSampler.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AnimationSampler.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,129 +9,127 @@ package de.javagl.jgltf.impl.v2; - /** - * An animation sampler combines timestamps with a sequence of output - * values and defines an interpolation algorithm. - * - * Auto-generated for animation.sampler.schema.json - * + * An animation sampler combines timestamps with a sequence of output + * values and defines an interpolation algorithm. + *

+ * Auto-generated for animation.sampler.schema.json + * */ public class AnimationSampler - extends GlTFProperty -{ + extends GlTFProperty { /** - * The index of an accessor containing keyframe timestamps. (required) - * + * The index of an accessor containing keyframe timestamps. (required) + * */ private Integer input; /** - * Interpolation algorithm. (optional)
- * Default: "LINEAR"
- * Valid values: [LINEAR, STEP, CUBICSPLINE] - * + * Interpolation algorithm. (optional)
+ * Default: "LINEAR"
+ * Valid values: [LINEAR, STEP, CUBICSPLINE] + * */ private String interpolation; /** - * The index of an accessor, containing keyframe output values. - * (required) - * + * The index of an accessor, containing keyframe output values. + * (required) + * */ private Integer output; /** - * The index of an accessor containing keyframe timestamps. (required) - * + * The index of an accessor containing keyframe timestamps. (required) + * + * @return The input + * + */ + public Integer getInput() { + return this.input; + } + + /** + * The index of an accessor containing keyframe timestamps. (required) + * * @param input The input to set * @throws NullPointerException If the given value is null - * + * */ public void setInput(Integer input) { if (input == null) { - throw new NullPointerException((("Invalid value for input: "+ input)+", may not be null")); + throw new NullPointerException((("Invalid value for input: " + input) + ", may not be null")); } this.input = input; } /** - * The index of an accessor containing keyframe timestamps. (required) - * - * @return The input - * + * Interpolation algorithm. (optional)
+ * Default: "LINEAR"
+ * Valid values: [LINEAR, STEP, CUBICSPLINE] + * + * @return The interpolation + * */ - public Integer getInput() { - return this.input; + public String getInterpolation() { + return this.interpolation; } /** - * Interpolation algorithm. (optional)
- * Default: "LINEAR"
- * Valid values: [LINEAR, STEP, CUBICSPLINE] - * + * Interpolation algorithm. (optional)
+ * Default: "LINEAR"
+ * Valid values: [LINEAR, STEP, CUBICSPLINE] + * * @param interpolation The interpolation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setInterpolation(String interpolation) { if (interpolation == null) { this.interpolation = interpolation; - return ; + return; } - if (((!"LINEAR".equals(interpolation))&&(!"STEP".equals(interpolation)))&&(!"CUBICSPLINE".equals(interpolation))) { - throw new IllegalArgumentException((("Invalid value for interpolation: "+ interpolation)+", valid: [LINEAR, STEP, CUBICSPLINE]")); + if (((!"LINEAR".equals(interpolation)) && (!"STEP".equals(interpolation))) && (!"CUBICSPLINE".equals(interpolation))) { + throw new IllegalArgumentException((("Invalid value for interpolation: " + interpolation) + ", valid: [LINEAR, STEP, CUBICSPLINE]")); } this.interpolation = interpolation; } /** - * Interpolation algorithm. (optional)
- * Default: "LINEAR"
- * Valid values: [LINEAR, STEP, CUBICSPLINE] - * - * @return The interpolation - * + * Returns the default value of the interpolation
+ * + * @return The default interpolation + * @see #getInterpolation + * */ - public String getInterpolation() { - return this.interpolation; + public String defaultInterpolation() { + return "LINEAR"; } /** - * Returns the default value of the interpolation
- * @see #getInterpolation - * - * @return The default interpolation - * + * The index of an accessor, containing keyframe output values. + * (required) + * + * @return The output + * */ - public String defaultInterpolation() { - return "LINEAR"; + public Integer getOutput() { + return this.output; } /** - * The index of an accessor, containing keyframe output values. - * (required) - * + * The index of an accessor, containing keyframe output values. + * (required) + * * @param output The output to set * @throws NullPointerException If the given value is null - * + * */ public void setOutput(Integer output) { if (output == null) { - throw new NullPointerException((("Invalid value for output: "+ output)+", may not be null")); + throw new NullPointerException((("Invalid value for output: " + output) + ", may not be null")); } this.output = output; } - /** - * The index of an accessor, containing keyframe output values. - * (required) - * - * @return The output - * - */ - public Integer getOutput() { - return this.output; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Asset.java b/src/main/java/de/javagl/jgltf/impl/v2/Asset.java index 3b067f5..d4434a3 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Asset.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Asset.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,144 +9,142 @@ package de.javagl.jgltf.impl.v2; - /** - * Metadata about the glTF asset. - * - * Auto-generated for asset.schema.json - * + * Metadata about the glTF asset. + *

+ * Auto-generated for asset.schema.json + * */ public class Asset - extends GlTFProperty -{ + extends GlTFProperty { /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * */ private String copyright; /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * */ private String generator; /** - * The glTF version in the form of `<major>.<minor>` that - * this asset targets. (required) - * + * The glTF version in the form of `<major>.<minor>` that + * this asset targets. (required) + * */ private String version; /** - * The minimum glTF version in the form of `<major>.<minor>` - * that this asset targets. This property **MUST NOT** be greater than - * the asset version. (optional) - * + * The minimum glTF version in the form of `<major>.<minor>` + * that this asset targets. This property **MUST NOT** be greater than + * the asset version. (optional) + * */ private String minVersion; /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * + * @return The copyright + * + */ + public String getCopyright() { + return this.copyright; + } + + /** + * A copyright message suitable for display to credit the content + * creator. (optional) + * * @param copyright The copyright to set - * + * */ public void setCopyright(String copyright) { if (copyright == null) { this.copyright = copyright; - return ; + return; } this.copyright = copyright; } /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * - * @return The copyright - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * + * @return The generator + * */ - public String getCopyright() { - return this.copyright; + public String getGenerator() { + return this.generator; } /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * * @param generator The generator to set - * + * */ public void setGenerator(String generator) { if (generator == null) { this.generator = generator; - return ; + return; } this.generator = generator; } /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * - * @return The generator - * + * The glTF version in the form of `<major>.<minor>` that + * this asset targets. (required) + * + * @return The version + * */ - public String getGenerator() { - return this.generator; + public String getVersion() { + return this.version; } /** - * The glTF version in the form of `<major>.<minor>` that - * this asset targets. (required) - * + * The glTF version in the form of `<major>.<minor>` that + * this asset targets. (required) + * * @param version The version to set * @throws NullPointerException If the given value is null - * + * */ public void setVersion(String version) { if (version == null) { - throw new NullPointerException((("Invalid value for version: "+ version)+", may not be null")); + throw new NullPointerException((("Invalid value for version: " + version) + ", may not be null")); } this.version = version; } /** - * The glTF version in the form of `<major>.<minor>` that - * this asset targets. (required) - * - * @return The version - * + * The minimum glTF version in the form of `<major>.<minor>` + * that this asset targets. This property **MUST NOT** be greater than + * the asset version. (optional) + * + * @return The minVersion + * */ - public String getVersion() { - return this.version; + public String getMinVersion() { + return this.minVersion; } /** - * The minimum glTF version in the form of `<major>.<minor>` - * that this asset targets. This property **MUST NOT** be greater than - * the asset version. (optional) - * + * The minimum glTF version in the form of `<major>.<minor>` + * that this asset targets. This property **MUST NOT** be greater than + * the asset version. (optional) + * * @param minVersion The minVersion to set - * + * */ public void setMinVersion(String minVersion) { if (minVersion == null) { this.minVersion = minVersion; - return ; + return; } this.minVersion = minVersion; } - /** - * The minimum glTF version in the form of `<major>.<minor>` - * that this asset targets. This property **MUST NOT** be greater than - * the asset version. (optional) - * - * @return The minVersion - * - */ - public String getMinVersion() { - return this.minVersion; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Buffer.java b/src/main/java/de/javagl/jgltf/impl/v2/Buffer.java index 76af0d3..5e5635a 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Buffer.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Buffer.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,82 +9,80 @@ package de.javagl.jgltf.impl.v2; - /** - * A buffer points to binary geometry, animation, or skins. - * - * Auto-generated for buffer.schema.json - * + * A buffer points to binary geometry, animation, or skins. + *

+ * Auto-generated for buffer.schema.json + * */ public class Buffer - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The URI (or IRI) of the buffer. (optional) - * + * The URI (or IRI) of the buffer. (optional) + * */ private String uri; /** - * The length of the buffer in bytes. (required)
- * Minimum: 1 (inclusive) - * + * The length of the buffer in bytes. (required)
+ * Minimum: 1 (inclusive) + * */ private Integer byteLength; /** - * The URI (or IRI) of the buffer. (optional) - * + * The URI (or IRI) of the buffer. (optional) + * + * @return The uri + * + */ + public String getUri() { + return this.uri; + } + + /** + * The URI (or IRI) of the buffer. (optional) + * * @param uri The uri to set - * + * */ public void setUri(String uri) { if (uri == null) { this.uri = uri; - return ; + return; } this.uri = uri; } /** - * The URI (or IRI) of the buffer. (optional) - * - * @return The uri - * + * The length of the buffer in bytes. (required)
+ * Minimum: 1 (inclusive) + * + * @return The byteLength + * */ - public String getUri() { - return this.uri; + public Integer getByteLength() { + return this.byteLength; } /** - * The length of the buffer in bytes. (required)
- * Minimum: 1 (inclusive) - * + * The length of the buffer in bytes. (required)
+ * Minimum: 1 (inclusive) + * * @param byteLength The byteLength to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteLength(Integer byteLength) { if (byteLength == null) { - throw new NullPointerException((("Invalid value for byteLength: "+ byteLength)+", may not be null")); + throw new NullPointerException((("Invalid value for byteLength: " + byteLength) + ", may not be null")); } - if (byteLength< 1) { + if (byteLength < 1) { throw new IllegalArgumentException("byteLength < 1"); } this.byteLength = byteLength; } - /** - * The length of the buffer in bytes. (required)
- * Minimum: 1 (inclusive) - * - * @return The byteLength - * - */ - public Integer getByteLength() { - return this.byteLength; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/BufferView.java b/src/main/java/de/javagl/jgltf/impl/v2/BufferView.java index 9b0b25c..059181f 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/BufferView.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/BufferView.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,216 +9,214 @@ package de.javagl.jgltf.impl.v2; - /** - * A view into a buffer generally representing a subset of the buffer. - * - * Auto-generated for bufferView.schema.json - * + * A view into a buffer generally representing a subset of the buffer. + *

+ * Auto-generated for bufferView.schema.json + * */ public class BufferView - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The index of the buffer. (required) - * + * The index of the buffer. (required) + * */ private Integer buffer; /** - * The offset into the buffer in bytes. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The offset into the buffer in bytes. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The length of the bufferView in bytes. (required)
- * Minimum: 1 (inclusive) - * + * The length of the bufferView in bytes. (required)
+ * Minimum: 1 (inclusive) + * */ private Integer byteLength; /** - * The stride, in bytes. (optional)
- * Minimum: 4 (inclusive)
- * Maximum: 252 (inclusive) - * + * The stride, in bytes. (optional)
+ * Minimum: 4 (inclusive)
+ * Maximum: 252 (inclusive) + * */ private Integer byteStride; /** - * The hint representing the intended GPU buffer type to use with this - * buffer view. (optional)
- * Valid values: [34962, 34963] - * + * The hint representing the intended GPU buffer type to use with this + * buffer view. (optional)
+ * Valid values: [34962, 34963] + * */ private Integer target; /** - * The index of the buffer. (required) - * + * The index of the buffer. (required) + * + * @return The buffer + * + */ + public Integer getBuffer() { + return this.buffer; + } + + /** + * The index of the buffer. (required) + * * @param buffer The buffer to set * @throws NullPointerException If the given value is null - * + * */ public void setBuffer(Integer buffer) { if (buffer == null) { - throw new NullPointerException((("Invalid value for buffer: "+ buffer)+", may not be null")); + throw new NullPointerException((("Invalid value for buffer: " + buffer) + ", may not be null")); } this.buffer = buffer; } /** - * The index of the buffer. (required) - * - * @return The buffer - * + * The offset into the buffer in bytes. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public Integer getBuffer() { - return this.buffer; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The offset into the buffer in bytes. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The offset into the buffer in bytes. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { this.byteOffset = byteOffset; - return ; + return; } - if (byteOffset< 0) { + if (byteOffset < 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * The offset into the buffer in bytes. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * Returns the default value of the byteOffset
+ * + * @return The default byteOffset + * @see #getByteOffset + * */ - public Integer getByteOffset() { - return this.byteOffset; + public Integer defaultByteOffset() { + return 0; } /** - * Returns the default value of the byteOffset
- * @see #getByteOffset - * - * @return The default byteOffset - * + * The length of the bufferView in bytes. (required)
+ * Minimum: 1 (inclusive) + * + * @return The byteLength + * */ - public Integer defaultByteOffset() { - return 0; + public Integer getByteLength() { + return this.byteLength; } /** - * The length of the bufferView in bytes. (required)
- * Minimum: 1 (inclusive) - * + * The length of the bufferView in bytes. (required)
+ * Minimum: 1 (inclusive) + * * @param byteLength The byteLength to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteLength(Integer byteLength) { if (byteLength == null) { - throw new NullPointerException((("Invalid value for byteLength: "+ byteLength)+", may not be null")); + throw new NullPointerException((("Invalid value for byteLength: " + byteLength) + ", may not be null")); } - if (byteLength< 1) { + if (byteLength < 1) { throw new IllegalArgumentException("byteLength < 1"); } this.byteLength = byteLength; } /** - * The length of the bufferView in bytes. (required)
- * Minimum: 1 (inclusive) - * - * @return The byteLength - * + * The stride, in bytes. (optional)
+ * Minimum: 4 (inclusive)
+ * Maximum: 252 (inclusive) + * + * @return The byteStride + * */ - public Integer getByteLength() { - return this.byteLength; + public Integer getByteStride() { + return this.byteStride; } /** - * The stride, in bytes. (optional)
- * Minimum: 4 (inclusive)
- * Maximum: 252 (inclusive) - * + * The stride, in bytes. (optional)
+ * Minimum: 4 (inclusive)
+ * Maximum: 252 (inclusive) + * * @param byteStride The byteStride to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteStride(Integer byteStride) { if (byteStride == null) { this.byteStride = byteStride; - return ; + return; } if (byteStride > 252) { throw new IllegalArgumentException("byteStride > 252"); } - if (byteStride< 4) { + if (byteStride < 4) { throw new IllegalArgumentException("byteStride < 4"); } this.byteStride = byteStride; } /** - * The stride, in bytes. (optional)
- * Minimum: 4 (inclusive)
- * Maximum: 252 (inclusive) - * - * @return The byteStride - * + * The hint representing the intended GPU buffer type to use with this + * buffer view. (optional)
+ * Valid values: [34962, 34963] + * + * @return The target + * */ - public Integer getByteStride() { - return this.byteStride; + public Integer getTarget() { + return this.target; } /** - * The hint representing the intended GPU buffer type to use with this - * buffer view. (optional)
- * Valid values: [34962, 34963] - * + * The hint representing the intended GPU buffer type to use with this + * buffer view. (optional)
+ * Valid values: [34962, 34963] + * * @param target The target to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTarget(Integer target) { if (target == null) { this.target = target; - return ; + return; } - if ((target!= 34962)&&(target!= 34963)) { - throw new IllegalArgumentException((("Invalid value for target: "+ target)+", valid: [34962, 34963]")); + if ((target != 34962) && (target != 34963)) { + throw new IllegalArgumentException((("Invalid value for target: " + target) + ", valid: [34962, 34963]")); } this.target = target; } - /** - * The hint representing the intended GPU buffer type to use with this - * buffer view. (optional)
- * Valid values: [34962, 34963] - * - * @return The target - * - */ - public Integer getTarget() { - return this.target; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Camera.java b/src/main/java/de/javagl/jgltf/impl/v2/Camera.java index 65473d8..bfcd256 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Camera.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Camera.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,127 +9,125 @@ package de.javagl.jgltf.impl.v2; - /** - * A camera's projection. A node **MAY** reference a camera to apply a - * transform to place the camera in the scene. - * - * Auto-generated for camera.schema.json - * + * A camera's projection. A node **MAY** reference a camera to apply a + * transform to place the camera in the scene. + *

+ * Auto-generated for camera.schema.json + * */ public class Camera - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. This property **MUST NOT** be defined when - * `perspective` is defined. (optional) - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. This property **MUST NOT** be defined when + * `perspective` is defined. (optional) + * */ private CameraOrthographic orthographic; /** - * A perspective camera containing properties to create a perspective - * projection matrix. This property **MUST NOT** be defined when - * `orthographic` is defined. (optional) - * + * A perspective camera containing properties to create a perspective + * projection matrix. This property **MUST NOT** be defined when + * `orthographic` is defined. (optional) + * */ private CameraPerspective perspective; /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
- * Valid values: [perspective, orthographic] - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
+ * Valid values: [perspective, orthographic] + * */ private String type; /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. This property **MUST NOT** be defined when - * `perspective` is defined. (optional) - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. This property **MUST NOT** be defined when + * `perspective` is defined. (optional) + * + * @return The orthographic + * + */ + public CameraOrthographic getOrthographic() { + return this.orthographic; + } + + /** + * An orthographic camera containing properties to create an orthographic + * projection matrix. This property **MUST NOT** be defined when + * `perspective` is defined. (optional) + * * @param orthographic The orthographic to set - * + * */ public void setOrthographic(CameraOrthographic orthographic) { if (orthographic == null) { this.orthographic = orthographic; - return ; + return; } this.orthographic = orthographic; } /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. This property **MUST NOT** be defined when - * `perspective` is defined. (optional) - * - * @return The orthographic - * + * A perspective camera containing properties to create a perspective + * projection matrix. This property **MUST NOT** be defined when + * `orthographic` is defined. (optional) + * + * @return The perspective + * */ - public CameraOrthographic getOrthographic() { - return this.orthographic; + public CameraPerspective getPerspective() { + return this.perspective; } /** - * A perspective camera containing properties to create a perspective - * projection matrix. This property **MUST NOT** be defined when - * `orthographic` is defined. (optional) - * + * A perspective camera containing properties to create a perspective + * projection matrix. This property **MUST NOT** be defined when + * `orthographic` is defined. (optional) + * * @param perspective The perspective to set - * + * */ public void setPerspective(CameraPerspective perspective) { if (perspective == null) { this.perspective = perspective; - return ; + return; } this.perspective = perspective; } /** - * A perspective camera containing properties to create a perspective - * projection matrix. This property **MUST NOT** be defined when - * `orthographic` is defined. (optional) - * - * @return The perspective - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
+ * Valid values: [perspective, orthographic] + * + * @return The type + * */ - public CameraPerspective getPerspective() { - return this.perspective; + public String getType() { + return this.type; } /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
- * Valid values: [perspective, orthographic] - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
+ * Valid values: [perspective, orthographic] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); + throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); } - if ((!"perspective".equals(type))&&(!"orthographic".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [perspective, orthographic]")); + if ((!"perspective".equals(type)) && (!"orthographic".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [perspective, orthographic]")); } this.type = type; } - /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
- * Valid values: [perspective, orthographic] - * - * @return The type - * - */ - public String getType() { - return this.type; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/CameraOrthographic.java b/src/main/java/de/javagl/jgltf/impl/v2/CameraOrthographic.java index b4c3225..be71da7 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/CameraOrthographic.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/CameraOrthographic.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,167 +9,165 @@ package de.javagl.jgltf.impl.v2; - /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. - * - * Auto-generated for camera.orthographic.schema.json - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. + *

+ * Auto-generated for camera.orthographic.schema.json + * */ public class CameraOrthographic - extends GlTFProperty -{ + extends GlTFProperty { /** - * The floating-point horizontal magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * + * The floating-point horizontal magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * */ private Float xmag; /** - * The floating-point vertical magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * + * The floating-point vertical magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * */ private Float ymag; /** - * The floating-point distance to the far clipping plane. This value - * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than - * `znear`. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. This value + * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than + * `znear`. (required)
+ * Minimum: 0.0 (exclusive) + * */ private Float zfar; /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (inclusive) + * */ private Float znear; /** - * The floating-point horizontal magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * + * The floating-point horizontal magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * + * @return The xmag + * + */ + public Float getXmag() { + return this.xmag; + } + + /** + * The floating-point horizontal magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * * @param xmag The xmag to set * @throws NullPointerException If the given value is null - * + * */ public void setXmag(Float xmag) { if (xmag == null) { - throw new NullPointerException((("Invalid value for xmag: "+ xmag)+", may not be null")); + throw new NullPointerException((("Invalid value for xmag: " + xmag) + ", may not be null")); } this.xmag = xmag; } /** - * The floating-point horizontal magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * - * @return The xmag - * + * The floating-point vertical magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * + * @return The ymag + * */ - public Float getXmag() { - return this.xmag; + public Float getYmag() { + return this.ymag; } /** - * The floating-point vertical magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * + * The floating-point vertical magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * * @param ymag The ymag to set * @throws NullPointerException If the given value is null - * + * */ public void setYmag(Float ymag) { if (ymag == null) { - throw new NullPointerException((("Invalid value for ymag: "+ ymag)+", may not be null")); + throw new NullPointerException((("Invalid value for ymag: " + ymag) + ", may not be null")); } this.ymag = ymag; } /** - * The floating-point vertical magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * - * @return The ymag - * + * The floating-point distance to the far clipping plane. This value + * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than + * `znear`. (required)
+ * Minimum: 0.0 (exclusive) + * + * @return The zfar + * */ - public Float getYmag() { - return this.ymag; + public Float getZfar() { + return this.zfar; } /** - * The floating-point distance to the far clipping plane. This value - * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than - * `znear`. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. This value + * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than + * `znear`. (required)
+ * Minimum: 0.0 (exclusive) + * * @param zfar The zfar to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZfar(Float zfar) { if (zfar == null) { - throw new NullPointerException((("Invalid value for zfar: "+ zfar)+", may not be null")); + throw new NullPointerException((("Invalid value for zfar: " + zfar) + ", may not be null")); } - if (zfar<= 0.0D) { + if (zfar <= 0.0D) { throw new IllegalArgumentException("zfar <= 0.0"); } this.zfar = zfar; } /** - * The floating-point distance to the far clipping plane. This value - * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than - * `znear`. (required)
- * Minimum: 0.0 (exclusive) - * - * @return The zfar - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (inclusive) + * + * @return The znear + * */ - public Float getZfar() { - return this.zfar; + public Float getZnear() { + return this.znear; } /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (inclusive) + * * @param znear The znear to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZnear(Float znear) { if (znear == null) { - throw new NullPointerException((("Invalid value for znear: "+ znear)+", may not be null")); + throw new NullPointerException((("Invalid value for znear: " + znear) + ", may not be null")); } - if (znear< 0.0D) { + if (znear < 0.0D) { throw new IllegalArgumentException("znear < 0.0"); } this.znear = znear; } - /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (inclusive) - * - * @return The znear - * - */ - public Float getZnear() { - return this.znear; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/CameraPerspective.java b/src/main/java/de/javagl/jgltf/impl/v2/CameraPerspective.java index 01434ca..57cb721 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/CameraPerspective.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/CameraPerspective.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,168 +9,166 @@ package de.javagl.jgltf.impl.v2; - /** - * A perspective camera containing properties to create a perspective - * projection matrix. - * - * Auto-generated for camera.perspective.schema.json - * + * A perspective camera containing properties to create a perspective + * projection matrix. + *

+ * Auto-generated for camera.perspective.schema.json + * */ public class CameraPerspective - extends GlTFProperty -{ + extends GlTFProperty { /** - * The floating-point aspect ratio of the field of view. (optional)
- * Minimum: 0.0 (exclusive) - * + * The floating-point aspect ratio of the field of view. (optional)
+ * Minimum: 0.0 (exclusive) + * */ private Float aspectRatio; /** - * The floating-point vertical field of view in radians. This value - * **SHOULD** be less than π. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point vertical field of view in radians. This value + * **SHOULD** be less than π. (required)
+ * Minimum: 0.0 (exclusive) + * */ private Float yfov; /** - * The floating-point distance to the far clipping plane. (optional)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. (optional)
+ * Minimum: 0.0 (exclusive) + * */ private Float zfar; /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (exclusive) + * */ private Float znear; /** - * The floating-point aspect ratio of the field of view. (optional)
- * Minimum: 0.0 (exclusive) - * + * The floating-point aspect ratio of the field of view. (optional)
+ * Minimum: 0.0 (exclusive) + * + * @return The aspectRatio + * + */ + public Float getAspectRatio() { + return this.aspectRatio; + } + + /** + * The floating-point aspect ratio of the field of view. (optional)
+ * Minimum: 0.0 (exclusive) + * * @param aspectRatio The aspectRatio to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAspectRatio(Float aspectRatio) { if (aspectRatio == null) { this.aspectRatio = aspectRatio; - return ; + return; } - if (aspectRatio<= 0.0D) { + if (aspectRatio <= 0.0D) { throw new IllegalArgumentException("aspectRatio <= 0.0"); } this.aspectRatio = aspectRatio; } /** - * The floating-point aspect ratio of the field of view. (optional)
- * Minimum: 0.0 (exclusive) - * - * @return The aspectRatio - * + * The floating-point vertical field of view in radians. This value + * **SHOULD** be less than π. (required)
+ * Minimum: 0.0 (exclusive) + * + * @return The yfov + * */ - public Float getAspectRatio() { - return this.aspectRatio; + public Float getYfov() { + return this.yfov; } /** - * The floating-point vertical field of view in radians. This value - * **SHOULD** be less than π. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point vertical field of view in radians. This value + * **SHOULD** be less than π. (required)
+ * Minimum: 0.0 (exclusive) + * * @param yfov The yfov to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setYfov(Float yfov) { if (yfov == null) { - throw new NullPointerException((("Invalid value for yfov: "+ yfov)+", may not be null")); + throw new NullPointerException((("Invalid value for yfov: " + yfov) + ", may not be null")); } - if (yfov<= 0.0D) { + if (yfov <= 0.0D) { throw new IllegalArgumentException("yfov <= 0.0"); } this.yfov = yfov; } /** - * The floating-point vertical field of view in radians. This value - * **SHOULD** be less than π. (required)
- * Minimum: 0.0 (exclusive) - * - * @return The yfov - * + * The floating-point distance to the far clipping plane. (optional)
+ * Minimum: 0.0 (exclusive) + * + * @return The zfar + * */ - public Float getYfov() { - return this.yfov; + public Float getZfar() { + return this.zfar; } /** - * The floating-point distance to the far clipping plane. (optional)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. (optional)
+ * Minimum: 0.0 (exclusive) + * * @param zfar The zfar to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZfar(Float zfar) { if (zfar == null) { this.zfar = zfar; - return ; + return; } - if (zfar<= 0.0D) { + if (zfar <= 0.0D) { throw new IllegalArgumentException("zfar <= 0.0"); } this.zfar = zfar; } /** - * The floating-point distance to the far clipping plane. (optional)
- * Minimum: 0.0 (exclusive) - * - * @return The zfar - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (exclusive) + * + * @return The znear + * */ - public Float getZfar() { - return this.zfar; + public Float getZnear() { + return this.znear; } /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the near clipping plane. (required)
+ * Minimum: 0.0 (exclusive) + * * @param znear The znear to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZnear(Float znear) { if (znear == null) { - throw new NullPointerException((("Invalid value for znear: "+ znear)+", may not be null")); + throw new NullPointerException((("Invalid value for znear: " + znear) + ", may not be null")); } - if (znear<= 0.0D) { + if (znear <= 0.0D) { throw new IllegalArgumentException("znear <= 0.0"); } this.znear = znear; } - /** - * The floating-point distance to the near clipping plane. (required)
- * Minimum: 0.0 (exclusive) - * - * @return The znear - * - */ - public Float getZnear() { - return this.znear; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/GlTF.java b/src/main/java/de/javagl/jgltf/impl/v2/GlTF.java index 9cf71fc..879b1b8 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/GlTF.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/GlTF.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,206 +13,205 @@ /** - * The root object for a glTF asset. - * - * Auto-generated for glTF.schema.json - * + * The root object for a glTF asset. + *

+ * Auto-generated for glTF.schema.json + * */ public class GlTF - extends GlTFProperty -{ + extends GlTFProperty { /** - * Names of glTF extensions used in this asset. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * Names of glTF extensions used in this asset. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List extensionsUsed; /** - * Names of glTF extensions required to properly load this asset. - * (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * Names of glTF extensions required to properly load this asset. + * (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List extensionsRequired; /** - * An array of accessors. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A typed view into a buffer view that contains raw binary - * data. (optional) - * + * An array of accessors. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A typed view into a buffer view that contains raw binary + * data. (optional) + * */ private List accessors; /** - * An array of keyframe animations. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A keyframe animation. (optional) - * + * An array of keyframe animations. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A keyframe animation. (optional) + * */ private List animations; /** - * Metadata about the glTF asset. (required) - * + * Metadata about the glTF asset. (required) + * */ private Asset asset; /** - * An array of buffers. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A buffer points to binary geometry, animation, or skins. - * (optional) - * + * An array of buffers. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A buffer points to binary geometry, animation, or skins. + * (optional) + * */ private List buffers; /** - * An array of bufferViews. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A view into a buffer generally representing a subset of - * the buffer. (optional) - * + * An array of bufferViews. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A view into a buffer generally representing a subset of + * the buffer. (optional) + * */ private List bufferViews; /** - * An array of cameras. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A camera's projection. A node **MAY** reference a camera - * to apply a transform to place the camera in the scene. (optional) - * + * An array of cameras. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A camera's projection. A node **MAY** reference a camera + * to apply a transform to place the camera in the scene. (optional) + * */ private List cameras; /** - * An array of images. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   Image data used to create a texture. Image **MAY** be - * referenced by an URI (or IRI) or a buffer view index. (optional) - * + * An array of images. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Image data used to create a texture. Image **MAY** be + * referenced by an URI (or IRI) or a buffer view index. (optional) + * */ private List images; /** - * An array of materials. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The material appearance of a primitive. (optional) - * + * An array of materials. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The material appearance of a primitive. (optional) + * */ private List materials; /** - * An array of meshes. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A set of primitives to be rendered. Its global transform - * is defined by a node that references it. (optional) - * + * An array of meshes. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A set of primitives to be rendered. Its global transform + * is defined by a node that references it. (optional) + * */ private List meshes; /** - * An array of nodes. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A node in the node hierarchy. When the node contains - * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and - * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any - * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS - * properties are converted to matrices and postmultiplied in the `T * R - * * S` order to compose the transformation matrix; first the scale is - * applied to the vertices, then the rotation, and then the translation. - * If none are provided, the transform is the identity. When a node is - * targeted for animation (referenced by an animation.channel.target), - * `matrix` **MUST NOT** be present. (optional) - * + * An array of nodes. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A node in the node hierarchy. When the node contains + * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and + * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any + * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS + * properties are converted to matrices and postmultiplied in the `T * R + * * S` order to compose the transformation matrix; first the scale is + * applied to the vertices, then the rotation, and then the translation. + * If none are provided, the transform is the identity. When a node is + * targeted for animation (referenced by an animation.channel.target), + * `matrix` **MUST NOT** be present. (optional) + * */ private List nodes; /** - * An array of samplers. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   Texture sampler properties for filtering and wrapping - * modes. (optional) - * + * An array of samplers. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Texture sampler properties for filtering and wrapping + * modes. (optional) + * */ private List samplers; /** - * The index of the default scene. (optional) - * + * The index of the default scene. (optional) + * */ private Integer scene; /** - * An array of scenes. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The root nodes of a scene. (optional) - * + * An array of scenes. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The root nodes of a scene. (optional) + * */ private List scenes; /** - * An array of skins. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   Joints and matrices defining a skin. (optional) - * + * An array of skins. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Joints and matrices defining a skin. (optional) + * */ private List skins; /** - * An array of textures. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A texture and its sampler. (optional) - * + * An array of textures. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A texture and its sampler. (optional) + * */ private List textures; /** - * Names of glTF extensions used in this asset. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * Names of glTF extensions used in this asset. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The extensionsUsed + * + */ + public List getExtensionsUsed() { + return this.extensionsUsed; + } + + /** + * Names of glTF extensions used in this asset. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * * @param extensionsUsed The extensionsUsed to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setExtensionsUsed(List extensionsUsed) { if (extensionsUsed == null) { this.extensionsUsed = extensionsUsed; - return ; + return; } - if (extensionsUsed.size()< 1) { + if (extensionsUsed.size() < 1) { throw new IllegalArgumentException("Number of extensionsUsed elements is < 1"); } this.extensionsUsed = extensionsUsed; } /** - * Names of glTF extensions used in this asset. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * - * @return The extensionsUsed - * - */ - public List getExtensionsUsed() { - return this.extensionsUsed; - } - - /** - * Add the given extensionsUsed. The extensionsUsed of this instance will - * be replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given extensionsUsed. The extensionsUsed of this instance will + * be replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addExtensionsUsed(String element) { if (element == null) { @@ -220,7 +219,7 @@ public void addExtensionsUsed(String element) { } List oldList = this.extensionsUsed; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -228,15 +227,15 @@ public void addExtensionsUsed(String element) { } /** - * Remove the given extensionsUsed. The extensionsUsed of this instance - * will be replaced with a list that contains all previous elements, - * except for the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given extensionsUsed. The extensionsUsed of this instance + * will be replaced with a list that contains all previous elements, + * except for the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeExtensionsUsed(String element) { if (element == null) { @@ -244,7 +243,7 @@ public void removeExtensionsUsed(String element) { } List oldList = this.extensionsUsed; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -256,50 +255,50 @@ public void removeExtensionsUsed(String element) { } /** - * Names of glTF extensions required to properly load this asset. - * (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * Names of glTF extensions required to properly load this asset. + * (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The extensionsRequired + * + */ + public List getExtensionsRequired() { + return this.extensionsRequired; + } + + /** + * Names of glTF extensions required to properly load this asset. + * (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * * @param extensionsRequired The extensionsRequired to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setExtensionsRequired(List extensionsRequired) { if (extensionsRequired == null) { this.extensionsRequired = extensionsRequired; - return ; + return; } - if (extensionsRequired.size()< 1) { + if (extensionsRequired.size() < 1) { throw new IllegalArgumentException("Number of extensionsRequired elements is < 1"); } this.extensionsRequired = extensionsRequired; } /** - * Names of glTF extensions required to properly load this asset. - * (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * - * @return The extensionsRequired - * - */ - public List getExtensionsRequired() { - return this.extensionsRequired; - } - - /** - * Add the given extensionsRequired. The extensionsRequired of this - * instance will be replaced with a list that contains all previous - * elements, and additionally the new element. - * + * Add the given extensionsRequired. The extensionsRequired of this + * instance will be replaced with a list that contains all previous + * elements, and additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addExtensionsRequired(String element) { if (element == null) { @@ -307,7 +306,7 @@ public void addExtensionsRequired(String element) { } List oldList = this.extensionsRequired; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -315,15 +314,15 @@ public void addExtensionsRequired(String element) { } /** - * Remove the given extensionsRequired. The extensionsRequired of this - * instance will be replaced with a list that contains all previous - * elements, except for the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given extensionsRequired. The extensionsRequired of this + * instance will be replaced with a list that contains all previous + * elements, except for the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeExtensionsRequired(String element) { if (element == null) { @@ -331,7 +330,7 @@ public void removeExtensionsRequired(String element) { } List oldList = this.extensionsRequired; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -343,50 +342,50 @@ public void removeExtensionsRequired(String element) { } /** - * An array of accessors. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A typed view into a buffer view that contains raw binary - * data. (optional) - * + * An array of accessors. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A typed view into a buffer view that contains raw binary + * data. (optional) + * + * @return The accessors + * + */ + public List getAccessors() { + return this.accessors; + } + + /** + * An array of accessors. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A typed view into a buffer view that contains raw binary + * data. (optional) + * * @param accessors The accessors to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAccessors(List accessors) { if (accessors == null) { this.accessors = accessors; - return ; + return; } - if (accessors.size()< 1) { + if (accessors.size() < 1) { throw new IllegalArgumentException("Number of accessors elements is < 1"); } this.accessors = accessors; } /** - * An array of accessors. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A typed view into a buffer view that contains raw binary - * data. (optional) - * - * @return The accessors - * - */ - public List getAccessors() { - return this.accessors; - } - - /** - * Add the given accessors. The accessors of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given accessors. The accessors of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addAccessors(Accessor element) { if (element == null) { @@ -394,7 +393,7 @@ public void addAccessors(Accessor element) { } List oldList = this.accessors; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -402,15 +401,15 @@ public void addAccessors(Accessor element) { } /** - * Remove the given accessors. The accessors of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given accessors. The accessors of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeAccessors(Accessor element) { if (element == null) { @@ -418,7 +417,7 @@ public void removeAccessors(Accessor element) { } List oldList = this.accessors; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -430,48 +429,48 @@ public void removeAccessors(Accessor element) { } /** - * An array of keyframe animations. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A keyframe animation. (optional) - * + * An array of keyframe animations. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A keyframe animation. (optional) + * + * @return The animations + * + */ + public List getAnimations() { + return this.animations; + } + + /** + * An array of keyframe animations. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A keyframe animation. (optional) + * * @param animations The animations to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAnimations(List animations) { if (animations == null) { this.animations = animations; - return ; + return; } - if (animations.size()< 1) { + if (animations.size() < 1) { throw new IllegalArgumentException("Number of animations elements is < 1"); } this.animations = animations; } /** - * An array of keyframe animations. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A keyframe animation. (optional) - * - * @return The animations - * - */ - public List getAnimations() { - return this.animations; - } - - /** - * Add the given animations. The animations of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given animations. The animations of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addAnimations(Animation element) { if (element == null) { @@ -479,7 +478,7 @@ public void addAnimations(Animation element) { } List oldList = this.animations; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -487,15 +486,15 @@ public void addAnimations(Animation element) { } /** - * Remove the given animations. The animations of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given animations. The animations of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeAnimations(Animation element) { if (element == null) { @@ -503,7 +502,7 @@ public void removeAnimations(Animation element) { } List oldList = this.animations; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -515,74 +514,74 @@ public void removeAnimations(Animation element) { } /** - * Metadata about the glTF asset. (required) - * + * Metadata about the glTF asset. (required) + * + * @return The asset + * + */ + public Asset getAsset() { + return this.asset; + } + + /** + * Metadata about the glTF asset. (required) + * * @param asset The asset to set * @throws NullPointerException If the given value is null - * + * */ public void setAsset(Asset asset) { if (asset == null) { - throw new NullPointerException((("Invalid value for asset: "+ asset)+", may not be null")); + throw new NullPointerException((("Invalid value for asset: " + asset) + ", may not be null")); } this.asset = asset; } /** - * Metadata about the glTF asset. (required) - * - * @return The asset - * + * An array of buffers. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A buffer points to binary geometry, animation, or skins. + * (optional) + * + * @return The buffers + * */ - public Asset getAsset() { - return this.asset; + public List getBuffers() { + return this.buffers; } /** - * An array of buffers. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A buffer points to binary geometry, animation, or skins. - * (optional) - * + * An array of buffers. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A buffer points to binary geometry, animation, or skins. + * (optional) + * * @param buffers The buffers to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBuffers(List buffers) { if (buffers == null) { this.buffers = buffers; - return ; + return; } - if (buffers.size()< 1) { + if (buffers.size() < 1) { throw new IllegalArgumentException("Number of buffers elements is < 1"); } this.buffers = buffers; } /** - * An array of buffers. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A buffer points to binary geometry, animation, or skins. - * (optional) - * - * @return The buffers - * - */ - public List getBuffers() { - return this.buffers; - } - - /** - * Add the given buffers. The buffers of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given buffers. The buffers of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addBuffers(Buffer element) { if (element == null) { @@ -590,7 +589,7 @@ public void addBuffers(Buffer element) { } List oldList = this.buffers; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -598,15 +597,15 @@ public void addBuffers(Buffer element) { } /** - * Remove the given buffers. The buffers of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given buffers. The buffers of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeBuffers(Buffer element) { if (element == null) { @@ -614,7 +613,7 @@ public void removeBuffers(Buffer element) { } List oldList = this.buffers; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -626,50 +625,50 @@ public void removeBuffers(Buffer element) { } /** - * An array of bufferViews. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A view into a buffer generally representing a subset of - * the buffer. (optional) - * + * An array of bufferViews. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A view into a buffer generally representing a subset of + * the buffer. (optional) + * + * @return The bufferViews + * + */ + public List getBufferViews() { + return this.bufferViews; + } + + /** + * An array of bufferViews. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A view into a buffer generally representing a subset of + * the buffer. (optional) + * * @param bufferViews The bufferViews to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBufferViews(List bufferViews) { if (bufferViews == null) { this.bufferViews = bufferViews; - return ; + return; } - if (bufferViews.size()< 1) { + if (bufferViews.size() < 1) { throw new IllegalArgumentException("Number of bufferViews elements is < 1"); } this.bufferViews = bufferViews; } /** - * An array of bufferViews. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A view into a buffer generally representing a subset of - * the buffer. (optional) - * - * @return The bufferViews - * - */ - public List getBufferViews() { - return this.bufferViews; - } - - /** - * Add the given bufferViews. The bufferViews of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given bufferViews. The bufferViews of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addBufferViews(BufferView element) { if (element == null) { @@ -677,7 +676,7 @@ public void addBufferViews(BufferView element) { } List oldList = this.bufferViews; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -685,15 +684,15 @@ public void addBufferViews(BufferView element) { } /** - * Remove the given bufferViews. The bufferViews of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given bufferViews. The bufferViews of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeBufferViews(BufferView element) { if (element == null) { @@ -701,7 +700,7 @@ public void removeBufferViews(BufferView element) { } List oldList = this.bufferViews; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -713,50 +712,50 @@ public void removeBufferViews(BufferView element) { } /** - * An array of cameras. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A camera's projection. A node **MAY** reference a camera - * to apply a transform to place the camera in the scene. (optional) - * + * An array of cameras. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A camera's projection. A node **MAY** reference a camera + * to apply a transform to place the camera in the scene. (optional) + * + * @return The cameras + * + */ + public List getCameras() { + return this.cameras; + } + + /** + * An array of cameras. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A camera's projection. A node **MAY** reference a camera + * to apply a transform to place the camera in the scene. (optional) + * * @param cameras The cameras to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCameras(List cameras) { if (cameras == null) { this.cameras = cameras; - return ; + return; } - if (cameras.size()< 1) { + if (cameras.size() < 1) { throw new IllegalArgumentException("Number of cameras elements is < 1"); } this.cameras = cameras; } /** - * An array of cameras. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A camera's projection. A node **MAY** reference a camera - * to apply a transform to place the camera in the scene. (optional) - * - * @return The cameras - * - */ - public List getCameras() { - return this.cameras; - } - - /** - * Add the given cameras. The cameras of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given cameras. The cameras of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addCameras(Camera element) { if (element == null) { @@ -764,7 +763,7 @@ public void addCameras(Camera element) { } List oldList = this.cameras; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -772,15 +771,15 @@ public void addCameras(Camera element) { } /** - * Remove the given cameras. The cameras of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given cameras. The cameras of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeCameras(Camera element) { if (element == null) { @@ -788,7 +787,7 @@ public void removeCameras(Camera element) { } List oldList = this.cameras; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -800,50 +799,50 @@ public void removeCameras(Camera element) { } /** - * An array of images. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   Image data used to create a texture. Image **MAY** be - * referenced by an URI (or IRI) or a buffer view index. (optional) - * + * An array of images. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Image data used to create a texture. Image **MAY** be + * referenced by an URI (or IRI) or a buffer view index. (optional) + * + * @return The images + * + */ + public List getImages() { + return this.images; + } + + /** + * An array of images. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Image data used to create a texture. Image **MAY** be + * referenced by an URI (or IRI) or a buffer view index. (optional) + * * @param images The images to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setImages(List images) { if (images == null) { this.images = images; - return ; + return; } - if (images.size()< 1) { + if (images.size() < 1) { throw new IllegalArgumentException("Number of images elements is < 1"); } this.images = images; } /** - * An array of images. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   Image data used to create a texture. Image **MAY** be - * referenced by an URI (or IRI) or a buffer view index. (optional) - * - * @return The images - * - */ - public List getImages() { - return this.images; - } - - /** - * Add the given images. The images of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given images. The images of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addImages(Image element) { if (element == null) { @@ -851,7 +850,7 @@ public void addImages(Image element) { } List oldList = this.images; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -859,15 +858,15 @@ public void addImages(Image element) { } /** - * Remove the given images. The images of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given images. The images of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeImages(Image element) { if (element == null) { @@ -875,7 +874,7 @@ public void removeImages(Image element) { } List oldList = this.images; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -887,48 +886,48 @@ public void removeImages(Image element) { } /** - * An array of materials. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The material appearance of a primitive. (optional) - * + * An array of materials. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The material appearance of a primitive. (optional) + * + * @return The materials + * + */ + public List getMaterials() { + return this.materials; + } + + /** + * An array of materials. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The material appearance of a primitive. (optional) + * * @param materials The materials to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMaterials(List materials) { if (materials == null) { this.materials = materials; - return ; + return; } - if (materials.size()< 1) { + if (materials.size() < 1) { throw new IllegalArgumentException("Number of materials elements is < 1"); } this.materials = materials; } /** - * An array of materials. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The material appearance of a primitive. (optional) - * - * @return The materials - * - */ - public List getMaterials() { - return this.materials; - } - - /** - * Add the given materials. The materials of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given materials. The materials of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addMaterials(Material element) { if (element == null) { @@ -936,7 +935,7 @@ public void addMaterials(Material element) { } List oldList = this.materials; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -944,15 +943,15 @@ public void addMaterials(Material element) { } /** - * Remove the given materials. The materials of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given materials. The materials of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeMaterials(Material element) { if (element == null) { @@ -960,7 +959,7 @@ public void removeMaterials(Material element) { } List oldList = this.materials; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -972,50 +971,50 @@ public void removeMaterials(Material element) { } /** - * An array of meshes. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A set of primitives to be rendered. Its global transform - * is defined by a node that references it. (optional) - * + * An array of meshes. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A set of primitives to be rendered. Its global transform + * is defined by a node that references it. (optional) + * + * @return The meshes + * + */ + public List getMeshes() { + return this.meshes; + } + + /** + * An array of meshes. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A set of primitives to be rendered. Its global transform + * is defined by a node that references it. (optional) + * * @param meshes The meshes to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMeshes(List meshes) { if (meshes == null) { this.meshes = meshes; - return ; + return; } - if (meshes.size()< 1) { + if (meshes.size() < 1) { throw new IllegalArgumentException("Number of meshes elements is < 1"); } this.meshes = meshes; } /** - * An array of meshes. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A set of primitives to be rendered. Its global transform - * is defined by a node that references it. (optional) - * - * @return The meshes - * - */ - public List getMeshes() { - return this.meshes; - } - - /** - * Add the given meshes. The meshes of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given meshes. The meshes of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addMeshes(Mesh element) { if (element == null) { @@ -1023,7 +1022,7 @@ public void addMeshes(Mesh element) { } List oldList = this.meshes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -1031,15 +1030,15 @@ public void addMeshes(Mesh element) { } /** - * Remove the given meshes. The meshes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given meshes. The meshes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeMeshes(Mesh element) { if (element == null) { @@ -1047,7 +1046,7 @@ public void removeMeshes(Mesh element) { } List oldList = this.meshes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -1059,66 +1058,66 @@ public void removeMeshes(Mesh element) { } /** - * An array of nodes. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A node in the node hierarchy. When the node contains - * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and - * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any - * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS - * properties are converted to matrices and postmultiplied in the `T * R - * * S` order to compose the transformation matrix; first the scale is - * applied to the vertices, then the rotation, and then the translation. - * If none are provided, the transform is the identity. When a node is - * targeted for animation (referenced by an animation.channel.target), - * `matrix` **MUST NOT** be present. (optional) - * + * An array of nodes. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A node in the node hierarchy. When the node contains + * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and + * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any + * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS + * properties are converted to matrices and postmultiplied in the `T * R + * * S` order to compose the transformation matrix; first the scale is + * applied to the vertices, then the rotation, and then the translation. + * If none are provided, the transform is the identity. When a node is + * targeted for animation (referenced by an animation.channel.target), + * `matrix` **MUST NOT** be present. (optional) + * + * @return The nodes + * + */ + public List getNodes() { + return this.nodes; + } + + /** + * An array of nodes. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A node in the node hierarchy. When the node contains + * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and + * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any + * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS + * properties are converted to matrices and postmultiplied in the `T * R + * * S` order to compose the transformation matrix; first the scale is + * applied to the vertices, then the rotation, and then the translation. + * If none are provided, the transform is the identity. When a node is + * targeted for animation (referenced by an animation.channel.target), + * `matrix` **MUST NOT** be present. (optional) + * * @param nodes The nodes to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setNodes(List nodes) { if (nodes == null) { this.nodes = nodes; - return ; + return; } - if (nodes.size()< 1) { + if (nodes.size() < 1) { throw new IllegalArgumentException("Number of nodes elements is < 1"); } this.nodes = nodes; } /** - * An array of nodes. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A node in the node hierarchy. When the node contains - * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and - * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any - * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS - * properties are converted to matrices and postmultiplied in the `T * R - * * S` order to compose the transformation matrix; first the scale is - * applied to the vertices, then the rotation, and then the translation. - * If none are provided, the transform is the identity. When a node is - * targeted for animation (referenced by an animation.channel.target), - * `matrix` **MUST NOT** be present. (optional) - * - * @return The nodes - * - */ - public List getNodes() { - return this.nodes; - } - - /** - * Add the given nodes. The nodes of this instance will be replaced with - * a list that contains all previous elements, and additionally the new - * element. - * + * Add the given nodes. The nodes of this instance will be replaced with + * a list that contains all previous elements, and additionally the new + * element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addNodes(Node element) { if (element == null) { @@ -1126,7 +1125,7 @@ public void addNodes(Node element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -1134,15 +1133,15 @@ public void addNodes(Node element) { } /** - * Remove the given nodes. The nodes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given nodes. The nodes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeNodes(Node element) { if (element == null) { @@ -1150,7 +1149,7 @@ public void removeNodes(Node element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -1162,50 +1161,50 @@ public void removeNodes(Node element) { } /** - * An array of samplers. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   Texture sampler properties for filtering and wrapping - * modes. (optional) - * + * An array of samplers. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Texture sampler properties for filtering and wrapping + * modes. (optional) + * + * @return The samplers + * + */ + public List getSamplers() { + return this.samplers; + } + + /** + * An array of samplers. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Texture sampler properties for filtering and wrapping + * modes. (optional) + * * @param samplers The samplers to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setSamplers(List samplers) { if (samplers == null) { this.samplers = samplers; - return ; + return; } - if (samplers.size()< 1) { + if (samplers.size() < 1) { throw new IllegalArgumentException("Number of samplers elements is < 1"); } this.samplers = samplers; } /** - * An array of samplers. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   Texture sampler properties for filtering and wrapping - * modes. (optional) - * - * @return The samplers - * - */ - public List getSamplers() { - return this.samplers; - } - - /** - * Add the given samplers. The samplers of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given samplers. The samplers of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addSamplers(Sampler element) { if (element == null) { @@ -1213,7 +1212,7 @@ public void addSamplers(Sampler element) { } List oldList = this.samplers; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -1221,15 +1220,15 @@ public void addSamplers(Sampler element) { } /** - * Remove the given samplers. The samplers of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given samplers. The samplers of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeSamplers(Sampler element) { if (element == null) { @@ -1237,7 +1236,7 @@ public void removeSamplers(Sampler element) { } List oldList = this.samplers; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -1249,72 +1248,72 @@ public void removeSamplers(Sampler element) { } /** - * The index of the default scene. (optional) - * + * The index of the default scene. (optional) + * + * @return The scene + * + */ + public Integer getScene() { + return this.scene; + } + + /** + * The index of the default scene. (optional) + * * @param scene The scene to set - * + * */ public void setScene(Integer scene) { if (scene == null) { this.scene = scene; - return ; + return; } this.scene = scene; } /** - * The index of the default scene. (optional) - * - * @return The scene - * + * An array of scenes. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The root nodes of a scene. (optional) + * + * @return The scenes + * */ - public Integer getScene() { - return this.scene; + public List getScenes() { + return this.scenes; } /** - * An array of scenes. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The root nodes of a scene. (optional) - * + * An array of scenes. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The root nodes of a scene. (optional) + * * @param scenes The scenes to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setScenes(List scenes) { if (scenes == null) { this.scenes = scenes; - return ; + return; } - if (scenes.size()< 1) { + if (scenes.size() < 1) { throw new IllegalArgumentException("Number of scenes elements is < 1"); } this.scenes = scenes; } /** - * An array of scenes. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The root nodes of a scene. (optional) - * - * @return The scenes - * - */ - public List getScenes() { - return this.scenes; - } - - /** - * Add the given scenes. The scenes of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given scenes. The scenes of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addScenes(Scene element) { if (element == null) { @@ -1322,7 +1321,7 @@ public void addScenes(Scene element) { } List oldList = this.scenes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -1330,15 +1329,15 @@ public void addScenes(Scene element) { } /** - * Remove the given scenes. The scenes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given scenes. The scenes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeScenes(Scene element) { if (element == null) { @@ -1346,7 +1345,7 @@ public void removeScenes(Scene element) { } List oldList = this.scenes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -1358,48 +1357,48 @@ public void removeScenes(Scene element) { } /** - * An array of skins. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   Joints and matrices defining a skin. (optional) - * + * An array of skins. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Joints and matrices defining a skin. (optional) + * + * @return The skins + * + */ + public List getSkins() { + return this.skins; + } + + /** + * An array of skins. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Joints and matrices defining a skin. (optional) + * * @param skins The skins to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setSkins(List skins) { if (skins == null) { this.skins = skins; - return ; + return; } - if (skins.size()< 1) { + if (skins.size() < 1) { throw new IllegalArgumentException("Number of skins elements is < 1"); } this.skins = skins; } /** - * An array of skins. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   Joints and matrices defining a skin. (optional) - * - * @return The skins - * - */ - public List getSkins() { - return this.skins; - } - - /** - * Add the given skins. The skins of this instance will be replaced with - * a list that contains all previous elements, and additionally the new - * element. - * + * Add the given skins. The skins of this instance will be replaced with + * a list that contains all previous elements, and additionally the new + * element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addSkins(Skin element) { if (element == null) { @@ -1407,7 +1406,7 @@ public void addSkins(Skin element) { } List oldList = this.skins; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -1415,15 +1414,15 @@ public void addSkins(Skin element) { } /** - * Remove the given skins. The skins of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given skins. The skins of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeSkins(Skin element) { if (element == null) { @@ -1431,7 +1430,7 @@ public void removeSkins(Skin element) { } List oldList = this.skins; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -1443,48 +1442,48 @@ public void removeSkins(Skin element) { } /** - * An array of textures. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A texture and its sampler. (optional) - * + * An array of textures. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A texture and its sampler. (optional) + * + * @return The textures + * + */ + public List getTextures() { + return this.textures; + } + + /** + * An array of textures. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A texture and its sampler. (optional) + * * @param textures The textures to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTextures(List textures) { if (textures == null) { this.textures = textures; - return ; + return; } - if (textures.size()< 1) { + if (textures.size() < 1) { throw new IllegalArgumentException("Number of textures elements is < 1"); } this.textures = textures; } /** - * An array of textures. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A texture and its sampler. (optional) - * - * @return The textures - * - */ - public List getTextures() { - return this.textures; - } - - /** - * Add the given textures. The textures of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given textures. The textures of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addTextures(Texture element) { if (element == null) { @@ -1492,7 +1491,7 @@ public void addTextures(Texture element) { } List oldList = this.textures; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -1500,15 +1499,15 @@ public void addTextures(Texture element) { } /** - * Remove the given textures. The textures of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given textures. The textures of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeTextures(Texture element) { if (element == null) { @@ -1516,7 +1515,7 @@ public void removeTextures(Texture element) { } List oldList = this.textures; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/GlTFChildOfRootProperty.java b/src/main/java/de/javagl/jgltf/impl/v2/GlTFChildOfRootProperty.java index ae63ce2..fccd6ac 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/GlTFChildOfRootProperty.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/GlTFChildOfRootProperty.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,43 +9,41 @@ package de.javagl.jgltf.impl.v2; - /** - * Auto-generated for glTFChildOfRootProperty.schema.json - * + * Auto-generated for glTFChildOfRootProperty.schema.json + * */ public class GlTFChildOfRootProperty - extends GlTFProperty -{ + extends GlTFProperty { /** - * The user-defined name of this object. (optional) - * + * The user-defined name of this object. (optional) + * */ private String name; /** - * The user-defined name of this object. (optional) - * + * The user-defined name of this object. (optional) + * + * @return The name + * + */ + public String getName() { + return this.name; + } + + /** + * The user-defined name of this object. (optional) + * * @param name The name to set - * + * */ public void setName(String name) { if (name == null) { this.name = name; - return ; + return; } this.name = name; } - /** - * The user-defined name of this object. (optional) - * - * @return The name - * - */ - public String getName() { - return this.name; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/GlTFProperty.java b/src/main/java/de/javagl/jgltf/impl/v2/GlTFProperty.java index ca055cb..d444aea 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/GlTFProperty.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/GlTFProperty.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,55 +13,55 @@ /** - * Auto-generated for glTFProperty.schema.json - * + * Auto-generated for glTFProperty.schema.json + * */ public class GlTFProperty { /** - * JSON object with extension-specific objects. (optional) - * + * JSON object with extension-specific objects. (optional) + * */ private Map extensions; /** - * Application-specific data. (optional) - * + * Application-specific data. (optional) + * */ private Object extras; /** - * JSON object with extension-specific objects. (optional) - * + * JSON object with extension-specific objects. (optional) + * + * @return The extensions + * + */ + public Map getExtensions() { + return this.extensions; + } + + /** + * JSON object with extension-specific objects. (optional) + * * @param extensions The extensions to set - * + * */ public void setExtensions(Map extensions) { if (extensions == null) { this.extensions = extensions; - return ; + return; } this.extensions = extensions; } /** - * JSON object with extension-specific objects. (optional) - * - * @return The extensions - * - */ - public Map getExtensions() { - return this.extensions; - } - - /** - * Add the given extensions. The extensions of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given extensions. The extensions of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addExtensions(String key, Object value) { if (key == null) { @@ -72,7 +72,7 @@ public void addExtensions(String key, Object value) { } Map oldMap = this.extensions; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -80,15 +80,15 @@ public void addExtensions(String key, Object value) { } /** - * Remove the given extensions. The extensions of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
- * If this new map would be empty, then it will be set to - * null. - * + * Remove the given extensions. The extensions of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
+ * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeExtensions(String key) { if (key == null) { @@ -96,7 +96,7 @@ public void removeExtensions(String key) { } Map oldMap = this.extensions; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -108,27 +108,27 @@ public void removeExtensions(String key) { } /** - * Application-specific data. (optional) - * + * Application-specific data. (optional) + * + * @return The extras + * + */ + public Object getExtras() { + return this.extras; + } + + /** + * Application-specific data. (optional) + * * @param extras The extras to set - * + * */ public void setExtras(Object extras) { if (extras == null) { this.extras = extras; - return ; + return; } this.extras = extras; } - /** - * Application-specific data. (optional) - * - * @return The extras - * - */ - public Object getExtras() { - return this.extras; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Image.java b/src/main/java/de/javagl/jgltf/impl/v2/Image.java index 3e82a67..16e670c 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Image.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Image.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,113 +9,111 @@ package de.javagl.jgltf.impl.v2; - /** - * Image data used to create a texture. Image **MAY** be referenced by an - * URI (or IRI) or a buffer view index. - * - * Auto-generated for image.schema.json - * + * Image data used to create a texture. Image **MAY** be referenced by an + * URI (or IRI) or a buffer view index. + *

+ * Auto-generated for image.schema.json + * */ public class Image - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The URI (or IRI) of the image. (optional) - * + * The URI (or IRI) of the image. (optional) + * */ private String uri; /** - * The image's media type. This field **MUST** be defined when - * `bufferView` is defined. (optional)
- * Valid values: [image/jpeg, image/png] - * + * The image's media type. This field **MUST** be defined when + * `bufferView` is defined. (optional)
+ * Valid values: [image/jpeg, image/png] + * */ private String mimeType; /** - * The index of the bufferView that contains the image. This field **MUST - * NOT** be defined when `uri` is defined. (optional) - * + * The index of the bufferView that contains the image. This field **MUST + * NOT** be defined when `uri` is defined. (optional) + * */ private Integer bufferView; /** - * The URI (or IRI) of the image. (optional) - * + * The URI (or IRI) of the image. (optional) + * + * @return The uri + * + */ + public String getUri() { + return this.uri; + } + + /** + * The URI (or IRI) of the image. (optional) + * * @param uri The uri to set - * + * */ public void setUri(String uri) { if (uri == null) { this.uri = uri; - return ; + return; } this.uri = uri; } /** - * The URI (or IRI) of the image. (optional) - * - * @return The uri - * + * The image's media type. This field **MUST** be defined when + * `bufferView` is defined. (optional)
+ * Valid values: [image/jpeg, image/png] + * + * @return The mimeType + * */ - public String getUri() { - return this.uri; + public String getMimeType() { + return this.mimeType; } /** - * The image's media type. This field **MUST** be defined when - * `bufferView` is defined. (optional)
- * Valid values: [image/jpeg, image/png] - * + * The image's media type. This field **MUST** be defined when + * `bufferView` is defined. (optional)
+ * Valid values: [image/jpeg, image/png] + * * @param mimeType The mimeType to set - * + * */ public void setMimeType(String mimeType) { if (mimeType == null) { this.mimeType = mimeType; - return ; + return; } this.mimeType = mimeType; } /** - * The image's media type. This field **MUST** be defined when - * `bufferView` is defined. (optional)
- * Valid values: [image/jpeg, image/png] - * - * @return The mimeType - * + * The index of the bufferView that contains the image. This field **MUST + * NOT** be defined when `uri` is defined. (optional) + * + * @return The bufferView + * */ - public String getMimeType() { - return this.mimeType; + public Integer getBufferView() { + return this.bufferView; } /** - * The index of the bufferView that contains the image. This field **MUST - * NOT** be defined when `uri` is defined. (optional) - * + * The index of the bufferView that contains the image. This field **MUST + * NOT** be defined when `uri` is defined. (optional) + * * @param bufferView The bufferView to set - * + * */ public void setBufferView(Integer bufferView) { if (bufferView == null) { this.bufferView = bufferView; - return ; + return; } this.bufferView = bufferView; } - /** - * The index of the bufferView that contains the image. This field **MUST - * NOT** be defined when `uri` is defined. (optional) - * - * @return The bufferView - * - */ - public Integer getBufferView() { - return this.bufferView; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Material.java b/src/main/java/de/javagl/jgltf/impl/v2/Material.java index 18cd6a9..61dfbb8 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Material.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Material.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,204 +9,218 @@ package de.javagl.jgltf.impl.v2; - /** - * The material appearance of a primitive. - * - * Auto-generated for material.schema.json - * + * The material appearance of a primitive. + *

+ * Auto-generated for material.schema.json + * */ public class Material - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * A set of parameter values that are used to define the - * metallic-roughness material model from Physically Based Rendering - * (PBR) methodology. When undefined, all the default values of - * `pbrMetallicRoughness` **MUST** apply. (optional) - * + * A set of parameter values that are used to define the + * metallic-roughness material model from Physically Based Rendering + * (PBR) methodology. When undefined, all the default values of + * `pbrMetallicRoughness` **MUST** apply. (optional) + * */ private MaterialPbrMetallicRoughness pbrMetallicRoughness; /** - * The tangent space normal texture. (optional) - * + * The tangent space normal texture. (optional) + * */ private MaterialNormalTextureInfo normalTexture; /** - * The occlusion texture. (optional) - * + * The occlusion texture. (optional) + * */ private MaterialOcclusionTextureInfo occlusionTexture; /** - * The emissive texture. (optional) - * + * The emissive texture. (optional) + * */ private TextureInfo emissiveTexture; /** - * The factors for the emissive color of the material. (optional)
- * Default: [0.0,0.0,0.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0.0 (inclusive)
- *   Maximum: 1.0 (inclusive) - * + * The factors for the emissive color of the material. (optional)
+ * Default: [0.0,0.0,0.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0.0 (inclusive)
+ *   Maximum: 1.0 (inclusive) + * */ private float[] emissiveFactor; /** - * The alpha rendering mode of the material. (optional)
- * Default: "OPAQUE"
- * Valid values: [OPAQUE, MASK, BLEND] - * + * The alpha rendering mode of the material. (optional)
+ * Default: "OPAQUE"
+ * Valid values: [OPAQUE, MASK, BLEND] + * */ private String alphaMode; /** - * The alpha cutoff value of the material. (optional)
- * Default: 0.5
- * Minimum: 0.0 (inclusive) - * + * The alpha cutoff value of the material. (optional)
+ * Default: 0.5
+ * Minimum: 0.0 (inclusive) + * */ private Float alphaCutoff; /** - * Specifies whether the material is double sided. (optional)
- * Default: false - * + * Specifies whether the material is double sided. (optional)
+ * Default: false + * */ private Boolean doubleSided; /** - * A set of parameter values that are used to define the - * metallic-roughness material model from Physically Based Rendering - * (PBR) methodology. When undefined, all the default values of - * `pbrMetallicRoughness` **MUST** apply. (optional) - * + * A set of parameter values that are used to define the + * metallic-roughness material model from Physically Based Rendering + * (PBR) methodology. When undefined, all the default values of + * `pbrMetallicRoughness` **MUST** apply. (optional) + * + * @return The pbrMetallicRoughness + * + */ + public MaterialPbrMetallicRoughness getPbrMetallicRoughness() { + return this.pbrMetallicRoughness; + } + + /** + * A set of parameter values that are used to define the + * metallic-roughness material model from Physically Based Rendering + * (PBR) methodology. When undefined, all the default values of + * `pbrMetallicRoughness` **MUST** apply. (optional) + * * @param pbrMetallicRoughness The pbrMetallicRoughness to set - * + * */ public void setPbrMetallicRoughness(MaterialPbrMetallicRoughness pbrMetallicRoughness) { if (pbrMetallicRoughness == null) { this.pbrMetallicRoughness = pbrMetallicRoughness; - return ; + return; } this.pbrMetallicRoughness = pbrMetallicRoughness; } /** - * A set of parameter values that are used to define the - * metallic-roughness material model from Physically Based Rendering - * (PBR) methodology. When undefined, all the default values of - * `pbrMetallicRoughness` **MUST** apply. (optional) - * - * @return The pbrMetallicRoughness - * + * The tangent space normal texture. (optional) + * + * @return The normalTexture + * */ - public MaterialPbrMetallicRoughness getPbrMetallicRoughness() { - return this.pbrMetallicRoughness; + public MaterialNormalTextureInfo getNormalTexture() { + return this.normalTexture; } /** - * The tangent space normal texture. (optional) - * + * The tangent space normal texture. (optional) + * * @param normalTexture The normalTexture to set - * + * */ public void setNormalTexture(MaterialNormalTextureInfo normalTexture) { if (normalTexture == null) { this.normalTexture = normalTexture; - return ; + return; } this.normalTexture = normalTexture; } /** - * The tangent space normal texture. (optional) - * - * @return The normalTexture - * + * The occlusion texture. (optional) + * + * @return The occlusionTexture + * */ - public MaterialNormalTextureInfo getNormalTexture() { - return this.normalTexture; + public MaterialOcclusionTextureInfo getOcclusionTexture() { + return this.occlusionTexture; } /** - * The occlusion texture. (optional) - * + * The occlusion texture. (optional) + * * @param occlusionTexture The occlusionTexture to set - * + * */ public void setOcclusionTexture(MaterialOcclusionTextureInfo occlusionTexture) { if (occlusionTexture == null) { this.occlusionTexture = occlusionTexture; - return ; + return; } this.occlusionTexture = occlusionTexture; } /** - * The occlusion texture. (optional) - * - * @return The occlusionTexture - * + * The emissive texture. (optional) + * + * @return The emissiveTexture + * */ - public MaterialOcclusionTextureInfo getOcclusionTexture() { - return this.occlusionTexture; + public TextureInfo getEmissiveTexture() { + return this.emissiveTexture; } /** - * The emissive texture. (optional) - * + * The emissive texture. (optional) + * * @param emissiveTexture The emissiveTexture to set - * + * */ public void setEmissiveTexture(TextureInfo emissiveTexture) { if (emissiveTexture == null) { this.emissiveTexture = emissiveTexture; - return ; + return; } this.emissiveTexture = emissiveTexture; } /** - * The emissive texture. (optional) - * - * @return The emissiveTexture - * + * The factors for the emissive color of the material. (optional)
+ * Default: [0.0,0.0,0.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0.0 (inclusive)
+ *   Maximum: 1.0 (inclusive) + * + * @return The emissiveFactor + * */ - public TextureInfo getEmissiveTexture() { - return this.emissiveTexture; + public float[] getEmissiveFactor() { + return this.emissiveFactor; } /** - * The factors for the emissive color of the material. (optional)
- * Default: [0.0,0.0,0.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0.0 (inclusive)
- *   Maximum: 1.0 (inclusive) - * + * The factors for the emissive color of the material. (optional)
+ * Default: [0.0,0.0,0.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0.0 (inclusive)
+ *   Maximum: 1.0 (inclusive) + * * @param emissiveFactor The emissiveFactor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setEmissiveFactor(float[] emissiveFactor) { if (emissiveFactor == null) { this.emissiveFactor = emissiveFactor; - return ; + return; } - if (emissiveFactor.length< 3) { + if (emissiveFactor.length < 3) { throw new IllegalArgumentException("Number of emissiveFactor elements is < 3"); } if (emissiveFactor.length > 3) { throw new IllegalArgumentException("Number of emissiveFactor elements is > 3"); } - for (float emissiveFactorElement: emissiveFactor) { + for (float emissiveFactorElement : emissiveFactor) { if (emissiveFactorElement > 1.0D) { throw new IllegalArgumentException("emissiveFactorElement > 1.0"); } - if (emissiveFactorElement< 0.0D) { + if (emissiveFactorElement < 0.0D) { throw new IllegalArgumentException("emissiveFactorElement < 0.0"); } } @@ -214,152 +228,136 @@ public void setEmissiveFactor(float[] emissiveFactor) { } /** - * The factors for the emissive color of the material. (optional)
- * Default: [0.0,0.0,0.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0.0 (inclusive)
- *   Maximum: 1.0 (inclusive) - * - * @return The emissiveFactor - * + * Returns the default value of the emissiveFactor
+ * + * @return The default emissiveFactor + * @see #getEmissiveFactor + * */ - public float[] getEmissiveFactor() { - return this.emissiveFactor; + public float[] defaultEmissiveFactor() { + return new float[]{0.0F, 0.0F, 0.0F}; } /** - * Returns the default value of the emissiveFactor
- * @see #getEmissiveFactor - * - * @return The default emissiveFactor - * + * The alpha rendering mode of the material. (optional)
+ * Default: "OPAQUE"
+ * Valid values: [OPAQUE, MASK, BLEND] + * + * @return The alphaMode + * */ - public float[] defaultEmissiveFactor() { - return new float[] { 0.0F, 0.0F, 0.0F }; + public String getAlphaMode() { + return this.alphaMode; } /** - * The alpha rendering mode of the material. (optional)
- * Default: "OPAQUE"
- * Valid values: [OPAQUE, MASK, BLEND] - * + * The alpha rendering mode of the material. (optional)
+ * Default: "OPAQUE"
+ * Valid values: [OPAQUE, MASK, BLEND] + * * @param alphaMode The alphaMode to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAlphaMode(String alphaMode) { if (alphaMode == null) { this.alphaMode = alphaMode; - return ; + return; } - if (((!"OPAQUE".equals(alphaMode))&&(!"MASK".equals(alphaMode)))&&(!"BLEND".equals(alphaMode))) { - throw new IllegalArgumentException((("Invalid value for alphaMode: "+ alphaMode)+", valid: [OPAQUE, MASK, BLEND]")); + if (((!"OPAQUE".equals(alphaMode)) && (!"MASK".equals(alphaMode))) && (!"BLEND".equals(alphaMode))) { + throw new IllegalArgumentException((("Invalid value for alphaMode: " + alphaMode) + ", valid: [OPAQUE, MASK, BLEND]")); } this.alphaMode = alphaMode; } /** - * The alpha rendering mode of the material. (optional)
- * Default: "OPAQUE"
- * Valid values: [OPAQUE, MASK, BLEND] - * - * @return The alphaMode - * + * Returns the default value of the alphaMode
+ * + * @return The default alphaMode + * @see #getAlphaMode + * */ - public String getAlphaMode() { - return this.alphaMode; + public String defaultAlphaMode() { + return "OPAQUE"; } /** - * Returns the default value of the alphaMode
- * @see #getAlphaMode - * - * @return The default alphaMode - * + * The alpha cutoff value of the material. (optional)
+ * Default: 0.5
+ * Minimum: 0.0 (inclusive) + * + * @return The alphaCutoff + * */ - public String defaultAlphaMode() { - return "OPAQUE"; + public Float getAlphaCutoff() { + return this.alphaCutoff; } /** - * The alpha cutoff value of the material. (optional)
- * Default: 0.5
- * Minimum: 0.0 (inclusive) - * + * The alpha cutoff value of the material. (optional)
+ * Default: 0.5
+ * Minimum: 0.0 (inclusive) + * * @param alphaCutoff The alphaCutoff to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAlphaCutoff(Float alphaCutoff) { if (alphaCutoff == null) { this.alphaCutoff = alphaCutoff; - return ; + return; } - if (alphaCutoff< 0.0D) { + if (alphaCutoff < 0.0D) { throw new IllegalArgumentException("alphaCutoff < 0.0"); } this.alphaCutoff = alphaCutoff; } /** - * The alpha cutoff value of the material. (optional)
- * Default: 0.5
- * Minimum: 0.0 (inclusive) - * - * @return The alphaCutoff - * - */ - public Float getAlphaCutoff() { - return this.alphaCutoff; - } - - /** - * Returns the default value of the alphaCutoff
- * @see #getAlphaCutoff - * + * Returns the default value of the alphaCutoff
+ * * @return The default alphaCutoff - * + * @see #getAlphaCutoff + * */ public Float defaultAlphaCutoff() { - return 0.5F; + return 0.5F; } /** - * Specifies whether the material is double sided. (optional)
- * Default: false - * + * Specifies whether the material is double sided. (optional)
+ * Default: false + * * @param doubleSided The doubleSided to set - * + * */ public void setDoubleSided(Boolean doubleSided) { if (doubleSided == null) { this.doubleSided = doubleSided; - return ; + return; } this.doubleSided = doubleSided; } /** - * Specifies whether the material is double sided. (optional)
- * Default: false - * + * Specifies whether the material is double sided. (optional)
+ * Default: false + * * @return The doubleSided - * + * */ public Boolean isDoubleSided() { return this.doubleSided; } /** - * Returns the default value of the doubleSided
- * @see #isDoubleSided - * + * Returns the default value of the doubleSided
+ * * @return The default doubleSided - * + * @see #isDoubleSided + * */ public Boolean defaultDoubleSided() { return false; diff --git a/src/main/java/de/javagl/jgltf/impl/v2/MaterialNormalTextureInfo.java b/src/main/java/de/javagl/jgltf/impl/v2/MaterialNormalTextureInfo.java index 082dea0..b10b41c 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/MaterialNormalTextureInfo.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/MaterialNormalTextureInfo.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,60 +9,58 @@ package de.javagl.jgltf.impl.v2; - /** - * Auto-generated for material.normalTextureInfo.schema.json - * + * Auto-generated for material.normalTextureInfo.schema.json + * */ public class MaterialNormalTextureInfo - extends TextureInfo -{ + extends TextureInfo { /** - * The scalar parameter applied to each normal vector of the normal - * texture. (optional)
- * Default: 1.0 - * + * The scalar parameter applied to each normal vector of the normal + * texture. (optional)
+ * Default: 1.0 + * */ private Float scale; /** - * The scalar parameter applied to each normal vector of the normal - * texture. (optional)
- * Default: 1.0 - * + * The scalar parameter applied to each normal vector of the normal + * texture. (optional)
+ * Default: 1.0 + * + * @return The scale + * + */ + public Float getScale() { + return this.scale; + } + + /** + * The scalar parameter applied to each normal vector of the normal + * texture. (optional)
+ * Default: 1.0 + * * @param scale The scale to set - * + * */ public void setScale(Float scale) { if (scale == null) { this.scale = scale; - return ; + return; } this.scale = scale; } /** - * The scalar parameter applied to each normal vector of the normal - * texture. (optional)
- * Default: 1.0 - * - * @return The scale - * - */ - public Float getScale() { - return this.scale; - } - - /** - * Returns the default value of the scale
- * @see #getScale - * + * Returns the default value of the scale
+ * * @return The default scale - * + * @see #getScale + * */ public Float defaultScale() { - return 1.0F; + return 1.0F; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/MaterialOcclusionTextureInfo.java b/src/main/java/de/javagl/jgltf/impl/v2/MaterialOcclusionTextureInfo.java index c5052d6..b383262 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/MaterialOcclusionTextureInfo.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/MaterialOcclusionTextureInfo.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,74 +9,72 @@ package de.javagl.jgltf.impl.v2; - /** - * Auto-generated for material.occlusionTextureInfo.schema.json - * + * Auto-generated for material.occlusionTextureInfo.schema.json + * */ public class MaterialOcclusionTextureInfo - extends TextureInfo -{ + extends TextureInfo { /** - * A scalar multiplier controlling the amount of occlusion applied. - * (optional)
- * Default: 1.0
- * Minimum: 0.0 (inclusive)
- * Maximum: 1.0 (inclusive) - * + * A scalar multiplier controlling the amount of occlusion applied. + * (optional)
+ * Default: 1.0
+ * Minimum: 0.0 (inclusive)
+ * Maximum: 1.0 (inclusive) + * */ private Float strength; /** - * A scalar multiplier controlling the amount of occlusion applied. - * (optional)
- * Default: 1.0
- * Minimum: 0.0 (inclusive)
- * Maximum: 1.0 (inclusive) - * + * A scalar multiplier controlling the amount of occlusion applied. + * (optional)
+ * Default: 1.0
+ * Minimum: 0.0 (inclusive)
+ * Maximum: 1.0 (inclusive) + * + * @return The strength + * + */ + public Float getStrength() { + return this.strength; + } + + /** + * A scalar multiplier controlling the amount of occlusion applied. + * (optional)
+ * Default: 1.0
+ * Minimum: 0.0 (inclusive)
+ * Maximum: 1.0 (inclusive) + * * @param strength The strength to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setStrength(Float strength) { if (strength == null) { this.strength = strength; - return ; + return; } if (strength > 1.0D) { throw new IllegalArgumentException("strength > 1.0"); } - if (strength< 0.0D) { + if (strength < 0.0D) { throw new IllegalArgumentException("strength < 0.0"); } this.strength = strength; } /** - * A scalar multiplier controlling the amount of occlusion applied. - * (optional)
- * Default: 1.0
- * Minimum: 0.0 (inclusive)
- * Maximum: 1.0 (inclusive) - * - * @return The strength - * - */ - public Float getStrength() { - return this.strength; - } - - /** - * Returns the default value of the strength
- * @see #getStrength - * + * Returns the default value of the strength
+ * * @return The default strength - * + * @see #getStrength + * */ public Float defaultStrength() { - return 1.0F; + return 1.0F; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/MaterialPbrMetallicRoughness.java b/src/main/java/de/javagl/jgltf/impl/v2/MaterialPbrMetallicRoughness.java index b539f5d..73797dd 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/MaterialPbrMetallicRoughness.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/MaterialPbrMetallicRoughness.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,87 +9,101 @@ package de.javagl.jgltf.impl.v2; - /** - * A set of parameter values that are used to define the - * metallic-roughness material model from Physically-Based Rendering - * (PBR) methodology. - * - * Auto-generated for material.pbrMetallicRoughness.schema.json - * + * A set of parameter values that are used to define the + * metallic-roughness material model from Physically-Based Rendering + * (PBR) methodology. + *

+ * Auto-generated for material.pbrMetallicRoughness.schema.json + * */ public class MaterialPbrMetallicRoughness - extends GlTFProperty -{ + extends GlTFProperty { /** - * The factors for the base color of the material. (optional)
- * Default: [1.0,1.0,1.0,1.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0.0 (inclusive)
- *   Maximum: 1.0 (inclusive) - * + * The factors for the base color of the material. (optional)
+ * Default: [1.0,1.0,1.0,1.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0.0 (inclusive)
+ *   Maximum: 1.0 (inclusive) + * */ private float[] baseColorFactor; /** - * The base color texture. (optional) - * + * The base color texture. (optional) + * */ private TextureInfo baseColorTexture; /** - * The factor for the metalness of the material. (optional)
- * Default: 1.0
- * Minimum: 0.0 (inclusive)
- * Maximum: 1.0 (inclusive) - * + * The factor for the metalness of the material. (optional)
+ * Default: 1.0
+ * Minimum: 0.0 (inclusive)
+ * Maximum: 1.0 (inclusive) + * */ private Float metallicFactor; /** - * The factor for the roughness of the material. (optional)
- * Default: 1.0
- * Minimum: 0.0 (inclusive)
- * Maximum: 1.0 (inclusive) - * + * The factor for the roughness of the material. (optional)
+ * Default: 1.0
+ * Minimum: 0.0 (inclusive)
+ * Maximum: 1.0 (inclusive) + * */ private Float roughnessFactor; /** - * The metallic-roughness texture. (optional) - * + * The metallic-roughness texture. (optional) + * */ private TextureInfo metallicRoughnessTexture; /** - * The factors for the base color of the material. (optional)
- * Default: [1.0,1.0,1.0,1.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0.0 (inclusive)
- *   Maximum: 1.0 (inclusive) - * + * The factors for the base color of the material. (optional)
+ * Default: [1.0,1.0,1.0,1.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0.0 (inclusive)
+ *   Maximum: 1.0 (inclusive) + * + * @return The baseColorFactor + * + */ + public float[] getBaseColorFactor() { + return this.baseColorFactor; + } + + /** + * The factors for the base color of the material. (optional)
+ * Default: [1.0,1.0,1.0,1.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0.0 (inclusive)
+ *   Maximum: 1.0 (inclusive) + * * @param baseColorFactor The baseColorFactor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBaseColorFactor(float[] baseColorFactor) { if (baseColorFactor == null) { this.baseColorFactor = baseColorFactor; - return ; + return; } - if (baseColorFactor.length< 4) { + if (baseColorFactor.length < 4) { throw new IllegalArgumentException("Number of baseColorFactor elements is < 4"); } if (baseColorFactor.length > 4) { throw new IllegalArgumentException("Number of baseColorFactor elements is > 4"); } - for (float baseColorFactorElement: baseColorFactor) { + for (float baseColorFactorElement : baseColorFactor) { if (baseColorFactorElement > 1.0D) { throw new IllegalArgumentException("baseColorFactorElement > 1.0"); } - if (baseColorFactorElement< 0.0D) { + if (baseColorFactorElement < 0.0D) { throw new IllegalArgumentException("baseColorFactorElement < 0.0"); } } @@ -97,176 +111,160 @@ public void setBaseColorFactor(float[] baseColorFactor) { } /** - * The factors for the base color of the material. (optional)
- * Default: [1.0,1.0,1.0,1.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0.0 (inclusive)
- *   Maximum: 1.0 (inclusive) - * - * @return The baseColorFactor - * + * Returns the default value of the baseColorFactor
+ * + * @return The default baseColorFactor + * @see #getBaseColorFactor + * */ - public float[] getBaseColorFactor() { - return this.baseColorFactor; + public float[] defaultBaseColorFactor() { + return new float[]{1.0F, 1.0F, 1.0F, 1.0F}; } /** - * Returns the default value of the baseColorFactor
- * @see #getBaseColorFactor - * - * @return The default baseColorFactor - * + * The base color texture. (optional) + * + * @return The baseColorTexture + * */ - public float[] defaultBaseColorFactor() { - return new float[] { 1.0F, 1.0F, 1.0F, 1.0F }; + public TextureInfo getBaseColorTexture() { + return this.baseColorTexture; } /** - * The base color texture. (optional) - * + * The base color texture. (optional) + * * @param baseColorTexture The baseColorTexture to set - * + * */ public void setBaseColorTexture(TextureInfo baseColorTexture) { if (baseColorTexture == null) { this.baseColorTexture = baseColorTexture; - return ; + return; } this.baseColorTexture = baseColorTexture; } /** - * The base color texture. (optional) - * - * @return The baseColorTexture - * + * The factor for the metalness of the material. (optional)
+ * Default: 1.0
+ * Minimum: 0.0 (inclusive)
+ * Maximum: 1.0 (inclusive) + * + * @return The metallicFactor + * */ - public TextureInfo getBaseColorTexture() { - return this.baseColorTexture; + public Float getMetallicFactor() { + return this.metallicFactor; } /** - * The factor for the metalness of the material. (optional)
- * Default: 1.0
- * Minimum: 0.0 (inclusive)
- * Maximum: 1.0 (inclusive) - * + * The factor for the metalness of the material. (optional)
+ * Default: 1.0
+ * Minimum: 0.0 (inclusive)
+ * Maximum: 1.0 (inclusive) + * * @param metallicFactor The metallicFactor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMetallicFactor(Float metallicFactor) { if (metallicFactor == null) { this.metallicFactor = metallicFactor; - return ; + return; } if (metallicFactor > 1.0D) { throw new IllegalArgumentException("metallicFactor > 1.0"); } - if (metallicFactor< 0.0D) { + if (metallicFactor < 0.0D) { throw new IllegalArgumentException("metallicFactor < 0.0"); } this.metallicFactor = metallicFactor; } /** - * The factor for the metalness of the material. (optional)
- * Default: 1.0
- * Minimum: 0.0 (inclusive)
- * Maximum: 1.0 (inclusive) - * - * @return The metallicFactor - * + * Returns the default value of the metallicFactor
+ * + * @return The default metallicFactor + * @see #getMetallicFactor + * */ - public Float getMetallicFactor() { - return this.metallicFactor; + public Float defaultMetallicFactor() { + return 1.0F; } /** - * Returns the default value of the metallicFactor
- * @see #getMetallicFactor - * - * @return The default metallicFactor - * + * The factor for the roughness of the material. (optional)
+ * Default: 1.0
+ * Minimum: 0.0 (inclusive)
+ * Maximum: 1.0 (inclusive) + * + * @return The roughnessFactor + * */ - public Float defaultMetallicFactor() { - return 1.0F; + public Float getRoughnessFactor() { + return this.roughnessFactor; } /** - * The factor for the roughness of the material. (optional)
- * Default: 1.0
- * Minimum: 0.0 (inclusive)
- * Maximum: 1.0 (inclusive) - * + * The factor for the roughness of the material. (optional)
+ * Default: 1.0
+ * Minimum: 0.0 (inclusive)
+ * Maximum: 1.0 (inclusive) + * * @param roughnessFactor The roughnessFactor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setRoughnessFactor(Float roughnessFactor) { if (roughnessFactor == null) { this.roughnessFactor = roughnessFactor; - return ; + return; } if (roughnessFactor > 1.0D) { throw new IllegalArgumentException("roughnessFactor > 1.0"); } - if (roughnessFactor< 0.0D) { + if (roughnessFactor < 0.0D) { throw new IllegalArgumentException("roughnessFactor < 0.0"); } this.roughnessFactor = roughnessFactor; } /** - * The factor for the roughness of the material. (optional)
- * Default: 1.0
- * Minimum: 0.0 (inclusive)
- * Maximum: 1.0 (inclusive) - * - * @return The roughnessFactor - * + * Returns the default value of the roughnessFactor
+ * + * @return The default roughnessFactor + * @see #getRoughnessFactor + * */ - public Float getRoughnessFactor() { - return this.roughnessFactor; + public Float defaultRoughnessFactor() { + return 1.0F; } /** - * Returns the default value of the roughnessFactor
- * @see #getRoughnessFactor - * - * @return The default roughnessFactor - * + * The metallic-roughness texture. (optional) + * + * @return The metallicRoughnessTexture + * */ - public Float defaultRoughnessFactor() { - return 1.0F; + public TextureInfo getMetallicRoughnessTexture() { + return this.metallicRoughnessTexture; } /** - * The metallic-roughness texture. (optional) - * + * The metallic-roughness texture. (optional) + * * @param metallicRoughnessTexture The metallicRoughnessTexture to set - * + * */ public void setMetallicRoughnessTexture(TextureInfo metallicRoughnessTexture) { if (metallicRoughnessTexture == null) { this.metallicRoughnessTexture = metallicRoughnessTexture; - return ; + return; } this.metallicRoughnessTexture = metallicRoughnessTexture; } - /** - * The metallic-roughness texture. (optional) - * - * @return The metallicRoughnessTexture - * - */ - public TextureInfo getMetallicRoughnessTexture() { - return this.metallicRoughnessTexture; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Mesh.java b/src/main/java/de/javagl/jgltf/impl/v2/Mesh.java index a99ae4f..756ab15 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Mesh.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Mesh.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,84 +13,83 @@ /** - * A set of primitives to be rendered. Its global transform is defined by - * a node that references it. - * - * Auto-generated for mesh.schema.json - * + * A set of primitives to be rendered. Its global transform is defined by + * a node that references it. + *

+ * Auto-generated for mesh.schema.json + * */ public class Mesh - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * An array of primitives, each defining geometry to be rendered. - * (required)
- * Minimum number of items: 1
- * Array elements:
- *   Geometry to be rendered with the given material. - * (optional) - * + * An array of primitives, each defining geometry to be rendered. + * (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Geometry to be rendered with the given material. + * (optional) + * */ private List primitives; /** - * Array of weights to be applied to the morph targets. The number of - * array elements **MUST** match the number of morph targets. - * (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * Array of weights to be applied to the morph targets. The number of + * array elements **MUST** match the number of morph targets. + * (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List weights; /** - * An array of primitives, each defining geometry to be rendered. - * (required)
- * Minimum number of items: 1
- * Array elements:
- *   Geometry to be rendered with the given material. - * (optional) - * + * An array of primitives, each defining geometry to be rendered. + * (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Geometry to be rendered with the given material. + * (optional) + * + * @return The primitives + * + */ + public List getPrimitives() { + return this.primitives; + } + + /** + * An array of primitives, each defining geometry to be rendered. + * (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   Geometry to be rendered with the given material. + * (optional) + * * @param primitives The primitives to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setPrimitives(List primitives) { if (primitives == null) { - throw new NullPointerException((("Invalid value for primitives: "+ primitives)+", may not be null")); + throw new NullPointerException((("Invalid value for primitives: " + primitives) + ", may not be null")); } - if (primitives.size()< 1) { + if (primitives.size() < 1) { throw new IllegalArgumentException("Number of primitives elements is < 1"); } this.primitives = primitives; } /** - * An array of primitives, each defining geometry to be rendered. - * (required)
- * Minimum number of items: 1
- * Array elements:
- *   Geometry to be rendered with the given material. - * (optional) - * - * @return The primitives - * - */ - public List getPrimitives() { - return this.primitives; - } - - /** - * Add the given primitives. The primitives of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Add the given primitives. The primitives of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addPrimitives(MeshPrimitive element) { if (element == null) { @@ -98,7 +97,7 @@ public void addPrimitives(MeshPrimitive element) { } List oldList = this.primitives; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -106,13 +105,13 @@ public void addPrimitives(MeshPrimitive element) { } /** - * Remove the given primitives. The primitives of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one. - * + * Remove the given primitives. The primitives of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removePrimitives(MeshPrimitive element) { if (element == null) { @@ -120,7 +119,7 @@ public void removePrimitives(MeshPrimitive element) { } List oldList = this.primitives; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -128,52 +127,52 @@ public void removePrimitives(MeshPrimitive element) { } /** - * Array of weights to be applied to the morph targets. The number of - * array elements **MUST** match the number of morph targets. - * (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * Array of weights to be applied to the morph targets. The number of + * array elements **MUST** match the number of morph targets. + * (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The weights + * + */ + public List getWeights() { + return this.weights; + } + + /** + * Array of weights to be applied to the morph targets. The number of + * array elements **MUST** match the number of morph targets. + * (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * * @param weights The weights to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWeights(List weights) { if (weights == null) { this.weights = weights; - return ; + return; } - if (weights.size()< 1) { + if (weights.size() < 1) { throw new IllegalArgumentException("Number of weights elements is < 1"); } this.weights = weights; } /** - * Array of weights to be applied to the morph targets. The number of - * array elements **MUST** match the number of morph targets. - * (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * - * @return The weights - * - */ - public List getWeights() { - return this.weights; - } - - /** - * Add the given weights. The weights of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given weights. The weights of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addWeights(Float element) { if (element == null) { @@ -181,7 +180,7 @@ public void addWeights(Float element) { } List oldList = this.weights; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -189,15 +188,15 @@ public void addWeights(Float element) { } /** - * Remove the given weights. The weights of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given weights. The weights of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeWeights(Float element) { if (element == null) { @@ -205,7 +204,7 @@ public void removeWeights(Float element) { } List oldList = this.weights; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/MeshPrimitive.java b/src/main/java/de/javagl/jgltf/impl/v2/MeshPrimitive.java index 4fd57a3..860519e 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/MeshPrimitive.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/MeshPrimitive.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -15,90 +15,89 @@ /** - * Geometry to be rendered with the given material. - * - * Auto-generated for mesh.primitive.schema.json - * + * Geometry to be rendered with the given material. + *

+ * Auto-generated for mesh.primitive.schema.json + * */ public class MeshPrimitive - extends GlTFProperty -{ + extends GlTFProperty { /** - * A plain JSON object, where each key corresponds to a mesh attribute - * semantic and each value is the index of the accessor containing - * attribute's data. (required) - * + * A plain JSON object, where each key corresponds to a mesh attribute + * semantic and each value is the index of the accessor containing + * attribute's data. (required) + * */ private Map attributes; /** - * The index of the accessor that contains the vertex indices. (optional) - * + * The index of the accessor that contains the vertex indices. (optional) + * */ private Integer indices; /** - * The index of the material to apply to this primitive when rendering. - * (optional) - * + * The index of the material to apply to this primitive when rendering. + * (optional) + * */ private Integer material; /** - * The topology type of primitives to render. (optional)
- * Default: 4
- * Valid values: [0, 1, 2, 3, 4, 5, 6] - * + * The topology type of primitives to render. (optional)
+ * Default: 4
+ * Valid values: [0, 1, 2, 3, 4, 5, 6] + * */ private Integer mode; /** - * An array of morph targets. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A plain JSON object specifying attributes displacements in - * a morph target, where each key corresponds to one of the three - * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and - * each value is the index of the accessor containing the attribute - * displacements' data. (optional) - * + * An array of morph targets. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A plain JSON object specifying attributes displacements in + * a morph target, where each key corresponds to one of the three + * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and + * each value is the index of the accessor containing the attribute + * displacements' data. (optional) + * */ private List> targets; /** - * A plain JSON object, where each key corresponds to a mesh attribute - * semantic and each value is the index of the accessor containing - * attribute's data. (required) - * + * A plain JSON object, where each key corresponds to a mesh attribute + * semantic and each value is the index of the accessor containing + * attribute's data. (required) + * + * @return The attributes + * + */ + public Map getAttributes() { + return this.attributes; + } + + /** + * A plain JSON object, where each key corresponds to a mesh attribute + * semantic and each value is the index of the accessor containing + * attribute's data. (required) + * * @param attributes The attributes to set * @throws NullPointerException If the given value is null - * + * */ public void setAttributes(Map attributes) { if (attributes == null) { - throw new NullPointerException((("Invalid value for attributes: "+ attributes)+", may not be null")); + throw new NullPointerException((("Invalid value for attributes: " + attributes) + ", may not be null")); } this.attributes = attributes; } /** - * A plain JSON object, where each key corresponds to a mesh attribute - * semantic and each value is the index of the accessor containing - * attribute's data. (required) - * - * @return The attributes - * - */ - public Map getAttributes() { - return this.attributes; - } - - /** - * Add the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Add the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAttributes(String key, Integer value) { if (key == null) { @@ -109,7 +108,7 @@ public void addAttributes(String key, Integer value) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -117,13 +116,13 @@ public void addAttributes(String key, Integer value) { } /** - * Remove the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key. - * + * Remove the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAttributes(String key) { if (key == null) { @@ -131,7 +130,7 @@ public void removeAttributes(String key) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap!= null) { + if (oldMap != null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -139,150 +138,150 @@ public void removeAttributes(String key) { } /** - * The index of the accessor that contains the vertex indices. (optional) - * + * The index of the accessor that contains the vertex indices. (optional) + * + * @return The indices + * + */ + public Integer getIndices() { + return this.indices; + } + + /** + * The index of the accessor that contains the vertex indices. (optional) + * * @param indices The indices to set - * + * */ public void setIndices(Integer indices) { if (indices == null) { this.indices = indices; - return ; + return; } this.indices = indices; } /** - * The index of the accessor that contains the vertex indices. (optional) - * - * @return The indices - * + * The index of the material to apply to this primitive when rendering. + * (optional) + * + * @return The material + * */ - public Integer getIndices() { - return this.indices; + public Integer getMaterial() { + return this.material; } /** - * The index of the material to apply to this primitive when rendering. - * (optional) - * + * The index of the material to apply to this primitive when rendering. + * (optional) + * * @param material The material to set - * + * */ public void setMaterial(Integer material) { if (material == null) { this.material = material; - return ; + return; } this.material = material; } /** - * The index of the material to apply to this primitive when rendering. - * (optional) - * - * @return The material - * + * The topology type of primitives to render. (optional)
+ * Default: 4
+ * Valid values: [0, 1, 2, 3, 4, 5, 6] + * + * @return The mode + * */ - public Integer getMaterial() { - return this.material; + public Integer getMode() { + return this.mode; } /** - * The topology type of primitives to render. (optional)
- * Default: 4
- * Valid values: [0, 1, 2, 3, 4, 5, 6] - * + * The topology type of primitives to render. (optional)
+ * Default: 4
+ * Valid values: [0, 1, 2, 3, 4, 5, 6] + * * @param mode The mode to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMode(Integer mode) { if (mode == null) { this.mode = mode; - return ; + return; } - if (((((((mode!= 0)&&(mode!= 1))&&(mode!= 2))&&(mode!= 3))&&(mode!= 4))&&(mode!= 5))&&(mode!= 6)) { - throw new IllegalArgumentException((("Invalid value for mode: "+ mode)+", valid: [0, 1, 2, 3, 4, 5, 6]")); + if (((((((mode != 0) && (mode != 1)) && (mode != 2)) && (mode != 3)) && (mode != 4)) && (mode != 5)) && (mode != 6)) { + throw new IllegalArgumentException((("Invalid value for mode: " + mode) + ", valid: [0, 1, 2, 3, 4, 5, 6]")); } this.mode = mode; } /** - * The topology type of primitives to render. (optional)
- * Default: 4
- * Valid values: [0, 1, 2, 3, 4, 5, 6] - * - * @return The mode - * + * Returns the default value of the mode
+ * + * @return The default mode + * @see #getMode + * */ - public Integer getMode() { - return this.mode; + public Integer defaultMode() { + return 4; } /** - * Returns the default value of the mode
- * @see #getMode - * - * @return The default mode - * + * An array of morph targets. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A plain JSON object specifying attributes displacements in + * a morph target, where each key corresponds to one of the three + * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and + * each value is the index of the accessor containing the attribute + * displacements' data. (optional) + * + * @return The targets + * */ - public Integer defaultMode() { - return 4; + public List> getTargets() { + return this.targets; } /** - * An array of morph targets. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A plain JSON object specifying attributes displacements in - * a morph target, where each key corresponds to one of the three - * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and - * each value is the index of the accessor containing the attribute - * displacements' data. (optional) - * + * An array of morph targets. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   A plain JSON object specifying attributes displacements in + * a morph target, where each key corresponds to one of the three + * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and + * each value is the index of the accessor containing the attribute + * displacements' data. (optional) + * * @param targets The targets to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTargets(List> targets) { if (targets == null) { this.targets = targets; - return ; + return; } - if (targets.size()< 1) { + if (targets.size() < 1) { throw new IllegalArgumentException("Number of targets elements is < 1"); } this.targets = targets; } /** - * An array of morph targets. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   A plain JSON object specifying attributes displacements in - * a morph target, where each key corresponds to one of the three - * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and - * each value is the index of the accessor containing the attribute - * displacements' data. (optional) - * - * @return The targets - * - */ - public List> getTargets() { - return this.targets; - } - - /** - * Add the given targets. The targets of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given targets. The targets of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addTargets(Map element) { if (element == null) { @@ -290,7 +289,7 @@ public void addTargets(Map element) { } List> oldList = this.targets; List> newList = new ArrayList>(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -298,15 +297,15 @@ public void addTargets(Map element) { } /** - * Remove the given targets. The targets of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given targets. The targets of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeTargets(Map element) { if (element == null) { @@ -314,7 +313,7 @@ public void removeTargets(Map element) { } List> oldList = this.targets; List> newList = new ArrayList>(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Node.java b/src/main/java/de/javagl/jgltf/impl/v2/Node.java index ab2a9fe..0f40dbe 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Node.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Node.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,147 +13,160 @@ /** - * A node in the node hierarchy. When the node contains `skin`, all - * `mesh.primitives` **MUST** contain `JOINTS_0` and `WEIGHTS_0` - * attributes. A node **MAY** have either a `matrix` or any combination - * of `translation`/`rotation`/`scale` (TRS) properties. TRS properties - * are converted to matrices and postmultiplied in the `T * R * S` order - * to compose the transformation matrix; first the scale is applied to - * the vertices, then the rotation, and then the translation. If none are - * provided, the transform is the identity. When a node is targeted for - * animation (referenced by an animation.channel.target), `matrix` **MUST - * NOT** be present. - * - * Auto-generated for node.schema.json - * + * A node in the node hierarchy. When the node contains `skin`, all + * `mesh.primitives` **MUST** contain `JOINTS_0` and `WEIGHTS_0` + * attributes. A node **MAY** have either a `matrix` or any combination + * of `translation`/`rotation`/`scale` (TRS) properties. TRS properties + * are converted to matrices and postmultiplied in the `T * R * S` order + * to compose the transformation matrix; first the scale is applied to + * the vertices, then the rotation, and then the translation. If none are + * provided, the transform is the identity. When a node is targeted for + * animation (referenced by an animation.channel.target), `matrix` **MUST + * NOT** be present. + *

+ * Auto-generated for node.schema.json + * */ public class Node - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The index of the camera referenced by this node. (optional) - * + * The index of the camera referenced by this node. (optional) + * */ private Integer camera; /** - * The indices of this node's children. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0 (inclusive) - * + * The indices of this node's children. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0 (inclusive) + * */ private List children; /** - * The index of the skin referenced by this node. (optional) - * + * The index of the skin referenced by this node. (optional) + * */ private Integer skin; /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
- * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
- * Number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
+ * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+ * Number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] matrix; /** - * The index of the mesh in this node. (optional) - * + * The index of the mesh in this node. (optional) + * */ private Integer mesh; /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
- * Default: [0.0,0.0,0.0,1.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: -1.0 (inclusive)
- *   Maximum: 1.0 (inclusive) - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
+ * Default: [0.0,0.0,0.0,1.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: -1.0 (inclusive)
+ *   Maximum: 1.0 (inclusive) + * */ private float[] rotation; /** - * The node's non-uniform scale, given as the scaling factors along the - * x, y, and z axes. (optional)
- * Default: [1.0,1.0,1.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * + * The node's non-uniform scale, given as the scaling factors along the + * x, y, and z axes. (optional)
+ * Default: [1.0,1.0,1.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] scale; /** - * The node's translation along the x, y, and z axes. (optional)
- * Default: [0.0,0.0,0.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * + * The node's translation along the x, y, and z axes. (optional)
+ * Default: [0.0,0.0,0.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * */ private float[] translation; /** - * The weights of the instantiated morph target. The number of array - * elements **MUST** match the number of morph targets of the referenced - * mesh. When defined, `mesh` **MUST** also be defined. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * The weights of the instantiated morph target. The number of array + * elements **MUST** match the number of morph targets of the referenced + * mesh. When defined, `mesh` **MUST** also be defined. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * */ private List weights; /** - * The index of the camera referenced by this node. (optional) - * + * The index of the camera referenced by this node. (optional) + * + * @return The camera + * + */ + public Integer getCamera() { + return this.camera; + } + + /** + * The index of the camera referenced by this node. (optional) + * * @param camera The camera to set - * + * */ public void setCamera(Integer camera) { if (camera == null) { this.camera = camera; - return ; + return; } this.camera = camera; } /** - * The index of the camera referenced by this node. (optional) - * - * @return The camera - * + * The indices of this node's children. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0 (inclusive) + * + * @return The children + * */ - public Integer getCamera() { - return this.camera; + public List getChildren() { + return this.children; } /** - * The indices of this node's children. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0 (inclusive) - * + * The indices of this node's children. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0 (inclusive) + * * @param children The children to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setChildren(List children) { if (children == null) { this.children = children; - return ; + return; } - if (children.size()< 1) { + if (children.size() < 1) { throw new IllegalArgumentException("Number of children elements is < 1"); } - for (Integer childrenElement: children) { - if (childrenElement< 0) { + for (Integer childrenElement : children) { + if (childrenElement < 0) { throw new IllegalArgumentException("childrenElement < 0"); } } @@ -161,27 +174,13 @@ public void setChildren(List children) { } /** - * The indices of this node's children. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0 (inclusive) - * - * @return The children - * - */ - public List getChildren() { - return this.children; - } - - /** - * Add the given children. The children of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given children. The children of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addChildren(Integer element) { if (element == null) { @@ -189,7 +188,7 @@ public void addChildren(Integer element) { } List oldList = this.children; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -197,15 +196,15 @@ public void addChildren(Integer element) { } /** - * Remove the given children. The children of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given children. The children of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeChildren(Integer element) { if (element == null) { @@ -213,7 +212,7 @@ public void removeChildren(Integer element) { } List oldList = this.children; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); @@ -225,49 +224,65 @@ public void removeChildren(Integer element) { } /** - * The index of the skin referenced by this node. (optional) - * + * The index of the skin referenced by this node. (optional) + * + * @return The skin + * + */ + public Integer getSkin() { + return this.skin; + } + + /** + * The index of the skin referenced by this node. (optional) + * * @param skin The skin to set - * + * */ public void setSkin(Integer skin) { if (skin == null) { this.skin = skin; - return ; + return; } this.skin = skin; } /** - * The index of the skin referenced by this node. (optional) - * - * @return The skin - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
+ * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+ * Number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The matrix + * */ - public Integer getSkin() { - return this.skin; + public float[] getMatrix() { + return this.matrix; } /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
- * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
- * Number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
+ * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+ * Number of items: 16
+ * Array elements:
+ *   The elements of this array (optional) + * * @param matrix The matrix to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMatrix(float[] matrix) { if (matrix == null) { this.matrix = matrix; - return ; + return; } - if (matrix.length< 16) { + if (matrix.length < 16) { throw new IllegalArgumentException("Number of matrix elements is < 16"); } if (matrix.length > 16) { @@ -277,87 +292,88 @@ public void setMatrix(float[] matrix) { } /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
- * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
- * Number of items: 16
- * Array elements:
- *   The elements of this array (optional) - * - * @return The matrix - * + * Returns the default value of the matrix
+ * + * @return The default matrix + * @see #getMatrix + * */ - public float[] getMatrix() { - return this.matrix; + public float[] defaultMatrix() { + return new float[]{1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F}; } /** - * Returns the default value of the matrix
- * @see #getMatrix - * - * @return The default matrix - * + * The index of the mesh in this node. (optional) + * + * @return The mesh + * */ - public float[] defaultMatrix() { - return new float[] { 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F }; + public Integer getMesh() { + return this.mesh; } /** - * The index of the mesh in this node. (optional) - * + * The index of the mesh in this node. (optional) + * * @param mesh The mesh to set - * + * */ public void setMesh(Integer mesh) { if (mesh == null) { this.mesh = mesh; - return ; + return; } this.mesh = mesh; } /** - * The index of the mesh in this node. (optional) - * - * @return The mesh - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
+ * Default: [0.0,0.0,0.0,1.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: -1.0 (inclusive)
+ *   Maximum: 1.0 (inclusive) + * + * @return The rotation + * */ - public Integer getMesh() { - return this.mesh; + public float[] getRotation() { + return this.rotation; } /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
- * Default: [0.0,0.0,0.0,1.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: -1.0 (inclusive)
- *   Maximum: 1.0 (inclusive) - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
+ * Default: [0.0,0.0,0.0,1.0]
+ * Number of items: 4
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: -1.0 (inclusive)
+ *   Maximum: 1.0 (inclusive) + * * @param rotation The rotation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setRotation(float[] rotation) { if (rotation == null) { this.rotation = rotation; - return ; + return; } - if (rotation.length< 4) { + if (rotation.length < 4) { throw new IllegalArgumentException("Number of rotation elements is < 4"); } if (rotation.length > 4) { throw new IllegalArgumentException("Number of rotation elements is > 4"); } - for (float rotationElement: rotation) { + for (float rotationElement : rotation) { if (rotationElement > 1.0D) { throw new IllegalArgumentException("rotationElement > 1.0"); } - if (rotationElement<-1.0D) { + if (rotationElement < -1.0D) { throw new IllegalArgumentException("rotationElement < -1.0"); } } @@ -365,52 +381,50 @@ public void setRotation(float[] rotation) { } /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
- * Default: [0.0,0.0,0.0,1.0]
- * Number of items: 4
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: -1.0 (inclusive)
- *   Maximum: 1.0 (inclusive) - * - * @return The rotation - * + * Returns the default value of the rotation
+ * + * @return The default rotation + * @see #getRotation + * */ - public float[] getRotation() { - return this.rotation; + public float[] defaultRotation() { + return new float[]{0.0F, 0.0F, 0.0F, 1.0F}; } /** - * Returns the default value of the rotation
- * @see #getRotation - * - * @return The default rotation - * + * The node's non-uniform scale, given as the scaling factors along the + * x, y, and z axes. (optional)
+ * Default: [1.0,1.0,1.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The scale + * */ - public float[] defaultRotation() { - return new float[] { 0.0F, 0.0F, 0.0F, 1.0F }; + public float[] getScale() { + return this.scale; } /** - * The node's non-uniform scale, given as the scaling factors along the - * x, y, and z axes. (optional)
- * Default: [1.0,1.0,1.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * + * The node's non-uniform scale, given as the scaling factors along the + * x, y, and z axes. (optional)
+ * Default: [1.0,1.0,1.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * * @param scale The scale to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setScale(float[] scale) { if (scale == null) { this.scale = scale; - return ; + return; } - if (scale.length< 3) { + if (scale.length < 3) { throw new IllegalArgumentException("Number of scale elements is < 3"); } if (scale.length > 3) { @@ -420,49 +434,48 @@ public void setScale(float[] scale) { } /** - * The node's non-uniform scale, given as the scaling factors along the - * x, y, and z axes. (optional)
- * Default: [1.0,1.0,1.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * - * @return The scale - * + * Returns the default value of the scale
+ * + * @return The default scale + * @see #getScale + * */ - public float[] getScale() { - return this.scale; + public float[] defaultScale() { + return new float[]{1.0F, 1.0F, 1.0F}; } /** - * Returns the default value of the scale
- * @see #getScale - * - * @return The default scale - * + * The node's translation along the x, y, and z axes. (optional)
+ * Default: [0.0,0.0,0.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The translation + * */ - public float[] defaultScale() { - return new float[] { 1.0F, 1.0F, 1.0F }; + public float[] getTranslation() { + return this.translation; } /** - * The node's translation along the x, y, and z axes. (optional)
- * Default: [0.0,0.0,0.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * + * The node's translation along the x, y, and z axes. (optional)
+ * Default: [0.0,0.0,0.0]
+ * Number of items: 3
+ * Array elements:
+ *   The elements of this array (optional) + * * @param translation The translation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTranslation(float[] translation) { if (translation == null) { this.translation = translation; - return ; + return; } - if (translation.length< 3) { + if (translation.length < 3) { throw new IllegalArgumentException("Number of translation elements is < 3"); } if (translation.length > 3) { @@ -472,77 +485,63 @@ public void setTranslation(float[] translation) { } /** - * The node's translation along the x, y, and z axes. (optional)
- * Default: [0.0,0.0,0.0]
- * Number of items: 3
- * Array elements:
- *   The elements of this array (optional) - * - * @return The translation - * + * Returns the default value of the translation
+ * + * @return The default translation + * @see #getTranslation + * */ - public float[] getTranslation() { - return this.translation; + public float[] defaultTranslation() { + return new float[]{0.0F, 0.0F, 0.0F}; } /** - * Returns the default value of the translation
- * @see #getTranslation - * - * @return The default translation - * + * The weights of the instantiated morph target. The number of array + * elements **MUST** match the number of morph targets of the referenced + * mesh. When defined, `mesh` **MUST** also be defined. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * + * @return The weights + * */ - public float[] defaultTranslation() { - return new float[] { 0.0F, 0.0F, 0.0F }; + public List getWeights() { + return this.weights; } /** - * The weights of the instantiated morph target. The number of array - * elements **MUST** match the number of morph targets of the referenced - * mesh. When defined, `mesh` **MUST** also be defined. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * + * The weights of the instantiated morph target. The number of array + * elements **MUST** match the number of morph targets of the referenced + * mesh. When defined, `mesh` **MUST** also be defined. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional) + * * @param weights The weights to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWeights(List weights) { if (weights == null) { this.weights = weights; - return ; + return; } - if (weights.size()< 1) { + if (weights.size() < 1) { throw new IllegalArgumentException("Number of weights elements is < 1"); } this.weights = weights; } /** - * The weights of the instantiated morph target. The number of array - * elements **MUST** match the number of morph targets of the referenced - * mesh. When defined, `mesh` **MUST** also be defined. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional) - * - * @return The weights - * - */ - public List getWeights() { - return this.weights; - } - - /** - * Add the given weights. The weights of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given weights. The weights of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addWeights(Float element) { if (element == null) { @@ -550,7 +549,7 @@ public void addWeights(Float element) { } List oldList = this.weights; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -558,15 +557,15 @@ public void addWeights(Float element) { } /** - * Remove the given weights. The weights of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given weights. The weights of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeWeights(Float element) { if (element == null) { @@ -574,7 +573,7 @@ public void removeWeights(Float element) { } List oldList = this.weights; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Sampler.java b/src/main/java/de/javagl/jgltf/impl/v2/Sampler.java index 9a0f350..fd9226e 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Sampler.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Sampler.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,192 +9,190 @@ package de.javagl.jgltf.impl.v2; - /** - * Texture sampler properties for filtering and wrapping modes. - * - * Auto-generated for sampler.schema.json - * + * Texture sampler properties for filtering and wrapping modes. + *

+ * Auto-generated for sampler.schema.json + * */ public class Sampler - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * Magnification filter. (optional)
- * Valid values: [9728, 9729] - * + * Magnification filter. (optional)
+ * Valid values: [9728, 9729] + * */ private Integer magFilter; /** - * Minification filter. (optional)
- * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * + * Minification filter. (optional)
+ * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * */ private Integer minFilter; /** - * S (U) wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * + * S (U) wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * */ private Integer wrapS; /** - * T (V) wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * + * T (V) wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * */ private Integer wrapT; /** - * Magnification filter. (optional)
- * Valid values: [9728, 9729] - * + * Magnification filter. (optional)
+ * Valid values: [9728, 9729] + * + * @return The magFilter + * + */ + public Integer getMagFilter() { + return this.magFilter; + } + + /** + * Magnification filter. (optional)
+ * Valid values: [9728, 9729] + * * @param magFilter The magFilter to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMagFilter(Integer magFilter) { if (magFilter == null) { this.magFilter = magFilter; - return ; + return; } - if ((magFilter!= 9728)&&(magFilter!= 9729)) { - throw new IllegalArgumentException((("Invalid value for magFilter: "+ magFilter)+", valid: [9728, 9729]")); + if ((magFilter != 9728) && (magFilter != 9729)) { + throw new IllegalArgumentException((("Invalid value for magFilter: " + magFilter) + ", valid: [9728, 9729]")); } this.magFilter = magFilter; } /** - * Magnification filter. (optional)
- * Valid values: [9728, 9729] - * - * @return The magFilter - * + * Minification filter. (optional)
+ * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * + * @return The minFilter + * */ - public Integer getMagFilter() { - return this.magFilter; + public Integer getMinFilter() { + return this.minFilter; } /** - * Minification filter. (optional)
- * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * + * Minification filter. (optional)
+ * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * * @param minFilter The minFilter to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMinFilter(Integer minFilter) { if (minFilter == null) { this.minFilter = minFilter; - return ; + return; } - if ((((((minFilter!= 9728)&&(minFilter!= 9729))&&(minFilter!= 9984))&&(minFilter!= 9985))&&(minFilter!= 9986))&&(minFilter!= 9987)) { - throw new IllegalArgumentException((("Invalid value for minFilter: "+ minFilter)+", valid: [9728, 9729, 9984, 9985, 9986, 9987]")); + if ((((((minFilter != 9728) && (minFilter != 9729)) && (minFilter != 9984)) && (minFilter != 9985)) && (minFilter != 9986)) && (minFilter != 9987)) { + throw new IllegalArgumentException((("Invalid value for minFilter: " + minFilter) + ", valid: [9728, 9729, 9984, 9985, 9986, 9987]")); } this.minFilter = minFilter; } /** - * Minification filter. (optional)
- * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * - * @return The minFilter - * + * S (U) wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * + * @return The wrapS + * */ - public Integer getMinFilter() { - return this.minFilter; + public Integer getWrapS() { + return this.wrapS; } /** - * S (U) wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * + * S (U) wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * * @param wrapS The wrapS to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWrapS(Integer wrapS) { if (wrapS == null) { this.wrapS = wrapS; - return ; + return; } - if (((wrapS!= 33071)&&(wrapS!= 33648))&&(wrapS!= 10497)) { - throw new IllegalArgumentException((("Invalid value for wrapS: "+ wrapS)+", valid: [33071, 33648, 10497]")); + if (((wrapS != 33071) && (wrapS != 33648)) && (wrapS != 10497)) { + throw new IllegalArgumentException((("Invalid value for wrapS: " + wrapS) + ", valid: [33071, 33648, 10497]")); } this.wrapS = wrapS; } /** - * S (U) wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * - * @return The wrapS - * + * Returns the default value of the wrapS
+ * + * @return The default wrapS + * @see #getWrapS + * */ - public Integer getWrapS() { - return this.wrapS; + public Integer defaultWrapS() { + return 10497; } /** - * Returns the default value of the wrapS
- * @see #getWrapS - * - * @return The default wrapS - * + * T (V) wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * + * @return The wrapT + * */ - public Integer defaultWrapS() { - return 10497; + public Integer getWrapT() { + return this.wrapT; } /** - * T (V) wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * + * T (V) wrapping mode. (optional)
+ * Default: 10497
+ * Valid values: [33071, 33648, 10497] + * * @param wrapT The wrapT to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWrapT(Integer wrapT) { if (wrapT == null) { this.wrapT = wrapT; - return ; + return; } - if (((wrapT!= 33071)&&(wrapT!= 33648))&&(wrapT!= 10497)) { - throw new IllegalArgumentException((("Invalid value for wrapT: "+ wrapT)+", valid: [33071, 33648, 10497]")); + if (((wrapT != 33071) && (wrapT != 33648)) && (wrapT != 10497)) { + throw new IllegalArgumentException((("Invalid value for wrapT: " + wrapT) + ", valid: [33071, 33648, 10497]")); } this.wrapT = wrapT; } /** - * T (V) wrapping mode. (optional)
- * Default: 10497
- * Valid values: [33071, 33648, 10497] - * - * @return The wrapT - * - */ - public Integer getWrapT() { - return this.wrapT; - } - - /** - * Returns the default value of the wrapT
- * @see #getWrapT - * + * Returns the default value of the wrapT
+ * * @return The default wrapT - * + * @see #getWrapT + * */ public Integer defaultWrapT() { - return 10497; + return 10497; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Scene.java b/src/main/java/de/javagl/jgltf/impl/v2/Scene.java index c064edf..769e28d 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Scene.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Scene.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,47 +13,60 @@ /** - * The root nodes of a scene. - * - * Auto-generated for scene.schema.json - * + * The root nodes of a scene. + *

+ * Auto-generated for scene.schema.json + * */ public class Scene - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The indices of each root node. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0 (inclusive) - * + * The indices of each root node. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0 (inclusive) + * */ private List nodes; /** - * The indices of each root node. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0 (inclusive) - * + * The indices of each root node. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0 (inclusive) + * + * @return The nodes + * + */ + public List getNodes() { + return this.nodes; + } + + /** + * The indices of each root node. (optional)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0 (inclusive) + * * @param nodes The nodes to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setNodes(List nodes) { if (nodes == null) { this.nodes = nodes; - return ; + return; } - if (nodes.size()< 1) { + if (nodes.size() < 1) { throw new IllegalArgumentException("Number of nodes elements is < 1"); } - for (Integer nodesElement: nodes) { - if (nodesElement< 0) { + for (Integer nodesElement : nodes) { + if (nodesElement < 0) { throw new IllegalArgumentException("nodesElement < 0"); } } @@ -61,27 +74,13 @@ public void setNodes(List nodes) { } /** - * The indices of each root node. (optional)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0 (inclusive) - * - * @return The nodes - * - */ - public List getNodes() { - return this.nodes; - } - - /** - * Add the given nodes. The nodes of this instance will be replaced with - * a list that contains all previous elements, and additionally the new - * element. - * + * Add the given nodes. The nodes of this instance will be replaced with + * a list that contains all previous elements, and additionally the new + * element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addNodes(Integer element) { if (element == null) { @@ -89,7 +88,7 @@ public void addNodes(Integer element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -97,15 +96,15 @@ public void addNodes(Integer element) { } /** - * Remove the given nodes. The nodes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
- * If this new list would be empty, then it will be set to - * null. - * + * Remove the given nodes. The nodes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
+ * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeNodes(Integer element) { if (element == null) { @@ -113,7 +112,7 @@ public void removeNodes(Integer element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Skin.java b/src/main/java/de/javagl/jgltf/impl/v2/Skin.java index 8b1ccdd..fa72721 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Skin.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Skin.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,108 +13,121 @@ /** - * Joints and matrices defining a skin. - * - * Auto-generated for skin.schema.json - * + * Joints and matrices defining a skin. + *

+ * Auto-generated for skin.schema.json + * */ public class Skin - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The index of the accessor containing the floating-point 4x4 - * inverse-bind matrices. (optional) - * + * The index of the accessor containing the floating-point 4x4 + * inverse-bind matrices. (optional) + * */ private Integer inverseBindMatrices; /** - * The index of the node used as a skeleton root. (optional) - * + * The index of the node used as a skeleton root. (optional) + * */ private Integer skeleton; /** - * Indices of skeleton nodes, used as joints in this skin. (required)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0 (inclusive) - * + * Indices of skeleton nodes, used as joints in this skin. (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0 (inclusive) + * */ private List joints; /** - * The index of the accessor containing the floating-point 4x4 - * inverse-bind matrices. (optional) - * + * The index of the accessor containing the floating-point 4x4 + * inverse-bind matrices. (optional) + * + * @return The inverseBindMatrices + * + */ + public Integer getInverseBindMatrices() { + return this.inverseBindMatrices; + } + + /** + * The index of the accessor containing the floating-point 4x4 + * inverse-bind matrices. (optional) + * * @param inverseBindMatrices The inverseBindMatrices to set - * + * */ public void setInverseBindMatrices(Integer inverseBindMatrices) { if (inverseBindMatrices == null) { this.inverseBindMatrices = inverseBindMatrices; - return ; + return; } this.inverseBindMatrices = inverseBindMatrices; } /** - * The index of the accessor containing the floating-point 4x4 - * inverse-bind matrices. (optional) - * - * @return The inverseBindMatrices - * + * The index of the node used as a skeleton root. (optional) + * + * @return The skeleton + * */ - public Integer getInverseBindMatrices() { - return this.inverseBindMatrices; + public Integer getSkeleton() { + return this.skeleton; } /** - * The index of the node used as a skeleton root. (optional) - * + * The index of the node used as a skeleton root. (optional) + * * @param skeleton The skeleton to set - * + * */ public void setSkeleton(Integer skeleton) { if (skeleton == null) { this.skeleton = skeleton; - return ; + return; } this.skeleton = skeleton; } /** - * The index of the node used as a skeleton root. (optional) - * - * @return The skeleton - * + * Indices of skeleton nodes, used as joints in this skin. (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0 (inclusive) + * + * @return The joints + * */ - public Integer getSkeleton() { - return this.skeleton; + public List getJoints() { + return this.joints; } /** - * Indices of skeleton nodes, used as joints in this skin. (required)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0 (inclusive) - * + * Indices of skeleton nodes, used as joints in this skin. (required)
+ * Minimum number of items: 1
+ * Array elements:
+ *   The elements of this array (optional)
+ *   Minimum: 0 (inclusive) + * * @param joints The joints to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setJoints(List joints) { if (joints == null) { - throw new NullPointerException((("Invalid value for joints: "+ joints)+", may not be null")); + throw new NullPointerException((("Invalid value for joints: " + joints) + ", may not be null")); } - if (joints.size()< 1) { + if (joints.size() < 1) { throw new IllegalArgumentException("Number of joints elements is < 1"); } - for (Integer jointsElement: joints) { - if (jointsElement< 0) { + for (Integer jointsElement : joints) { + if (jointsElement < 0) { throw new IllegalArgumentException("jointsElement < 0"); } } @@ -122,27 +135,13 @@ public void setJoints(List joints) { } /** - * Indices of skeleton nodes, used as joints in this skin. (required)
- * Minimum number of items: 1
- * Array elements:
- *   The elements of this array (optional)
- *   Minimum: 0 (inclusive) - * - * @return The joints - * - */ - public List getJoints() { - return this.joints; - } - - /** - * Add the given joints. The joints of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Add the given joints. The joints of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addJoints(Integer element) { if (element == null) { @@ -150,7 +149,7 @@ public void addJoints(Integer element) { } List oldList = this.joints; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.add(element); @@ -158,13 +157,13 @@ public void addJoints(Integer element) { } /** - * Remove the given joints. The joints of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one. - * + * Remove the given joints. The joints of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeJoints(Integer element) { if (element == null) { @@ -172,7 +171,7 @@ public void removeJoints(Integer element) { } List oldList = this.joints; List newList = new ArrayList(); - if (oldList!= null) { + if (oldList != null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Texture.java b/src/main/java/de/javagl/jgltf/impl/v2/Texture.java index bf1f5a3..f7cd642 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Texture.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Texture.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,86 +9,84 @@ package de.javagl.jgltf.impl.v2; - /** - * A texture and its sampler. - * - * Auto-generated for texture.schema.json - * + * A texture and its sampler. + *

+ * Auto-generated for texture.schema.json + * */ public class Texture - extends GlTFChildOfRootProperty -{ + extends GlTFChildOfRootProperty { /** - * The index of the sampler used by this texture. When undefined, a - * sampler with repeat wrapping and auto filtering **SHOULD** be used. - * (optional) - * + * The index of the sampler used by this texture. When undefined, a + * sampler with repeat wrapping and auto filtering **SHOULD** be used. + * (optional) + * */ private Integer sampler; /** - * The index of the image used by this texture. When undefined, an - * extension or other mechanism **SHOULD** supply an alternate texture - * source, otherwise behavior is undefined. (optional) - * + * The index of the image used by this texture. When undefined, an + * extension or other mechanism **SHOULD** supply an alternate texture + * source, otherwise behavior is undefined. (optional) + * */ private Integer source; /** - * The index of the sampler used by this texture. When undefined, a - * sampler with repeat wrapping and auto filtering **SHOULD** be used. - * (optional) - * + * The index of the sampler used by this texture. When undefined, a + * sampler with repeat wrapping and auto filtering **SHOULD** be used. + * (optional) + * + * @return The sampler + * + */ + public Integer getSampler() { + return this.sampler; + } + + /** + * The index of the sampler used by this texture. When undefined, a + * sampler with repeat wrapping and auto filtering **SHOULD** be used. + * (optional) + * * @param sampler The sampler to set - * + * */ public void setSampler(Integer sampler) { if (sampler == null) { this.sampler = sampler; - return ; + return; } this.sampler = sampler; } /** - * The index of the sampler used by this texture. When undefined, a - * sampler with repeat wrapping and auto filtering **SHOULD** be used. - * (optional) - * - * @return The sampler - * + * The index of the image used by this texture. When undefined, an + * extension or other mechanism **SHOULD** supply an alternate texture + * source, otherwise behavior is undefined. (optional) + * + * @return The source + * */ - public Integer getSampler() { - return this.sampler; + public Integer getSource() { + return this.source; } /** - * The index of the image used by this texture. When undefined, an - * extension or other mechanism **SHOULD** supply an alternate texture - * source, otherwise behavior is undefined. (optional) - * + * The index of the image used by this texture. When undefined, an + * extension or other mechanism **SHOULD** supply an alternate texture + * source, otherwise behavior is undefined. (optional) + * * @param source The source to set - * + * */ public void setSource(Integer source) { if (source == null) { this.source = source; - return ; + return; } this.source = source; } - /** - * The index of the image used by this texture. When undefined, an - * extension or other mechanism **SHOULD** supply an alternate texture - * source, otherwise behavior is undefined. (optional) - * - * @return The source - * - */ - public Integer getSource() { - return this.source; - } - } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/TextureInfo.java b/src/main/java/de/javagl/jgltf/impl/v2/TextureInfo.java index 8d4e6a1..e361716 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/TextureInfo.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/TextureInfo.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,99 +9,97 @@ package de.javagl.jgltf.impl.v2; - /** - * Reference to a texture. - * - * Auto-generated for textureInfo.schema.json - * + * Reference to a texture. + *

+ * Auto-generated for textureInfo.schema.json + * */ public class TextureInfo - extends GlTFProperty -{ + extends GlTFProperty { /** - * The index of the texture. (required) - * + * The index of the texture. (required) + * */ private Integer index; /** - * The set index of texture's TEXCOORD attribute used for texture - * coordinate mapping. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The set index of texture's TEXCOORD attribute used for texture + * coordinate mapping. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * */ private Integer texCoord; /** - * The index of the texture. (required) - * + * The index of the texture. (required) + * + * @return The index + * + */ + public Integer getIndex() { + return this.index; + } + + /** + * The index of the texture. (required) + * * @param index The index to set * @throws NullPointerException If the given value is null - * + * */ public void setIndex(Integer index) { if (index == null) { - throw new NullPointerException((("Invalid value for index: "+ index)+", may not be null")); + throw new NullPointerException((("Invalid value for index: " + index) + ", may not be null")); } this.index = index; } /** - * The index of the texture. (required) - * - * @return The index - * + * The set index of texture's TEXCOORD attribute used for texture + * coordinate mapping. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * + * @return The texCoord + * */ - public Integer getIndex() { - return this.index; + public Integer getTexCoord() { + return this.texCoord; } /** - * The set index of texture's TEXCOORD attribute used for texture - * coordinate mapping. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * + * The set index of texture's TEXCOORD attribute used for texture + * coordinate mapping. (optional)
+ * Default: 0
+ * Minimum: 0 (inclusive) + * * @param texCoord The texCoord to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTexCoord(Integer texCoord) { if (texCoord == null) { this.texCoord = texCoord; - return ; + return; } - if (texCoord< 0) { + if (texCoord < 0) { throw new IllegalArgumentException("texCoord < 0"); } this.texCoord = texCoord; } /** - * The set index of texture's TEXCOORD attribute used for texture - * coordinate mapping. (optional)
- * Default: 0
- * Minimum: 0 (inclusive) - * - * @return The texCoord - * - */ - public Integer getTexCoord() { - return this.texCoord; - } - - /** - * Returns the default value of the texCoord
- * @see #getTexCoord - * + * Returns the default value of the texCoord
+ * * @return The default texCoord - * + * @see #getTexCoord + * */ public Integer defaultTexCoord() { - return 0; + return 0; } } diff --git a/src/main/java/de/javagl/jgltf/model/AbstractAccessorData.java b/src/main/java/de/javagl/jgltf/model/AbstractAccessorData.java index 385ed38..f225510 100644 --- a/src/main/java/de/javagl/jgltf/model/AbstractAccessorData.java +++ b/src/main/java/de/javagl/jgltf/model/AbstractAccessorData.java @@ -32,13 +32,12 @@ /** * Package-private abstract base implementation of an {@link AccessorData} */ -abstract class AbstractAccessorData implements AccessorData -{ +abstract class AbstractAccessorData implements AccessorData { /** * The component type */ private final Class componentType; - + /** * The byte buffer of the buffer view that the accessor * refers to @@ -55,168 +54,143 @@ abstract class AbstractAccessorData implements AccessorData * The number of elements */ private final int numElements; - + /** * The {@link ElementType} */ private final ElementType elementType; - + /** * The number of bytes per component */ private final int numBytesPerComponent; - + /** - * The stride, in number of bytes, between two consecutive elements + * The stride, in number of bytes, between two consecutive elements */ private final int byteStridePerElement; /** * Default constructor - * + * * @param accessorComponentType The accessor component type - * @param componentType The component type - * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param numBytesPerComponent The number of bytes per component - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * @throws NullPointerException If the bufferViewByteBuffer is - * null + * @param componentType The component type + * @param bufferViewByteBuffer The byte buffer of the buffer view + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param numBytesPerComponent The number of bytes per component + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * @throws NullPointerException If the bufferViewByteBuffer is + * null */ - AbstractAccessorData(int accessorComponentType, Class componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, - int numElements, ElementType elementType, - int numBytesPerComponent, Integer byteStride) - { - Objects.requireNonNull(bufferViewByteBuffer, - "The bufferViewByteBuffer is null"); - + AbstractAccessorData(int accessorComponentType, Class componentType, + ByteBuffer bufferViewByteBuffer, int byteOffset, + int numElements, ElementType elementType, + int numBytesPerComponent, Integer byteStride) { + Objects.requireNonNull(bufferViewByteBuffer, + "The bufferViewByteBuffer is null"); + this.componentType = componentType; this.bufferViewByteBuffer = bufferViewByteBuffer; this.byteOffset = byteOffset; this.numElements = numElements; this.elementType = elementType; this.numBytesPerComponent = numBytesPerComponent; - if (byteStride == null || byteStride == 0) - { - this.byteStridePerElement = - elementType.getByteStride(accessorComponentType); - } - else - { + if (byteStride == null || byteStride == 0) { + this.byteStridePerElement = + elementType.getByteStride(accessorComponentType); + } else { this.byteStridePerElement = byteStride; } } - + @Override - public final Class getComponentType() - { + public final Class getComponentType() { return componentType; } @Override - public final int getNumElements() - { + public final int getNumElements() { return numElements; } @Override - public final int getNumComponentsPerElement() - { + public final int getNumComponentsPerElement() { return elementType.getNumComponents(); } @Override - public final int getTotalNumComponents() - { + public final int getTotalNumComponents() { return numElements * getNumComponentsPerElement(); } - + /** * Returns the index of the byte in the byte buffer where the specified * component starts - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The byte index */ - protected final int getByteIndex(int elementIndex, int componentIndex) - { + protected final int getByteIndex(int elementIndex, int componentIndex) { // Compute the byte index, including possible padding for // matrix columns, as specified in 3.6.2.4. Data Alignment - int byteIndex = byteOffset - + elementIndex * byteStridePerElement; - if (this.componentType == byte.class) - { - if (this.elementType == ElementType.MAT2) - { + int byteIndex = byteOffset + + elementIndex * byteStridePerElement; + if (this.componentType == byte.class) { + if (this.elementType == ElementType.MAT2) { int columnIndex = componentIndex / 2; int rowIndex = componentIndex % 2; byteIndex += columnIndex * 4 + rowIndex; - } - else if (this.elementType == ElementType.MAT3) - { + } else if (this.elementType == ElementType.MAT3) { int columnIndex = componentIndex / 3; int rowIndex = componentIndex % 3; byteIndex += columnIndex * 4 + rowIndex; - } - else - { + } else { byteIndex += componentIndex * numBytesPerComponent; } - } - else if (this.componentType == short.class) - { - if (this.elementType == ElementType.MAT3) - { + } else if (this.componentType == short.class) { + if (this.elementType == ElementType.MAT3) { int columnIndex = componentIndex / 3; int rowIndex = componentIndex % 3; byteIndex += columnIndex * 8 + rowIndex * 2; - } - else - { + } else { byteIndex += componentIndex * numBytesPerComponent; } - } - else - { + } else { byteIndex += componentIndex * numBytesPerComponent; } return byteIndex; } - - + + /** * Returns the underlying byte buffer - * + * * @return The byte buffer */ - protected final ByteBuffer getBufferViewByteBuffer() - { + protected final ByteBuffer getBufferViewByteBuffer() { return bufferViewByteBuffer; } - + /** * Returns the byte stride per element - * + * * @return The byte stride */ - protected final int getByteStridePerElement() - { + protected final int getByteStridePerElement() { return byteStridePerElement; } - + /** * Returns the number of bytes per component - * + * * @return The number of bytes per component */ - protected final int getNumBytesPerComponent() - { + protected final int getNumBytesPerComponent() { return numBytesPerComponent; } diff --git a/src/main/java/de/javagl/jgltf/model/AccessorByteData.java b/src/main/java/de/javagl/jgltf/model/AccessorByteData.java index 0b6eac4..b4c66f8 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorByteData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorByteData.java @@ -35,184 +35,172 @@ * A class for accessing the data that is described by an accessor. * It allows accessing the byte buffer of the buffer view of the * accessor, depending on the accessor parameters.
- *
+ *
* This data consists of several elements (for example, 3D byte vectors), - * which consist of several components (for example, the 3 byte values). + * which consist of several components (for example, the 3 byte values). */ -public final class AccessorByteData - extends AbstractAccessorData implements AccessorData -{ +public final class AccessorByteData + extends AbstractAccessorData implements AccessorData { /** * Whether the data should be interpreted as unsigned values */ private final boolean unsigned; - + /** - * Creates a new instance for accessing the data in the given + * Creates a new instance for accessing the data in the given * byte buffer, according to the rules described by the given * accessor parameters. - * @param componentType The component type + * + * @param componentType The component type * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * - * @throws NullPointerException If the bufferViewByteBuffer is - * null - * @throws IllegalArgumentException If the component type is not - * GL_BYTE or GL_UNSIGEND_BYTE + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * @throws NullPointerException If the bufferViewByteBuffer is + * null + * @throws IllegalArgumentException If the component type is not + * GL_BYTE or GL_UNSIGEND_BYTE * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity to provide the data for the accessor + * have a sufficient capacity to provide the data for the accessor */ public AccessorByteData(int componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, - ElementType elementType, Integer byteStride) - { - super(componentType, byte.class, bufferViewByteBuffer, byteOffset, - numElements, elementType, Byte.BYTES, byteStride); + ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, + ElementType elementType, Integer byteStride) { + super(componentType, byte.class, bufferViewByteBuffer, byteOffset, + numElements, elementType, Byte.BYTES, byteStride); AccessorDatas.validateByteType(componentType); this.unsigned = AccessorDatas.isUnsignedType(componentType); - int numBytesPerElement = - getNumComponentsPerElement() * getNumBytesPerComponent(); - AccessorDatas.validateCapacity(byteOffset, getNumElements(), - numBytesPerElement, getByteStridePerElement(), - bufferViewByteBuffer.capacity()); + int numBytesPerElement = + getNumComponentsPerElement() * getNumBytesPerComponent(); + AccessorDatas.validateCapacity(byteOffset, getNumElements(), + numBytesPerElement, getByteStridePerElement(), + bufferViewByteBuffer.capacity()); } - + /** * Returns whether the data should be interpreted as unsigned - * + * * @return Whether the data should be interpreted as unsigned */ - public boolean isUnsigned() - { + public boolean isUnsigned() { return unsigned; } - + /** * Returns the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public byte get(int elementIndex, int componentIndex) - { + public byte get(int elementIndex, int componentIndex) { int byteIndex = getByteIndex(elementIndex, componentIndex); return getBufferViewByteBuffer().get(byteIndex); } - + public float getFloat(int elementIndex, int componentIndex) { - byte value = get(elementIndex, componentIndex); + byte value = get(elementIndex, componentIndex); return unsigned ? Byte.toUnsignedInt(value) / (Byte.MAX_VALUE - Byte.MIN_VALUE) : Math.max(value / Byte.MAX_VALUE, -1.0F); } - + /** * Returns the value of the specified component - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public byte get(int globalComponentIndex) - { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public byte get(int globalComponentIndex) { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); return get(elementIndex, componentIndex); } /** * Set the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int elementIndex, int componentIndex, byte value) - { + public void set(int elementIndex, int componentIndex, byte value) { int byteIndex = getByteIndex(elementIndex, componentIndex); getBufferViewByteBuffer().put(byteIndex, value); } - + /** * Set the value of the specified component - * + * * @param globalComponentIndex The global component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int globalComponentIndex, byte value) - { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public void set(int globalComponentIndex, byte value) { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); set(elementIndex, componentIndex, value); } - - + + /** - * Returns the value of the specified component of the specified element, - * taking into account whether the data {@link #isUnsigned()}: If the data - * is unsigned, the returned byte value will be converted into an + * Returns the value of the specified component of the specified element, + * taking into account whether the data {@link #isUnsigned()}: If the data + * is unsigned, the returned byte value will be converted into an * unsigned integer value. - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int getInt(int elementIndex, int componentIndex) - { + public int getInt(int elementIndex, int componentIndex) { byte value = get(elementIndex, componentIndex); return unsigned ? Byte.toUnsignedInt(value) : value; } - + /** * Returns the value of the specified component, taking into account * whether the data {@link #isUnsigned()}: If the data is unsigned, * the returned byte value will be converted into an unsigned integer * value. - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int getInt(int globalComponentIndex) - { + public int getInt(int globalComponentIndex) { byte value = get(globalComponentIndex); return unsigned ? Byte.toUnsignedInt(value) : value; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public byte[] computeMin() - { + public byte[] computeMin() { byte result[] = new byte[getNumComponentsPerElement()]; Arrays.fill(result, Byte.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = (byte) Math.min(result[c], get(e, c)); } } @@ -220,42 +208,36 @@ public byte[] computeMin() } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public byte[] computeMax() - { + public byte[] computeMax() { byte result[] = new byte[getNumComponentsPerElement()]; Arrays.fill(result, Byte.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = (byte) Math.max(result[c], get(e, c)); } } return result; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getInt(int, int)}. - * + * * @return The minimum values */ - public int[] computeMinInt() - { + public int[] computeMinInt() { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.min(result[c], getInt(e, c)); } } @@ -263,88 +245,75 @@ public int[] computeMinInt() } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getInt(int, int)}. - * + * * @return The minimum values */ - public int[] computeMaxInt() - { + public int[] computeMaxInt() { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.max(result[c], getInt(e, c)); } } return result; } - + @Override - public ByteBuffer createByteBuffer() - { + public ByteBuffer createByteBuffer() { int totalNumComponents = getTotalNumComponents(); int totalBytes = totalNumComponents * getNumBytesPerComponent(); ByteBuffer result = ByteBuffer.allocateDirect(totalBytes) - .order(ByteOrder.nativeOrder()); - for (int i=0; i 0) - { + for (int e = 0; e < getNumElements(); e++) { + if (e > 0) { sb.append(", "); - if (elementsPerRow > 0 && (e % elementsPerRow) == 0) - { + if (elementsPerRow > 0 && (e % elementsPerRow) == 0) { sb.append("\n "); } } - if (nc > 1) - { + if (nc > 1) { sb.append("("); } - for (int c = 0; c < nc; c++) - { - if (c > 0) - { + for (int c = 0; c < nc; c++) { + if (c > 0) { sb.append(", "); } int component = getInt(e, c); sb.append(String.format(locale, format, component)); } - if (nc > 1) - { + if (nc > 1) { sb.append(")"); } } sb.append("]"); return sb.toString(); } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/AccessorData.java b/src/main/java/de/javagl/jgltf/model/AccessorData.java index 2f3d4be..abcdfa9 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorData.java @@ -30,34 +30,33 @@ /** * Interface for classes that provide typed access to raw accessor data. - * The exact type of the data (and thus, the implementing class) is + * The exact type of the data (and thus, the implementing class) is * defined by the {@link #getComponentType() component type}:
*

*/ -public interface AccessorData -{ +public interface AccessorData { /** * Returns the type of the components that this class provides access to. * This will usually be a primitive type, like float.class * or short.class. - * + * * @return The component type */ Class getComponentType(); - + /** * Returns the number of elements in this data (for example, the number * of 3D vectors) - * + * * @return The number of elements */ int getNumElements(); @@ -65,7 +64,7 @@ public interface AccessorData /** * Returns the number of components per element (for example, 3 if the * elements are 3D vectors) - * + * * @return The number of components per element */ int getNumComponentsPerElement(); @@ -73,7 +72,7 @@ public interface AccessorData /** * Returns the total number of components (that is, the number of elements * multiplied with the number of components per element) - * + * * @return The total number of components */ int getTotalNumComponents(); @@ -82,12 +81,12 @@ public interface AccessorData * Creates a new, direct byte buffer (with native byte order) that * contains the data for the accessor, in a compact form, * without any offset, and without any additional stride (that is, - * all elements will be tightly packed). - * + * all elements will be tightly packed). + * * @return The byte buffer */ ByteBuffer createByteBuffer(); - + float getFloat(int elementIndex, int componentIndex); } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/AccessorDatas.java b/src/main/java/de/javagl/jgltf/model/AccessorDatas.java index 1d5f6ee..bae3fca 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorDatas.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorDatas.java @@ -34,26 +34,31 @@ * that allow a typed access to the data that is contained in the * buffer view that the accessor refers to.
*
- * Unless otherwise noted, none of the arguments to these methods may + * Unless otherwise noted, none of the arguments to these methods may * be null. */ -public class AccessorDatas -{ +public class AccessorDatas { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(AccessorDatas.class.getName()); - - + private static final Logger logger = + Logger.getLogger(AccessorDatas.class.getName()); + + + /** + * Private constructor to prevent instantiation + */ + private AccessorDatas() { + // Private constructor to prevent instantiation + } + /** * Create the {@link AccessorData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorData} */ - public static AccessorData create(AccessorModel accessorModel) - { + public static AccessorData create(AccessorModel accessorModel) { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); ByteBuffer bufferViewData = bufferViewModel.getBufferViewData(); return create(accessorModel, bufferViewData); @@ -62,566 +67,502 @@ public static AccessorData create(AccessorModel accessorModel) /** * Create the {@link AccessorData} for the given {@link AccessorModel} * that refers to the data from the given buffer. - * + * * @param accessorModel The {@link AccessorModel} - * @param byteBuffer The byte buffer containing the data + * @param byteBuffer The byte buffer containing the data * @return The {@link AccessorData} */ public static AccessorData create( - AccessorModel accessorModel, ByteBuffer byteBuffer) - { - if (accessorModel.getComponentDataType() == byte.class) - { + AccessorModel accessorModel, ByteBuffer byteBuffer) { + if (accessorModel.getComponentDataType() == byte.class) { return createByte(accessorModel, byteBuffer); } - if (accessorModel.getComponentDataType() == short.class) - { + if (accessorModel.getComponentDataType() == short.class) { return createShort(accessorModel, byteBuffer); } - if (accessorModel.getComponentDataType() == int.class) - { + if (accessorModel.getComponentDataType() == int.class) { return createInt(accessorModel, byteBuffer); } - if (accessorModel.getComponentDataType() == float.class) - { + if (accessorModel.getComponentDataType() == float.class) { return createFloat(accessorModel, byteBuffer); } // Should never happen logger.severe("Invalid component data type: " - + accessorModel.getComponentDataType()); + + accessorModel.getComponentDataType()); return null; } - + /** * Create an {@link AccessorData} depending on the given component type. * This will return an {@link AccessorByteData}, {@link AccessorShortData}, * {@link AccessorIntData} or {@link AccessorFloatData} - * - * @param componentType The component type, as a GL constant (for example, - * GL_UNSIGNED_SHORT or GL_FLOAT) + * + * @param componentType The component type, as a GL constant (for example, + * GL_UNSIGNED_SHORT or GL_FLOAT) * @param bufferViewData The buffer view data that the accessor refers to - * @param byteOffset The byte offset for the accessor - * @param count The count (number of elements) for the accessor - * @param elementType The {@link ElementType} - * For example, if the accessor type is "VEC3", then this - * will be 3 - * @param byteStride The optional byte stride for the accessor data + * @param byteOffset The byte offset for the accessor + * @param count The count (number of elements) for the accessor + * @param elementType The {@link ElementType} + * For example, if the accessor type is "VEC3", then this + * will be 3 + * @param byteStride The optional byte stride for the accessor data * @return The {@link AccessorData} * @throws IllegalArgumentException If the given component type is - * not a valid GL constant + * not a valid GL constant */ public static AccessorData create( - int componentType, ByteBuffer bufferViewData, int byteOffset, - int count, ElementType elementType, Integer byteStride) - { - if (isByteType(componentType)) - { + int componentType, ByteBuffer bufferViewData, int byteOffset, + int count, ElementType elementType, Integer byteStride) { + if (isByteType(componentType)) { return new AccessorByteData( - componentType, bufferViewData, byteOffset, count, - elementType, byteStride); + componentType, bufferViewData, byteOffset, count, + elementType, byteStride); } - if (isShortType(componentType)) - { + if (isShortType(componentType)) { return new AccessorShortData( - componentType, bufferViewData, byteOffset, count, - elementType, byteStride); + componentType, bufferViewData, byteOffset, count, + elementType, byteStride); } - if (isIntType(componentType)) - { + if (isIntType(componentType)) { return new AccessorIntData( - componentType, bufferViewData, byteOffset, count, - elementType, byteStride); + componentType, bufferViewData, byteOffset, count, + elementType, byteStride); } - if (isFloatType(componentType)) - { + if (isFloatType(componentType)) { return new AccessorFloatData( - componentType, bufferViewData, byteOffset, count, - elementType, byteStride); + componentType, bufferViewData, byteOffset, count, + elementType, byteStride); } throw new IllegalArgumentException( - "Not a valid component type: " + componentType); + "Not a valid component type: " + componentType); } - - - + /** * Returns whether the given constant is GL_BYTE or - * GL_UNSIGNED_BYTE. - * + * GL_UNSIGNED_BYTE. + * * @param type The type constant * @return Whether the type is a byte type */ - public static boolean isByteType(int type) - { - return - type == GltfConstants.GL_BYTE || - type == GltfConstants.GL_UNSIGNED_BYTE; + public static boolean isByteType(int type) { + return + type == GltfConstants.GL_BYTE || + type == GltfConstants.GL_UNSIGNED_BYTE; } - + /** * Returns whether the given constant is GL_SHORT or - * GL_UNSIGNED_SHORT. - * + * GL_UNSIGNED_SHORT. + * * @param type The type constant * @return Whether the type is a short type */ - public static boolean isShortType(int type) - { - return - type == GltfConstants.GL_SHORT || - type == GltfConstants.GL_UNSIGNED_SHORT; + public static boolean isShortType(int type) { + return + type == GltfConstants.GL_SHORT || + type == GltfConstants.GL_UNSIGNED_SHORT; } /** * Returns whether the given constant is GL_INT or - * GL_UNSIGNED_INT. - * + * GL_UNSIGNED_INT. + * * @param type The type constant * @return Whether the type is an int type */ - public static boolean isIntType(int type) - { - return - type == GltfConstants.GL_INT || - type == GltfConstants.GL_UNSIGNED_INT; + public static boolean isIntType(int type) { + return + type == GltfConstants.GL_INT || + type == GltfConstants.GL_UNSIGNED_INT; } /** * Returns whether the given constant is GL_FLOAT. - * + * * @param type The type constant * @return Whether the type is a float type */ - public static boolean isFloatType(int type) - { + public static boolean isFloatType(int type) { return type == GltfConstants.GL_FLOAT; } /** * Returns whether the given constant is GL_UNSIGNED_BYTE, * GL_UNSIGNED_SHORT or GL_UNSIGNED_INT. - * + * * @param type The type constant * @return Whether the type is an unsigned type */ - static boolean isUnsignedType(int type) - { - return - type == GltfConstants.GL_UNSIGNED_BYTE || - type == GltfConstants.GL_UNSIGNED_SHORT || - type == GltfConstants.GL_UNSIGNED_INT; + static boolean isUnsignedType(int type) { + return + type == GltfConstants.GL_UNSIGNED_BYTE || + type == GltfConstants.GL_UNSIGNED_SHORT || + type == GltfConstants.GL_UNSIGNED_INT; } - - + /** - * Make sure that the given type is GL_BYTE or - * GL_UNSIGNED_BYTE, and throw an + * Make sure that the given type is GL_BYTE or + * GL_UNSIGNED_BYTE, and throw an * IllegalArgumentException if this is not the case. - * + * * @param type The type constant - * @throws IllegalArgumentException If the given type is not - * GL_BYTE or GL_UNSIGNED_BYTE + * @throws IllegalArgumentException If the given type is not + * GL_BYTE or GL_UNSIGNED_BYTE */ - static void validateByteType(int type) - { - if (!isByteType(type)) - { + static void validateByteType(int type) { + if (!isByteType(type)) { throw new IllegalArgumentException( - "The type is not GL_BYTE or GL_UNSIGNED_BYTE, but " + - GltfConstants.stringFor(type)); + "The type is not GL_BYTE or GL_UNSIGNED_BYTE, but " + + GltfConstants.stringFor(type)); } } /** - * Make sure that the given type is GL_SHORT or - * GL_UNSIGNED_SHORT, and throw an + * Make sure that the given type is GL_SHORT or + * GL_UNSIGNED_SHORT, and throw an * IllegalArgumentException if this is not the case. - * + * * @param type The type constant - * @throws IllegalArgumentException If the given type is not - * GL_SHORT or GL_UNSIGNED_BYTE + * @throws IllegalArgumentException If the given type is not + * GL_SHORT or GL_UNSIGNED_BYTE */ - static void validateShortType(int type) - { - if (!isShortType(type)) - { + static void validateShortType(int type) { + if (!isShortType(type)) { throw new IllegalArgumentException( - "The type is not GL_SHORT or GL_UNSIGNED_SHORT, but " + - GltfConstants.stringFor(type)); + "The type is not GL_SHORT or GL_UNSIGNED_SHORT, but " + + GltfConstants.stringFor(type)); } } - + /** - * Make sure that the given type is GL_INT or - * GL_UNSIGNED_INT, and throw an + * Make sure that the given type is GL_INT or + * GL_UNSIGNED_INT, and throw an * IllegalArgumentException if this is not the case. - * + * * @param type The type constant - * @throws IllegalArgumentException If the given type is not - * GL_INT or GL_UNSIGNED_INT + * @throws IllegalArgumentException If the given type is not + * GL_INT or GL_UNSIGNED_INT */ - static void validateIntType(int type) - { - if (!isIntType(type)) - { + static void validateIntType(int type) { + if (!isIntType(type)) { throw new IllegalArgumentException( - "The type is not GL_INT or GL_UNSIGNED_INT, but " + - GltfConstants.stringFor(type)); + "The type is not GL_INT or GL_UNSIGNED_INT, but " + + GltfConstants.stringFor(type)); } } /** - * Make sure that the given type is GL_FLOAT, and throw an + * Make sure that the given type is GL_FLOAT, and throw an * IllegalArgumentException if this is not the case. - * + * * @param type The type constant - * @throws IllegalArgumentException If the given type is not - * GL_FLOAT + * @throws IllegalArgumentException If the given type is not + * GL_FLOAT */ - static void validateFloatType(int type) - { - if (!isFloatType(type)) - { + static void validateFloatType(int type) { + if (!isFloatType(type)) { throw new IllegalArgumentException( - "The type is not GL_FLOAT, but " + - GltfConstants.stringFor(type)); + "The type is not GL_FLOAT, but " + + GltfConstants.stringFor(type)); } } - - - + /** * Creates an {@link AccessorByteData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorByteData} - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessor is not GL_BYTE or GL_UNSIGNED_BYTE + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessor is not GL_BYTE or GL_UNSIGNED_BYTE */ - public static AccessorByteData createByte(AccessorModel accessorModel) - { + public static AccessorByteData createByte(AccessorModel accessorModel) { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); return createByte(accessorModel, bufferViewModel.getBufferViewData()); } - + /** * Creates an {@link AccessorByteData} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewByteBuffer The byte buffer of the - * {@link BufferViewModel} referenced by the {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewByteBuffer The byte buffer of the + * {@link BufferViewModel} referenced by the {@link AccessorModel} * @return The {@link AccessorByteData} - * @throws NullPointerException If any argument is null - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_BYTE or - * GL_UNSIGNED_BYTE + * @throws NullPointerException If any argument is null + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_BYTE or + * GL_UNSIGNED_BYTE */ private static AccessorByteData createByte( - AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) - { - return new AccessorByteData(accessorModel.getComponentType(), - bufferViewByteBuffer, - accessorModel.getByteOffset(), - accessorModel.getCount(), - accessorModel.getElementType(), - accessorModel.getByteStride()); + AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) { + return new AccessorByteData(accessorModel.getComponentType(), + bufferViewByteBuffer, + accessorModel.getByteOffset(), + accessorModel.getCount(), + accessorModel.getElementType(), + accessorModel.getByteStride()); } - + /** * Creates an {@link AccessorShortData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorShortData} - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_SHORT or - * GL_UNSIGNED_SHORT + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_SHORT or + * GL_UNSIGNED_SHORT */ - public static AccessorShortData createShort(AccessorModel accessorModel) - { + public static AccessorShortData createShort(AccessorModel accessorModel) { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); return createShort(accessorModel, bufferViewModel.getBufferViewData()); } - + /** * Creates an {@link AccessorShortData} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewByteBuffer The byte buffer of the - * {@link BufferViewModel} referenced by the {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewByteBuffer The byte buffer of the + * {@link BufferViewModel} referenced by the {@link AccessorModel} * @return The {@link AccessorShortData} - * @throws NullPointerException If any argument is null - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_SHORT or - * GL_UNSIGNED_SHORT + * @throws NullPointerException If any argument is null + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_SHORT or + * GL_UNSIGNED_SHORT */ private static AccessorShortData createShort( - AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) - { - return new AccessorShortData(accessorModel.getComponentType(), - bufferViewByteBuffer, - accessorModel.getByteOffset(), - accessorModel.getCount(), - accessorModel.getElementType(), - accessorModel.getByteStride()); + AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) { + return new AccessorShortData(accessorModel.getComponentType(), + bufferViewByteBuffer, + accessorModel.getByteOffset(), + accessorModel.getCount(), + accessorModel.getElementType(), + accessorModel.getByteStride()); } - /** * Creates an {@link AccessorIntData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorIntData} - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_INT or GL_UNSIGNED_INT + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_INT or GL_UNSIGNED_INT */ - public static AccessorIntData createInt(AccessorModel accessorModel) - { + public static AccessorIntData createInt(AccessorModel accessorModel) { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); return createInt(accessorModel, bufferViewModel.getBufferViewData()); } - + /** * Creates an {@link AccessorIntData} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewByteBuffer The byte buffer of the - * {@link BufferViewModel} referenced by the {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewByteBuffer The byte buffer of the + * {@link BufferViewModel} referenced by the {@link AccessorModel} * @return The {@link AccessorIntData} - * @throws NullPointerException If any argument is null - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_INT or GL_UNSIGNED_INT + * @throws NullPointerException If any argument is null + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_INT or GL_UNSIGNED_INT */ private static AccessorIntData createInt( - AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) - { - return new AccessorIntData(accessorModel.getComponentType(), - bufferViewByteBuffer, - accessorModel.getByteOffset(), - accessorModel.getCount(), - accessorModel.getElementType(), - accessorModel.getByteStride()); + AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) { + return new AccessorIntData(accessorModel.getComponentType(), + bufferViewByteBuffer, + accessorModel.getByteOffset(), + accessorModel.getCount(), + accessorModel.getElementType(), + accessorModel.getByteStride()); } - + /** * Creates an {@link AccessorFloatData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorFloatData} - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_FLOAT + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_FLOAT */ - public static AccessorFloatData createFloat(AccessorModel accessorModel) - { + public static AccessorFloatData createFloat(AccessorModel accessorModel) { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); return createFloat(accessorModel, bufferViewModel.getBufferViewData()); } - + /** * Creates an {@link AccessorFloatData} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewByteBuffer The byte buffer of the - * {@link BufferViewModel} referenced by the {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewByteBuffer The byte buffer of the + * {@link BufferViewModel} referenced by the {@link AccessorModel} * @return The {@link AccessorFloatData} - * @throws NullPointerException If any argument is null - * @throws IllegalArgumentException If the + * @throws NullPointerException If any argument is null + * @throws IllegalArgumentException If the */ private static AccessorFloatData createFloat( - AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) - { - return new AccessorFloatData(accessorModel.getComponentType(), - bufferViewByteBuffer, - accessorModel.getByteOffset(), - accessorModel.getCount(), - accessorModel.getElementType(), - accessorModel.getByteStride()); + AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) { + return new AccessorFloatData(accessorModel.getComponentType(), + bufferViewByteBuffer, + accessorModel.getByteOffset(), + accessorModel.getCount(), + accessorModel.getElementType(), + accessorModel.getByteStride()); } /** * Validate that the given {@link AccessorModel} parameters are valid for * accessing a buffer with the given capacity - * - * @param byteOffset The byte offset - * @param numElements The number of elements - * @param numBytesPerElement The number of bytes per element + * + * @param byteOffset The byte offset + * @param numElements The number of elements + * @param numBytesPerElement The number of bytes per element * @param byteStridePerElement The byte stride - * @param bufferCapacity The buffer capacity + * @param bufferCapacity The buffer capacity * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity + * have a sufficient capacity */ static void validateCapacity(int byteOffset, int numElements, - int numBytesPerElement, int byteStridePerElement, int bufferCapacity) - { - int expectedCapacity = - (numElements - 1) * byteStridePerElement + numBytesPerElement; - if (expectedCapacity > bufferCapacity) - { + int numBytesPerElement, int byteStridePerElement, int bufferCapacity) { + int expectedCapacity = + (numElements - 1) * byteStridePerElement + numBytesPerElement; + if (expectedCapacity > bufferCapacity) { throw new IllegalArgumentException( - "The accessorModel has an offset of " + byteOffset + " and " + - numElements + " elements with a byte stride of " + - byteStridePerElement + " and a size of " + numBytesPerElement + - ", requiring " + expectedCapacity + - " bytes, but the buffer view has only " + - bufferCapacity + " bytes"); + "The accessorModel has an offset of " + byteOffset + " and " + + numElements + " elements with a byte stride of " + + byteStridePerElement + " and a size of " + numBytesPerElement + + ", requiring " + expectedCapacity + + " bytes, but the buffer view has only " + + bufferCapacity + " bytes"); } } - - + /** - * Compute the the minimum component values of the given + * Compute the the minimum component values of the given * {@link AccessorData} - * + * * @param accessorData The {@link AccessorData} * @return The minimum values * @throws IllegalArgumentException If the given model has an unknown type */ - public static Number[] computeMin(AccessorData accessorData) - { - if (accessorData instanceof AccessorByteData) - { - AccessorByteData accessorByteData = - (AccessorByteData) accessorData; + public static Number[] computeMin(AccessorData accessorData) { + if (accessorData instanceof AccessorByteData) { + AccessorByteData accessorByteData = + (AccessorByteData) accessorData; return NumberArrays.asNumbers( - accessorByteData.computeMinInt()); + accessorByteData.computeMinInt()); } - if (accessorData instanceof AccessorShortData) - { - AccessorShortData accessorShortData = - (AccessorShortData) accessorData; + if (accessorData instanceof AccessorShortData) { + AccessorShortData accessorShortData = + (AccessorShortData) accessorData; return NumberArrays.asNumbers( - accessorShortData.computeMinInt()); + accessorShortData.computeMinInt()); } - if (accessorData instanceof AccessorIntData) - { - AccessorIntData accessorIntData = - (AccessorIntData) accessorData; + if (accessorData instanceof AccessorIntData) { + AccessorIntData accessorIntData = + (AccessorIntData) accessorData; return NumberArrays.asNumbers( - accessorIntData.computeMinLong()); + accessorIntData.computeMinLong()); } - if (accessorData instanceof AccessorFloatData) - { - AccessorFloatData accessorFloatData = - (AccessorFloatData) accessorData; + if (accessorData instanceof AccessorFloatData) { + AccessorFloatData accessorFloatData = + (AccessorFloatData) accessorData; return NumberArrays.asNumbers( - accessorFloatData.computeMin()); + accessorFloatData.computeMin()); } throw new IllegalArgumentException( - "Invalid data type: " + accessorData); + "Invalid data type: " + accessorData); } - + /** - * Compute the the maximum component values of the given + * Compute the the maximum component values of the given * {@link AccessorData} - * + * * @param accessorData The {@link AccessorData} * @return The maximum values * @throws IllegalArgumentException If the given model has an unknown type */ - public static Number[] computeMax(AccessorData accessorData) - { - if (accessorData instanceof AccessorByteData) - { - AccessorByteData accessorByteData = - (AccessorByteData) accessorData; + public static Number[] computeMax(AccessorData accessorData) { + if (accessorData instanceof AccessorByteData) { + AccessorByteData accessorByteData = + (AccessorByteData) accessorData; return NumberArrays.asNumbers( - accessorByteData.computeMaxInt()); + accessorByteData.computeMaxInt()); } - if (accessorData instanceof AccessorShortData) - { - AccessorShortData accessorShortData = - (AccessorShortData) accessorData; + if (accessorData instanceof AccessorShortData) { + AccessorShortData accessorShortData = + (AccessorShortData) accessorData; return NumberArrays.asNumbers( - accessorShortData.computeMaxInt()); + accessorShortData.computeMaxInt()); } - if (accessorData instanceof AccessorIntData) - { - AccessorIntData accessorIntData = - (AccessorIntData) accessorData; + if (accessorData instanceof AccessorIntData) { + AccessorIntData accessorIntData = + (AccessorIntData) accessorData; return NumberArrays.asNumbers( - accessorIntData.computeMaxLong()); + accessorIntData.computeMaxLong()); } - if (accessorData instanceof AccessorFloatData) - { - AccessorFloatData accessorFloatData = - (AccessorFloatData) accessorData; + if (accessorData instanceof AccessorFloatData) { + AccessorFloatData accessorFloatData = + (AccessorFloatData) accessorData; return NumberArrays.asNumbers( - accessorFloatData.computeMax()); + accessorFloatData.computeMax()); } throw new IllegalArgumentException( - "Invalid data type: " + accessorData); + "Invalid data type: " + accessorData); } - + /** * Creates a (possibly large!) string representation of the given - * {@link AccessorData}, by calling + * {@link AccessorData}, by calling * {@link AccessorByteData#createString(Locale, String, int)}, * {@link AccessorShortData#createString(Locale, String, int)}, * {@link AccessorIntData#createString(Locale, String, int)} or * {@link AccessorFloatData#createString(Locale, String, int)}, * depending on the type of the given data, with an unspecified * format string. - * - * @param accessorData The {@link AccessorData} + * + * @param accessorData The {@link AccessorData} * @param elementsPerRow The number of elements per row * @return The string */ public static String createString( - AccessorData accessorData, int elementsPerRow) - { - if (accessorData instanceof AccessorByteData) - { - AccessorByteData accessorByteData = - (AccessorByteData) accessorData; - String accessorDataString = - accessorByteData.createString( - Locale.ENGLISH, "%4d", elementsPerRow); + AccessorData accessorData, int elementsPerRow) { + if (accessorData instanceof AccessorByteData) { + AccessorByteData accessorByteData = + (AccessorByteData) accessorData; + String accessorDataString = + accessorByteData.createString( + Locale.ENGLISH, "%4d", elementsPerRow); return accessorDataString; } - if (accessorData instanceof AccessorShortData) - { - AccessorShortData accessorShortData = - (AccessorShortData) accessorData; - String accessorDataString = - accessorShortData.createString( - Locale.ENGLISH, "%6d", elementsPerRow); + if (accessorData instanceof AccessorShortData) { + AccessorShortData accessorShortData = + (AccessorShortData) accessorData; + String accessorDataString = + accessorShortData.createString( + Locale.ENGLISH, "%6d", elementsPerRow); return accessorDataString; } - if (accessorData instanceof AccessorIntData) - { - AccessorIntData accessorIntData = - (AccessorIntData) accessorData; - String accessorDataString = - accessorIntData.createString( - Locale.ENGLISH, "%11d", elementsPerRow); + if (accessorData instanceof AccessorIntData) { + AccessorIntData accessorIntData = + (AccessorIntData) accessorData; + String accessorDataString = + accessorIntData.createString( + Locale.ENGLISH, "%11d", elementsPerRow); return accessorDataString; } - if (accessorData instanceof AccessorFloatData) - { - AccessorFloatData accessorFloatData = - (AccessorFloatData) accessorData; - String accessorDataString = - accessorFloatData.createString( - Locale.ENGLISH, "%10.5f", elementsPerRow); + if (accessorData instanceof AccessorFloatData) { + AccessorFloatData accessorFloatData = + (AccessorFloatData) accessorData; + String accessorDataString = + accessorFloatData.createString( + Locale.ENGLISH, "%10.5f", elementsPerRow); return accessorDataString; } return "Unknown accessor data type: " + accessorData; } - - - /** - * Private constructor to prevent instantiation - */ - private AccessorDatas() - { - // Private constructor to prevent instantiation - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/AccessorFloatData.java b/src/main/java/de/javagl/jgltf/model/AccessorFloatData.java index 3ae8a0e..2809a29 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorFloatData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorFloatData.java @@ -35,133 +35,124 @@ * A class for accessing the data that is described by an accessor. * It allows accessing the byte buffer of the buffer view of the * accessor, depending on the accessor parameters.
- *
+ *
* This data consists of several elements (for example, 3D float vectors), - * which consist of several components (for example, the 3 float values). + * which consist of several components (for example, the 3 float values). */ -public final class AccessorFloatData - extends AbstractAccessorData - implements AccessorData -{ +public final class AccessorFloatData + extends AbstractAccessorData + implements AccessorData { /** - * Creates a new instance for accessing the data in the given + * Creates a new instance for accessing the data in the given * byte buffer, according to the rules described by the given * accessor parameters. - * @param componentType The component type + * + * @param componentType The component type * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * - * @throws NullPointerException If the bufferViewByteBuffer is - * null - * @throws IllegalArgumentException If the component type is not - * GL_FLOAT + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * @throws NullPointerException If the bufferViewByteBuffer is + * null + * @throws IllegalArgumentException If the component type is not + * GL_FLOAT * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity to provide the data for the accessor + * have a sufficient capacity to provide the data for the accessor */ public AccessorFloatData(int componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, - ElementType elementType, Integer byteStride) - { - super(componentType, float.class, bufferViewByteBuffer, byteOffset, - numElements, elementType, Float.BYTES, byteStride); + ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, + ElementType elementType, Integer byteStride) { + super(componentType, float.class, bufferViewByteBuffer, byteOffset, + numElements, elementType, Float.BYTES, byteStride); AccessorDatas.validateFloatType(componentType); - int numBytesPerElement = - getNumComponentsPerElement() * getNumBytesPerComponent(); - AccessorDatas.validateCapacity(byteOffset, getNumElements(), - numBytesPerElement, getByteStridePerElement(), - bufferViewByteBuffer.capacity()); + int numBytesPerElement = + getNumComponentsPerElement() * getNumBytesPerComponent(); + AccessorDatas.validateCapacity(byteOffset, getNumElements(), + numBytesPerElement, getByteStridePerElement(), + bufferViewByteBuffer.capacity()); } - + /** * Returns the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public float get(int elementIndex, int componentIndex) - { + public float get(int elementIndex, int componentIndex) { int byteIndex = getByteIndex(elementIndex, componentIndex); return getBufferViewByteBuffer().getFloat(byteIndex); } - + public float getFloat(int elementIndex, int componentIndex) { - return get(elementIndex, componentIndex); + return get(elementIndex, componentIndex); } - + /** * Returns the value of the specified component - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public float get(int globalComponentIndex) - { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public float get(int globalComponentIndex) { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); return get(elementIndex, componentIndex); } - + /** * Set the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int elementIndex, int componentIndex, float value) - { + public void set(int elementIndex, int componentIndex, float value) { int byteIndex = getByteIndex(elementIndex, componentIndex); getBufferViewByteBuffer().putFloat(byteIndex, value); } - + /** * Set the value of the specified component - * + * * @param globalComponentIndex The global component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int globalComponentIndex, float value) - { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public void set(int globalComponentIndex, float value) { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); set(elementIndex, componentIndex, value); } - - + + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public float[] computeMin() - { + public float[] computeMin() { float result[] = new float[getNumComponentsPerElement()]; Arrays.fill(result, Float.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.min(result[c], get(e, c)); } } @@ -169,87 +160,74 @@ public float[] computeMin() } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public float[] computeMax() - { + public float[] computeMax() { float result[] = new float[getNumComponentsPerElement()]; Arrays.fill(result, -Float.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.max(result[c], get(e, c)); } } return result; } - + @Override - public ByteBuffer createByteBuffer() - { + public ByteBuffer createByteBuffer() { int totalNumComponents = getTotalNumComponents(); int totalBytes = totalNumComponents * getNumBytesPerComponent(); ByteBuffer result = ByteBuffer.allocateDirect(totalBytes) - .order(ByteOrder.nativeOrder()); - for (int i=0; i 0) - { + for (int e = 0; e < getNumElements(); e++) { + if (e > 0) { sb.append(", "); - if (elementsPerRow > 0 && (e % elementsPerRow) == 0) - { + if (elementsPerRow > 0 && (e % elementsPerRow) == 0) { sb.append("\n "); } } - if (nc > 1) - { + if (nc > 1) { sb.append("("); } - for (int c = 0; c < nc; c++) - { - if (c > 0) - { + for (int c = 0; c < nc; c++) { + if (c > 0) { sb.append(", "); } float component = get(e, c); sb.append(String.format(locale, format, component)); } - if (nc > 1) - { + if (nc > 1) { sb.append(")"); } } sb.append("]"); return sb.toString(); } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/AccessorIntData.java b/src/main/java/de/javagl/jgltf/model/AccessorIntData.java index d119317..e0bae60 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorIntData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorIntData.java @@ -35,185 +35,173 @@ * A class for accessing the data that is described by an accessor. * It allows accessing the byte buffer of the buffer view of the * accessor, depending on the accessor parameters.
- *
+ *
* This data consists of several elements (for example, 3D int vectors), - * which consist of several components (for example, the 3 int values). + * which consist of several components (for example, the 3 int values). */ -public final class AccessorIntData - extends AbstractAccessorData - implements AccessorData -{ +public final class AccessorIntData + extends AbstractAccessorData + implements AccessorData { /** * Whether the data should be interpreted as unsigned values */ private final boolean unsigned; - + /** - * Creates a new instance for accessing the data in the given + * Creates a new instance for accessing the data in the given * byte buffer, according to the rules described by the given * accessor parameters. - * @param componentType The component type + * + * @param componentType The component type * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * - * @throws NullPointerException If the bufferViewByteBuffer is - * null - * @throws IllegalArgumentException If the component type is not - * GL_INT or GL_UNSIGEND_INT + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * @throws NullPointerException If the bufferViewByteBuffer is + * null + * @throws IllegalArgumentException If the component type is not + * GL_INT or GL_UNSIGEND_INT * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity to provide the data for the accessor + * have a sufficient capacity to provide the data for the accessor */ public AccessorIntData(int componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, - ElementType elementType, Integer byteStride) - { - super(componentType, int.class, bufferViewByteBuffer, byteOffset, - numElements, elementType, Integer.BYTES, byteStride); + ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, + ElementType elementType, Integer byteStride) { + super(componentType, int.class, bufferViewByteBuffer, byteOffset, + numElements, elementType, Integer.BYTES, byteStride); AccessorDatas.validateIntType(componentType); this.unsigned = AccessorDatas.isUnsignedType(componentType); - int numBytesPerElement = - getNumComponentsPerElement() * getNumBytesPerComponent(); - AccessorDatas.validateCapacity(byteOffset, getNumElements(), - numBytesPerElement, getByteStridePerElement(), - bufferViewByteBuffer.capacity()); + int numBytesPerElement = + getNumComponentsPerElement() * getNumBytesPerComponent(); + AccessorDatas.validateCapacity(byteOffset, getNumElements(), + numBytesPerElement, getByteStridePerElement(), + bufferViewByteBuffer.capacity()); } - + /** * Returns whether the data should be interpreted as unsigned - * + * * @return Whether the data should be interpreted as unsigned */ - public boolean isUnsigned() - { + public boolean isUnsigned() { return unsigned; } - + /** * Returns the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int get(int elementIndex, int componentIndex) - { + public int get(int elementIndex, int componentIndex) { int byteIndex = getByteIndex(elementIndex, componentIndex); return getBufferViewByteBuffer().getInt(byteIndex); } - + public float getFloat(int elementIndex, int componentIndex) { - int value = get(elementIndex, componentIndex); - return unsigned ? Integer.toUnsignedLong(value) / (Integer.MAX_VALUE - Integer.MIN_VALUE) : Math.max(value / Integer.MAX_VALUE, -1.0F); + int value = get(elementIndex, componentIndex); + return unsigned ? Integer.toUnsignedLong(value) / (Integer.MAX_VALUE - Integer.MIN_VALUE) : Math.max(value / Integer.MAX_VALUE, -1.0F); } - + /** * Returns the value of the specified component - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int get(int globalComponentIndex) - { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public int get(int globalComponentIndex) { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); return get(elementIndex, componentIndex); } /** * Set the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int elementIndex, int componentIndex, int value) - { + public void set(int elementIndex, int componentIndex, int value) { int byteIndex = getByteIndex(elementIndex, componentIndex); getBufferViewByteBuffer().putInt(byteIndex, value); } - + /** * Set the value of the specified component - * + * * @param globalComponentIndex The global component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int globalComponentIndex, int value) - { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public void set(int globalComponentIndex, int value) { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); set(elementIndex, componentIndex, value); } - + /** - * Returns the value of the specified component of the specified element, - * taking into account whether the data {@link #isUnsigned()}: If the data - * is unsigned, the returned int value will be converted into an + * Returns the value of the specified component of the specified element, + * taking into account whether the data {@link #isUnsigned()}: If the data + * is unsigned, the returned int value will be converted into an * unsigned long value. - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public long getLong(int elementIndex, int componentIndex) - { + public long getLong(int elementIndex, int componentIndex) { int value = get(elementIndex, componentIndex); return unsigned ? Integer.toUnsignedLong(value) : value; } - + /** * Returns the value of the specified component, taking into account * whether the data {@link #isUnsigned()}: If the data is unsigned, * the returned int value will be converted into an unsigned integer * value. - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public long getLong(int globalComponentIndex) - { + public long getLong(int globalComponentIndex) { int value = get(globalComponentIndex); return unsigned ? Integer.toUnsignedLong(value) : value; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public int[] computeMin() - { + public int[] computeMin() { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.min(result[c], get(e, c)); } } @@ -221,42 +209,36 @@ public int[] computeMin() } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public int[] computeMax() - { + public int[] computeMax() { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.max(result[c], get(e, c)); } } return result; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getLong(int, int)}. - * + * * @return The minimum values */ - public long[] computeMinLong() - { + public long[] computeMinLong() { long result[] = new long[getNumComponentsPerElement()]; Arrays.fill(result, Long.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.min(result[c], getLong(e, c)); } } @@ -264,88 +246,75 @@ public long[] computeMinLong() } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getLong(int, int)}. - * + * * @return The minimum values */ - public long[] computeMaxLong() - { + public long[] computeMaxLong() { long result[] = new long[getNumComponentsPerElement()]; Arrays.fill(result, Long.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.max(result[c], getLong(e, c)); } } return result; } - + @Override - public ByteBuffer createByteBuffer() - { + public ByteBuffer createByteBuffer() { int totalNumComponents = getTotalNumComponents(); int totalBytes = totalNumComponents * getNumBytesPerComponent(); ByteBuffer result = ByteBuffer.allocateDirect(totalBytes) - .order(ByteOrder.nativeOrder()); - for (int i=0; i 0) - { + for (int e = 0; e < getNumElements(); e++) { + if (e > 0) { sb.append(", "); - if (elementsPerRow > 0 && (e % elementsPerRow) == 0) - { + if (elementsPerRow > 0 && (e % elementsPerRow) == 0) { sb.append("\n "); } } - if (nc > 1) - { + if (nc > 1) { sb.append("("); } - for (int c = 0; c < nc; c++) - { - if (c > 0) - { + for (int c = 0; c < nc; c++) { + if (c > 0) { sb.append(", "); } long component = getLong(e, c); sb.append(String.format(locale, format, component)); } - if (nc > 1) - { + if (nc > 1) { sb.append(")"); } } sb.append("]"); return sb.toString(); } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/AccessorModel.java b/src/main/java/de/javagl/jgltf/model/AccessorModel.java index c24e5c7..45f56a0 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorModel.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorModel.java @@ -29,148 +29,147 @@ /** * Interface for a data accessor */ -public interface AccessorModel extends NamedModelElement -{ +public interface AccessorModel extends NamedModelElement { /** * Returns the {@link BufferViewModel} for the data that this accessor * provides access to. Typed access to the data is possible by obtaining * the {@link AccessorData} using {@link #getAccessorData()}. - * + * * @return The {@link BufferViewModel} */ BufferViewModel getBufferViewModel(); - + /** * Returns the component type of this accessor, as a GL constant. For * example, GL_FLOAT or GL_UNSIGNED_SHORT - * + * * @return The component type */ int getComponentType(); - + /** * Returns the data type of the components of this accessor. For example, * float.class or short.class. - * + * * @return The component data type */ Class getComponentDataType(); - + /** * Returns whether this accessor contains normalized data - * + * * @return Whether this accessor contains normalized data */ boolean isNormalized(); - + /** * Returns the size of one component, in bytes - * + * * @return The component size, in bytes */ int getComponentSizeInBytes(); - + /** * Returns the size of one element, in bytes. - * + *

* This does not include any padding that may have to be inserted * after the columns of certain matrix types (see section - * 3.6.2.4. "Data Alignment"). - * - * To obtain the padded size of the elements, - * {@link #getPaddedElementSizeInBytes()} can be used. - * + * 3.6.2.4. "Data Alignment"). + *

+ * To obtain the padded size of the elements, + * {@link #getPaddedElementSizeInBytes()} can be used. + * * @return The element size, in bytes */ int getElementSizeInBytes(); - + /** * Obtain the padded size of one element, in bytes. - * + *

* This does include any padding that may have to be inserted * after the columns of certain matrix types (see section - * 3.6.2.4. "Data Alignment"). - * + * 3.6.2.4. "Data Alignment"). + *

* For example, for a MAT2 with BYTE components, this will return 8, - * which is equivalent to calling + * which is equivalent to calling *


      * ElementType elementType = accessorModel.getElementType();
-     * int componentType = accessorModel.getComponentType(); 
+     * int componentType = accessorModel.getComponentType();
      * int sizeWithPadding = elementType.getByteStride(componentType);
      * 
- * + *

* See {@link ElementType#getByteStride(int)}. - * + * * @return The padded element size, in bytes */ int getPaddedElementSizeInBytes(); - + /** - * Returns the byte offset of this accessor referring to its + * Returns the byte offset of this accessor referring to its * {@link BufferViewModel} - * + * * @return The byte offset */ int getByteOffset(); - + /** * Returns the number of elements that this accessor provides access to - * + * * @return The number of elements */ int getCount(); - + /** * Returns the {@link ElementType} that this accessor provides access to - * + * * @return The {@link ElementType} */ ElementType getElementType(); - + /** * Returns the byte stride between the starts of two consecutive elements * of this accessor. - * + *

* If this is 0, then the elements are tightly packed. This means that - * the byte stride is equal to the {@link #getElementSizeInBytes() element + * the byte stride is equal to the {@link #getElementSizeInBytes() element * size}. Note that for glTF 2.0, the byte stride for vertex attributes * must be a multiple 4. Callers must check whether the returned value * is 0 or not a multiple of 4 accordingly. - * + * * @return The byte stride */ int getByteStride(); - + /** * Returns the {@link AccessorData} for this accessor. The exact type - * of the returned {@link AccessorData} object will depend on the + * of the returned {@link AccessorData} object will depend on the * {@link #getComponentDataType() component data type}. It will be - * {@link AccessorByteData}, {@link AccessorShortData}, + * {@link AccessorByteData}, {@link AccessorShortData}, * {@link AccessorIntData} or {@link AccessorFloatData} for a component - * data type of byte.class, short.class, + * data type of byte.class, short.class, * int.class or float.class, respectively, - * and can be safely cast to the respective type. - * + * and can be safely cast to the respective type. + * * @return The {@link AccessorData} */ AccessorData getAccessorData(); - + /** - * Returns the minimum components of the {@link AccessorData}. The + * Returns the minimum components of the {@link AccessorData}. The * returned array will be a clone of the array that is stored internally, * and have a length that matches the {@link ElementType#getNumComponents() * number of components per element}. - * + * * @return The minimum components */ Number[] getMin(); - + /** - * Returns the maximum components of the {@link AccessorData}. The + * Returns the maximum components of the {@link AccessorData}. The * returned array will be a clone of the array that is stored internally, * and have a length that matches the {@link ElementType#getNumComponents() * number of components per element}. - * + * * @return The maximum components */ Number[] getMax(); diff --git a/src/main/java/de/javagl/jgltf/model/AccessorShortData.java b/src/main/java/de/javagl/jgltf/model/AccessorShortData.java index 44a29af..64303d9 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorShortData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorShortData.java @@ -35,186 +35,174 @@ * A class for accessing the data that is described by an accessor. * It allows accessing the byte buffer of the buffer view of the * accessor, depending on the accessor parameters.
- *
+ *
* This data consists of several elements (for example, 3D short vectors), - * which consist of several components (for example, the 3 short values). + * which consist of several components (for example, the 3 short values). */ -public final class AccessorShortData - extends AbstractAccessorData - implements AccessorData -{ +public final class AccessorShortData + extends AbstractAccessorData + implements AccessorData { /** * Whether the data should be interpreted as unsigned values */ private final boolean unsigned; - + /** - * Creates a new instance for accessing the data in the given + * Creates a new instance for accessing the data in the given * byte buffer, according to the rules described by the given * accessor parameters. - * @param componentType The component type + * + * @param componentType The component type * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * - * @throws NullPointerException If the bufferViewByteBuffer is - * null - * @throws IllegalArgumentException If the component type is not - * GL_SHORT or GL_UNSIGEND_SHORT + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * @throws NullPointerException If the bufferViewByteBuffer is + * null + * @throws IllegalArgumentException If the component type is not + * GL_SHORT or GL_UNSIGEND_SHORT * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity to provide the data for the accessor + * have a sufficient capacity to provide the data for the accessor */ public AccessorShortData(int componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, - ElementType elementType, Integer byteStride) - { - super(componentType, short.class, bufferViewByteBuffer, byteOffset, - numElements, elementType, Short.BYTES, byteStride); + ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, + ElementType elementType, Integer byteStride) { + super(componentType, short.class, bufferViewByteBuffer, byteOffset, + numElements, elementType, Short.BYTES, byteStride); AccessorDatas.validateShortType(componentType); this.unsigned = AccessorDatas.isUnsignedType(componentType); - int numBytesPerElement = - getNumComponentsPerElement() * getNumBytesPerComponent(); - AccessorDatas.validateCapacity(byteOffset, getNumElements(), - numBytesPerElement, getByteStridePerElement(), - bufferViewByteBuffer.capacity()); + int numBytesPerElement = + getNumComponentsPerElement() * getNumBytesPerComponent(); + AccessorDatas.validateCapacity(byteOffset, getNumElements(), + numBytesPerElement, getByteStridePerElement(), + bufferViewByteBuffer.capacity()); } - + /** * Returns whether the data should be interpreted as unsigned - * + * * @return Whether the data should be interpreted as unsigned */ - public boolean isUnsigned() - { + public boolean isUnsigned() { return unsigned; } - + /** * Returns the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public short get(int elementIndex, int componentIndex) - { + public short get(int elementIndex, int componentIndex) { int byteIndex = getByteIndex(elementIndex, componentIndex); return getBufferViewByteBuffer().getShort(byteIndex); } - + public float getFloat(int elementIndex, int componentIndex) { - short value = get(elementIndex, componentIndex); - return unsigned ? Short.toUnsignedInt(value) / (Short.MAX_VALUE - Short.MIN_VALUE) : Math.max(value / Short.MAX_VALUE, -1.0F); + short value = get(elementIndex, componentIndex); + return unsigned ? Short.toUnsignedInt(value) / (Short.MAX_VALUE - Short.MIN_VALUE) : Math.max(value / Short.MAX_VALUE, -1.0F); } - + /** * Returns the value of the specified component - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public short get(int globalComponentIndex) - { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public short get(int globalComponentIndex) { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); return get(elementIndex, componentIndex); } /** * Set the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int elementIndex, int componentIndex, short value) - { + public void set(int elementIndex, int componentIndex, short value) { int byteIndex = getByteIndex(elementIndex, componentIndex); getBufferViewByteBuffer().putShort(byteIndex, value); } - + /** * Set the value of the specified component - * + * * @param globalComponentIndex The global component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int globalComponentIndex, short value) - { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public void set(int globalComponentIndex, short value) { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); set(elementIndex, componentIndex, value); } - - + + /** - * Returns the value of the specified component of the specified element, - * taking into account whether the data {@link #isUnsigned()}: If the data - * is unsigned, the returned short value will be converted into an + * Returns the value of the specified component of the specified element, + * taking into account whether the data {@link #isUnsigned()}: If the data + * is unsigned, the returned short value will be converted into an * unsigned integer value. - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int getInt(int elementIndex, int componentIndex) - { + public int getInt(int elementIndex, int componentIndex) { short value = get(elementIndex, componentIndex); return unsigned ? Short.toUnsignedInt(value) : value; } - + /** * Returns the value of the specified component, taking into account * whether the data {@link #isUnsigned()}: If the data is unsigned, * the returned short value will be converted into an unsigned integer * value. - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int getInt(int globalComponentIndex) - { + public int getInt(int globalComponentIndex) { short value = get(globalComponentIndex); return unsigned ? Short.toUnsignedInt(value) : value; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public short[] computeMin() - { + public short[] computeMin() { short result[] = new short[getNumComponentsPerElement()]; Arrays.fill(result, Short.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = (short) Math.min(result[c], get(e, c)); } } @@ -222,42 +210,36 @@ public short[] computeMin() } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public short[] computeMax() - { + public short[] computeMax() { short result[] = new short[getNumComponentsPerElement()]; Arrays.fill(result, Short.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = (short) Math.max(result[c], get(e, c)); } } return result; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getInt(int, int)}. - * + * * @return The minimum values */ - public int[] computeMinInt() - { + public int[] computeMinInt() { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.min(result[c], getInt(e, c)); } } @@ -265,88 +247,75 @@ public int[] computeMinInt() } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getInt(int, int)}. - * + * * @return The minimum values */ - public int[] computeMaxInt() - { + public int[] computeMaxInt() { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) - { - for (int c = 0; c < getNumComponentsPerElement(); c++) - { + for (int e = 0; e < getNumElements(); e++) { + for (int c = 0; c < getNumComponentsPerElement(); c++) { result[c] = Math.max(result[c], getInt(e, c)); } } return result; } - + @Override - public ByteBuffer createByteBuffer() - { + public ByteBuffer createByteBuffer() { int totalNumComponents = getTotalNumComponents(); int totalBytes = totalNumComponents * getNumBytesPerComponent(); ByteBuffer result = ByteBuffer.allocateDirect(totalBytes) - .order(ByteOrder.nativeOrder()); - for (int i=0; i 0) - { + for (int e = 0; e < getNumElements(); e++) { + if (e > 0) { sb.append(", "); - if (elementsPerRow > 0 && (e % elementsPerRow) == 0) - { + if (elementsPerRow > 0 && (e % elementsPerRow) == 0) { sb.append("\n "); } } - if (nc > 1) - { + if (nc > 1) { sb.append("("); } - for (int c = 0; c < nc; c++) - { - if (c > 0) - { + for (int c = 0; c < nc; c++) { + if (c > 0) { sb.append(", "); } int component = getInt(e, c); sb.append(String.format(locale, format, component)); } - if (nc > 1) - { + if (nc > 1) { sb.append(")"); } } sb.append("]"); return sb.toString(); } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/Accessors.java b/src/main/java/de/javagl/jgltf/model/Accessors.java index 381eb6e..f28f709 100644 --- a/src/main/java/de/javagl/jgltf/model/Accessors.java +++ b/src/main/java/de/javagl/jgltf/model/Accessors.java @@ -29,82 +29,98 @@ /** * Utility methods related to accessor properties.
*
- * Unless otherwise noted, none of the arguments to these methods may + * Unless otherwise noted, none of the arguments to these methods may * be null. */ -public class Accessors -{ +public class Accessors { /** - * Returns the number of components that one element has for the given + * Private constructor to prevent instantiation + */ + private Accessors() { + // Private constructor to prevent instantiation + } + + /** + * Returns the number of components that one element has for the given * accessor type. Valid parameters are *


      * "SCALAR" :  1
-     * "VEC2"   :  2 
-     * "VEC3"   :  3 
-     * "VEC4"   :  4 
-     * "MAT2"   :  4 
-     * "MAT3"   :  9 
+     * "VEC2"   :  2
+     * "VEC3"   :  3
+     * "VEC4"   :  4
+     * "MAT2"   :  4
+     * "MAT3"   :  9
      * "MAT4"   : 16
      * 
- * - * @param accessorType The accessor type. + * + * @param accessorType The accessor type. * @return The number of components * @throws IllegalArgumentException If the given type is none of the - * valid parameters + * valid parameters */ - public static int getNumComponentsForAccessorType(String accessorType) - { - switch (accessorType) - { - case "SCALAR": return 1; - case "VEC2": return 2; - case "VEC3": return 3; - case "VEC4": return 4; - case "MAT2": return 4; - case "MAT3": return 9; - case "MAT4": return 16; + public static int getNumComponentsForAccessorType(String accessorType) { + switch (accessorType) { + case "SCALAR": + return 1; + case "VEC2": + return 2; + case "VEC3": + return 3; + case "VEC4": + return 4; + case "MAT2": + return 4; + case "MAT3": + return 9; + case "MAT4": + return 16; default: break; } throw new IllegalArgumentException( - "Invalid accessor type: "+accessorType); + "Invalid accessor type: " + accessorType); } /** - * Returns the number of bytes that one component with the given + * Returns the number of bytes that one component with the given * accessor component type consists of. * Valid parameters are *

      * GL_BYTE           : 1
-     * GL_UNSIGNED_BYTE  : 1 
-     * GL_SHORT          : 2 
-     * GL_UNSIGNED_SHORT : 2 
-     * GL_INT            : 4 
-     * GL_UNSIGNED_INT   : 4 
+     * GL_UNSIGNED_BYTE  : 1
+     * GL_SHORT          : 2
+     * GL_UNSIGNED_SHORT : 2
+     * GL_INT            : 4
+     * GL_UNSIGNED_INT   : 4
      * GL_FLOAT          : 4
      * 
- * + * * @param componentType The component type * @return The number of bytes * @throws IllegalArgumentException If the given type is none of the - * valid parameters + * valid parameters */ - public static int getNumBytesForAccessorComponentType(int componentType) - { - switch (componentType) - { - case GltfConstants.GL_BYTE: return 1; - case GltfConstants.GL_UNSIGNED_BYTE: return 1; - case GltfConstants.GL_SHORT: return 2; - case GltfConstants.GL_UNSIGNED_SHORT: return 2; - case GltfConstants.GL_INT: return 4; - case GltfConstants.GL_UNSIGNED_INT: return 4; - case GltfConstants.GL_FLOAT: return 4; + public static int getNumBytesForAccessorComponentType(int componentType) { + switch (componentType) { + case GltfConstants.GL_BYTE: + return 1; + case GltfConstants.GL_UNSIGNED_BYTE: + return 1; + case GltfConstants.GL_SHORT: + return 2; + case GltfConstants.GL_UNSIGNED_SHORT: + return 2; + case GltfConstants.GL_INT: + return 4; + case GltfConstants.GL_UNSIGNED_INT: + return 4; + case GltfConstants.GL_FLOAT: + return 4; default: break; } throw new IllegalArgumentException( - "Invalid accessor component type: "+componentType); + "Invalid accessor component type: " + componentType); } /** @@ -113,43 +129,40 @@ public static int getNumBytesForAccessorComponentType(int componentType) *

      * GL_BYTE           : byte.class
      * GL_UNSIGNED_BYTE  : byte.class
-     * GL_SHORT          : short.class 
+     * GL_SHORT          : short.class
      * GL_UNSIGNED_SHORT : short.class
-     * GL_INT            : int.class 
+     * GL_INT            : int.class
      * GL_UNSIGNED_INT   : int.class
      * GL_FLOAT          : float.class
      * 
- * + * * @param componentType The component type * @return The data type * @throws IllegalArgumentException If the given type is none of the - * valid parameters + * valid parameters */ public static Class getDataTypeForAccessorComponentType( - int componentType) - { - switch (componentType) - { - case GltfConstants.GL_BYTE: return byte.class; - case GltfConstants.GL_UNSIGNED_BYTE: return byte.class; - case GltfConstants.GL_SHORT: return short.class; - case GltfConstants.GL_UNSIGNED_SHORT: return short.class; - case GltfConstants.GL_INT: return int.class; - case GltfConstants.GL_UNSIGNED_INT: return int.class; - case GltfConstants.GL_FLOAT: return float.class; + int componentType) { + switch (componentType) { + case GltfConstants.GL_BYTE: + return byte.class; + case GltfConstants.GL_UNSIGNED_BYTE: + return byte.class; + case GltfConstants.GL_SHORT: + return short.class; + case GltfConstants.GL_UNSIGNED_SHORT: + return short.class; + case GltfConstants.GL_INT: + return int.class; + case GltfConstants.GL_UNSIGNED_INT: + return int.class; + case GltfConstants.GL_FLOAT: + return float.class; default: break; } throw new IllegalArgumentException( - "Invalid accessor component type: "+componentType); + "Invalid accessor component type: " + componentType); } - /** - * Private constructor to prevent instantiation - */ - private Accessors() - { - // Private constructor to prevent instantiation - } - } diff --git a/src/main/java/de/javagl/jgltf/model/AnimationModel.java b/src/main/java/de/javagl/jgltf/model/AnimationModel.java index d237e71..de2dd58 100644 --- a/src/main/java/de/javagl/jgltf/model/AnimationModel.java +++ b/src/main/java/de/javagl/jgltf/model/AnimationModel.java @@ -31,91 +31,87 @@ /** * Interface for an animation */ -public interface AnimationModel extends NamedModelElement -{ +public interface AnimationModel extends NamedModelElement { + /** + * Returns an unmodifiable list containing the {@link Channel} instances + * of the animation + * + * @return The {@link Channel} instances + */ + List getChannels(); + /** * Enumeration of the different interpolation methods for an animation */ - public enum Interpolation - { + public enum Interpolation { /** * Stepwise interpolation */ STEP, - + /** * Linear interpolation */ LINEAR, - + /** * Cubic spline interpolation */ - CUBICSPLINE + CUBICSPLINE } - + /** * Interface for an animation channel */ - public interface Channel - { + public interface Channel { /** * Returns the {@link Sampler} for this channel - * + * * @return The {@link Sampler} */ Sampler getSampler(); - + /** * Returns the optional {@link NodeModel} to which the animated * property (path) belongs. - * + * * @return The {@link NodeModel} */ NodeModel getNodeModel(); - + /** * Returns the path describing the animated property - * + * * @return The path */ String getPath(); } - + /** * Interface for an animation sampler */ - public interface Sampler - { + public interface Sampler { /** * Returns the {@link AccessorModel} that contains the input (time * key frame) data - * + * * @return The input data */ AccessorModel getInput(); - + /** * Returns the {@link Interpolation} method - * + * * @return The {@link Interpolation} */ Interpolation getInterpolation(); - + /** * Returns the {@link AccessorModel} that contains the output (value * key frame) data - * + * * @return The output data */ AccessorModel getOutput(); } - - /** - * Returns an unmodifiable list containing the {@link Channel} instances - * of the animation - * - * @return The {@link Channel} instances - */ - List getChannels(); } diff --git a/src/main/java/de/javagl/jgltf/model/AssetModel.java b/src/main/java/de/javagl/jgltf/model/AssetModel.java index c3f58b7..4192a89 100644 --- a/src/main/java/de/javagl/jgltf/model/AssetModel.java +++ b/src/main/java/de/javagl/jgltf/model/AssetModel.java @@ -27,27 +27,26 @@ package de.javagl.jgltf.model; /** - * Interface for an asset. - * + * Interface for an asset. + *

* Note that this model does not include the version information that * will eventually be written as the gltf.asset.version. * This version information is intentionally hidden in the * model, and will depend on the version in which the model will * be written. */ -public interface AssetModel extends NamedModelElement -{ +public interface AssetModel extends NamedModelElement { /** * Returns the copyright message, suitable for display to credit * the content creator. - * + * * @return The copyright message */ String getCopyright(); - + /** * Returns the tool that generated this glTF model - * + * * @return The tool */ String getGenerator(); diff --git a/src/main/java/de/javagl/jgltf/model/BoundingBox.java b/src/main/java/de/javagl/jgltf/model/BoundingBox.java index 3f273ae..1b16ca4 100644 --- a/src/main/java/de/javagl/jgltf/model/BoundingBox.java +++ b/src/main/java/de/javagl/jgltf/model/BoundingBox.java @@ -31,43 +31,41 @@ /** * A very simple (package-private!) bounding box implementation */ -class BoundingBox -{ +class BoundingBox { /** * The minimum x coordinate */ private float minX; - + /** * The minimum y coordinate */ private float minY; - + /** * The minimum z coordinate */ private float minZ; - + /** * The maximum x coordinate */ private float maxX; - + /** * The maximum y coordinate */ private float maxY; - + /** * The maximum z coordinate */ private float maxZ; /** - * Creates a bounding box + * Creates a bounding box */ - BoundingBox() - { + BoundingBox() { minX = Float.MAX_VALUE; minY = Float.MAX_VALUE; minZ = Float.MAX_VALUE; @@ -75,16 +73,15 @@ class BoundingBox maxY = -Float.MAX_VALUE; maxZ = -Float.MAX_VALUE; } - + /** * Combine this bounding box with the given point - * + * * @param x The x-coordinate * @param y The y-coordinate * @param z The z-coordinate */ - void combine(float x, float y, float z) - { + void combine(float x, float y, float z) { minX = Math.min(minX, x); minY = Math.min(minY, y); minZ = Math.min(minZ, z); @@ -95,11 +92,10 @@ void combine(float x, float y, float z) /** * Combine this bounding box with the given one - * + * * @param other The other bounding box */ - void combine(BoundingBox other) - { + void combine(BoundingBox other) { Objects.requireNonNull(other, "The other bounding box may not be null"); minX = Math.min(minX, other.getMinX()); minY = Math.min(minY, other.getMinY()); @@ -114,8 +110,7 @@ void combine(BoundingBox other) * * @return The x-coordinate of the center */ - float getCenterX() - { + float getCenterX() { return getMinX() + getSizeX() * 0.5f; } @@ -124,8 +119,7 @@ float getCenterX() * * @return The y-coordinate of the center */ - float getCenterY() - { + float getCenterY() { return getMinY() + getSizeY() * 0.5f; } @@ -134,8 +128,7 @@ float getCenterY() * * @return The z-coordinate of the center */ - float getCenterZ() - { + float getCenterZ() { return getMinZ() + getSizeZ() * 0.5f; } @@ -144,8 +137,7 @@ float getCenterZ() * * @return The size in x-direction */ - float getSizeX() - { + float getSizeX() { return getMaxX() - getMinX(); } @@ -154,8 +146,7 @@ float getSizeX() * * @return The size in y-direction */ - float getSizeY() - { + float getSizeY() { return getMaxY() - getMinY(); } @@ -164,8 +155,7 @@ float getSizeY() * * @return The size in z-direction */ - float getSizeZ() - { + float getSizeZ() { return getMaxZ() - getMinZ(); } @@ -174,8 +164,7 @@ float getSizeZ() * * @return The minimum x coordinate */ - float getMinX() - { + float getMinX() { return minX; } @@ -184,8 +173,7 @@ float getMinX() * * @return The minimum y coordinate */ - float getMinY() - { + float getMinY() { return minY; } @@ -194,8 +182,7 @@ float getMinY() * * @return The minimum z coordinate */ - float getMinZ() - { + float getMinZ() { return minZ; } @@ -204,8 +191,7 @@ float getMinZ() * * @return The maximum x coordinate */ - float getMaxX() - { + float getMaxX() { return maxX; } @@ -214,8 +200,7 @@ float getMaxX() * * @return The maximum y coordinate */ - float getMaxY() - { + float getMaxY() { return maxY; } @@ -224,16 +209,14 @@ float getMaxY() * * @return The maximum z coordinate */ - float getMaxZ() - { + float getMaxZ() { return maxZ; } - + @Override - public String toString() - { - return "[(" + - getMinX() + "," + getMinY() + "," + getMinZ() + ")-(" + - getMaxX() + "," + getMaxY() + "," + getMaxZ() + ")]"; + public String toString() { + return "[(" + + getMinX() + "," + getMinY() + "," + getMinZ() + ")-(" + + getMaxX() + "," + getMaxY() + "," + getMaxZ() + ")]"; } } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/BoundingBoxComputer.java b/src/main/java/de/javagl/jgltf/model/BoundingBoxComputer.java index 46184c7..9bb94f2 100644 --- a/src/main/java/de/javagl/jgltf/model/BoundingBoxComputer.java +++ b/src/main/java/de/javagl/jgltf/model/BoundingBoxComputer.java @@ -33,112 +33,101 @@ /** * A (package-private!) utility class to compute bounding volumes */ -class BoundingBoxComputer -{ +class BoundingBoxComputer { /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(BoundingBoxComputer.class.getName()); - + Logger.getLogger(BoundingBoxComputer.class.getName()); + /** - * The {@link GltfModel} + * The {@link GltfModel} */ private final GltfModel gltfModel; - + /** * Create a new bounding box computer for the given {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} */ - BoundingBoxComputer(GltfModel gltfModel) - { + BoundingBoxComputer(GltfModel gltfModel) { this.gltfModel = gltfModel; } - + /** * Compute the bounding box of the {@link GltfModel} - * + * * @return The bounding box */ - BoundingBox compute() - { + BoundingBox compute() { BoundingBox boundingBox = new BoundingBox(); List sceneModels = gltfModel.getSceneModels(); - for (SceneModel sceneModel : sceneModels) - { + for (SceneModel sceneModel : sceneModels) { float rootTransform[] = MathUtils.createIdentity4x4(); computeSceneBoundingBox(sceneModel, rootTransform, boundingBox); } return boundingBox; } - + /** * Recursively compute the bounding box of the {@link MeshPrimitiveModel} - * objects of all {@link MeshModel} objects in the given {@link SceneModel} - * (including the respective global node transforms). + * objects of all {@link MeshModel} objects in the given {@link SceneModel} + * (including the respective global node transforms). * If the given result is null, then a new bounding box * will be created and returned. - * - * @param sceneModel The {@link SceneModel} - * @param transform The root transform, as a column major 4x4 matrix - * @param boundingBox The optional bounding box that will store the result + * + * @param sceneModel The {@link SceneModel} + * @param transform The root transform, as a column major 4x4 matrix + * @param boundingBox The optional bounding box that will store the result * @return The result */ private BoundingBox computeSceneBoundingBox( - SceneModel sceneModel, float transform[], BoundingBox boundingBox) - { + SceneModel sceneModel, float transform[], BoundingBox boundingBox) { BoundingBox localResult = boundingBox; - if (localResult == null) - { + if (localResult == null) { localResult = new BoundingBox(); } List nodeModels = sceneModel.getNodeModels(); - for (NodeModel nodeModel : nodeModels) - { + for (NodeModel nodeModel : nodeModels) { computeNodeBoundingBox(nodeModel, transform, localResult); } return localResult; } - - + + /** * Recursively compute the bounding box of the {@link MeshPrimitiveModel} - * objects of all {@link MeshModel} objects in the given {@link NodeModel} - * and its children (including the respective global node transforms). + * objects of all {@link MeshModel} objects in the given {@link NodeModel} + * and its children (including the respective global node transforms). * If the given result is null, then a new bounding box * will be created and returned. - * - * @param nodeModel The {@link NodeModel} + * + * @param nodeModel The {@link NodeModel} * @param parentTransform The transform, as a column major 4x4 matrix - * @param boundingBox The optional bounding box that will store the result + * @param boundingBox The optional bounding box that will store the result * @return The result */ private BoundingBox computeNodeBoundingBox( - NodeModel nodeModel, float parentTransform[], BoundingBox boundingBox) - { + NodeModel nodeModel, float parentTransform[], BoundingBox boundingBox) { BoundingBox result = boundingBox; - if (result == null) - { + if (result == null) { result = new BoundingBox(); } float[] localTransform = nodeModel.computeLocalTransform(null); float[] transform = new float[16]; MathUtils.mul4x4(parentTransform, localTransform, transform); - + List meshModels = nodeModel.getMeshModels(); - for (MeshModel meshModel : meshModels) - { + for (MeshModel meshModel : meshModels) { BoundingBox meshBoundingBox = - computeMeshBoundingBox( - meshModel, transform, result); + computeMeshBoundingBox( + meshModel, transform, result); result.combine(meshBoundingBox); } - + List children = nodeModel.getChildren(); - for (NodeModel child : children) - { + for (NodeModel child : children) { computeNodeBoundingBox(child, transform, result); } return result; @@ -149,111 +138,97 @@ private BoundingBox computeNodeBoundingBox( * the given transform. * If the given result is null, then a new bounding box * will be created and returned. - * - * @param meshModel The {@link MeshModel} - * @param transform The optional transform. If this is null, - * then the identity matrix will be assumed. - * @param boundingBox The optional bounding box that will store the result + * + * @param meshModel The {@link MeshModel} + * @param transform The optional transform. If this is null, + * then the identity matrix will be assumed. + * @param boundingBox The optional bounding box that will store the result * @return The result */ private BoundingBox computeMeshBoundingBox( - MeshModel meshModel, float transform[], BoundingBox boundingBox) - { + MeshModel meshModel, float transform[], BoundingBox boundingBox) { BoundingBox result = boundingBox; - if (result == null) - { + if (result == null) { result = new BoundingBox(); } - - List primitives = - meshModel.getMeshPrimitiveModels(); - for (MeshPrimitiveModel meshPrimitiveModel : primitives) - { + + List primitives = + meshModel.getMeshPrimitiveModels(); + for (MeshPrimitiveModel meshPrimitiveModel : primitives) { BoundingBox meshPrimitiveBoundingBox = - computeBoundingBox(meshPrimitiveModel, transform); - if (meshPrimitiveBoundingBox != null) - { + computeBoundingBox(meshPrimitiveModel, transform); + if (meshPrimitiveBoundingBox != null) { result.combine(meshPrimitiveBoundingBox); } } return result; } - + /** * Compute the bounding box of the given {@link MeshPrimitiveModel}, under * the given transform. - * + * * @param meshPrimitiveModel The {@link MeshPrimitiveModel} - * @param transform The optional transform. If this is null, - * then the identity matrix will be assumed. + * @param transform The optional transform. If this is null, + * then the identity matrix will be assumed. * @return The {@link BoundingBox}, or null if the given - * {@link MeshPrimitiveModel} does not refer to an {@link AccessorModel} + * {@link MeshPrimitiveModel} does not refer to an {@link AccessorModel} * with its "POSITION" attribute. If if refers to * an {@link AccessorModel} that does not contain 3D float elements, * then a warning will be printed and null will be - * returned. + * returned. */ private BoundingBox computeBoundingBox( - MeshPrimitiveModel meshPrimitiveModel, float transform[]) - { - Map attributes = - meshPrimitiveModel.getAttributes(); + MeshPrimitiveModel meshPrimitiveModel, float transform[]) { + Map attributes = + meshPrimitiveModel.getAttributes(); String positionsAttributeName = "POSITION"; AccessorModel accessorModel = attributes.get(positionsAttributeName); - if (accessorModel == null) - { + if (accessorModel == null) { return null; } - + ElementType accessorType = accessorModel.getElementType(); int numComponents = accessorType.getNumComponents(); - if (numComponents < 3) - { - logger.warning("Mesh primitive " + positionsAttributeName + - " attribute refers to an accessor with type " + accessorType + - " - expected \"VEC3\" or \"VEC4\""); + if (numComponents < 3) { + logger.warning("Mesh primitive " + positionsAttributeName + + " attribute refers to an accessor with type " + accessorType + + " - expected \"VEC3\" or \"VEC4\""); return null; } Class componentDataType = accessorModel.getComponentDataType(); - if (!componentDataType.equals(float.class)) - { - logger.warning("Mesh primitive " + positionsAttributeName + - " attribute refers to an accessor with component type " + - GltfConstants.stringFor(accessorModel.getComponentType()) + - " - expected GL_FLOAT"); + if (!componentDataType.equals(float.class)) { + logger.warning("Mesh primitive " + positionsAttributeName + + " attribute refers to an accessor with component type " + + GltfConstants.stringFor(accessorModel.getComponentType()) + + " - expected GL_FLOAT"); } - + AccessorData accessorData = accessorModel.getAccessorData(); - AccessorFloatData accessorFloatData = (AccessorFloatData)accessorData; - + AccessorFloatData accessorFloatData = (AccessorFloatData) accessorData; + float point[] = new float[3]; float transformedPoint[]; - if (transform != null) - { + if (transform != null) { transformedPoint = new float[3]; - } - else - { + } else { transformedPoint = point; } - + BoundingBox boundingBox = new BoundingBox(); - for (int e = 0; e < accessorData.getNumElements(); e++) - { - for (int c = 0; c < 3; c++) - { + for (int e = 0; e < accessorData.getNumElements(); e++) { + for (int c = 0; c < 3; c++) { point[c] = accessorFloatData.get(e, c); } - if (transform != null) - { + if (transform != null) { MathUtils.transformPoint3D(transform, point, transformedPoint); } boundingBox.combine( - transformedPoint[0], - transformedPoint[1], - transformedPoint[2]); + transformedPoint[0], + transformedPoint[1], + transformedPoint[2]); } return boundingBox; } - + } diff --git a/src/main/java/de/javagl/jgltf/model/BoundingBoxes.java b/src/main/java/de/javagl/jgltf/model/BoundingBoxes.java index 49c0988..1a046aa 100644 --- a/src/main/java/de/javagl/jgltf/model/BoundingBoxes.java +++ b/src/main/java/de/javagl/jgltf/model/BoundingBoxes.java @@ -34,40 +34,37 @@ * Note: This class is preliminary. It may be replaced with more * sophisticated bounding box computation methods in the future. */ -public class BoundingBoxes -{ +public class BoundingBoxes { + /** + * Private constructor to prevent instantiation + */ + private BoundingBoxes() { + // Private constructor to prevent instantiation + } + /** * Compute the bounding box of the given {@link GltfModel}. The result * will be an array [minX, minY, minZ, maxX, maxY, maxZ]. - * + * * @param gltfModel The {@link GltfModel} * @return The bounding box */ - public static float[] computeBoundingBoxMinMax(GltfModel gltfModel) - { + public static float[] computeBoundingBoxMinMax(GltfModel gltfModel) { Objects.requireNonNull(gltfModel, "The gltfModel may not be null"); - + BoundingBoxComputer boundingBoxComputer = - new BoundingBoxComputer(gltfModel); + new BoundingBoxComputer(gltfModel); BoundingBox boundingBox = boundingBoxComputer.compute(); - + float result[] = { - boundingBox.getMinX(), - boundingBox.getMinY(), - boundingBox.getMinZ(), - boundingBox.getMaxX(), - boundingBox.getMaxY(), - boundingBox.getMaxZ() + boundingBox.getMinX(), + boundingBox.getMinY(), + boundingBox.getMinZ(), + boundingBox.getMaxX(), + boundingBox.getMaxY(), + boundingBox.getMaxZ() }; return result; - - } - - /** - * Private constructor to prevent instantiation - */ - private BoundingBoxes() - { - // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/BufferModel.java b/src/main/java/de/javagl/jgltf/model/BufferModel.java index e349d5c..7e44614 100644 --- a/src/main/java/de/javagl/jgltf/model/BufferModel.java +++ b/src/main/java/de/javagl/jgltf/model/BufferModel.java @@ -31,30 +31,29 @@ /** * Interface for a buffer of a glTF asset */ -public interface BufferModel extends NamedModelElement -{ +public interface BufferModel extends NamedModelElement { /** * Returns the URI of the buffer data - * + * * @return The URI */ String getUri(); - + /** * Returns the length, in bytes, of the {@link #getBufferData() buffer data} - * + * * @return The buffer length, in bytes */ int getByteLength(); - + /** - * Returns the actual buffer data. This will return a slice of the buffer - * that is stored internally. Thus, changes to the contents of this buffer - * will affect this model, but modifications of the position and limit of + * Returns the actual buffer data. This will return a slice of the buffer + * that is stored internally. Thus, changes to the contents of this buffer + * will affect this model, but modifications of the position and limit of * the returned buffer will not affect this model.
- * + * * @return The buffer data */ ByteBuffer getBufferData(); - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/BufferViewModel.java b/src/main/java/de/javagl/jgltf/model/BufferViewModel.java index faeb983..7107ff3 100644 --- a/src/main/java/de/javagl/jgltf/model/BufferViewModel.java +++ b/src/main/java/de/javagl/jgltf/model/BufferViewModel.java @@ -29,55 +29,54 @@ import java.nio.ByteBuffer; /** - * Interface for a buffer view, which represents a slice of a + * Interface for a buffer view, which represents a slice of a * {@link BufferModel} */ -public interface BufferViewModel extends NamedModelElement -{ +public interface BufferViewModel extends NamedModelElement { /** * Return the actual data that this view stands for. This will be a new - * slice of the buffer of the data that is stored internally. Changes + * slice of the buffer of the data that is stored internally. Changes * in the position or limit of this buffer will not affect this model - * + * * @return The buffer view data */ ByteBuffer getBufferViewData(); /** * Returns the {@link BufferModel} that this view refers to - * + * * @return The {@link BufferModel} */ BufferModel getBufferModel(); - + /** * Returns the offset of this view referring to the buffer - * + * * @return The offset, in bytes */ int getByteOffset(); - + /** * Returns the length of this view, in bytes - * + * * @return The length, in bytes */ int getByteLength(); - + /** * Returns the stride between two consecutive elements of this buffer view, * in bytes. If this is null, then the elements are tightly * packed. - * + * * @return The stride, in bytes */ Integer getByteStride(); - + /** * Returns the (optional) target that this buffer should be bound to. - * If this is not null, then it will be the GL constant for - * GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER. - * + * If this is not null, then it will be the GL constant for + * GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER. + * * @return The target, or null */ Integer getTarget(); diff --git a/src/main/java/de/javagl/jgltf/model/CameraModel.java b/src/main/java/de/javagl/jgltf/model/CameraModel.java index 21b8a86..17e82b7 100644 --- a/src/main/java/de/javagl/jgltf/model/CameraModel.java +++ b/src/main/java/de/javagl/jgltf/model/CameraModel.java @@ -33,36 +33,35 @@ /** * An interface for a camera that is attached to a {@link NodeModel} */ -public interface CameraModel extends NamedModelElement -{ +public interface CameraModel extends NamedModelElement { /** * Returns the {@link CameraOrthographicModel}, or null if * this is a perspective camera - * + * * @return The {@link CameraOrthographicModel} */ CameraOrthographicModel getCameraOrthographicModel(); - + /** * Returns the {@link CameraPerspectiveModel}, or null if * this is an orthographic camera - * + * * @return The {@link CameraPerspectiveModel} */ CameraPerspectiveModel getCameraPerspectiveModel(); - + /** * Compute the projection matrix for this camera.
*
- * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * - * @param result The result array - * @param aspectRatio An optional aspect ratio that should be used. - * If this is null, then the aspect ratio of the - * camera will be used. + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * + * @param result The result array + * @param aspectRatio An optional aspect ratio that should be used. + * If this is null, then the aspect ratio of the + * camera will be used. * @return The result array */ float[] computeProjectionMatrix(float result[], Float aspectRatio); @@ -70,21 +69,21 @@ public interface CameraModel extends NamedModelElement /** * Create the supplier of the projection matrix for this camera model.
*
- * The matrix will be provided as a float array with 16 elements, + * The matrix will be provided as a float array with 16 elements, * storing the matrix entries in column-major order.
*
- * Note: If the type of the camera that this {@link CameraModel} was - * created for is neither "perspective" nor + * Note: If the type of the camera that this {@link CameraModel} was + * created for is neither "perspective" nor * "orthographic", * then the supplier will print an error message and return * the identity matrix. - * + * * @param aspectRatioSupplier The optional supplier for the aspect - * ratio of the camera. If this is null, then the - * aspect ratio of the camera will be used. + * ratio of the camera. If this is null, then the + * aspect ratio of the camera will be used. * @return The supplier */ Supplier createProjectionMatrixSupplier( - DoubleSupplier aspectRatioSupplier); + DoubleSupplier aspectRatioSupplier); } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/CameraOrthographicModel.java b/src/main/java/de/javagl/jgltf/model/CameraOrthographicModel.java index 5c37e37..ae5420d 100644 --- a/src/main/java/de/javagl/jgltf/model/CameraOrthographicModel.java +++ b/src/main/java/de/javagl/jgltf/model/CameraOrthographicModel.java @@ -29,34 +29,33 @@ /** * Interface for an orthographic camera */ -public interface CameraOrthographicModel -{ +public interface CameraOrthographicModel { /** * Returns the horizontal magnification - * + * * @return The magnification */ Float getXmag(); /** * Returns the vertical magnification - * + * * @return The magnification */ Float getYmag(); - + /** * Returns the distance of the far clipping plane - * + * * @return The distance */ Float getZfar(); - + /** * Returns the distance of the near clipping plane - * + * * @return The distance */ Float getZnear(); - + } diff --git a/src/main/java/de/javagl/jgltf/model/CameraPerspectiveModel.java b/src/main/java/de/javagl/jgltf/model/CameraPerspectiveModel.java index 7d0a41d..e9ebe08 100644 --- a/src/main/java/de/javagl/jgltf/model/CameraPerspectiveModel.java +++ b/src/main/java/de/javagl/jgltf/model/CameraPerspectiveModel.java @@ -29,34 +29,33 @@ /** * Interface for an perspective camera */ -public interface CameraPerspectiveModel -{ +public interface CameraPerspectiveModel { /** * Returns the aspect ratio - * + * * @return The aspect ratio */ Float getAspectRatio(); - + /** * Returns the FOV, in y-direction, in radians - * + * * @return The FOV */ Float getYfov(); - + /** * Returns the distance of the far clipping plane - * + * * @return The distance */ Float getZfar(); - + /** * Returns the distance of the near clipping plane - * + * * @return The distance */ Float getZnear(); - + } diff --git a/src/main/java/de/javagl/jgltf/model/ElementType.java b/src/main/java/de/javagl/jgltf/model/ElementType.java index 6c8112d..873ba28 100644 --- a/src/main/java/de/javagl/jgltf/model/ElementType.java +++ b/src/main/java/de/javagl/jgltf/model/ElementType.java @@ -29,73 +29,104 @@ /** * Enumeration of the possible types of elements of an accessor */ -public enum ElementType -{ +public enum ElementType { /** * The scalar type */ SCALAR(1), - + /** * The 2D vector type */ VEC2(2), - + /** * The 3D vector type */ VEC3(3), - + /** * The 4D vector type */ VEC4(4), - + /** * The 2x2 matrix type */ MAT2(4), - + /** * The 3x3 matrix type */ MAT3(9), - + /** * The 4x4 matrix type */ MAT4(16); - + /** * The number of components that one element consists of */ private final int numComponents; - + /** * Creates a new instance with the given number of components - * + * * @param numComponents The number of components */ - ElementType(int numComponents) - { + ElementType(int numComponents) { this.numComponents = numComponents; } - + + /** + * Returns whether the given string is a valid element type name, and may be + * passed to ElementType.valueOf without causing an exception. + * + * @param s The string + * @return Whether the given string is a valid element type + */ + public static boolean contains(String s) { + for (ElementType elementType : values()) { + if (elementType.name().equals(s)) { + return true; + } + } + return false; + } + + /** + * Returns the element type for the given string. If the string is + * null or does not describe a valid element type, + * then null is returned + * + * @param string The string + * @return The element type + */ + public static ElementType forString(String string) { + if (string == null) { + return null; + } + if (!contains(string)) { + return null; + } + return ElementType.valueOf(string); + } + /** * Returns the number of components that one element consists of - * + * * @return The number of components */ - public int getNumComponents() - { + public int getNumComponents() { return numComponents; } - + /** * Obtains the byte stride that is implied for this element type with * the given component type, including any padding bytes that * may have to be inserted for matrix types. - * + *

* According to the specification (section 3.6.2.4, Data Alignment), * padding bytes may have to be inserted after each column of matrix: *

    @@ -112,72 +143,26 @@ public int getNumComponents() * have to be inserted after each column * *
- * + * * @param componentType The component type * @return The byte stride */ - public int getByteStride(int componentType) - { + public int getByteStride(int componentType) { int n = Accessors.getNumBytesForAccessorComponentType(componentType); - if (n == 1) - { - if (this == MAT2) - { + if (n == 1) { + if (this == MAT2) { return 8; } - if (this == MAT3) - { + if (this == MAT3) { return 12; } } - if (n == 2) - { - if (this == MAT3) - { + if (n == 2) { + if (this == MAT3) { return 24; } } return numComponents * n; } - - /** - * Returns whether the given string is a valid element type name, and may be - * passed to ElementType.valueOf without causing an exception. - * - * @param s The string - * @return Whether the given string is a valid element type - */ - public static boolean contains(String s) - { - for (ElementType elementType : values()) - { - if (elementType.name().equals(s)) - { - return true; - } - } - return false; - } - - /** - * Returns the element type for the given string. If the string is - * null or does not describe a valid element type, - * then null is returned - * - * @param string The string - * @return The element type - */ - public static ElementType forString(String string) - { - if (string == null) - { - return null; - } - if (!contains(string)) - { - return null; - } - return ElementType.valueOf(string); - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/ExtensionsModel.java b/src/main/java/de/javagl/jgltf/model/ExtensionsModel.java index 263fb81..e77d04c 100644 --- a/src/main/java/de/javagl/jgltf/model/ExtensionsModel.java +++ b/src/main/java/de/javagl/jgltf/model/ExtensionsModel.java @@ -32,14 +32,13 @@ * An interface for the information about the extensions that are used in a * {@link GltfModel}. */ -public interface ExtensionsModel -{ +public interface ExtensionsModel { /** * Returns the list of extension names that are declared as the * extensionsUsed in the glTF asset. - * + *

* The list should be assumed to be unmodifiable. - * + * * @return The list of used extensions */ List getExtensionsUsed(); @@ -47,9 +46,9 @@ public interface ExtensionsModel /** * Returns the list of extension names that are declared as the * extensionsRequired in the glTF asset. - * + *

* The list should be assumed to be unmodifiable. - * + * * @return The list of required extensions */ List getExtensionsRequired(); diff --git a/src/main/java/de/javagl/jgltf/model/GltfAnimations.java b/src/main/java/de/javagl/jgltf/model/GltfAnimations.java index 095ce0e..a2a9a2c 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfAnimations.java +++ b/src/main/java/de/javagl/jgltf/model/GltfAnimations.java @@ -26,11 +26,6 @@ */ package de.javagl.jgltf.model; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.logging.Logger; - import de.javagl.jgltf.model.AnimationModel.Channel; import de.javagl.jgltf.model.AnimationModel.Interpolation; import de.javagl.jgltf.model.AnimationModel.Sampler; @@ -40,372 +35,334 @@ import de.javagl.jgltf.model.animation.AnimationManager.AnimationPolicy; import de.javagl.jgltf.model.animation.InterpolatorType; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.logging.Logger; + /** * Utility methods to create {@link AnimationManager} instances that - * contain {@link Animation} instances that correspond to the - * {@link AnimationModel} instances of a glTF + * contain {@link Animation} instances that correspond to the + * {@link AnimationModel} instances of a glTF */ -@Deprecated //Please use com.modularmods.mcgltf.animation.GltfAnimationCreator to compatible with CUBICSPLINE interpolation -public class GltfAnimations -{ +@Deprecated +//Please use com.modularmods.mcgltf.animation.GltfAnimationCreator to compatible with CUBICSPLINE interpolation +public class GltfAnimations { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfAnimations.class.getName()); - + private static final Logger logger = + Logger.getLogger(GltfAnimations.class.getName()); + /** - * Create a new {@link AnimationManager} using the given + * Private constructor to prevent instantiation + */ + private GltfAnimations() { + // Private constructor to prevent instantiation + } + + /** + * Create a new {@link AnimationManager} using the given * {@link AnimationPolicy} - * + * * @param animationPolicy The {@link AnimationPolicy} * @return The {@link AnimationManager} */ public static AnimationManager createAnimationManager( - AnimationPolicy animationPolicy) - { - AnimationManager animationManager = - new AnimationManager(animationPolicy); + AnimationPolicy animationPolicy) { + AnimationManager animationManager = + new AnimationManager(animationPolicy); return animationManager; } - + /** - * Create all model {@link Animation} instances from the given + * Create all model {@link Animation} instances from the given * {@link AnimationModel} instances - * + * * @param animationModels The {@link AnimationModel} instances * @return The model animations */ public static List createModelAnimations( - Iterable animationModels) - { - Objects.requireNonNull(animationModels, - "The animationModels may not be null"); + Iterable animationModels) { + Objects.requireNonNull(animationModels, + "The animationModels may not be null"); List allModelAnimations = new ArrayList(); - for (AnimationModel animationModel : animationModels) - { + for (AnimationModel animationModel : animationModels) { List channels = animationModel.getChannels(); - List modelAnimations = - createModelAnimationsForChannels(channels); + List modelAnimations = + createModelAnimationsForChannels(channels); allModelAnimations.addAll(modelAnimations); } return allModelAnimations; } - + /** - * Create one {@link Animation} for each {@link AnimationModel.Channel}. - * If there is any error or inconsistency in the given data, then a + * Create one {@link Animation} for each {@link Channel}. + * If there is any error or inconsistency in the given data, then a * warning will be printed and the respective animation will be * skipped. - * - * @param channels The {@link AnimationModel.Channel} list + * + * @param channels The {@link Channel} list * @return The list of model animations */ private static List createModelAnimationsForChannels( - Iterable channels) - { + Iterable channels) { List modelAnimations = new ArrayList(); - for (Channel channel : channels) - { + for (Channel channel : channels) { Animation modelAnimation = createModelAnimation(channel); - if (modelAnimation != null) - { + if (modelAnimation != null) { modelAnimations.add(modelAnimation); } } return modelAnimations; } - - + /** - * Create the {@link Animation} for the given - * {@link AnimationModel.Channel}. If there is any error or inconsistency - * in the given data, then a warning will be printed and null + * Create the {@link Animation} for the given + * {@link Channel}. If there is any error or inconsistency + * in the given data, then a warning will be printed and null * will be returned. - * - * @param channel The {@link AnimationModel.Channel} + * + * @param channel The {@link Channel} * @return The {@link Animation}, or null. */ - private static Animation createModelAnimation(Channel channel) - { + private static Animation createModelAnimation(Channel channel) { Sampler sampler = channel.getSampler(); Interpolation interpolation = sampler.getInterpolation(); NodeModel nodeModel = channel.getNodeModel(); String path = channel.getPath(); - - AnimationListener animationListener = - createAnimationListener(nodeModel, path); - if (animationListener == null) - { + + AnimationListener animationListener = + createAnimationListener(nodeModel, path); + if (animationListener == null) { return null; } - InterpolatorType interpolatorType = - typeForInterpolation(interpolation, path); - + InterpolatorType interpolatorType = + typeForInterpolation(interpolation, path); + AccessorModel input = sampler.getInput(); AccessorData inputData = input.getAccessorData(); - if (!(inputData instanceof AccessorFloatData)) - { + if (!(inputData instanceof AccessorFloatData)) { logger.warning("Input data is not an AccessorFloatData, but " - + inputData.getClass()); + + inputData.getClass()); return null; } - AccessorFloatData inputFloatData = (AccessorFloatData)inputData; + AccessorFloatData inputFloatData = (AccessorFloatData) inputData; AccessorModel output = sampler.getOutput(); AccessorData outputData = output.getAccessorData(); - if (!(outputData instanceof AccessorFloatData)) - { + if (!(outputData instanceof AccessorFloatData)) { logger.warning("Output data is not an AccessorFloatData, but " - + outputData.getClass()); + + outputData.getClass()); return null; } - AccessorFloatData outputFloatData = (AccessorFloatData)outputData; - - Animation modelAnimation = - createAnimation(inputFloatData, outputFloatData, interpolatorType); + AccessorFloatData outputFloatData = (AccessorFloatData) outputData; + + Animation modelAnimation = + createAnimation(inputFloatData, outputFloatData, interpolatorType); modelAnimation.addAnimationListener(animationListener); return modelAnimation; } - + /** * Returns the {@link InterpolatorType} for the given {@link Interpolation} * and path - * + * * @param interpolation The {@link Interpolation} - * @param path The path + * @param path The path * @return The {@link InterpolatorType} */ private static InterpolatorType typeForInterpolation( - Interpolation interpolation, String path) - { - switch (interpolation) - { - case LINEAR: - { - if (path.equals("rotation")) - { + Interpolation interpolation, String path) { + switch (interpolation) { + case LINEAR: { + if (path.equals("rotation")) { return InterpolatorType.SLERP; } return InterpolatorType.LINEAR; } - case STEP: - { + case STEP: { return InterpolatorType.STEP; } - - case CUBICSPLINE: - { + + case CUBICSPLINE: { } default: logger.warning("This interpolation type is not supported yet"); break; } logger.warning( - "Interpolation type not supported: " + interpolation); + "Interpolation type not supported: " + interpolation); return InterpolatorType.LINEAR; } - - /** - * Creates a new {@link Animation} from + * Creates a new {@link Animation} from * the given input data - * - * @param timeData The (1D) {@link AccessorFloatData} containing the - * time key frames - * @param outputData The output data that contains the value key frames + * + * @param timeData The (1D) {@link AccessorFloatData} containing the + * time key frames + * @param outputData The output data that contains the value key frames * @param interpolatorType The {@link InterpolatorType} that should - * be used + * be used * @return The {@link Animation} */ static Animation createAnimation( - AccessorFloatData timeData, - AccessorFloatData outputData, - InterpolatorType interpolatorType) - { + AccessorFloatData timeData, + AccessorFloatData outputData, + InterpolatorType interpolatorType) { int numKeyElements = timeData.getNumElements(); float keys[] = new float[numKeyElements]; - for (int e=0; e"translation", "rotation", - * "scale" or "weights", then a warning + * path is not "translation", "rotation", + * "scale" or "weights", then a warning * will be printed and null will be returned. - * + * * @param nodeModel The {@link NodeModel} - * @param path The path + * @param path The path * @return The {@link AnimationListener} */ private static AnimationListener createAnimationListener( - NodeModel nodeModel, String path) - { - switch (path) - { + NodeModel nodeModel, String path) { + switch (path) { case "translation": return createTranslationAnimationListener(nodeModel); - + case "rotation": return createRotationAnimationListener(nodeModel); - + case "scale": return createScaleAnimationListener(nodeModel); - + case "weights": return createWeightsAnimationListener(nodeModel); - + default: break; } logger.warning("Animation channel target path must be " - + "\"translation\", \"rotation\", \"scale\" or \"weights\", " - + "but is " + path); + + "\"translation\", \"rotation\", \"scale\" or \"weights\", " + + "but is " + path); return null; } - + /** * Creates an {@link AnimationListener} that writes the animation data - * into the {@link NodeModel#getTranslation() translation} of the + * into the {@link NodeModel#getTranslation() translation} of the * {@link NodeModel}. - * + * * @param nodeModel The {@link NodeModel} * @return The {@link AnimationListener} */ private static AnimationListener createTranslationAnimationListener( - NodeModel nodeModel) - { + NodeModel nodeModel) { return (animation, timeS, values) -> { float translation[] = nodeModel.getTranslation(); - if (translation == null) - { + if (translation == null) { translation = values.clone(); nodeModel.setTranslation(translation); - } - else - { + } else { System.arraycopy(values, 0, translation, 0, values.length); } }; } - + /** * Creates an {@link AnimationListener} that writes the animation data - * into the {@link NodeModel#getRotation() rotation} of the + * into the {@link NodeModel#getRotation() rotation} of the * {@link NodeModel}. - * + * * @param nodeModel The {@link NodeModel} * @return The {@link AnimationListener} */ private static AnimationListener createRotationAnimationListener( - NodeModel nodeModel) - { + NodeModel nodeModel) { return (animation, timeS, values) -> { float rotation[] = nodeModel.getRotation(); - if (rotation == null) - { + if (rotation == null) { rotation = values.clone(); nodeModel.setRotation(rotation); - } - else - { + } else { System.arraycopy(values, 0, rotation, 0, values.length); } }; } - + /** * Creates an {@link AnimationListener} that writes the animation data - * into the {@link NodeModel#getScale() scale} of the + * into the {@link NodeModel#getScale() scale} of the * {@link NodeModel}. - * + * * @param nodeModel The {@link NodeModel} * @return The {@link AnimationListener} */ private static AnimationListener createScaleAnimationListener( - NodeModel nodeModel) - { + NodeModel nodeModel) { return (animation, timeS, values) -> { float scale[] = nodeModel.getScale(); - if (scale == null) - { + if (scale == null) { scale = values.clone(); nodeModel.setScale(scale); - } - else - { + } else { System.arraycopy(values, 0, scale, 0, values.length); } }; } - + /** * Creates an {@link AnimationListener} that writes the animation data - * into the {@link NodeModel#getWeights() weights} of the + * into the {@link NodeModel#getWeights() weights} of the * {@link NodeModel}. - * + * * @param nodeModel The {@link NodeModel} * @return The {@link AnimationListener} */ private static AnimationListener createWeightsAnimationListener( - NodeModel nodeModel) - { + NodeModel nodeModel) { return (animation, timeS, values) -> { float weights[] = nodeModel.getWeights(); - if (weights == null) - { + if (weights == null) { weights = values.clone(); nodeModel.setWeights(weights); - } - else - { + } else { System.arraycopy(values, 0, weights, 0, values.length); } }; } - - - /** - * Private constructor to prevent instantiation - */ - private GltfAnimations() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/GltfConstants.java b/src/main/java/de/javagl/jgltf/model/GltfConstants.java index 63d0c58..64134af 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfConstants.java +++ b/src/main/java/de/javagl/jgltf/model/GltfConstants.java @@ -30,35 +30,33 @@ /** * Some common OpenGL constants that are used in glTF */ -public class GltfConstants -{ +public class GltfConstants { /** * The GL_BGR constant (32992) */ public static final int GL_BGR = 32992; - + /** * The GL_RGB constant (6407) */ public static final int GL_RGB = 6407; - + /** * The GL_RGBA constant (6408) */ public static final int GL_RGBA = 6408; - + /** * The GL_BGRA constant (32993) */ public static final int GL_BGRA = 32993; - - - + + /** * The GL_BYTE constant (5120) */ public static final int GL_BYTE = 5120; - + /** * The GL_UNSIGNED_BYTE constant (5121) */ @@ -68,12 +66,12 @@ public class GltfConstants * The GL_SHORT constant (5122) */ public static final int GL_SHORT = 5122; - + /** * The GL_UNSIGNED_SHORT constant (5123) */ public static final int GL_UNSIGNED_SHORT = 5123; - + /** * The GL_INT constant (5124) */ @@ -83,14 +81,13 @@ public class GltfConstants * The GL_UNSIGNED_INT constant (5125) */ public static final int GL_UNSIGNED_INT = 5125; - + /** * The GL_FLOAT constant (5126) */ public static final int GL_FLOAT = 5126; - - + /** * The GL_FLOAT_VEC2 constant (35664) */ @@ -159,14 +156,14 @@ public class GltfConstants /** * The GL_SAMPLER_2D constant (35678) */ - public static final int GL_SAMPLER_2D = 35678; - + public static final int GL_SAMPLER_2D = 35678; + /** * The GL_SAMPLER_CUBE constant (35680) */ public static final int GL_SAMPLER_CUBE = 35680; - - + + /** * The GL_POINTS constant (0) */ @@ -190,7 +187,7 @@ public class GltfConstants /** * The GL_TRIANGLES constant (4) */ - public static final int GL_TRIANGLES = 4; + public static final int GL_TRIANGLES = 4; /** * The GL_TRIANGLE_STRIP constant (5) @@ -201,239 +198,236 @@ public class GltfConstants * The GL_TRIANGLE_FAN constant (6) */ public static final int GL_TRIANGLE_FAN = 6; - - - + + /** * The GL_VERTEX_SHADER constant (35633) */ - public static final int GL_VERTEX_SHADER = 35633; - + public static final int GL_VERTEX_SHADER = 35633; + /** * The GL_VERTEX_SHADER constant (35632) */ - public static final int GL_FRAGMENT_SHADER = 35632; - - - + public static final int GL_FRAGMENT_SHADER = 35632; + + /** * The GL_TEXTURE_2D constant (3553) */ public static final int GL_TEXTURE_2D = 3553; - - - + + /** * The GL_ARRAY_BUFFER constant (34962) */ - public static final int GL_ARRAY_BUFFER = 34962; - + public static final int GL_ARRAY_BUFFER = 34962; + /** * The GL_ELEMENT_ARRAY_BUFFER constant (34963) */ public static final int GL_ELEMENT_ARRAY_BUFFER = 34963; - - + + // glEnable for technique.states - + /** * The GL_BLEND constant (3042) */ public static final int GL_BLEND = 3042; - + /** * The GL_CULL_FACE constant (2884) */ public static final int GL_CULL_FACE = 2884; - + /** * The GL_DEPTH_TEST constant (2929) */ public static final int GL_DEPTH_TEST = 2929; - + /** * The GL_POLYGON_OFFSET_FILL constant (32823) */ public static final int GL_POLYGON_OFFSET_FILL = 32823; - + /** * The GL_SAMPLE_ALPHA_TO_COVERAGE constant (32926) */ public static final int GL_SAMPLE_ALPHA_TO_COVERAGE = 32926; - + /** * The GL_SCISSOR_TEST constant (3089) */ public static final int GL_SCISSOR_TEST = 3089; // glBlendEquationSeparate - + /** * The GL_FUNC_ADD constant (32774) */ public static final int GL_FUNC_ADD = 32774; - + /** * The GL_FUNC_SUBTRACT constant (32778) */ public static final int GL_FUNC_SUBTRACT = 32778; - + /** * The GL_FUNC_REVERSE_SUBTRACT constant (32779) */ public static final int GL_FUNC_REVERSE_SUBTRACT = 32779; // glBlendFuncSeparate - + /** * The GL_ZERO constant (0) */ public static final int GL_ZERO = 0; - + /** * The GL_ONE constant (1) */ public static final int GL_ONE = 1; - + /** * The GL_SRC_COLOR constant (768) */ public static final int GL_SRC_COLOR = 768; - + /** * The GL_ONE_MINUS_SRC_COLOR constant (769) */ public static final int GL_ONE_MINUS_SRC_COLOR = 769; - + /** * The GL_DST_COLOR constant (774) */ public static final int GL_DST_COLOR = 774; - + /** * The GL_ONE_MINUS_DST_COLOR constant (775) */ public static final int GL_ONE_MINUS_DST_COLOR = 775; - + /** * The GL_SRC_ALPHA constant (770) */ public static final int GL_SRC_ALPHA = 770; - + /** * The GL_ONE_MINUS_SRC_ALPHA constant (771) */ public static final int GL_ONE_MINUS_SRC_ALPHA = 771; - + /** * The GL_DST_ALPHA constant (772) */ public static final int GL_DST_ALPHA = 772; - + /** * The GL_ONE_MINUS_DST_ALPHA constant (773) */ public static final int GL_ONE_MINUS_DST_ALPHA = 773; - + /** * The GL_CONSTANT_COLOR constant (32769) */ public static final int GL_CONSTANT_COLOR = 32769; - + /** * The GL_ONE_MINUS_CONSTANT_COLOR constant (32770) */ public static final int GL_ONE_MINUS_CONSTANT_COLOR = 32770; - + /** * The GL_CONSTANT_ALPHA constant (32771) */ public static final int GL_CONSTANT_ALPHA = 32771; - + /** * The GL_ONE_MINUS_CONSTANT_ALPHA constant (32772) */ public static final int GL_ONE_MINUS_CONSTANT_ALPHA = 32772; - + /** * The GL_SRC_ALPHA_SATURATE constant (776) */ public static final int GL_SRC_ALPHA_SATURATE = 776; // glCullFace - + /** * The GL_FRONT constant (1028) */ public static final int GL_FRONT = 1028; - + /** * The GL_BACK constant (1029) */ public static final int GL_BACK = 1029; - + /** * The GL_FRONT_AND_BACK constant (1032) */ public static final int GL_FRONT_AND_BACK = 1032; // glDepthFunc - + /** * The GL_NEVER constant (512) */ public static final int GL_NEVER = 512; - + /** * The GL_LESS constant (513) */ public static final int GL_LESS = 513; - + /** * The GL_LEQUAL constant (515) */ public static final int GL_LEQUAL = 515; - + /** * The GL_EQUAL constant (514) */ public static final int GL_EQUAL = 514; - + /** * The GL_GREATER constant (516) */ public static final int GL_GREATER = 516; - + /** * The GL_NOTEQUAL constant (517) */ public static final int GL_NOTEQUAL = 517; - + /** * The GL_GEQUAL constant (518) */ public static final int GL_GEQUAL = 518; - + /** * The GL_ALWAYS constant (519) */ public static final int GL_ALWAYS = 519; // glFrontFace - + /** * The GL_CW constant (2304) */ public static final int GL_CW = 2304; - + /** * The GL_CCW constant (2305) */ - public static final int GL_CCW = 2305; - - + public static final int GL_CCW = 2305; + + // glTexParameter - + /** * The GL_NEAREST constant (9728) */ @@ -465,7 +459,7 @@ public class GltfConstants public static final int GL_LINEAR_MIPMAP_LINEAR = 9987; // glSamplerParameter - + /** * The GL_REPEAT constant (10497) */ @@ -486,139 +480,213 @@ public class GltfConstants */ public static final int GL_CLAMP_TO_BORDER = 33069; - - + + /** + * Private constructor to prevent instantiation + */ + private GltfConstants() { + // Private constructor to prevent instantiation + } + /** * Returns the String representation of the given constant - * + * * @param constant The constant * @return The String for the constant */ - public static String stringFor(int constant) - { - switch (constant) - { - case GL_BGR : return "GL_BGR"; - case GL_RGB : return "GL_RGB"; - case GL_RGBA : return "GL_RGBA"; - case GL_BGRA : return "GL_BGRA"; - - case GL_BYTE : return "GL_BYTE"; - case GL_UNSIGNED_BYTE : return "GL_UNSIGNED_BYTE"; - case GL_SHORT : return "GL_SHORT"; - case GL_UNSIGNED_SHORT : return "GL_UNSIGNED_SHORT"; - case GL_INT : return "GL_INT"; - case GL_UNSIGNED_INT : return "GL_UNSIGNED_INT"; - case GL_FLOAT : return "GL_FLOAT"; - - case GL_FLOAT_VEC2 : return "GL_FLOAT_VEC2"; - case GL_FLOAT_VEC3 : return "GL_FLOAT_VEC3"; - case GL_FLOAT_VEC4 : return "GL_FLOAT_VEC4"; - case GL_INT_VEC2 : return "GL_INT_VEC2"; - case GL_INT_VEC3 : return "GL_INT_VEC3"; - case GL_INT_VEC4 : return "GL_INT_VEC4"; - case GL_BOOL : return "GL_BOOL"; - case GL_BOOL_VEC2 : return "GL_BOOL_VEC2"; - case GL_BOOL_VEC3 : return "GL_BOOL_VEC3"; - case GL_BOOL_VEC4 : return "GL_BOOL_VEC4"; - case GL_FLOAT_MAT2 : return "GL_FLOAT_MAT2"; - case GL_FLOAT_MAT3 : return "GL_FLOAT_MAT3"; - case GL_FLOAT_MAT4 : return "GL_FLOAT_MAT4"; - case GL_SAMPLER_2D : return "GL_SAMPLER_2D"; - - case GL_POINTS: return "GL_ZERO or GL_POINTS"; - case GL_LINES: return "GL_ONE or GL_LINES"; - case GL_LINE_LOOP: return "GL_LINE_LOOP"; - case GL_LINE_STRIP: return "GL_LINE_STRIP"; - case GL_TRIANGLES: return "GL_TRIANGLES"; - case GL_TRIANGLE_STRIP: return "GL_TRIANGLE_STRIP"; - - case GL_VERTEX_SHADER: return "GL_VERTEX_SHADER"; - case GL_FRAGMENT_SHADER: return "GL_FRAGMENT_SHADER"; - - case GL_TEXTURE_2D: return "GL_TEXTURE_2D"; - - case GL_ARRAY_BUFFER: return "GL_ARRAY_BUFFER"; - case GL_ELEMENT_ARRAY_BUFFER: return "GL_ELEMENT_ARRAY_BUFFER"; - + public static String stringFor(int constant) { + switch (constant) { + case GL_BGR: + return "GL_BGR"; + case GL_RGB: + return "GL_RGB"; + case GL_RGBA: + return "GL_RGBA"; + case GL_BGRA: + return "GL_BGRA"; + + case GL_BYTE: + return "GL_BYTE"; + case GL_UNSIGNED_BYTE: + return "GL_UNSIGNED_BYTE"; + case GL_SHORT: + return "GL_SHORT"; + case GL_UNSIGNED_SHORT: + return "GL_UNSIGNED_SHORT"; + case GL_INT: + return "GL_INT"; + case GL_UNSIGNED_INT: + return "GL_UNSIGNED_INT"; + case GL_FLOAT: + return "GL_FLOAT"; + + case GL_FLOAT_VEC2: + return "GL_FLOAT_VEC2"; + case GL_FLOAT_VEC3: + return "GL_FLOAT_VEC3"; + case GL_FLOAT_VEC4: + return "GL_FLOAT_VEC4"; + case GL_INT_VEC2: + return "GL_INT_VEC2"; + case GL_INT_VEC3: + return "GL_INT_VEC3"; + case GL_INT_VEC4: + return "GL_INT_VEC4"; + case GL_BOOL: + return "GL_BOOL"; + case GL_BOOL_VEC2: + return "GL_BOOL_VEC2"; + case GL_BOOL_VEC3: + return "GL_BOOL_VEC3"; + case GL_BOOL_VEC4: + return "GL_BOOL_VEC4"; + case GL_FLOAT_MAT2: + return "GL_FLOAT_MAT2"; + case GL_FLOAT_MAT3: + return "GL_FLOAT_MAT3"; + case GL_FLOAT_MAT4: + return "GL_FLOAT_MAT4"; + case GL_SAMPLER_2D: + return "GL_SAMPLER_2D"; + + case GL_POINTS: + return "GL_ZERO or GL_POINTS"; + case GL_LINES: + return "GL_ONE or GL_LINES"; + case GL_LINE_LOOP: + return "GL_LINE_LOOP"; + case GL_LINE_STRIP: + return "GL_LINE_STRIP"; + case GL_TRIANGLES: + return "GL_TRIANGLES"; + case GL_TRIANGLE_STRIP: + return "GL_TRIANGLE_STRIP"; + + case GL_VERTEX_SHADER: + return "GL_VERTEX_SHADER"; + case GL_FRAGMENT_SHADER: + return "GL_FRAGMENT_SHADER"; + + case GL_TEXTURE_2D: + return "GL_TEXTURE_2D"; + + case GL_ARRAY_BUFFER: + return "GL_ARRAY_BUFFER"; + case GL_ELEMENT_ARRAY_BUFFER: + return "GL_ELEMENT_ARRAY_BUFFER"; + // glEnable for technique.states - case GL_BLEND: return "GL_BLEND"; - case GL_CULL_FACE: return "GL_CULL_FACE"; - case GL_DEPTH_TEST: return "GL_DEPTH_TEST"; - case GL_POLYGON_OFFSET_FILL: return "GL_POLYGON_OFFSET_FILL"; - case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_BLEND: + return "GL_BLEND"; + case GL_CULL_FACE: + return "GL_CULL_FACE"; + case GL_DEPTH_TEST: + return "GL_DEPTH_TEST"; + case GL_POLYGON_OFFSET_FILL: + return "GL_POLYGON_OFFSET_FILL"; + case GL_SAMPLE_ALPHA_TO_COVERAGE: return "GL_SAMPLE_ALPHA_TO_COVERAGE"; - case GL_SCISSOR_TEST: return "GL_SCISSOR_TEST"; + case GL_SCISSOR_TEST: + return "GL_SCISSOR_TEST"; // glBlendEquationSeparate - case GL_FUNC_ADD: return "GL_FUNC_ADD"; - case GL_FUNC_SUBTRACT: return "GL_FUNC_SUBTRACT"; - case GL_FUNC_REVERSE_SUBTRACT: return "GL_FUNC_REVERSE_SUBTRACT"; + case GL_FUNC_ADD: + return "GL_FUNC_ADD"; + case GL_FUNC_SUBTRACT: + return "GL_FUNC_SUBTRACT"; + case GL_FUNC_REVERSE_SUBTRACT: + return "GL_FUNC_REVERSE_SUBTRACT"; // glBlendFuncSeparate //case GL_ZERO: return "GL_ZERO"; // see GL_POINTS //case GL_ONE: return "GL_ONE"; // see GL_LINES - case GL_SRC_COLOR: return "GL_SRC_COLOR"; - case GL_ONE_MINUS_SRC_COLOR: return "GL_ONE_MINUS_SRC_COLOR"; - case GL_DST_COLOR: return "GL_DST_COLOR"; - case GL_ONE_MINUS_DST_COLOR: return "GL_ONE_MINUS_DST_COLOR"; - case GL_SRC_ALPHA: return "GL_SRC_ALPHA"; - case GL_ONE_MINUS_SRC_ALPHA: return "GL_ONE_MINUS_SRC_ALPHA"; - case GL_DST_ALPHA: return "GL_DST_ALPHA"; - case GL_ONE_MINUS_DST_ALPHA: return "GL_ONE_MINUS_DST_ALPHA"; - case GL_CONSTANT_COLOR: return "GL_CONSTANT_COLOR"; - case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_SRC_COLOR: + return "GL_SRC_COLOR"; + case GL_ONE_MINUS_SRC_COLOR: + return "GL_ONE_MINUS_SRC_COLOR"; + case GL_DST_COLOR: + return "GL_DST_COLOR"; + case GL_ONE_MINUS_DST_COLOR: + return "GL_ONE_MINUS_DST_COLOR"; + case GL_SRC_ALPHA: + return "GL_SRC_ALPHA"; + case GL_ONE_MINUS_SRC_ALPHA: + return "GL_ONE_MINUS_SRC_ALPHA"; + case GL_DST_ALPHA: + return "GL_DST_ALPHA"; + case GL_ONE_MINUS_DST_ALPHA: + return "GL_ONE_MINUS_DST_ALPHA"; + case GL_CONSTANT_COLOR: + return "GL_CONSTANT_COLOR"; + case GL_ONE_MINUS_CONSTANT_COLOR: return "GL_ONE_MINUS_CONSTANT_COLOR"; - case GL_CONSTANT_ALPHA: return "GL_CONSTANT_ALPHA"; - case GL_ONE_MINUS_CONSTANT_ALPHA: + case GL_CONSTANT_ALPHA: + return "GL_CONSTANT_ALPHA"; + case GL_ONE_MINUS_CONSTANT_ALPHA: return "GL_ONE_MINUS_CONSTANT_ALPHA"; - case GL_SRC_ALPHA_SATURATE: return "GL_SRC_ALPHA_SATURATE"; + case GL_SRC_ALPHA_SATURATE: + return "GL_SRC_ALPHA_SATURATE"; // glCullFace - case GL_FRONT: return "GL_FRONT"; - case GL_BACK: return "GL_BACK"; - case GL_FRONT_AND_BACK: return "GL_FRONT_AND_BACK"; + case GL_FRONT: + return "GL_FRONT"; + case GL_BACK: + return "GL_BACK"; + case GL_FRONT_AND_BACK: + return "GL_FRONT_AND_BACK"; // glDepthFunc - case GL_NEVER: return "GL_NEVER"; - case GL_LESS: return "GL_LESS"; - case GL_LEQUAL: return "GL_LEQUAL"; - case GL_EQUAL: return "GL_EQUAL"; - case GL_GREATER: return "GL_GREATER"; - case GL_NOTEQUAL: return "GL_NOTEQUAL"; - case GL_GEQUAL: return "GL_GEQUAL"; - case GL_ALWAYS: return "GL_ALWAYS"; + case GL_NEVER: + return "GL_NEVER"; + case GL_LESS: + return "GL_LESS"; + case GL_LEQUAL: + return "GL_LEQUAL"; + case GL_EQUAL: + return "GL_EQUAL"; + case GL_GREATER: + return "GL_GREATER"; + case GL_NOTEQUAL: + return "GL_NOTEQUAL"; + case GL_GEQUAL: + return "GL_GEQUAL"; + case GL_ALWAYS: + return "GL_ALWAYS"; // glFrontFace - case GL_CW: return "GL_CW"; - case GL_CCW: return "GL_CCW"; - + case GL_CW: + return "GL_CW"; + case GL_CCW: + return "GL_CCW"; + // glTexParameter - case GL_NEAREST : return "GL_NEAREST"; - case GL_LINEAR : return "GL_LINEAR"; - case GL_NEAREST_MIPMAP_NEAREST : return "GL_NEAREST_MIPMAP_NEAREST"; - case GL_LINEAR_MIPMAP_NEAREST : return "GL_LINEAR_MIPMAP_NEAREST"; - case GL_NEAREST_MIPMAP_LINEAR : return "GL_NEAREST_MIPMAP_LINEAR"; - case GL_LINEAR_MIPMAP_LINEAR : return "GL_LINEAR_MIPMAP_LINEAR"; - + case GL_NEAREST: + return "GL_NEAREST"; + case GL_LINEAR: + return "GL_LINEAR"; + case GL_NEAREST_MIPMAP_NEAREST: + return "GL_NEAREST_MIPMAP_NEAREST"; + case GL_LINEAR_MIPMAP_NEAREST: + return "GL_LINEAR_MIPMAP_NEAREST"; + case GL_NEAREST_MIPMAP_LINEAR: + return "GL_NEAREST_MIPMAP_LINEAR"; + case GL_LINEAR_MIPMAP_LINEAR: + return "GL_LINEAR_MIPMAP_LINEAR"; + // glSamplerParameter - case GL_REPEAT : return "GL_REPEAT"; - case GL_MIRRORED_REPEAT : return "GL_MIRRORED_REPEAT"; - case GL_CLAMP_TO_EDGE : return "GL_CLAMP_TO_EDGE"; - case GL_CLAMP_TO_BORDER : return "GL_CLAMP_TO_BORDER"; - + case GL_REPEAT: + return "GL_REPEAT"; + case GL_MIRRORED_REPEAT: + return "GL_MIRRORED_REPEAT"; + case GL_CLAMP_TO_EDGE: + return "GL_CLAMP_TO_EDGE"; + case GL_CLAMP_TO_BORDER: + return "GL_CLAMP_TO_BORDER"; + default: - return "UNKNOWN_GL_CONSTANT["+constant+"]"; + return "UNKNOWN_GL_CONSTANT[" + constant + "]"; } } - - /** - * Private constructor to prevent instantiation - */ - private GltfConstants() - { - // Private constructor to prevent instantiation - } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/GltfException.java b/src/main/java/de/javagl/jgltf/model/GltfException.java index a63f7f5..b87344a 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfException.java +++ b/src/main/java/de/javagl/jgltf/model/GltfException.java @@ -29,8 +29,7 @@ /** * An exception that may be thrown to indicate an error inside a glTF asset. */ -public class GltfException extends RuntimeException -{ +public class GltfException extends RuntimeException { /** * Serial UID */ @@ -38,22 +37,20 @@ public class GltfException extends RuntimeException /** * Creates a new exception with the given message - * - * @param message The message + * + * @param message The message */ - public GltfException(String message) - { + public GltfException(String message) { super(message); } /** * Creates a new exception with the given message and cause - * - * @param message The message - * @param cause The cause + * + * @param message The message + * @param cause The cause */ - public GltfException(String message, Throwable cause) - { + public GltfException(String message, Throwable cause) { super(message, cause); } } diff --git a/src/main/java/de/javagl/jgltf/model/GltfModel.java b/src/main/java/de/javagl/jgltf/model/GltfModel.java index 06fc1f2..dd07613 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfModel.java +++ b/src/main/java/de/javagl/jgltf/model/GltfModel.java @@ -31,119 +31,118 @@ /** * Interface for a model that was created from a glTF asset */ -public interface GltfModel extends ModelElement -{ +public interface GltfModel extends ModelElement { /** - * Returns an unmodifiable view on the list of {@link AccessorModel} + * Returns an unmodifiable view on the list of {@link AccessorModel} * instances that have been created for the glTF. - * + * * @return The {@link AccessorModel} instances */ List getAccessorModels(); - + /** - * Returns an unmodifiable view on the list of {@link AnimationModel} + * Returns an unmodifiable view on the list of {@link AnimationModel} * instances that have been created for the glTF. - * + * * @return The {@link AnimationModel} instances */ List getAnimationModels(); /** - * Returns an unmodifiable view on the list of {@link BufferModel} + * Returns an unmodifiable view on the list of {@link BufferModel} * instances that have been created for the glTF. - * + * * @return The {@link BufferModel} instances */ List getBufferModels(); /** - * Returns an unmodifiable view on the list of {@link BufferViewModel} + * Returns an unmodifiable view on the list of {@link BufferViewModel} * instances that have been created for the glTF. - * + * * @return The {@link BufferViewModel} instances */ List getBufferViewModels(); - + /** - * Returns an unmodifiable view on the list of {@link CameraModel} + * Returns an unmodifiable view on the list of {@link CameraModel} * instances that have been created for the glTF. - * + * * @return The {@link CameraModel} instances */ List getCameraModels(); /** - * Returns an unmodifiable view on the list of {@link ImageModel} + * Returns an unmodifiable view on the list of {@link ImageModel} * instances that have been created for the glTF. - * + * * @return The {@link ImageModel} instances */ List getImageModels(); - + /** - * Returns an unmodifiable view on the list of {@link MaterialModel} + * Returns an unmodifiable view on the list of {@link MaterialModel} * instances that have been created for the glTF. - * + * * @return The {@link MaterialModel} instances */ List getMaterialModels(); /** - * Returns an unmodifiable view on the list of {@link MeshModel} + * Returns an unmodifiable view on the list of {@link MeshModel} * instances that have been created for the glTF. - * + * * @return The {@link MeshModel} instances */ List getMeshModels(); - + /** - * Returns an unmodifiable view on the list of {@link NodeModel} + * Returns an unmodifiable view on the list of {@link NodeModel} * instances that have been created for the glTF. - * + * * @return The {@link NodeModel} instances */ List getNodeModels(); /** - * Returns an unmodifiable view on the list of {@link SceneModel} + * Returns an unmodifiable view on the list of {@link SceneModel} * instances that have been created for the glTF. - * + * * @return The {@link SceneModel} instances */ List getSceneModels(); /** - * Returns an unmodifiable view on the list of {@link SkinModel} + * Returns an unmodifiable view on the list of {@link SkinModel} * instances that have been created for the glTF. - * + * * @return The {@link SkinModel} instances */ List getSkinModels(); /** - * Returns an unmodifiable view on the list of {@link TextureModel} + * Returns an unmodifiable view on the list of {@link TextureModel} * instances that have been created for the glTF. - * + * * @return The {@link TextureModel} instances */ List getTextureModels(); - + /** * Returns the {@link ExtensionsModel} that summarizes information * about the extensions that are used in the glTF. - * + * * @return The {@link ExtensionsModel} */ ExtensionsModel getExtensionsModel(); - + /** * Returns the {@link AssetModel} that contains information * about the asset that is represented with this model. - * + * * @return The {@link AssetModel} */ AssetModel getAssetModel(); - + } diff --git a/src/main/java/de/javagl/jgltf/model/GltfModels.java b/src/main/java/de/javagl/jgltf/model/GltfModels.java index 25fa4e4..31daaac 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfModels.java +++ b/src/main/java/de/javagl/jgltf/model/GltfModels.java @@ -35,37 +35,32 @@ /** * Methods to create {@link GltfModel} instances from a {@link GltfAsset} */ -public class GltfModels -{ +public class GltfModels { + /** + * Private constructor to prevent instantiation + */ + private GltfModels() { + // Private constructor to prevent instantiation + } + /** * Creates a {@link GltfModel} instance from the given {@link GltfAsset} - * + * * @param gltfAsset The {@link GltfAsset} * @return The {@link GltfModel} - * @throws IllegalArgumentException If the given asset has an - * unknown version + * @throws IllegalArgumentException If the given asset has an + * unknown version */ - public static GltfModel create(GltfAsset gltfAsset) - { - if (gltfAsset instanceof GltfAssetV1) - { - GltfAssetV1 gltfAssetV1 = (GltfAssetV1)gltfAsset; + public static GltfModel create(GltfAsset gltfAsset) { + if (gltfAsset instanceof GltfAssetV1) { + GltfAssetV1 gltfAssetV1 = (GltfAssetV1) gltfAsset; return new GltfModelV1(gltfAssetV1); } - if (gltfAsset instanceof GltfAssetV2) - { - GltfAssetV2 gltfAssetV2 = (GltfAssetV2)gltfAsset; + if (gltfAsset instanceof GltfAssetV2) { + GltfAssetV2 gltfAssetV2 = (GltfAssetV2) gltfAsset; return GltfModelCreatorV2.create(gltfAssetV2); } throw new IllegalArgumentException( - "The glTF asset has an unknown version: " + gltfAsset); - } - - /** - * Private constructor to prevent instantiation - */ - private GltfModels() - { - // Private constructor to prevent instantiation + "The glTF asset has an unknown version: " + gltfAsset); } } diff --git a/src/main/java/de/javagl/jgltf/model/GltfUtils.java b/src/main/java/de/javagl/jgltf/model/GltfUtils.java index f24df3d..265d9d5 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfUtils.java +++ b/src/main/java/de/javagl/jgltf/model/GltfUtils.java @@ -26,48 +26,43 @@ */ package de.javagl.jgltf.model; -import java.util.Objects; - import de.javagl.jgltf.impl.v1.Asset; import de.javagl.jgltf.impl.v1.GlTF; +import java.util.Objects; + /** * Utility methods related to {@link GlTF} instances */ -public class GltfUtils -{ +public class GltfUtils { + /** + * Private constructor to prevent instantiation + */ + private GltfUtils() { + // Private constructor to prevent instantiation + } + /** * Returns the version string that is reported by the {@link Asset} in * the given {@link GlTF}. If it does not have an {@link Asset}, or * the version string in the asset is null, then * this method will return the string "1.0.0". - * + * * @param gltf The {@link GlTF} * @return The version string */ - public static String getVersion(GlTF gltf) - { + public static String getVersion(GlTF gltf) { Objects.requireNonNull(gltf, "The gltf is null"); Asset asset = gltf.getAsset(); - if (asset == null) - { + if (asset == null) { return "1.0"; } String version = asset.getVersion(); - if (version == null) - { + if (version == null) { return "1.0"; } return version; } - - /** - * Private constructor to prevent instantiation - */ - private GltfUtils() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/ImageModel.java b/src/main/java/de/javagl/jgltf/model/ImageModel.java index 9b06746..b5bd8bc 100644 --- a/src/main/java/de/javagl/jgltf/model/ImageModel.java +++ b/src/main/java/de/javagl/jgltf/model/ImageModel.java @@ -31,38 +31,37 @@ /** * Interface for an image in a glTF asset */ -public interface ImageModel extends NamedModelElement -{ +public interface ImageModel extends NamedModelElement { /** * Returns the URI of the image data (optional) - * + * * @return The URI */ String getUri(); - + /** - * Returns the MIME type of the image data that is contained in + * Returns the MIME type of the image data that is contained in * the buffer view - * + * * @return The MIME type */ String getMimeType(); - + /** * Returns the (optional) {@link BufferViewModel} that contains * the image data - * + * * @return The {@link BufferViewModel} */ BufferViewModel getBufferViewModel(); - + /** * Returns the actual image data. This will return a slice of the * buffer that is stored internally. Thus, changes to the contents - * of this buffer will affect this model, but modifications of the - * position and limit of the returned buffer will not affect this + * of this buffer will affect this model, but modifications of the + * position and limit of the returned buffer will not affect this * model.
- * + * * @return The image data */ ByteBuffer getImageData(); diff --git a/src/main/java/de/javagl/jgltf/model/MaterialModel.java b/src/main/java/de/javagl/jgltf/model/MaterialModel.java index fd6c690..a5eb86d 100644 --- a/src/main/java/de/javagl/jgltf/model/MaterialModel.java +++ b/src/main/java/de/javagl/jgltf/model/MaterialModel.java @@ -29,7 +29,6 @@ /** * Interface for a material model */ -public interface MaterialModel extends NamedModelElement -{ +public interface MaterialModel extends NamedModelElement { // No common methods } diff --git a/src/main/java/de/javagl/jgltf/model/MathUtils.java b/src/main/java/de/javagl/jgltf/model/MathUtils.java index 1e61d15..03dbb9a 100644 --- a/src/main/java/de/javagl/jgltf/model/MathUtils.java +++ b/src/main/java/de/javagl/jgltf/model/MathUtils.java @@ -32,53 +32,57 @@ import java.util.logging.Logger; /** - * Mathematical utility methods. These methods are mainly related to - * computations on arrays that represent matrices.
+ * Mathematical utility methods. These methods are mainly related to + * computations on arrays that represent matrices.
*
- * Unless otherwise noted, the matrices are assumed to be in + * Unless otherwise noted, the matrices are assumed to be in * column-major order.
*
* Unless otherwise noted, none of the arguments to these * methods may be null.
*
- * Unless otherwise noted, each 4x4 matrix is assumed to have a length of - * at least 16, and each 3x3 matrix is assumed to have a length of + * Unless otherwise noted, each 4x4 matrix is assumed to have a length of + * at least 16, and each 3x3 matrix is assumed to have a length of * at least 9. Points in 3D are assumed to have a length of at least 3. - * + *

* TODO This class should not be considered as part of the public API! */ -public class MathUtils -{ +public class MathUtils { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(MathUtils.class.getName()); - + private static final Logger logger = + Logger.getLogger(MathUtils.class.getName()); + /** * Epsilon for floating point computations */ private static final float FLOAT_EPSILON = 1e-8f; - + + /** + * Private constructor to prevent instantiation + */ + private MathUtils() { + // Private constructor to prevent instantiation + } + /** * Creates a 4x4 identity matrix - * + * * @return The matrix */ - public static float[] createIdentity4x4() - { + public static float[] createIdentity4x4() { float m[] = new float[16]; setIdentity4x4(m); return m; } - + /** * Set the given matrix to be the identity matrix. - * + * * @param m The matrix */ - public static void setIdentity4x4(float m[]) - { + public static void setIdentity4x4(float m[]) { Arrays.fill(m, 0.0f); m[0] = 1.0f; m[5] = 1.0f; @@ -87,64 +91,60 @@ public static void setIdentity4x4(float m[]) } /** - * Set the given matrix to be the identity matrix. - * + * Set the given matrix to be the identity matrix. + * * @param m The matrix */ - static void setIdentity3x3(float m[]) - { + static void setIdentity3x3(float m[]) { Arrays.fill(m, 0.0f); m[0] = 1.0f; m[4] = 1.0f; m[8] = 1.0f; } - + /** - * Copy the contents of the source array to the given target array. - * The length of the shorter array will determine how many elements + * Copy the contents of the source array to the given target array. + * The length of the shorter array will determine how many elements * are copied. - * + * * @param source The source array * @param target The target array */ - static void set(float source[], float target[]) - { - System.arraycopy(source, 0, target, 0, - Math.min(source.length, target.length)); + static void set(float source[], float target[]) { + System.arraycopy(source, 0, target, 0, + Math.min(source.length, target.length)); } - + /** - * Obtains the upper 3x3 matrix (which describes the rotation- and - * scaling part of the transformation) of the given 4x4 source matrix, - * and writes it into the given target 3x3 matrix. - * + * Obtains the upper 3x3 matrix (which describes the rotation- and + * scaling part of the transformation) of the given 4x4 source matrix, + * and writes it into the given target 3x3 matrix. + * * @param sourceMatrix4x4 The source matrix * @param targetMatrix3x3 The target matrix */ public static void getRotationScale( - float sourceMatrix4x4[], float targetMatrix3x3[]) - { - targetMatrix3x3[0] = sourceMatrix4x4[ 0]; - targetMatrix3x3[1] = sourceMatrix4x4[ 1]; - targetMatrix3x3[2] = sourceMatrix4x4[ 2]; - targetMatrix3x3[3] = sourceMatrix4x4[ 4]; - targetMatrix3x3[4] = sourceMatrix4x4[ 5]; - targetMatrix3x3[5] = sourceMatrix4x4[ 6]; - targetMatrix3x3[6] = sourceMatrix4x4[ 8]; - targetMatrix3x3[7] = sourceMatrix4x4[ 9]; + float sourceMatrix4x4[], float targetMatrix3x3[]) { + targetMatrix3x3[0] = sourceMatrix4x4[0]; + targetMatrix3x3[1] = sourceMatrix4x4[1]; + targetMatrix3x3[2] = sourceMatrix4x4[2]; + targetMatrix3x3[3] = sourceMatrix4x4[4]; + targetMatrix3x3[4] = sourceMatrix4x4[5]; + targetMatrix3x3[5] = sourceMatrix4x4[6]; + targetMatrix3x3[6] = sourceMatrix4x4[8]; + targetMatrix3x3[7] = sourceMatrix4x4[9]; targetMatrix3x3[8] = sourceMatrix4x4[10]; - + } - + /** * Transpose the given matrix, and write the result into the given - * target matrix. - * + * target matrix. + * * @param m The input matrix * @param t The target matrix */ - static void transpose3x3(float m[], float t[]) - { + static void transpose3x3(float m[], float t[]) { float m0 = m[0]; float m1 = m[1]; float m2 = m[2]; @@ -164,42 +164,41 @@ static void transpose3x3(float m[], float t[]) t[7] = m5; t[8] = m8; } - + /** * Transpose the given matrix, and write the result into the given - * target matrix. - * + * target matrix. + * * @param m The input matrix * @param t The target matrix */ - public static void transpose4x4(float m[], float t[]) - { - float m0 = m[ 0]; - float m1 = m[ 1]; - float m2 = m[ 2]; - float m3 = m[ 3]; - float m4 = m[ 4]; - float m5 = m[ 5]; - float m6 = m[ 6]; - float m7 = m[ 7]; - float m8 = m[ 8]; - float m9 = m[ 9]; + public static void transpose4x4(float m[], float t[]) { + float m0 = m[0]; + float m1 = m[1]; + float m2 = m[2]; + float m3 = m[3]; + float m4 = m[4]; + float m5 = m[5]; + float m6 = m[6]; + float m7 = m[7]; + float m8 = m[8]; + float m9 = m[9]; float mA = m[10]; float mB = m[11]; float mC = m[12]; float mD = m[13]; float mE = m[14]; float mF = m[15]; - t[ 0] = m0; - t[ 1] = m4; - t[ 2] = m8; - t[ 3] = mC; - t[ 4] = m1; - t[ 5] = m5; - t[ 6] = m9; - t[ 7] = mD; - t[ 8] = m2; - t[ 9] = m6; + t[0] = m0; + t[1] = m4; + t[2] = m8; + t[3] = mC; + t[4] = m1; + t[5] = m5; + t[6] = m9; + t[7] = mD; + t[8] = m2; + t[9] = m6; t[10] = mA; t[11] = mE; t[12] = m3; @@ -207,26 +206,25 @@ public static void transpose4x4(float m[], float t[]) t[14] = mB; t[15] = mF; } - + /** * Fills the given result matrix with the product of the given matrices. - * + * * @param a The first matrix * @param b The second matrix * @param m The result matrix */ - public static void mul4x4(float a[], float b[], float m[]) - { - float a00 = a[ 0]; - float a10 = a[ 1]; - float a20 = a[ 2]; - float a30 = a[ 3]; - float a01 = a[ 4]; - float a11 = a[ 5]; - float a21 = a[ 6]; - float a31 = a[ 7]; - float a02 = a[ 8]; - float a12 = a[ 9]; + public static void mul4x4(float a[], float b[], float m[]) { + float a00 = a[0]; + float a10 = a[1]; + float a20 = a[2]; + float a30 = a[3]; + float a01 = a[4]; + float a11 = a[5]; + float a21 = a[6]; + float a31 = a[7]; + float a02 = a[8]; + float a12 = a[9]; float a22 = a[10]; float a32 = a[11]; float a03 = a[12]; @@ -234,16 +232,16 @@ public static void mul4x4(float a[], float b[], float m[]) float a23 = a[14]; float a33 = a[15]; - float b00 = b[ 0]; - float b10 = b[ 1]; - float b20 = b[ 2]; - float b30 = b[ 3]; - float b01 = b[ 4]; - float b11 = b[ 5]; - float b21 = b[ 6]; - float b31 = b[ 7]; - float b02 = b[ 8]; - float b12 = b[ 9]; + float b00 = b[0]; + float b10 = b[1]; + float b20 = b[2]; + float b30 = b[3]; + float b01 = b[4]; + float b11 = b[5]; + float b21 = b[6]; + float b31 = b[7]; + float b02 = b[8]; + float b12 = b[9]; float b22 = b[10]; float b32 = b[11]; float b03 = b[12]; @@ -271,16 +269,16 @@ public static void mul4x4(float a[], float b[], float m[]) float m32 = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32; float m33 = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33; - m[ 0] = m00; - m[ 1] = m10; - m[ 2] = m20; - m[ 3] = m30; - m[ 4] = m01; - m[ 5] = m11; - m[ 6] = m21; - m[ 7] = m31; - m[ 8] = m02; - m[ 9] = m12; + m[0] = m00; + m[1] = m10; + m[2] = m20; + m[3] = m30; + m[4] = m01; + m[5] = m11; + m[6] = m21; + m[7] = m31; + m[8] = m02; + m[9] = m12; m[10] = m22; m[11] = m32; m[12] = m03; @@ -288,35 +286,33 @@ public static void mul4x4(float a[], float b[], float m[]) m[14] = m23; m[15] = m33; } - /** - * Fills the given matrix, with the values for the rotation that is - * described by the given quaternion. None of the arguments may be - * null. The quaternion must have at least length 4. - * + * Fills the given matrix, with the values for the rotation that is + * described by the given quaternion. None of the arguments may be + * null. The quaternion must have at least length 4. + * * @param q The quaternion * @param m The matrix */ - public static void quaternionToMatrix4x4(float q[], float m[]) - { - float invLength = 1.0f / (float)Math.sqrt(dot(q, q)); + public static void quaternionToMatrix4x4(float q[], float m[]) { + float invLength = 1.0f / (float) Math.sqrt(dot(q, q)); // Adapted from javax.vecmath.Matrix4f float qx = q[0] * invLength; float qy = q[1] * invLength; float qz = q[2] * invLength; float qw = q[3] * invLength; - m[ 0] = 1.0f - 2.0f * qy * qy - 2.0f * qz * qz; - m[ 1] = 2.0f * (qx * qy + qw * qz); - m[ 2] = 2.0f * (qx * qz - qw * qy); - m[ 3] = 0.0f; - m[ 4] = 2.0f * (qx * qy - qw * qz); - m[ 5] = 1.0f - 2.0f * qx * qx - 2.0f * qz * qz; - m[ 6] = 2.0f * (qy * qz + qw * qx); - m[ 7] = 0.0f; - m[ 8] = 2.0f * (qx * qz + qw * qy); - m[ 9] = 2.0f * (qy * qz - qw * qx); + m[0] = 1.0f - 2.0f * qy * qy - 2.0f * qz * qz; + m[1] = 2.0f * (qx * qy + qw * qz); + m[2] = 2.0f * (qx * qz - qw * qy); + m[3] = 0.0f; + m[4] = 2.0f * (qx * qy - qw * qz); + m[5] = 1.0f - 2.0f * qx * qx - 2.0f * qz * qz; + m[6] = 2.0f * (qy * qz + qw * qx); + m[7] = 0.0f; + m[8] = 2.0f * (qx * qz + qw * qy); + m[9] = 2.0f * (qy * qz - qw * qx); m[10] = 1.0f - 2.0f * qx * qx - 2.0f * qy * qy; m[11] = 0.0f; m[12] = 0.0f; @@ -324,30 +320,29 @@ public static void quaternionToMatrix4x4(float q[], float m[]) m[14] = 0.0f; m[15] = 1.0f; } - + /** * Inverts the given matrix and writes the result into the given target - * matrix. If the given matrix is not invertible, then the target matrix - * will be set to identity. - * - * @param m The input matrix + * matrix. If the given matrix is not invertible, then the target matrix + * will be set to identity. + * + * @param m The input matrix * @param inv The inverse matrix */ - public static void invert4x4(float m[], float inv[]) - { - // Adapted from The Mesa 3-D graphics library. + public static void invert4x4(float m[], float inv[]) { + // Adapted from The Mesa 3-D graphics library. // Copyright (C) 1999-2007 Brian Paul All Rights Reserved. // Published under the MIT license (see the header of this file) - float m0 = m[ 0]; - float m1 = m[ 1]; - float m2 = m[ 2]; - float m3 = m[ 3]; - float m4 = m[ 4]; - float m5 = m[ 5]; - float m6 = m[ 6]; - float m7 = m[ 7]; - float m8 = m[ 8]; - float m9 = m[ 9]; + float m0 = m[0]; + float m1 = m[1]; + float m2 = m[2]; + float m3 = m[3]; + float m4 = m[4]; + float m5 = m[5]; + float m6 = m[6]; + float m7 = m[7]; + float m8 = m[8]; + float m9 = m[9]; float mA = m[10]; float mB = m[11]; float mC = m[12]; @@ -355,68 +350,64 @@ public static void invert4x4(float m[], float inv[]) float mE = m[14]; float mF = m[15]; - inv[ 0] = m5 * mA * mF - m5 * mB * mE - m9 * m6 * mF + - m9 * m7 * mE + mD * m6 * mB - mD * m7 * mA; - inv[ 4] = -m4 * mA * mF + m4 * mB * mE + m8 * m6 * mF - - m8 * m7 * mE - mC * m6 * mB + mC * m7 * mA; - inv[ 8] = m4 * m9 * mF - m4 * mB * mD - m8 * m5 * mF + - m8 * m7 * mD + mC * m5 * mB - mC * m7 * m9; - inv[12] = -m4 * m9 * mE + m4 * mA * mD + m8 * m5 * mE - - m8 * m6 * mD - mC * m5 * mA + mC * m6 * m9; - inv[ 1] = -m1 * mA * mF + m1 * mB * mE + m9 * m2 * mF - - m9 * m3 * mE - mD * m2 * mB + mD * m3 * mA; - inv[ 5] = m0 * mA * mF - m0 * mB * mE - m8 * m2 * mF + - m8 * m3 * mE + mC * m2 * mB - mC * m3 * mA; - inv[ 9] = -m0 * m9 * mF + m0 * mB * mD + m8 * m1 * mF - - m8 * m3 * mD - mC * m1 * mB + mC * m3 * m9; - inv[13] = m0 * m9 * mE - m0 * mA * mD - m8 * m1 * mE + - m8 * m2 * mD + mC * m1 * mA - mC * m2 * m9; - inv[ 2] = m1 * m6 * mF - m1 * m7 * mE - m5 * m2 * mF + - m5 * m3 * mE + mD * m2 * m7 - mD * m3 * m6; - inv[ 6] = -m0 * m6 * mF + m0 * m7 * mE + m4 * m2 * mF - - m4 * m3 * mE - mC * m2 * m7 + mC * m3 * m6; - inv[10] = m0 * m5 * mF - m0 * m7 * mD - m4 * m1 * mF + - m4 * m3 * mD + mC * m1 * m7 - mC * m3 * m5; - inv[14] = -m0 * m5 * mE + m0 * m6 * mD + m4 * m1 * mE - - m4 * m2 * mD - mC * m1 * m6 + mC * m2 * m5; - inv[ 3] = -m1 * m6 * mB + m1 * m7 * mA + m5 * m2 * mB - - m5 * m3 * mA - m9 * m2 * m7 + m9 * m3 * m6; - inv[ 7] = m0 * m6 * mB - m0 * m7 * mA - m4 * m2 * mB + - m4 * m3 * mA + m8 * m2 * m7 - m8 * m3 * m6; - inv[11] = -m0 * m5 * mB + m0 * m7 * m9 + m4 * m1 * mB - - m4 * m3 * m9 - m8 * m1 * m7 + m8 * m3 * m5; - inv[15] = m0 * m5 * mA - m0 * m6 * m9 - m4 * m1 * mA + - m4 * m2 * m9 + m8 * m1 * m6 - m8 * m2 * m5; + inv[0] = m5 * mA * mF - m5 * mB * mE - m9 * m6 * mF + + m9 * m7 * mE + mD * m6 * mB - mD * m7 * mA; + inv[4] = -m4 * mA * mF + m4 * mB * mE + m8 * m6 * mF - + m8 * m7 * mE - mC * m6 * mB + mC * m7 * mA; + inv[8] = m4 * m9 * mF - m4 * mB * mD - m8 * m5 * mF + + m8 * m7 * mD + mC * m5 * mB - mC * m7 * m9; + inv[12] = -m4 * m9 * mE + m4 * mA * mD + m8 * m5 * mE - + m8 * m6 * mD - mC * m5 * mA + mC * m6 * m9; + inv[1] = -m1 * mA * mF + m1 * mB * mE + m9 * m2 * mF - + m9 * m3 * mE - mD * m2 * mB + mD * m3 * mA; + inv[5] = m0 * mA * mF - m0 * mB * mE - m8 * m2 * mF + + m8 * m3 * mE + mC * m2 * mB - mC * m3 * mA; + inv[9] = -m0 * m9 * mF + m0 * mB * mD + m8 * m1 * mF - + m8 * m3 * mD - mC * m1 * mB + mC * m3 * m9; + inv[13] = m0 * m9 * mE - m0 * mA * mD - m8 * m1 * mE + + m8 * m2 * mD + mC * m1 * mA - mC * m2 * m9; + inv[2] = m1 * m6 * mF - m1 * m7 * mE - m5 * m2 * mF + + m5 * m3 * mE + mD * m2 * m7 - mD * m3 * m6; + inv[6] = -m0 * m6 * mF + m0 * m7 * mE + m4 * m2 * mF - + m4 * m3 * mE - mC * m2 * m7 + mC * m3 * m6; + inv[10] = m0 * m5 * mF - m0 * m7 * mD - m4 * m1 * mF + + m4 * m3 * mD + mC * m1 * m7 - mC * m3 * m5; + inv[14] = -m0 * m5 * mE + m0 * m6 * mD + m4 * m1 * mE - + m4 * m2 * mD - mC * m1 * m6 + mC * m2 * m5; + inv[3] = -m1 * m6 * mB + m1 * m7 * mA + m5 * m2 * mB - + m5 * m3 * mA - m9 * m2 * m7 + m9 * m3 * m6; + inv[7] = m0 * m6 * mB - m0 * m7 * mA - m4 * m2 * mB + + m4 * m3 * mA + m8 * m2 * m7 - m8 * m3 * m6; + inv[11] = -m0 * m5 * mB + m0 * m7 * m9 + m4 * m1 * mB - + m4 * m3 * m9 - m8 * m1 * m7 + m8 * m3 * m5; + inv[15] = m0 * m5 * mA - m0 * m6 * m9 - m4 * m1 * mA + + m4 * m2 * m9 + m8 * m1 * m6 - m8 * m2 * m5; // (Ain't that pretty?) - + float det = m0 * inv[0] + m1 * inv[4] + m2 * inv[8] + m3 * inv[12]; - if (Math.abs(det) <= FLOAT_EPSILON) - { - if (logger.isLoggable(Level.FINE)) - { + if (Math.abs(det) <= FLOAT_EPSILON) { + if (logger.isLoggable(Level.FINE)) { logger.fine("Matrix is not invertible, determinant is " + det - + ", returning identity"); + + ", returning identity"); } setIdentity4x4(inv); return; } float invDet = 1.0f / det; - for (int i = 0; i < 16; i++) - { + for (int i = 0; i < 16; i++) { inv[i] *= invDet; } - } - + } + /** * Inverts the given matrix and writes the result into the given target - * matrix. If the given matrix is not invertible, then the target matrix - * will be set to identity. - * - * @param m The input matrix + * matrix. If the given matrix is not invertible, then the target matrix + * will be set to identity. + * + * @param m The input matrix * @param inv The inverse matrix */ - public static void invert3x3(float m[], float inv[]) - { + public static void invert3x3(float m[], float inv[]) { // Adapted from http://stackoverflow.com/a/18504573 float m0 = m[0]; float m1 = m[1]; @@ -428,14 +419,12 @@ public static void invert3x3(float m[], float inv[]) float m7 = m[7]; float m8 = m[8]; float det = m0 * (m4 * m8 - m5 * m7) - - m3 * (m1 * m8 - m7 * m2) + - m6 * (m1 * m5 - m4 * m2); - if (Math.abs(det) <= FLOAT_EPSILON) - { - if (logger.isLoggable(Level.FINE)) - { + m3 * (m1 * m8 - m7 * m2) + + m6 * (m1 * m5 - m4 * m2); + if (Math.abs(det) <= FLOAT_EPSILON) { + if (logger.isLoggable(Level.FINE)) { logger.fine("Matrix is not invertible, determinant is " + det - + ", returning identity"); + + ", returning identity"); } setIdentity3x3(inv); return; @@ -449,43 +438,41 @@ public static void invert3x3(float m[], float inv[]) inv[7] = (m1 * m6 - m0 * m7) * invDet; inv[2] = (m1 * m5 - m2 * m4) * invDet; inv[5] = (m2 * m3 - m0 * m5) * invDet; - inv[8] = (m0 * m4 - m1 * m3) * invDet; + inv[8] = (m0 * m4 - m1 * m3) * invDet; } - + /** * Writes the given matrix into the given result matrix, with the * given values added to the translation component - * - * @param m The input matrix - * @param x The x-translation - * @param y The y-translation - * @param z The z-translation + * + * @param m The input matrix + * @param x The x-translation + * @param y The y-translation + * @param z The z-translation * @param result The result matrix */ public static void translate( - float m[], float x, float y, float z, float result[]) - { - set(m, result); + float m[], float x, float y, float z, float result[]) { + set(m, result); result[12] += x; result[13] += y; result[14] += z; } - + /** - * Fill the given matrix to describe an infinite perspective projection - * with the given parameters. - * + * Fill the given matrix to describe an infinite perspective projection + * with the given parameters. + * * @param fovyDeg The Field-Of-View, in y-direction, in degrees - * @param aspect The aspect ratio - * @param zNear The z-value of the near clipping plane - * @param m The matrix to fill + * @param aspect The aspect ratio + * @param zNear The z-value of the near clipping plane + * @param m The matrix to fill */ public static void infinitePerspective4x4( - float fovyDeg, float aspect, float zNear, float m[]) - { + float fovyDeg, float aspect, float zNear, float m[]) { setIdentity4x4(m); - float fovyRad = (float)Math.toRadians(fovyDeg); - float t = (float)Math.tan(0.5 * fovyRad); + float fovyRad = (float) Math.toRadians(fovyDeg); + float t = (float) Math.tan(0.5 * fovyRad); m[0] = 1.0f / (aspect * t); m[5] = 1.0f / t; m[10] = -1.0f; @@ -493,23 +480,22 @@ public static void infinitePerspective4x4( m[14] = 2.0f * zNear; m[15] = 0.0f; } - + /** * Fill the given matrix to describe a perspective projection with the - * given parameters. - * + * given parameters. + * * @param fovyDeg The Field-Of-View, in y-direction, in degrees - * @param aspect The aspect ratio - * @param zNear The z-value of the near clipping plane - * @param zFar The z-value of the far clipping plane - * @param m The matrix to fill + * @param aspect The aspect ratio + * @param zNear The z-value of the near clipping plane + * @param zFar The z-value of the far clipping plane + * @param m The matrix to fill */ public static void perspective4x4( - float fovyDeg, float aspect, float zNear, float zFar, float m[]) - { + float fovyDeg, float aspect, float zNear, float zFar, float m[]) { setIdentity4x4(m); - float fovyRad = (float)Math.toRadians(fovyDeg); - float t = (float)Math.tan(0.5 * fovyRad); + float fovyRad = (float) Math.toRadians(fovyDeg); + float t = (float) Math.tan(0.5 * fovyRad); m[0] = 1.0f / (aspect * t); m[5] = 1.0f / t; m[10] = (zFar + zNear) / (zNear - zFar); @@ -517,44 +503,37 @@ public static void perspective4x4( m[14] = 2.0f * zFar * zNear / (zNear - zFar); m[15] = 0.0f; } - - + /** - * Computes the dot product of the given arrays. The arrays must have + * Computes the dot product of the given arrays. The arrays must have * equal length. - * + * * @param a The first array * @param b The second array * @return The dot product */ - private static float dot(float a[], float b[]) - { + private static float dot(float a[], float b[]) { float sum = 0; - for (int i=0; inull. If it is not null, * then it must either have 3x3 elements or 4x4 elements. - * + * * @param array The array * @return The string representation */ - public static String createMatrixString(float array[]) - { - if (array == null) - { + public static String createMatrixString(float array[]) { + if (array == null) { return "null"; } - if (array.length == 9) - { + if (array.length == 9) { return createMatrixString(array, 3, 3); } - if (array.length == 16) - { + if (array.length == 16) { return createMatrixString(array, 4, 4); } - return "WARNING: Not a matrix: "+Arrays.toString(array); + return "WARNING: Not a matrix: " + Arrays.toString(array); } - + /** * Creates a string representation of the given matrix, which is given * in column-major order - * + * * @param array The array storing the matrix - * @param rows The number of rows - * @param cols The number of columns + * @param rows The number of rows + * @param cols The number of columns * @return The string representation */ - private static String createMatrixString(float array[], int rows, int cols) - { + private static String createMatrixString(float array[], int rows, int cols) { StringBuilder sb = new StringBuilder(); - for (int r=0; rnull. If it is not null, * then it must either have 3x3 elements or 4x4 elements.
*
- * The individual elements of the matrix will be formatted (in an + * The individual elements of the matrix will be formatted (in an * unspecified way) so that the matrix entries are aligned. - * + * * @param array The array * @return The string representation */ - public static String createFormattedMatrixString(float array[]) - { - if (array == null) - { + public static String createFormattedMatrixString(float array[]) { + if (array == null) { return "null"; } String format = "%10.5f "; - if (array.length == 9) - { + if (array.length == 9) { return createFormattedMatrixString(array, 3, 3, format); } - if (array.length == 16) - { + if (array.length == 16) { return createFormattedMatrixString(array, 4, 4, format); } - return "WARNING: Not a matrix: "+Arrays.toString(array); + return "WARNING: Not a matrix: " + Arrays.toString(array); } - + /** * Creates a string representation of the given matrix, which is given * in column-major order. The elements of the matrix will be formatted * with the given string. - * - * @param array The array storing the matrix - * @param rows The number of rows - * @param cols The number of columns + * + * @param array The array storing the matrix + * @param rows The number of rows + * @param cols The number of columns * @param format The format string * @return The string representation */ private static String createFormattedMatrixString( - float array[], int rows, int cols, String format) - { + float array[], int rows, int cols, String format) { StringBuilder sb = new StringBuilder(); - for (int r = 0; r < rows; r++) - { - for (int c = 0; c < cols; c++) - { + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { sb.append(String.format( - Locale.ENGLISH, format, array[r + c * cols])); + Locale.ENGLISH, format, array[r + c * cols])); } sb.append("\n"); } return sb.toString(); } - /** - * Private constructor to prevent instantiation + * Computes a0-a1, and stores the result in the given array. + *

+ * This assumes that the given arrays are non-null + * and have equal lengths. + * + * @param a0 The first array + * @param a1 The second array + * @param result The array that stores the result */ - private MathUtils() - { - // Private constructor to prevent instantiation + public static void subtract(float[] a0, float[] a1, float[] result) { + for (int i = 0; i < a0.length; i++) { + result[i] = a0[i] - a1[i]; + } + } + + /** + * Computes the cross product of a0 and a1, and stores the result in + * the given array. + *

+ * This assumes that the given arrays are non-null + * and have length 3. + * + * @param a0 The first array + * @param a1 The second array + * @param result The array that stores the result + */ + public static void cross(float a0[], float a1[], float result[]) { + result[0] = a0[1] * a1[2] - a0[2] * a1[1]; + result[1] = a0[2] * a1[0] - a0[0] * a1[2]; + result[2] = a0[0] * a1[1] - a0[1] * a1[0]; + } + + /** + * Compute the length of the given vector + * + * @param a The vector + * @return The length + */ + public static float computeLength(float a[]) { + float sum = 0; + for (int i = 0; i < a.length; i++) { + sum += a[i] * a[i]; + } + float r = (float) Math.sqrt(sum); + return r; + } + + /** + * Normalizes the given array, and stores the result in the given array. + *

+ * This assumes that the given arrays are non-null + * and have the same length. + * + * @param a The array + * @param result The array that stores the result + */ + public static void normalize(float a[], float result[]) { + float scaling = 1.0f / computeLength(a); + scale(a, scaling, result); + } + + /** + * Scales the given vector with the given factor, and stores the result + * in the given array. + *

+ * This assumes that the given arrays are non-null + * and have equal lengths. + * + * @param a The vector + * @param factor The scaling factor + * @param result The array that will store the result + */ + public static void scale(float a[], float factor, float result[]) { + for (int i = 0; i < a.length; i++) { + result[i] = a[i] * factor; + } } - - - /** - * Computes a0-a1, and stores the result in the given array. - * - * This assumes that the given arrays are non-null - * and have equal lengths. - * - * @param a0 The first array - * @param a1 The second array - * @param result The array that stores the result - */ - public static void subtract(float[] a0, float[] a1, float[] result) - { - for (int i = 0; i < a0.length; i++) - { - result[i] = a0[i] - a1[i]; - } - } - - /** - * Computes the cross product of a0 and a1, and stores the result in - * the given array. - * - * This assumes that the given arrays are non-null - * and have length 3. - * - * @param a0 The first array - * @param a1 The second array - * @param result The array that stores the result - */ - public static void cross(float a0[], float a1[], float result[]) - { - result[0] = a0[1] * a1[2] - a0[2] * a1[1]; - result[1] = a0[2] * a1[0] - a0[0] * a1[2]; - result[2] = a0[0] * a1[1] - a0[1] * a1[0]; - } - - /** - * Compute the length of the given vector - * - * @param a The vector - * @return The length - */ - public static float computeLength(float a[]) - { - float sum = 0; - for (int i=0; inull - * and have the same length. - * - * @param a The array - * @param result The array that stores the result - */ - public static void normalize(float a[], float result[]) - { - float scaling = 1.0f / computeLength(a); - scale(a, scaling, result); - } - - /** - * Scales the given vector with the given factor, and stores the result - * in the given array. - * - * This assumes that the given arrays are non-null - * and have equal lengths. - * - * @param a The vector - * @param factor The scaling factor - * @param result The array that will store the result - */ - public static void scale(float a[], float factor, float result[]) - { - for (int i = 0; i < a.length; i++) - { - result[i] = a[i] * factor; - } - } } diff --git a/src/main/java/de/javagl/jgltf/model/MeshModel.java b/src/main/java/de/javagl/jgltf/model/MeshModel.java index 4f5c3b2..d1b6c87 100644 --- a/src/main/java/de/javagl/jgltf/model/MeshModel.java +++ b/src/main/java/de/javagl/jgltf/model/MeshModel.java @@ -31,21 +31,20 @@ /** * Interface for a mesh that is part of a glTF asset */ -public interface MeshModel extends NamedModelElement -{ +public interface MeshModel extends NamedModelElement { /** * Returns an unmodifiable view on the {@link MeshPrimitiveModel} objects * that this mesh consists of - * + * * @return The {@link MeshPrimitiveModel} objects */ List getMeshPrimitiveModels(); - + /** - * Returns a reference to the default morph target weights, - * or null if no default morph target weights have + * Returns a reference to the default morph target weights, + * or null if no default morph target weights have * been defined - * + * * @return The morph target weights */ float[] getWeights(); diff --git a/src/main/java/de/javagl/jgltf/model/MeshPrimitiveModel.java b/src/main/java/de/javagl/jgltf/model/MeshPrimitiveModel.java index 74bcebd..476d855 100644 --- a/src/main/java/de/javagl/jgltf/model/MeshPrimitiveModel.java +++ b/src/main/java/de/javagl/jgltf/model/MeshPrimitiveModel.java @@ -32,45 +32,44 @@ /** * Interface for a primitive that is part of a mesh */ -public interface MeshPrimitiveModel extends ModelElement -{ +public interface MeshPrimitiveModel extends ModelElement { /** * Returns an unmodifiable view on the mapping from attribute names to * the {@link AccessorModel} instances for the attribute data - * + * * @return The attributes mapping */ Map getAttributes(); - + /** * Return an {@link AccessorModel} for the indices, or null * if this primitive describes non-indexed geometry - * - * @return The indices + * + * @return The indices */ AccessorModel getIndices(); - + /** * Returns the rendering mode, as a (GL) constant, standing for * GL_POINTS, GL_TRIANGLES etc. - * + * * @return The rendering mode */ int getMode(); - + /** * Returns the {@link MaterialModel} that should be used for rendering * this mesh primitive - * + * * @return The {@link MaterialModel} */ MaterialModel getMaterialModel(); - + /** * Returns an unmodifiable view on the list of morph targets. Each element * of this list will be an unmodifiable map. Each map maps the attribute * name to the {@link AccessorModel} that provides the morph target data. - * + * * @return The morph targets */ List> getTargets(); diff --git a/src/main/java/de/javagl/jgltf/model/ModelElement.java b/src/main/java/de/javagl/jgltf/model/ModelElement.java index 43c1a45..8924d1f 100644 --- a/src/main/java/de/javagl/jgltf/model/ModelElement.java +++ b/src/main/java/de/javagl/jgltf/model/ModelElement.java @@ -32,19 +32,18 @@ * Interface for all classes of the model package. This is corresponds to * the GlTFProperty of the original glTF asset. */ -public interface ModelElement -{ +public interface ModelElement { /** * Returns the extensions of this element. This is a mapping from * property names to the JSON objects. - * + * * @return The extensions */ Map getExtensions(); - + /** - * Returns the extras of this element. - * + * Returns the extras of this element. + * * @return The extras */ Object getExtras(); diff --git a/src/main/java/de/javagl/jgltf/model/NamedModelElement.java b/src/main/java/de/javagl/jgltf/model/NamedModelElement.java index 1870a6c..765e9b5 100644 --- a/src/main/java/de/javagl/jgltf/model/NamedModelElement.java +++ b/src/main/java/de/javagl/jgltf/model/NamedModelElement.java @@ -31,12 +31,11 @@ * This is the name that was given to the GlTFChildOfRootProperty * of the original glTF asset. */ -public interface NamedModelElement extends ModelElement -{ +public interface NamedModelElement extends ModelElement { /** * Returns the name of this element, or null if this element * does not have an associated name. - * + * * @return The optional name */ String getName(); diff --git a/src/main/java/de/javagl/jgltf/model/NodeModel.java b/src/main/java/de/javagl/jgltf/model/NodeModel.java index a8fc11b..e4f2034 100644 --- a/src/main/java/de/javagl/jgltf/model/NodeModel.java +++ b/src/main/java/de/javagl/jgltf/model/NodeModel.java @@ -32,27 +32,26 @@ /** * Interface for a node that is part of a scene hierarchy */ -public interface NodeModel extends NamedModelElement -{ +public interface NodeModel extends NamedModelElement { /** * Returns the parent of this node, or null if this is * a root node - * + * * @return The parent */ NodeModel getParent(); /** * Returns an unmodifiable view on the list of children of this node - * + * * @return The children */ List getChildren(); - + /** * Returns an unmodifiable view on the list of {@link MeshModel} instances * that are attached to this node. - * + * * @return The {@link MeshModel} list */ List getMeshModels(); @@ -60,124 +59,124 @@ public interface NodeModel extends NamedModelElement /** * Returns the {@link SkinModel} for this node, or null if * this node is not associated with a skin - * + * * @return The {@link SkinModel} */ SkinModel getSkinModel(); - + /** * Returns the {@link CameraModel} for this node, or null if * this node is not associated with a camera - * + * * @return The {@link CameraModel} */ CameraModel getCameraModel(); - + + /** + * Returns a reference to the array storing the matrix of this node. + * This is a 16-element array containing the matrix in column-major order, + * or null if no matrix was set. + * + * @return The matrix + */ + float[] getMatrix(); + /** * Set the matrix of this node to be a reference to the given * array.
*
- * The matrix is assumed to be a 16-element array containing the matrix - * in column-major order. If the given matrix is null, then + * The matrix is assumed to be a 16-element array containing the matrix + * in column-major order. If the given matrix is null, then * the {@link #getTranslation() translation}, * {@link #getRotation() rotation}, and - * {@link #getScale() scale} properties will be used for determining the + * {@link #getScale() scale} properties will be used for determining the * local transform. - * + * * @param matrix The matrix * @throws IllegalArgumentException If the given array does not have - * a length of 16 + * a length of 16 */ void setMatrix(float matrix[]); - + /** - * Returns a reference to the array storing the matrix of this node. - * This is a 16-element array containing the matrix in column-major order, - * or null if no matrix was set. - * - * @return The matrix + * Returns a reference to the array storing the translation of this + * node, or null if no translation was set. + * + * @return The translation */ - float[] getMatrix(); + float[] getTranslation(); /** * Set the translation of this node to be a reference to the given - * array. - * + * array. + * * @param translation The translation * @throws IllegalArgumentException If the given array does not have - * a length of 3 + * a length of 3 */ void setTranslation(float translation[]); - + /** - * Returns a reference to the array storing the translation of this - * node, or null if no translation was set. - * - * @return The translation + * Returns a reference to the array storing the rotation of this + * node, or null if no rotation was set + * + * @return The rotation */ - float[] getTranslation(); + float[] getRotation(); /** * Set the rotation of this node to be a reference to the given * array. The array is assumed to be a quaternion, consisting of 4 * float elements. - * + * * @param rotation The rotation * @throws IllegalArgumentException If the given array does not have - * a length of 4 + * a length of 4 */ void setRotation(float rotation[]); - + /** - * Returns a reference to the array storing the rotation of this - * node, or null if no rotation was set - * - * @return The rotation + * Returns a reference to the array storing the scale of this + * node, or null if no scale was set + * + * @return The scale */ - float[] getRotation(); + float[] getScale(); /** * Set the scale of this node to be a reference to the given * array. - * + * * @param scale The scale * @throws IllegalArgumentException If the given array does not have - * a length of 3 + * a length of 3 */ void setScale(float scale[]); /** - * Returns a reference to the array storing the scale of this - * node, or null if no scale was set - * - * @return The scale + * Returns a reference to the morph target weights, + * or null if no morph target weights have been defined + * + * @return The morph target weights */ - float[] getScale(); - + float[] getWeights(); + /** * Set the morph target weights to be a reference to the given - * array. - * + * array. + * * @param weights The weights */ void setWeights(float weights[]); - - /** - * Returns a reference to the morph target weights, - * or null if no morph target weights have been defined - * - * @return The morph target weights - */ - float[] getWeights(); - + /** * Computes the local transform of this node.
*
- * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * * @param result The result array * @return The result array */ @@ -186,39 +185,39 @@ public interface NodeModel extends NamedModelElement /** * Computes the global transform of this node.
*
- * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * * @param result The result array * @return The result array */ float[] computeGlobalTransform(float result[]); /** - * Creates a supplier for the global transform matrix of this node + * Creates a supplier for the global transform matrix of this node * model.
- *
- * The matrix will be provided as a float array with 16 elements, + *
+ * The matrix will be provided as a float array with 16 elements, * storing the matrix entries in column-major order.
*
* Note: The supplier MAY always return the same array instance. - * Callers MUST NOT store or modify the returned array. - * + * Callers MUST NOT store or modify the returned array. + * * @return The supplier */ Supplier createGlobalTransformSupplier(); /** * Creates a supplier for the local transform matrix of this node model.
- *
- * The matrix will be provided as a float array with 16 elements, + *
+ * The matrix will be provided as a float array with 16 elements, * storing the matrix entries in column-major order.
*
* Note: The supplier MAY always return the same array instance. - * Callers MUST NOT store or modify the returned array. - * + * Callers MUST NOT store or modify the returned array. + * * @return The supplier */ Supplier createLocalTransformSupplier(); diff --git a/src/main/java/de/javagl/jgltf/model/NumberArrays.java b/src/main/java/de/javagl/jgltf/model/NumberArrays.java index 45ec126..dd2da19 100644 --- a/src/main/java/de/javagl/jgltf/model/NumberArrays.java +++ b/src/main/java/de/javagl/jgltf/model/NumberArrays.java @@ -29,62 +29,53 @@ /** * Methods to convert primitive arrays to arrays of Number objects */ -class NumberArrays -{ +class NumberArrays { + /** + * Private constructor to prevent instantiation + */ + private NumberArrays() { + // Private constructor to prevent instantiation + } + /** * Convert the given array into a Number array - * + * * @param array The array * @return The result */ - static Number[] asNumbers(int array[]) - { + static Number[] asNumbers(int array[]) { Number result[] = new Number[array.length]; - for (int i = 0; i < array.length; i++) - { + for (int i = 0; i < array.length; i++) { result[i] = array[i]; } return result; - } + } /** * Convert the given array into a Number array - * + * * @param array The array * @return The result */ - static Number[] asNumbers(long array[]) - { + static Number[] asNumbers(long array[]) { Number result[] = new Number[array.length]; - for (int i = 0; i < array.length; i++) - { + for (int i = 0; i < array.length; i++) { result[i] = array[i]; } return result; } - + /** * Convert the given array into a Number array - * + * * @param array The array * @return The result */ - static Number[] asNumbers(float array[]) - { + static Number[] asNumbers(float array[]) { Number result[] = new Number[array.length]; - for (int i = 0; i < array.length; i++) - { + for (int i = 0; i < array.length; i++) { result[i] = array[i]; } return result; } - - - /** - * Private constructor to prevent instantiation - */ - private NumberArrays() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/Optionals.java b/src/main/java/de/javagl/jgltf/model/Optionals.java index d7a8d67..72b3a43 100644 --- a/src/main/java/de/javagl/jgltf/model/Optionals.java +++ b/src/main/java/de/javagl/jgltf/model/Optionals.java @@ -32,160 +32,137 @@ /** * Utility methods related to values that are optional. These values may - * be null, and the utility methods will provide default - * values in this case. + * be null, and the utility methods will provide default + * values in this case. */ -public class Optionals -{ +public class Optionals { + /** + * Private constructor to prevent instantiation + */ + private Optionals() { + // Private constructor to prevent instantiation + } + /** * Returns the given list, or an unmodifiable empty list if the * given list is null. - * - * @param The element type - * + * + * @param The element type * @param list The list * @return The result */ - public static List of(List list) - { + public static List of(List list) { return of(list, Collections.emptyList()); } - + /** * Returns the specified element from the given list, or null * if the list is null or the index is not valid. - * - * @param The element type - * - * @param list The list + * + * @param The element type + * @param list The list * @param index The index * @return The element */ - public static T get(List list, int index) - { - if (list == null) - { + public static T get(List list, int index) { + if (list == null) { return null; } - if (index < 0) - { + if (index < 0) { return null; } - if (index >= list.size()) - { + if (index >= list.size()) { return null; } return list.get(index); } - + /** * Returns the given map, or an unmodifiable empty map if the * given map is null. - * + * * @param The key type * @param The value type - * * @param map The map * @return The result */ - public static Map of(Map map) - { - return of (map, Collections.emptyMap()); + public static Map of(Map map) { + return of(map, Collections.emptyMap()); } - + /** * Returns the given value, or the default value if the given value * is null. - * - * @param The value type - * - * @param value The value + * + * @param The value type + * @param value The value * @param defaultValue The default value * @return The result */ - public static T of(T value, T defaultValue) - { + public static T of(T value, T defaultValue) { return value != null ? value : defaultValue; } - + /** * Returns the value that is associated with the given key in the * given map, or null if either the key or the map * is null. - * + * * @param The value type - * * @param key The key * @param map The map * @return The value */ - public static V get(Object key, Map map) - { - if (key == null) - { + public static V get(Object key, Map map) { + if (key == null) { return null; } - if (map == null) - { + if (map == null) { return null; } return map.get(key); } - + /** * Returns a clone of the given array, or null if the * given array is null - * + * * @param array The array * @return The result */ - public static float[] clone(float array[]) - { - if (array == null) - { + public static float[] clone(float array[]) { + if (array == null) { return null; } return array.clone(); } - + /** * Returns a clone of the given array, or null if the * given array is null - * + * * @param array The array * @return The result */ - public static int[] clone(int array[]) - { - if (array == null) - { + public static int[] clone(int array[]) { + if (array == null) { return null; } return array.clone(); } - + /** * Returns a clone of the given array, or null if the * given array is null - * + * * @param array The array * @return The result */ - public static boolean[] clone(boolean array[]) - { - if (array == null) - { + public static boolean[] clone(boolean array[]) { + if (array == null) { return null; } return array.clone(); } - - /** - * Private constructor to prevent instantiation - */ - private Optionals() - { - // Private constructor to prevent instantiation - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/SceneModel.java b/src/main/java/de/javagl/jgltf/model/SceneModel.java index ebf3cae..bfeaf55 100644 --- a/src/main/java/de/javagl/jgltf/model/SceneModel.java +++ b/src/main/java/de/javagl/jgltf/model/SceneModel.java @@ -31,12 +31,11 @@ /** * Interface for a scene that was read from a glTF asset */ -public interface SceneModel extends NamedModelElement -{ +public interface SceneModel extends NamedModelElement { /** - * Returns an unmodifiable view on the the list of all root + * Returns an unmodifiable view on the the list of all root * {@link NodeModel} instances of the scene - * + * * @return The {@link NodeModel} instances */ List getNodeModels(); diff --git a/src/main/java/de/javagl/jgltf/model/SkinModel.java b/src/main/java/de/javagl/jgltf/model/SkinModel.java index e21138d..f464673 100644 --- a/src/main/java/de/javagl/jgltf/model/SkinModel.java +++ b/src/main/java/de/javagl/jgltf/model/SkinModel.java @@ -31,54 +31,53 @@ /** * Interface for a skin of a glTF asset */ -public interface SkinModel extends NamedModelElement -{ +public interface SkinModel extends NamedModelElement { /** * Provides the bind shape matrix of the skin.
*
- * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * * @param result The result array * @return The result array */ float[] getBindShapeMatrix(float result[]); - + /** * Returns an unmodifiable list containing the joint nodes of the skeleton - * + * * @return The joint nodes */ List getJoints(); - + /** * Returns the skeleton root node. If the return value is null, - * then joint transforms refer to the scene root. - * + * then joint transforms refer to the scene root. + * * @return The skeleton node */ NodeModel getSkeleton(); - + /** - * Returns the {@link AccessorModel} that provides the data for the + * Returns the {@link AccessorModel} that provides the data for the * inverse bind matrices, one for each {@link #getJoints() joint} - * + * * @return The inverse bind matrices accessor */ AccessorModel getInverseBindMatrices(); - + /** * Convenience function to obtain the inverse bind matrix for the joint * with the given index.
*
- * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * - * @param index The index of the joint + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * + * @param index The index of the joint * @param result The result array * @return The result array */ diff --git a/src/main/java/de/javagl/jgltf/model/Suppliers.java b/src/main/java/de/javagl/jgltf/model/Suppliers.java index 779d987..8219d61 100644 --- a/src/main/java/de/javagl/jgltf/model/Suppliers.java +++ b/src/main/java/de/javagl/jgltf/model/Suppliers.java @@ -32,31 +32,34 @@ /** * Utility methods to create Supplier instances */ -public class Suppliers -{ +public class Suppliers { /** - * Create a supplier of a 4x4 matrix that is computed by applying + * Private constructor to prevent instantiation + */ + private Suppliers() { + // Private constructor to prevent instantiation + } + + /** + * Create a supplier of a 4x4 matrix that is computed by applying * the given computer to the given object and a 16-element array.
*
- * If the given object is null, then the identity + * If the given object is null, then the identity * matrix will be supplied.
*
* Note: The supplier MAY always return the same array instance. * Callers MUST NOT store or modify the returned array. - * - * @param The object type - * - * @param object The object + * + * @param The object type + * @param object The object * @param computer The computer function * @return The supplier */ public static Supplier createTransformSupplier( - T object, BiConsumer computer) - { + T object, BiConsumer computer) { float transform[] = new float[16]; - if (object == null) - { - return () -> + if (object == null) { + return () -> { MathUtils.setIdentity4x4(transform); return transform; @@ -68,13 +71,4 @@ public static Supplier createTransformSupplier( return transform; }; } - - - /** - * Private constructor to prevent instantiation - */ - private Suppliers() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/TextureModel.java b/src/main/java/de/javagl/jgltf/model/TextureModel.java index 986d464..863dc6e 100644 --- a/src/main/java/de/javagl/jgltf/model/TextureModel.java +++ b/src/main/java/de/javagl/jgltf/model/TextureModel.java @@ -29,39 +29,38 @@ /** * Interface for a texture in a glTF asset */ -public interface TextureModel extends NamedModelElement -{ +public interface TextureModel extends NamedModelElement { /** * Return the magnification filter constant - * + * * @return The constant */ Integer getMagFilter(); /** * Return the minification filter constant - * + * * @return The constant */ Integer getMinFilter(); /** * Return the wrapping constant for S-direction - * + * * @return The constant */ Integer getWrapS(); /** * Return the wrapping constant for T-direction - * + * * @return The constant */ Integer getWrapT(); - + /** * Returns the {@link ImageModel} that backs this texture - * + * * @return The {@link ImageModel} */ ImageModel getImageModel(); diff --git a/src/main/java/de/javagl/jgltf/model/Utils.java b/src/main/java/de/javagl/jgltf/model/Utils.java index 74a403b..fa5f375 100644 --- a/src/main/java/de/javagl/jgltf/model/Utils.java +++ b/src/main/java/de/javagl/jgltf/model/Utils.java @@ -29,32 +29,28 @@ /** * Utility methods. These should not be considered as part of the public API. */ -public class Utils -{ +public class Utils { + /** + * Private constructor to prevent instantiation + */ + private Utils() { + // Private constructor to prevent instantiation + } + /** * Validate that the given array is not null and has the * given length. If this is not the case, return a new array with the * specified length. - * - * @param array The array + * + * @param array The array * @param length The length * @return The array, or a new array with the desired length */ - public static float[] validate(float array[], int length) - { - if (array != null && array.length == length) - { + public static float[] validate(float array[], int length) { + if (array != null && array.length == length) { return array; } return new float[length]; } - /** - * Private constructor to prevent instantiation - */ - private Utils() - { - // Private constructor to prevent instantiation - } - } diff --git a/src/main/java/de/javagl/jgltf/model/animation/Animation.java b/src/main/java/de/javagl/jgltf/model/animation/Animation.java index 0382473..3782bdf 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/Animation.java +++ b/src/main/java/de/javagl/jgltf/model/animation/Animation.java @@ -32,148 +32,137 @@ /** * A class representing a generic animation. The animation consists of - * a mapping between time key frames and values, and allows - * {@link AnimationListener}s to be informed about the progress of the - * animation, including the current time and the (interpolated) values + * a mapping between time key frames and values, and allows + * {@link AnimationListener}s to be informed about the progress of the + * animation, including the current time and the (interpolated) values * for this time point. */ -public final class Animation -{ +public final class Animation { /** * The key frame times, in seconds */ private final float timesS[]; - + /** * The values. Each element of this array corresponds to one key * frame time */ private final float values[][]; - + /** * The interpolator for the values */ private final Interpolator interpolator; - + /** * A pre-allocated array of the output values that will be passed * to the listeners. The listeners are not allowed to store or * modify this array. */ private final float outputValues[]; - + /** * The {@link AnimationListener}s that are informed about the progress * of this animation */ private final List listeners; - + /** - * Creates a new animation with the given time key frames and the + * Creates a new animation with the given time key frames and the * corresponding values. - * - * @param timesS The time key frames, in seconds - * @param values The values. Each element of this array consists of the - * values for the corresponding key frame time. + * + * @param timesS The time key frames, in seconds + * @param values The values. Each element of this array consists of the + * values for the corresponding key frame time. * @param interpolatorType The {@link InterpolatorType} that will be - * used for interpolating the values - * @throws NullPointerException If either of the given parameters is - * null, or the given values array contains null - * elements + * used for interpolating the values + * @throws NullPointerException If either of the given parameters is + * null, or the given values array contains null + * elements * @throws IllegalArgumentException If any of the given arrays has a - * length of 0 + * length of 0 * @throws IllegalArgumentException If any of the given values arrays - * has a length that is different from the length of the times array. + * has a length that is different from the length of the times array. */ public Animation( - float timesS[], - float values[][], - InterpolatorType interpolatorType) - { + float timesS[], + float values[][], + InterpolatorType interpolatorType) { Objects.requireNonNull(timesS, "The times may not be null"); Objects.requireNonNull(values, "The values may not be null"); - if (timesS.length == 0) - { + if (timesS.length == 0) { throw new IllegalArgumentException( - "The keys may not have a length of 0"); + "The keys may not have a length of 0"); } - if (values.length != timesS.length) - { + if (values.length != timesS.length) { throw new IllegalArgumentException( - "The values must have a length of "+timesS.length+", " + - "but have a length of "+values.length); + "The values must have a length of " + timesS.length + ", " + + "but have a length of " + values.length); } this.timesS = timesS.clone(); this.values = new float[values.length][]; - for (int i=0; i(); } - + /** * Returns the start time of this animation, in seconds - * + * * @return The start time */ - float getStartTimeS() - { + float getStartTimeS() { return timesS[0]; } - + /** * Returns the end time of this animation, in seconds - * + * * @return The end time */ - float getEndTimeS() - { - return timesS[timesS.length-1]; + float getEndTimeS() { + return timesS[timesS.length - 1]; } - + /** * Returns the duration of this animation, in seconds - * + * * @return The duration */ - float getDurationS() - { + float getDurationS() { return getEndTimeS() - getStartTimeS(); } - + /** * Add the given {@link AnimationListener} to be informed about any * progress in this animation - * + * * @param listener The listener to add */ - public void addAnimationListener(AnimationListener listener) - { + public void addAnimationListener(AnimationListener listener) { listeners.add(listener); } /** - * Remove the given {@link AnimationListener} - * + * Remove the given {@link AnimationListener} + * * @param listener The listener to remove */ - public void removeAnimationListener(AnimationListener listener) - { + public void removeAnimationListener(AnimationListener listener) { listeners.remove(listener); } - + /** * Package-private method to update this animation based on the given time, * and inform all registered listeners. - * + * * @param timeS The time, in seconds */ - void update(float timeS) - { + void update(float timeS) { int index0 = InterpolatorKeys.computeIndex(timeS, timesS); int index1 = Math.min(timesS.length - 1, index0 + 1); float alpha = InterpolatorKeys.computeAlpha(timeS, timesS, index0); @@ -182,14 +171,13 @@ void update(float timeS) //System.out.println("index0 "+index0); //System.out.println("index1 "+index1); //System.out.println("alpha "+alpha); - + float a[] = values[index0]; float b[] = values[index1]; interpolator.interpolate(a, b, alpha, outputValues); - for (AnimationListener listener : listeners) - { + for (AnimationListener listener : listeners) { listener.animationUpdated(this, timeS, outputValues); } } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/animation/AnimationListener.java b/src/main/java/de/javagl/jgltf/model/animation/AnimationListener.java index d6e9f5c..fb65eaf 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/AnimationListener.java +++ b/src/main/java/de/javagl/jgltf/model/animation/AnimationListener.java @@ -30,19 +30,18 @@ * Interface for classes that want to be informed about the progress * of an {@link Animation} */ -public interface AnimationListener -{ +public interface AnimationListener { /** * Will be called when the given {@link Animation} was updated.
*
* Note: The given array of interpolated output values MAY * be reused for multiple calls. Implementors of this method MUST NOT * store or modify the given array. - * + * * @param source The source {@link Animation} - * @param timeS The time, in seconds + * @param timeS The time, in seconds * @param values The interpolated values for the given time */ void animationUpdated( - Animation source, float timeS, float values[]); + Animation source, float timeS, float values[]); } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/animation/AnimationManager.java b/src/main/java/de/javagl/jgltf/model/animation/AnimationManager.java index 3d70c3c..b6c710f 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/AnimationManager.java +++ b/src/main/java/de/javagl/jgltf/model/animation/AnimationManager.java @@ -32,256 +32,222 @@ import java.util.concurrent.CopyOnWriteArrayList; /** - * A class that manages several {@link Animation} instances, and dispatches + * A class that manages several {@link Animation} instances, and dispatches * any updates in the (global) time to these animations. */ -public final class AnimationManager -{ +public final class AnimationManager { /** - * A policy describing how the animations should be executed + * The {@link AnimationPolicy} */ - public enum AnimationPolicy - { - /** - * Indicates that the animations should be executed only - * once, and then removed from the {@link AnimationManager} - */ - ONCE, - - /** - * Indicates that the animations should be executed in - * a ping-pong fashion - */ - PING_PONG, - - /** - * Indicates that the animations should be looped - */ - LOOP - } - + private final AnimationPolicy animationPolicy; /** - * The {@link AnimationPolicy} + * The list of {@link Animation} instances maintained by this manager */ - private final AnimationPolicy animationPolicy; - + private final List animations; + /** + * The list of {@link AnimationManagerListener}s that want to be + * informed about changes in this manager + */ + private final List animationManagerListeners; /** * The start time, in nanoseconds */ private long startNs; - /** * The current time, in nanoseconds */ private long currentNs; - - /** - * The list of {@link Animation} instances maintained by this manager - */ - private final List animations; - /** * The maximum {@link Animation#getEndTimeS()} of all animations */ private float maxEndTimeS; - - /** - * The list of {@link AnimationManagerListener}s that want to be - * informed about changes in this manager - */ - private final List animationManagerListeners; - + /** * Creates a new, empty animation manager - * + * * @param animationPolicy The {@link AnimationPolicy} */ - public AnimationManager(AnimationPolicy animationPolicy) - { + public AnimationManager(AnimationPolicy animationPolicy) { this.animationPolicy = animationPolicy; this.startNs = System.nanoTime(); this.currentNs = startNs; this.animations = new CopyOnWriteArrayList(); this.maxEndTimeS = 0.0f; - this.animationManagerListeners = - new CopyOnWriteArrayList(); + this.animationManagerListeners = + new CopyOnWriteArrayList(); } - + /** * Reset this manager to its initial state. This will also update * all {@link Animation}s with a time of 0.0. */ - public void reset() - { + public void reset() { startNs = System.nanoTime(); currentNs = System.nanoTime(); performStep(0); } - + /** * Returns the current animation time, in seconds - * + * * @return The animation time */ - float getCurrentTimeS() - { + float getCurrentTimeS() { long timeNs = currentNs - startNs; float timeS = timeNs * 1e-9f; return timeS; } - + /** * Add the given {@link Animation} to this manager. - * + * * @param animation The {@link Animation} to add */ - public void addAnimation(Animation animation) - { + public void addAnimation(Animation animation) { Objects.requireNonNull(animation, "The animation may not be null"); animations.add(animation); updateMaxEndTime(); } - + /** * Add all {@link Animation}s of the given sequence to this manager - * + * * @param animations The {@link Animation}s to add */ - public void addAnimations(Iterable animations) - { - for (Animation animation : animations) - { + public void addAnimations(Iterable animations) { + for (Animation animation : animations) { addAnimation(animation); } } - - + /** * Remove the given {@link Animation} from this manager - * + * * @param animation The {@link Animation} to remove */ - public void removeAnimation(Animation animation) - { + public void removeAnimation(Animation animation) { animations.remove(animation); updateMaxEndTime(); } - + /** * Remove all {@link Animation}s of the given sequence from this manager - * + * * @param animations The {@link Animation}s to remove */ - public void removeAnimations(Iterable animations) - { - for (Animation animation : animations) - { + public void removeAnimations(Iterable animations) { + for (Animation animation : animations) { removeAnimation(animation); } } - + /** * Returns an unmodifiable view on the animations that are stored * in this manager - * + * * @return The animations */ - public List getAnimations() - { + public List getAnimations() { return Collections.unmodifiableList(animations); } - + /** - * Update the {@link #maxEndTimeS}, the maximum end time of any + * Update the {@link #maxEndTimeS}, the maximum end time of any * {@link Animation} */ - private void updateMaxEndTime() - { + private void updateMaxEndTime() { maxEndTimeS = 0.0f; - for (Animation animation : animations) - { + for (Animation animation : animations) { maxEndTimeS = Math.max(maxEndTimeS, animation.getEndTimeS()); } } - + /** * Perform a time step, with the given size (in nanoseconds), and * update all {@link Animation}s - * + * * @param deltaNs The time step size, in nanoseconds */ - void performStep(long deltaNs) - { + void performStep(long deltaNs) { currentNs += deltaNs; float currentTimeS = getCurrentTimeS(); - if (animationPolicy == AnimationPolicy.ONCE && - currentTimeS > maxEndTimeS) - { + if (animationPolicy == AnimationPolicy.ONCE && + currentTimeS > maxEndTimeS) { animations.clear(); return; } - for (Animation animation : animations) - { - if (animationPolicy == AnimationPolicy.LOOP) - { + for (Animation animation : animations) { + if (animationPolicy == AnimationPolicy.LOOP) { float loopTimeS = currentTimeS % maxEndTimeS; animation.update(loopTimeS); - } - else if (animationPolicy == AnimationPolicy.PING_PONG) - { - int interval = (int)(currentTimeS / maxEndTimeS); + } else if (animationPolicy == AnimationPolicy.PING_PONG) { + int interval = (int) (currentTimeS / maxEndTimeS); float loopTimeS = currentTimeS % maxEndTimeS; float pingPongTimeS = loopTimeS; - if ((interval & 1) != 0) - { - pingPongTimeS = maxEndTimeS - loopTimeS; + if ((interval & 1) != 0) { + pingPongTimeS = maxEndTimeS - loopTimeS; } animation.update(pingPongTimeS); - } - else - { + } else { animation.update(currentTimeS); } } fireAnimationsUpdated(); } - + /** * Add the given {@link AnimationManagerListener} to be informed about * changes in this manager - * + * * @param listener The listener to add */ public void addAnimationManagerListener( - AnimationManagerListener listener) - { + AnimationManagerListener listener) { animationManagerListeners.add(listener); } - + /** * Remove the given {@link AnimationManagerListener} - * + * * @param listener The listener to remove */ public void removeAnimationManagerListener( - AnimationManagerListener listener) - { + AnimationManagerListener listener) { animationManagerListeners.remove(listener); } - - + /** * Inform all registered {@link AnimationManagerListener}s that * the animations have been updated */ - private void fireAnimationsUpdated() - { - for (AnimationManagerListener listener : animationManagerListeners) - { + private void fireAnimationsUpdated() { + for (AnimationManagerListener listener : animationManagerListeners) { listener.animationsUpdated(this); } } - - - + + + /** + * A policy describing how the animations should be executed + */ + public enum AnimationPolicy { + /** + * Indicates that the animations should be executed only + * once, and then removed from the {@link AnimationManager} + */ + ONCE, + + /** + * Indicates that the animations should be executed in + * a ping-pong fashion + */ + PING_PONG, + + /** + * Indicates that the animations should be looped + */ + LOOP + } + + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/animation/AnimationManagerListener.java b/src/main/java/de/javagl/jgltf/model/animation/AnimationManagerListener.java index 9fc527f..4839a1c 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/AnimationManagerListener.java +++ b/src/main/java/de/javagl/jgltf/model/animation/AnimationManagerListener.java @@ -30,12 +30,11 @@ * Interface for classes that want to be informed about changes * in an {@link AnimationManager} */ -public interface AnimationManagerListener -{ +public interface AnimationManagerListener { /** * Will be called when the {@link Animation}s in the given * {@link AnimationManager} have been updated - * + * * @param source The {@link AnimationManager} */ void animationsUpdated(AnimationManager source); diff --git a/src/main/java/de/javagl/jgltf/model/animation/AnimationRunner.java b/src/main/java/de/javagl/jgltf/model/animation/AnimationRunner.java index 0c0b96d..8eaf0dc 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/AnimationRunner.java +++ b/src/main/java/de/javagl/jgltf/model/animation/AnimationRunner.java @@ -31,48 +31,41 @@ /** * Simple utility class to run an {@link AnimationManager} in an own thread */ -public final class AnimationRunner -{ +public final class AnimationRunner { /** * The {@link AnimationManager} */ private final AnimationManager animationManager; - + /** + * The step size, in milliseconds + */ + private final long stepSizeMs = 10; /** * Whether this runner is currently running */ private boolean running = false; - /** * The animation thread */ private Thread animationThread; - - /** - * The step size, in milliseconds - */ - private final long stepSizeMs = 10; - + /** * Create a new runner for the given {@link AnimationManager} - * + * * @param animationManager The {@link AnimationManager} */ - public AnimationRunner(AnimationManager animationManager) - { - Objects.requireNonNull(animationManager, - "The animationManager may not be null"); + public AnimationRunner(AnimationManager animationManager) { + Objects.requireNonNull(animationManager, + "The animationManager may not be null"); this.animationManager = animationManager; } - + /** * Start this runner. If the runner is already {@link #isRunning()}, * then this has no effect. */ - public synchronized void start() - { - if (isRunning()) - { + public synchronized void start() { + if (isRunning()) { return; } animationThread = new Thread(this::runAnimations, "animationThread"); @@ -80,15 +73,13 @@ public synchronized void start() animationThread.start(); running = true; } - + /** * Stop this runner. If the runner is not {@link #isRunning()}, * then this has no effect. */ - public synchronized void stop() - { - if (!isRunning()) - { + public synchronized void stop() { + if (!isRunning()) { return; } running = false; @@ -97,37 +88,31 @@ public synchronized void stop() /** * Returns whether this runner is currently running - * - * @return Whether this runner is currently running + * + * @return Whether this runner is currently running */ - boolean isRunning() - { + boolean isRunning() { return running; } - + /** * Will be called in an own thread to perform time steps in the * {@link AnimationManager} */ - private void runAnimations() - { + private void runAnimations() { long previousNs = System.nanoTime(); - while (isRunning()) - { + while (isRunning()) { long currentNs = System.nanoTime(); long deltaNs = currentNs - previousNs; animationManager.performStep(deltaNs); previousNs = currentNs; - try - { + try { Thread.sleep(stepSizeMs); - } - catch (InterruptedException e) - { + } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } } - + } diff --git a/src/main/java/de/javagl/jgltf/model/animation/Interpolator.java b/src/main/java/de/javagl/jgltf/model/animation/Interpolator.java index 9c95d96..1a4da8d 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/Interpolator.java +++ b/src/main/java/de/javagl/jgltf/model/animation/Interpolator.java @@ -27,24 +27,23 @@ package de.javagl.jgltf.model.animation; /** - * Package-private interface for classes that can interpolate between + * Package-private interface for classes that can interpolate between * (equal-length) arrays of float values */ -interface Interpolator -{ +interface Interpolator { /** - * Interpolate between a and b, based on + * Interpolate between a and b, based on * the given alpha value (that is usually in [0,1]), and place the * results in the given result array. None of the given arrays may * be null, and they must all have the same length. - * - * @param a The first array - * @param b The second array - * @param alpha The interpolation value + * + * @param a The first array + * @param b The second array + * @param alpha The interpolation value * @param result The array that will store the result - * @throws NullPointerException If any argument is null - * @throws IndexOutOfBoundsException May be thrown if the arrays do not - * have the same length + * @throws NullPointerException If any argument is null + * @throws IndexOutOfBoundsException May be thrown if the arrays do not + * have the same length */ void interpolate(float a[], float b[], float alpha, float result[]); } diff --git a/src/main/java/de/javagl/jgltf/model/animation/InterpolatorKeys.java b/src/main/java/de/javagl/jgltf/model/animation/InterpolatorKeys.java index 0998434..62228f2 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/InterpolatorKeys.java +++ b/src/main/java/de/javagl/jgltf/model/animation/InterpolatorKeys.java @@ -29,73 +29,66 @@ import java.util.Arrays; /** - * Methods to compute {@link Interpolator} keys from a given value and a + * Methods to compute {@link Interpolator} keys from a given value and a * (sorted) float array */ -class InterpolatorKeys -{ +class InterpolatorKeys { /** * Compute the index of the segment that the given key belongs to. * If the given key is smaller than the smallest or larger than - * the largest key, then 0 or keys.length-1 will be returned, + * the largest key, then 0 or keys.length-1 will be returned, * respectively. - * - * @param key The key + * + * @param key The key * @param keys The sorted keys * @return The index for the key */ - static int computeIndex(float key, float keys[]) - { + static int computeIndex(float key, float keys[]) { int index = Arrays.binarySearch(keys, key); - if (index >= 0) - { + if (index >= 0) { return index; } return Math.max(0, -index - 2); } - + /** * Compute the alpha value for the given key. This is a value in [0,1], * describing the relative location of the key in the segment with the * given index. - * - * @param key The key - * @param keys The sorted keys + * + * @param key The key + * @param keys The sorted keys * @param index The index of the key * @return The alpha value */ - static float computeAlpha(float key, float keys[], int index) - { - if (key <= keys[0]) - { + static float computeAlpha(float key, float keys[], int index) { + if (key <= keys[0]) { return 0.0f; } - if (key >= keys[keys.length-1]) - { + if (key >= keys[keys.length - 1]) { return 1.0f; } float local = key - keys[index]; - float delta = keys[index+1] - keys[index]; + float delta = keys[index + 1] - keys[index]; float alpha = local / delta; return alpha; - + } - + /** * A basic test + * * @param args Not used */ - public static void main(String[] args) - { - float keys[] = { 1, 8, 11 }; - for (float d = -1; d <= 12; d+=0.1) - { + public static void main(String[] args) { + float keys[] = {1, 8, 11}; + for (float d = -1; d <= 12; d += 0.1) { int index = computeIndex(d, keys); float alpha = computeAlpha(d, keys, index); - System.out.println("For "+d); - System.out.println(" index "+index); - System.out.println(" alpha "+alpha); + System.out.println("For " + d); + System.out.println(" index " + index); + System.out.println(" alpha " + alpha); } } - + } diff --git a/src/main/java/de/javagl/jgltf/model/animation/InterpolatorType.java b/src/main/java/de/javagl/jgltf/model/animation/InterpolatorType.java index 65ad4d0..b153c7d 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/InterpolatorType.java +++ b/src/main/java/de/javagl/jgltf/model/animation/InterpolatorType.java @@ -3,20 +3,19 @@ /** * Enumeration of interpolator types */ -public enum InterpolatorType -{ +public enum InterpolatorType { /** * A linear interpolator */ LINEAR, - + /** - * A spherical linear interpolation (SLERP). The input values will - * be assumed to consist of 4 elements, which are interpreted as + * A spherical linear interpolation (SLERP). The input values will + * be assumed to consist of 4 elements, which are interpreted as * quaternions for the interpolation */ SLERP, - + /** * A stepwise interpolation */ diff --git a/src/main/java/de/javagl/jgltf/model/animation/Interpolators.java b/src/main/java/de/javagl/jgltf/model/animation/Interpolators.java index d6115ff..a828402 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/Interpolators.java +++ b/src/main/java/de/javagl/jgltf/model/animation/Interpolators.java @@ -29,25 +29,28 @@ /** * Methods to create {@link Interpolator} instances */ -class Interpolators -{ +class Interpolators { + /** + * Private constructor to prevent instantiation + */ + private Interpolators() { + // Private constructor to prevent instantiation + } + /** * Creates an {@link Interpolator} for the given {@link InterpolatorType}. - * If the given {@link InterpolatorType} is null, then + * If the given {@link InterpolatorType} is null, then * a {@link InterpolatorType#LINEAR linear} interpolator will be returned. - * + * * @param interpolatorType The {@link InterpolatorType} * @return The {@link Interpolator} */ - static Interpolator create(InterpolatorType interpolatorType) - { - if (interpolatorType == null) - { + static Interpolator create(InterpolatorType interpolatorType) { + if (interpolatorType == null) { return new LinearInterpolator(); } - switch (interpolatorType) - { - case SLERP: + switch (interpolatorType) { + case SLERP: return new SlerpQuaternionInterpolator(); case LINEAR: @@ -58,15 +61,7 @@ static Interpolator create(InterpolatorType interpolatorType) default: throw new IllegalArgumentException( - "Invalid interpolator type: "+interpolatorType); + "Invalid interpolator type: " + interpolatorType); } } - - /** - * Private constructor to prevent instantiation - */ - private Interpolators() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/animation/LinearInterpolator.java b/src/main/java/de/javagl/jgltf/model/animation/LinearInterpolator.java index 39db643..e1b7d49 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/LinearInterpolator.java +++ b/src/main/java/de/javagl/jgltf/model/animation/LinearInterpolator.java @@ -30,20 +30,17 @@ * Implementation of an {@link Interpolator} that interpolates linearly. * Hence the name. */ -class LinearInterpolator implements Interpolator -{ +class LinearInterpolator implements Interpolator { @Override public void interpolate( - float[] a, float[] b, float alpha, float[] result) - { - for (int i=0; i epsilon) - { - float omega = (float)Math.acos(dot); - float invSinOmega = 1.0f / (float)Math.sin(omega); - s0 = (float)Math.sin((1.0 - alpha) * omega) * invSinOmega; - s1 = (float)Math.sin(alpha * omega) * invSinOmega; - } - else - { + if ((1.0 - dot) > epsilon) { + float omega = (float) Math.acos(dot); + float invSinOmega = 1.0f / (float) Math.sin(omega); + s0 = (float) Math.sin((1.0 - alpha) * omega) * invSinOmega; + s1 = (float) Math.sin(alpha * omega) * invSinOmega; + } else { s0 = 1.0f - alpha; s1 = alpha; } diff --git a/src/main/java/de/javagl/jgltf/model/animation/StepInterpolator.java b/src/main/java/de/javagl/jgltf/model/animation/StepInterpolator.java index 17c7238..c916c4c 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/StepInterpolator.java +++ b/src/main/java/de/javagl/jgltf/model/animation/StepInterpolator.java @@ -29,12 +29,10 @@ /** * Implementation of an {@link Interpolator} that interpolates stepwise. */ -class StepInterpolator implements Interpolator -{ +class StepInterpolator implements Interpolator { @Override public void interpolate( - float[] a, float[] b, float alpha, float[] result) - { + float[] a, float[] b, float alpha, float[] result) { System.arraycopy(a, 0, result, 0, a.length); } diff --git a/src/main/java/de/javagl/jgltf/model/extensions/GltfExtensions.java b/src/main/java/de/javagl/jgltf/model/extensions/GltfExtensions.java index 07b0bcd..cf2e8c3 100644 --- a/src/main/java/de/javagl/jgltf/model/extensions/GltfExtensions.java +++ b/src/main/java/de/javagl/jgltf/model/extensions/GltfExtensions.java @@ -26,123 +26,107 @@ */ package de.javagl.jgltf.model.extensions; -import java.util.Map; - import com.google.gson.Gson; +import java.util.Map; + /** * Utility methods related to glTF extension objects. */ -public class GltfExtensions -{ +public class GltfExtensions { + /** + * Private constructor to prevent instantiation + */ + private GltfExtensions() { + // Private constructor to prevent instantiation + } + /** * Obtain the specified extension object from the given glTF property. - * + *

* If the given glTF object does not have an extension with the * given name, or this object cannot be converted to the given * target type, then null is returned. - * - * @param The type of the extension object - * - * @param gltfProperty The glTF property + * + * @param The type of the extension object + * @param gltfProperty The glTF property * @param extensionName The extension name * @param extensionType The extension type * @return The extension object, or null * @throws IllegalArgumentException If the given glTF property is neither - * a de.javagl.jgltf.impl.v1.GlTFProperty nor a - * a de.javagl.jgltf.impl.v2.GlTFProperty + * a de.javagl.jgltf.impl.v1.GlTFProperty nor a + * a de.javagl.jgltf.impl.v2.GlTFProperty */ public static T obtain( - Object gltfProperty, String extensionName, Class extensionType) - { - if (gltfProperty instanceof de.javagl.jgltf.impl.v1.GlTFProperty) - { - de.javagl.jgltf.impl.v1.GlTFProperty gltfPropertyV1 = - (de.javagl.jgltf.impl.v1.GlTFProperty) gltfProperty; + Object gltfProperty, String extensionName, Class extensionType) { + if (gltfProperty instanceof de.javagl.jgltf.impl.v1.GlTFProperty) { + de.javagl.jgltf.impl.v1.GlTFProperty gltfPropertyV1 = + (de.javagl.jgltf.impl.v1.GlTFProperty) gltfProperty; Map extensions = gltfPropertyV1.getExtensions(); return obtainInternal(extensions, extensionName, extensionType); } - if (gltfProperty instanceof de.javagl.jgltf.impl.v2.GlTFProperty) - { - de.javagl.jgltf.impl.v2.GlTFProperty gltfPropertyV2 = - (de.javagl.jgltf.impl.v2.GlTFProperty) gltfProperty; + if (gltfProperty instanceof de.javagl.jgltf.impl.v2.GlTFProperty) { + de.javagl.jgltf.impl.v2.GlTFProperty gltfPropertyV2 = + (de.javagl.jgltf.impl.v2.GlTFProperty) gltfProperty; Map extensions = gltfPropertyV2.getExtensions(); return obtainInternal(extensions, extensionName, extensionType); } throw new IllegalArgumentException( - "Not a valid glTF property: " + gltfProperty); + "Not a valid glTF property: " + gltfProperty); } /** * Internal method to obtain the extension object from the given map - * - * @param The type of the extension object - * @param extensions The optional extensions map + * + * @param The type of the extension object + * @param extensions The optional extensions map * @param extensionName The extension name * @param extensionType The extension type * @return The extension object, or null if it cannot be * obtained */ private static T obtainInternal( - Map extensions, - String extensionName, Class extensionType) - { - if (extensions == null) - { + Map extensions, + String extensionName, Class extensionType) { + if (extensions == null) { return null; } Object object = extensions.get(extensionName); - if (object == null) - { + if (object == null) { return null; } return convertValueOptional(object, extensionType); } - + /** * Convert the given object to the given target type - * - * @param The target type + * + * @param The target type * @param object The object - * @param type The target type + * @param type The target type * @return The result * @throws IllegalArgumentException If the conversion failed */ private static T convertValue(Object object, Class type) - throws IllegalArgumentException - { - Gson gson = new Gson(); + throws IllegalArgumentException { + Gson gson = new Gson(); return gson.fromJson(gson.toJsonTree(object), type); } - + /** - * Convert the given object to the given target type, returning + * Convert the given object to the given target type, returning * null if the conversion failed - * - * @param The target type + * + * @param The target type * @param object The object - * @param type The target type + * @param type The target type * @return The result */ - private static T convertValueOptional(Object object, Class type) - { - try - { + private static T convertValueOptional(Object object, Class type) { + try { return convertValue(object, type); - } - catch (IllegalArgumentException e) - { + } catch (IllegalArgumentException e) { return null; } } - - - - /** - * Private constructor to prevent instantiation - */ - private GltfExtensions() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/extensions/package-info.java b/src/main/java/de/javagl/jgltf/model/extensions/package-info.java index a1b875c..599bafb 100644 --- a/src/main/java/de/javagl/jgltf/model/extensions/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/extensions/package-info.java @@ -1,5 +1,5 @@ /** - * Classes related to glTF extension objects + * Classes related to glTF extension objects */ package de.javagl.jgltf.model.extensions; diff --git a/src/main/java/de/javagl/jgltf/model/gl/ProgramModel.java b/src/main/java/de/javagl/jgltf/model/gl/ProgramModel.java index 52d6307..addd74c 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/ProgramModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/ProgramModel.java @@ -26,33 +26,32 @@ */ package de.javagl.jgltf.model.gl; -import java.util.List; - import de.javagl.jgltf.model.NamedModelElement; +import java.util.List; + /** - * Interface for a program that consists of a vertex- and fragment + * Interface for a program that consists of a vertex- and fragment * {@link ShaderModel} */ -public interface ProgramModel extends NamedModelElement -{ +public interface ProgramModel extends NamedModelElement { /** * Return the {@link ShaderModel} for the vertex shader - * + * * @return The {@link ShaderModel} */ ShaderModel getVertexShaderModel(); - + /** * Return the {@link ShaderModel} for the fragment shader - * + * * @return The {@link ShaderModel} */ ShaderModel getFragmentShaderModel(); - + /** * Returns an unmodifiable list of the program attribute names - * + * * @return The attributes */ List getAttributes(); diff --git a/src/main/java/de/javagl/jgltf/model/gl/Semantic.java b/src/main/java/de/javagl/jgltf/model/gl/Semantic.java index 44a6c47..cce8c0d 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/Semantic.java +++ b/src/main/java/de/javagl/jgltf/model/gl/Semantic.java @@ -27,81 +27,80 @@ package de.javagl.jgltf.model.gl; /** - * Enumeration of the {@link TechniqueParametersModel#getSemantic() technique + * Enumeration of the {@link TechniqueParametersModel#getSemantic() technique * parameters semantics} */ -public enum Semantic -{ +public enum Semantic { /** * The LOCAL semantic */ LOCAL, - + /** * The MODEL semantic */ MODEL, - + /** * The VIEW semantic */ VIEW, - + /** * The PROJECTION semantic */ PROJECTION, - + /** * The MODELVIEW semantic */ MODELVIEW, - + /** * The MODELVIEWPROJECTION semantic */ MODELVIEWPROJECTION, - + /** * The MODELINVERSE semantic */ MODELINVERSE, - + /** * The VIEWINVERSE semantic */ VIEWINVERSE, - + /** * The MODELVIEWINVERSE semantic */ MODELVIEWINVERSE, - + /** * The PROJECTIONINVERSE semantic */ PROJECTIONINVERSE, - + /** * The MODELVIEWPROJECTIONINVERSE semantic */ MODELVIEWPROJECTIONINVERSE, - + /** * The MODELINVERSETRANSPOSE semantic */ MODELINVERSETRANSPOSE, - + /** * The MODELVIEWINVERSETRANSPOSE semantic */ MODELVIEWINVERSETRANSPOSE, - + /** * The VIEWPORT semantic */ VIEWPORT, - + /** * The JOINTMATRIX semantic */ @@ -110,41 +109,35 @@ public enum Semantic /** * Returns whether the given string is a valid semantic name, and may be * passed to Semantic.valueOf without causing an exception. - * + * * @param s The string * @return Whether the given string is a valid semantic */ - public static boolean contains(String s) - { - for (Semantic semantic : values()) - { - if (semantic.name().equals(s)) - { + public static boolean contains(String s) { + for (Semantic semantic : values()) { + if (semantic.name().equals(s)) { return true; } } return false; } - + /** - * Returns the semantic for the given string. If the string is + * Returns the semantic for the given string. If the string is * null or does not describe a valid semantic, * then null is returned - * + * * @param string The string * @return The semantic */ - public static Semantic forString(String string) - { - if (string == null) - { + public static Semantic forString(String string) { + if (string == null) { return null; } - if (!contains(string)) - { + if (!contains(string)) { return null; } return Semantic.valueOf(string); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/gl/ShaderModel.java b/src/main/java/de/javagl/jgltf/model/gl/ShaderModel.java index f482919..e1cd064 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/ShaderModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/ShaderModel.java @@ -26,34 +26,17 @@ */ package de.javagl.jgltf.model.gl; -import java.nio.ByteBuffer; - import de.javagl.jgltf.model.NamedModelElement; +import java.nio.ByteBuffer; + /** - * Interface for a shader + * Interface for a shader */ -public interface ShaderModel extends NamedModelElement -{ - /** - * Enumeration of different shader types - */ - public enum ShaderType - { - /** - * The vertex shader type - */ - VERTEX_SHADER, - - /** - * The fragment shader type - */ - FRAGMENT_SHADER - } - +public interface ShaderModel extends NamedModelElement { /** * Returns the URI of the shader data - * + * * @return The URI */ String getUri(); @@ -61,28 +44,43 @@ public enum ShaderType /** * Returns the actual shader data. This will return a slice of the * buffer that is stored internally. Thus, changes to the contents - * of this buffer will affect this model, but modifications of the - * position and limit of the returned buffer will not affect this + * of this buffer will affect this model, but modifications of the + * position and limit of the returned buffer will not affect this * model.
- * + * * @return The shader data */ ByteBuffer getShaderData(); - + /** * Returns the shader source code as a string. This is a convenience * function that simply returns the {@link #getShaderData() shader data} * as a string. - * + * * @return The shader source code */ String getShaderSource(); - + /** * Returns the {@link ShaderType} of this shader - * + * * @return The {@link ShaderType} */ ShaderType getShaderType(); - + + /** + * Enumeration of different shader types + */ + public enum ShaderType { + /** + * The vertex shader type + */ + VERTEX_SHADER, + + /** + * The fragment shader type + */ + FRAGMENT_SHADER + } + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/gl/TechniqueModel.java b/src/main/java/de/javagl/jgltf/model/gl/TechniqueModel.java index d847ed1..1e562cc 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/TechniqueModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/TechniqueModel.java @@ -26,60 +26,59 @@ */ package de.javagl.jgltf.model.gl; -import java.util.Map; - import de.javagl.jgltf.model.NamedModelElement; +import java.util.Map; + /** - * Interface for a rendering technique. Such a technique may be part of a - * core glTF 1.0 asset, an extension of a glTF 2.0 asset, or a custom + * Interface for a rendering technique. Such a technique may be part of a + * core glTF 1.0 asset, an extension of a glTF 2.0 asset, or a custom * implementation that is used internally. */ -public interface TechniqueModel extends NamedModelElement -{ +public interface TechniqueModel extends NamedModelElement { /** * Returns the {@link ProgramModel} that is used for implementing this * technique - * + * * @return The {@link ProgramModel} */ ProgramModel getProgramModel(); /** - * Returns an unmodifiable map that maps parameter names to + * Returns an unmodifiable map that maps parameter names to * {@link TechniqueParametersModel} instances - * + * * @return The parameters */ Map getParameters(); - + /** - * Returns an unmodifiable map that maps attribute names to + * Returns an unmodifiable map that maps attribute names to * parameter names - * + * * @return The mapping from attribute names to parameter names */ Map getAttributes(); - + /** * Returns the {@link TechniqueParametersModel} for the attribute * with the given name, or null if no such parameter - * exists. This is a convenience function and equivalent to + * exists. This is a convenience function and equivalent to *


      * techniqueModel.getParameters().get(
      *     techniqueModel.getAttributes().get(attributeName));
      * 
, * handling null-cases accordingly. - * + * * @param attributeName The attribute name * @return The {@link TechniqueParametersModel} */ TechniqueParametersModel getAttributeParameters(String attributeName); - + /** - * Returns an unmodifiable map that maps uniform names to + * Returns an unmodifiable map that maps uniform names to * parameter names - * + * * @return The uniforms */ Map getUniforms(); @@ -87,22 +86,22 @@ public interface TechniqueModel extends NamedModelElement /** * Returns the {@link TechniqueParametersModel} for the uniform * with the given name, or null if no such parameter - * exists. This is a convenience function and equivalent to + * exists. This is a convenience function and equivalent to *

      * techniqueModel.getParameters().get(
      *     techniqueModel.getUniforms().get(uniformName));
      * 
, * handling null-cases accordingly. - * + * * @param uniformName The uniform name * @return The {@link TechniqueParametersModel} */ TechniqueParametersModel getUniformParameters(String uniformName); - + /** * Returns the {@link TechniqueStatesModel}, or null if the * default technique states should be used. - * + * * @return The {@link TechniqueStatesModel} */ TechniqueStatesModel getTechniqueStatesModel(); diff --git a/src/main/java/de/javagl/jgltf/model/gl/TechniqueParametersModel.java b/src/main/java/de/javagl/jgltf/model/gl/TechniqueParametersModel.java index e495af7..ae7fdbd 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/TechniqueParametersModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/TechniqueParametersModel.java @@ -31,44 +31,43 @@ /** * An interface for describing {@link TechniqueModel} parameters */ -public interface TechniqueParametersModel -{ +public interface TechniqueParametersModel { /** * Returns the type of the parameter, as a GL constant. For example, * GL_INT or GL_FLOAT_VEC3 - * + * * @return The type */ int getType(); - + /** - * Returns the count - * + * Returns the count + * * @return The count */ int getCount(); - + /** * Returns the string describing the {@link Semantic} of this parameter. * This may be a string that starts with an underscore "_", * indicating a custom semantic - * + * * @return The {@link Semantic} string */ String getSemantic(); - + /** * Returns the value of this parameter - * + * * @return The value */ Object getValue(); - + /** * Returns the {@link NodeModel} of the node that this parameter - * refers to. This is, for example, used for computing the + * refers to. This is, for example, used for computing the * {@link Semantic#MODEL} matrix. - * + * * @return The {@link NodeModel} */ NodeModel getNodeModel(); diff --git a/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesFunctionsModel.java b/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesFunctionsModel.java index a78a1cc..a7a71a7 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesFunctionsModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesFunctionsModel.java @@ -29,88 +29,87 @@ /** * Interface for technique state function parameters.
*
- * Note: The method comments here are placeholders. For details, refer + * Note: The method comments here are placeholders. For details, refer * to the glTF 1.0 specification and an OpenGL documentation!
*
* Note: The methods in this interface may return references * to arrays that are stored internally. Callers should not store - * or modify the returned arrays! + * or modify the returned arrays! */ -public interface TechniqueStatesFunctionsModel -{ +public interface TechniqueStatesFunctionsModel { /** * Returns the blend color - * + * * @return The blend color */ float[] getBlendColor(); - + /** * Returns the blend equation - * + * * @return the blend equation */ int[] getBlendEquationSeparate(); - + /** * Returns the blend function - * + * * @return The blend function */ int[] getBlendFuncSeparate(); - + /** * Returns the color mask - * + * * @return The color mask */ boolean[] getColorMask(); - + /** * Returns the cull face - * + * * @return The cull face */ int[] getCullFace(); - + /** * Returns the depth func - * + * * @return The depth func */ int[] getDepthFunc(); - + /** * Returns the depth mask - * + * * @return The depth mask */ boolean[] getDepthMask(); - + /** * Returns the depth range - * + * * @return The depth range */ float[] getDepthRange(); - + /** * Returns the front face - * + * * @return The front face */ int[] getFrontFace(); - + /** * Returns the line width - * + * * @return The line width */ float[] getLineWidth(); - + /** * Returns the polygon offset - * + * * @return The polygon offset */ float[] getPolygonOffset(); diff --git a/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesModel.java b/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesModel.java index 58e1afa..304dbed 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesModel.java @@ -26,50 +26,47 @@ */ package de.javagl.jgltf.model.gl; +import de.javagl.jgltf.model.GltfConstants; + import java.util.Arrays; import java.util.List; -import de.javagl.jgltf.model.GltfConstants; - /** - * Interface for technique states. + * Interface for technique states. */ -public interface TechniqueStatesModel -{ +public interface TechniqueStatesModel { + /** + * Returns a list containing all possible states that may be contained + * in a technique.states.enable list. + * + * @return All possible states + */ + public static List getAllStates() { + List allStates = Arrays.asList( + GltfConstants.GL_BLEND, + GltfConstants.GL_CULL_FACE, + GltfConstants.GL_DEPTH_TEST, + GltfConstants.GL_POLYGON_OFFSET_FILL, + GltfConstants.GL_SAMPLE_ALPHA_TO_COVERAGE, + GltfConstants.GL_SCISSOR_TEST + ); + return allStates; + } + /** * Returns an unmodifiable list containing the enabled states, * or null if only the default states should be * enabled. - * + * * @return The enabled states */ List getEnable(); - + /** * Returns the {@link TechniqueStatesFunctionsModel}, or null * if the default technique states functions should be used. - * + * * @return The {@link TechniqueStatesFunctionsModel} */ TechniqueStatesFunctionsModel getTechniqueStatesFunctionsModel(); - - - /** - * Returns a list containing all possible states that may be contained - * in a technique.states.enable list. - * - * @return All possible states - */ - public static List getAllStates() - { - List allStates = Arrays.asList( - GltfConstants.GL_BLEND, - GltfConstants.GL_CULL_FACE, - GltfConstants.GL_DEPTH_TEST, - GltfConstants.GL_POLYGON_OFFSET_FILL, - GltfConstants.GL_SAMPLE_ALPHA_TO_COVERAGE, - GltfConstants.GL_SCISSOR_TEST - ); - return allStates; - } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultProgramModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultProgramModel.java index c813de6..74f6244 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultProgramModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultProgramModel.java @@ -26,91 +26,81 @@ */ package de.javagl.jgltf.model.gl.impl; +import de.javagl.jgltf.model.gl.ProgramModel; +import de.javagl.jgltf.model.gl.ShaderModel; +import de.javagl.jgltf.model.impl.AbstractNamedModelElement; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; -import de.javagl.jgltf.model.gl.ProgramModel; -import de.javagl.jgltf.model.gl.ShaderModel; -import de.javagl.jgltf.model.impl.AbstractNamedModelElement; - /** * Implementation of a {@link ProgramModel} */ public class DefaultProgramModel extends AbstractNamedModelElement - implements ProgramModel -{ + implements ProgramModel { + /** + * The attributes + */ + private final List attributes; /** * The vertex shader model */ private ShaderModel vertexShaderModel; - /** * The fragment shader model */ private ShaderModel fragmentShaderModel; - - /** - * The attributes - */ - private final List attributes; - + /** * Default constructor */ - public DefaultProgramModel() - { + public DefaultProgramModel() { this.attributes = new ArrayList(); } - + /** * Add the given attribute name to this program - * + * * @param attribute The attribute */ - public void addAttribute(String attribute) - { + public void addAttribute(String attribute) { attributes.add(attribute); } - + + @Override + public ShaderModel getVertexShaderModel() { + return vertexShaderModel; + } + /** * Set the vertex {@link ShaderModel} - * + * * @param vertexShaderModel The vertex {@link ShaderModel} */ - public void setVertexShaderModel(ShaderModel vertexShaderModel) - { + public void setVertexShaderModel(ShaderModel vertexShaderModel) { this.vertexShaderModel = Objects.requireNonNull(vertexShaderModel, - "The vertexShaderModel may not be null"); + "The vertexShaderModel may not be null"); } @Override - public ShaderModel getVertexShaderModel() - { - return vertexShaderModel; + public ShaderModel getFragmentShaderModel() { + return fragmentShaderModel; } - + /** * Set the fragment {@link ShaderModel} - * + * * @param fragmentShaderModel The fragment {@link ShaderModel} */ - public void setFragmentShaderModel(ShaderModel fragmentShaderModel) - { + public void setFragmentShaderModel(ShaderModel fragmentShaderModel) { this.fragmentShaderModel = Objects.requireNonNull(fragmentShaderModel, - "The fragmentShaderModel may not be null"); + "The fragmentShaderModel may not be null"); } @Override - public ShaderModel getFragmentShaderModel() - { - return fragmentShaderModel; - } - - @Override - public List getAttributes() - { + public List getAttributes() { return Collections.unmodifiableList(attributes); } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultShaderModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultShaderModel.java index 994147b..72028dd 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultShaderModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultShaderModel.java @@ -26,77 +26,68 @@ */ package de.javagl.jgltf.model.gl.impl; -import java.nio.ByteBuffer; - import de.javagl.jgltf.model.gl.ShaderModel; import de.javagl.jgltf.model.impl.AbstractNamedModelElement; import de.javagl.jgltf.model.io.Buffers; +import java.nio.ByteBuffer; + /** * Implementation of a {@link ShaderModel} */ public class DefaultShaderModel extends AbstractNamedModelElement - implements ShaderModel -{ + implements ShaderModel { /** - * The URI + * The URI */ private final String uri; - + /** + * The {@link ShaderType} + */ + private final ShaderType shaderType; /** * The actual raw shader data */ private ByteBuffer shaderData; /** - * The {@link de.javagl.jgltf.model.gl.ShaderModel.ShaderType} - */ - private final ShaderType shaderType; - - /** - * Default constructor - * - * @param uri The URI - * @param shaderType The - * {@link de.javagl.jgltf.model.gl.ShaderModel.ShaderType} + * Default constructor + * + * @param uri The URI + * @param shaderType The + * {@link ShaderType} */ - public DefaultShaderModel(String uri, ShaderType shaderType) - { + public DefaultShaderModel(String uri, ShaderType shaderType) { this.uri = uri; this.shaderType = shaderType; } - - /** - * Set the data of this shader - * - * @param shaderData The shader data - */ - public void setShaderData(ByteBuffer shaderData) - { - this.shaderData = shaderData; - } @Override - public String getUri() - { + public String getUri() { return uri; } @Override - public ByteBuffer getShaderData() - { + public ByteBuffer getShaderData() { return Buffers.createSlice(shaderData); } + /** + * Set the data of this shader + * + * @param shaderData The shader data + */ + public void setShaderData(ByteBuffer shaderData) { + this.shaderData = shaderData; + } + @Override - public String getShaderSource() - { + public String getShaderSource() { return Buffers.readAsString(shaderData); } - + @Override - public ShaderType getShaderType() - { + public ShaderType getShaderType() { return shaderType; } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueModel.java index c11e374..1044fcc 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueModel.java @@ -26,167 +26,149 @@ */ package de.javagl.jgltf.model.gl.impl; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; - import de.javagl.jgltf.model.gl.ProgramModel; import de.javagl.jgltf.model.gl.TechniqueModel; import de.javagl.jgltf.model.gl.TechniqueParametersModel; import de.javagl.jgltf.model.gl.TechniqueStatesModel; import de.javagl.jgltf.model.impl.AbstractNamedModelElement; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; + /** * Implementation of a {@link TechniqueModel} */ public class DefaultTechniqueModel extends AbstractNamedModelElement - implements TechniqueModel -{ - /** - * The {@link ProgramModel} - */ - private ProgramModel programModel; - + implements TechniqueModel { /** * The parameters */ private final Map parameters; - /** * The attributes */ private final Map attributes; - /** * The uniforms */ private final Map uniforms; - + /** + * The {@link ProgramModel} + */ + private ProgramModel programModel; /** * The {@link TechniqueStatesModel} */ private TechniqueStatesModel techniqueStatesModel; - + /** * Default constructor */ - public DefaultTechniqueModel() - { + public DefaultTechniqueModel() { this.parameters = new LinkedHashMap(); this.attributes = new LinkedHashMap(); this.uniforms = new LinkedHashMap(); } - + + @Override + public ProgramModel getProgramModel() { + return programModel; + } + /** * Set the {@link ProgramModel} - * + * * @param programModel The {@link ProgramModel} */ - public void setProgramModel(ProgramModel programModel) - { + public void setProgramModel(ProgramModel programModel) { this.programModel = programModel; } - - @Override - public ProgramModel getProgramModel() - { - return programModel; - } - + @Override - public Map getParameters() - { + public Map getParameters() { return Collections.unmodifiableMap(parameters); } - + /** * Add the given attribute to this technique - * + * * @param attributeName The attribute name * @param parameterName The parameter name */ - public void addAttribute(String attributeName, String parameterName) - { + public void addAttribute(String attributeName, String parameterName) { Objects.requireNonNull( - attributeName, "The attributeName may not be null"); + attributeName, "The attributeName may not be null"); Objects.requireNonNull( - parameterName, "The parameterName may not be null"); + parameterName, "The parameterName may not be null"); attributes.put(attributeName, parameterName); } - + /** * Add the given parameter to this technique - * - * @param parameterName The parameter name + * + * @param parameterName The parameter name * @param techniqueParametersModel The {@link TechniqueParametersModel} */ public void addParameter( - String parameterName, TechniqueParametersModel techniqueParametersModel) - { + String parameterName, TechniqueParametersModel techniqueParametersModel) { Objects.requireNonNull( - parameterName, "The parameterName may not be null"); - Objects.requireNonNull(techniqueParametersModel, - "The techniqueParametersModel may not be null"); + parameterName, "The parameterName may not be null"); + Objects.requireNonNull(techniqueParametersModel, + "The techniqueParametersModel may not be null"); parameters.put(parameterName, techniqueParametersModel); } @Override - public Map getAttributes() - { + public Map getAttributes() { return Collections.unmodifiableMap(attributes); } - + @Override - public TechniqueParametersModel getAttributeParameters(String attributeName) - { + public TechniqueParametersModel getAttributeParameters(String attributeName) { String parameterName = attributes.get(attributeName); return parameters.get(parameterName); } - + /** * Add the given uniform to this technique - * - * @param uniformName The uniform name + * + * @param uniformName The uniform name * @param parameterName The parameter name */ - public void addUniform(String uniformName, String parameterName) - { + public void addUniform(String uniformName, String parameterName) { Objects.requireNonNull( - uniformName, "The uniformName may not be null"); + uniformName, "The uniformName may not be null"); Objects.requireNonNull( - parameterName, "The parameterName may not be null"); + parameterName, "The parameterName may not be null"); uniforms.put(uniformName, parameterName); } - + @Override - public Map getUniforms() - { + public Map getUniforms() { return Collections.unmodifiableMap(uniforms); } @Override - public TechniqueParametersModel getUniformParameters(String uniformName) - { + public TechniqueParametersModel getUniformParameters(String uniformName) { String parameterName = uniforms.get(uniformName); return parameters.get(parameterName); } - + + @Override + public TechniqueStatesModel getTechniqueStatesModel() { + return techniqueStatesModel; + } + /** * Set the {@link TechniqueStatesModel} - * + * * @param techniqueStatesModel The {@link TechniqueStatesModel} */ public void setTechniqueStatesModel( - TechniqueStatesModel techniqueStatesModel) - { + TechniqueStatesModel techniqueStatesModel) { this.techniqueStatesModel = techniqueStatesModel; } - - @Override - public TechniqueStatesModel getTechniqueStatesModel() - { - return techniqueStatesModel; - } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueParametersModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueParametersModel.java index 2ffa9c1..e8e9c3e 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueParametersModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueParametersModel.java @@ -33,46 +33,44 @@ /** * Implementation of a {@link TechniqueParametersModel} */ -public class DefaultTechniqueParametersModel implements TechniqueParametersModel -{ +public class DefaultTechniqueParametersModel implements TechniqueParametersModel { /** * The type */ private final int type; - + /** * The count */ private final int count; - + /** * The {@link Semantic} semantic */ private final String semantic; - + /** * The value */ private final Object value; - + /** * The {@link NodeModel} */ private final NodeModel nodeModel; - + /** * Default constructor - * - * @param type The type - * @param count The count - * @param semantic The {@link Semantic} - * @param value The value + * + * @param type The type + * @param count The count + * @param semantic The {@link Semantic} + * @param value The value * @param nodeModel The {@link NodeModel} */ public DefaultTechniqueParametersModel( - int type, int count, String semantic, - Object value, NodeModel nodeModel) - { + int type, int count, String semantic, + Object value, NodeModel nodeModel) { this.type = type; this.count = count; this.semantic = semantic; @@ -81,32 +79,27 @@ public DefaultTechniqueParametersModel( } @Override - public int getType() - { + public int getType() { return type; } - + @Override - public int getCount() - { + public int getCount() { return count; } @Override - public String getSemantic() - { + public String getSemantic() { return semantic; } @Override - public Object getValue() - { + public Object getValue() { return value; } - + @Override - public NodeModel getNodeModel() - { + public NodeModel getNodeModel() { return nodeModel; } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesFunctionsModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesFunctionsModel.java index 5856c47..159a8db 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesFunctionsModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesFunctionsModel.java @@ -31,13 +31,12 @@ /** * Default implementation of a {@link TechniqueStatesFunctionsModel}.
*
- * Note: The method comments here are placeholders. For details, refer + * Note: The method comments here are placeholders. For details, refer * to the glTF 1.0 specification and an OpenGL documentation!
*
*/ public class DefaultTechniqueStatesFunctionsModel - implements TechniqueStatesFunctionsModel -{ + implements TechniqueStatesFunctionsModel { /** * The BlendColor */ @@ -96,14 +95,12 @@ public class DefaultTechniqueStatesFunctionsModel /** * Default constructor */ - public DefaultTechniqueStatesFunctionsModel() - { + public DefaultTechniqueStatesFunctionsModel() { // Default constructor } @Override - public float[] getBlendColor() - { + public float[] getBlendColor() { return blendColor; } @@ -112,14 +109,12 @@ public float[] getBlendColor() * * @param blendColor The BlendColor */ - public void setBlendColor(float[] blendColor) - { + public void setBlendColor(float[] blendColor) { this.blendColor = blendColor; } @Override - public int[] getBlendEquationSeparate() - { + public int[] getBlendEquationSeparate() { return blendEquationSeparate; } @@ -128,14 +123,12 @@ public int[] getBlendEquationSeparate() * * @param blendEquationSeparate The BlendEquationSeparate */ - public void setBlendEquationSeparate(int[] blendEquationSeparate) - { + public void setBlendEquationSeparate(int[] blendEquationSeparate) { this.blendEquationSeparate = blendEquationSeparate; } @Override - public int[] getBlendFuncSeparate() - { + public int[] getBlendFuncSeparate() { return blendFuncSeparate; } @@ -144,14 +137,12 @@ public int[] getBlendFuncSeparate() * * @param blendFuncSeparate The BlendFuncSeparate */ - public void setBlendFuncSeparate(int[] blendFuncSeparate) - { + public void setBlendFuncSeparate(int[] blendFuncSeparate) { this.blendFuncSeparate = blendFuncSeparate; } @Override - public boolean[] getColorMask() - { + public boolean[] getColorMask() { return colorMask; } @@ -160,14 +151,12 @@ public boolean[] getColorMask() * * @param colorMask The ColorMask */ - public void setColorMask(boolean[] colorMask) - { + public void setColorMask(boolean[] colorMask) { this.colorMask = colorMask; } @Override - public int[] getCullFace() - { + public int[] getCullFace() { return cullFace; } @@ -176,14 +165,12 @@ public int[] getCullFace() * * @param cullFace The CullFace */ - public void setCullFace(int[] cullFace) - { + public void setCullFace(int[] cullFace) { this.cullFace = cullFace; } @Override - public int[] getDepthFunc() - { + public int[] getDepthFunc() { return depthFunc; } @@ -192,14 +179,12 @@ public int[] getDepthFunc() * * @param depthFunc The DepthFunc */ - public void setDepthFunc(int[] depthFunc) - { + public void setDepthFunc(int[] depthFunc) { this.depthFunc = depthFunc; } @Override - public boolean[] getDepthMask() - { + public boolean[] getDepthMask() { return depthMask; } @@ -208,14 +193,12 @@ public boolean[] getDepthMask() * * @param depthMask The DepthMask */ - public void setDepthMask(boolean[] depthMask) - { + public void setDepthMask(boolean[] depthMask) { this.depthMask = depthMask; } @Override - public float[] getDepthRange() - { + public float[] getDepthRange() { return depthRange; } @@ -224,14 +207,12 @@ public float[] getDepthRange() * * @param depthRange The DepthRange */ - public void setDepthRange(float[] depthRange) - { + public void setDepthRange(float[] depthRange) { this.depthRange = depthRange; } @Override - public int[] getFrontFace() - { + public int[] getFrontFace() { return frontFace; } @@ -240,14 +221,12 @@ public int[] getFrontFace() * * @param frontFace The FrontFace */ - public void setFrontFace(int[] frontFace) - { + public void setFrontFace(int[] frontFace) { this.frontFace = frontFace; } @Override - public float[] getLineWidth() - { + public float[] getLineWidth() { return lineWidth; } @@ -256,14 +235,12 @@ public float[] getLineWidth() * * @param lineWidth The LineWidth */ - public void setLineWidth(float[] lineWidth) - { + public void setLineWidth(float[] lineWidth) { this.lineWidth = lineWidth; } @Override - public float[] getPolygonOffset() - { + public float[] getPolygonOffset() { return polygonOffset; } @@ -272,8 +249,7 @@ public float[] getPolygonOffset() * * @param polygonOffset The PolygonOffset */ - public void setPolygonOffset(float[] polygonOffset) - { + public void setPolygonOffset(float[] polygonOffset) { this.polygonOffset = polygonOffset; } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesModel.java index 7a95745..e359807 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesModel.java @@ -26,52 +26,47 @@ */ package de.javagl.jgltf.model.gl.impl; +import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; +import de.javagl.jgltf.model.gl.TechniqueStatesModel; + import java.util.ArrayList; import java.util.Collections; import java.util.List; -import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; -import de.javagl.jgltf.model.gl.TechniqueStatesModel; - /** * Implementation of a {@link TechniqueStatesModel} */ -public class DefaultTechniqueStatesModel implements TechniqueStatesModel -{ +public class DefaultTechniqueStatesModel implements TechniqueStatesModel { /** * The enabled states */ private final List enable; - + /** * The {@link TechniqueStatesFunctionsModel} */ private final TechniqueStatesFunctionsModel techniqueStatesFunctionsModel; - + /** * Default constructor - * - * @param enable The enabled states - * @param techniqueStatesFunctionsModel - * The {@link TechniqueStatesFunctionsModel} + * + * @param enable The enabled states + * @param techniqueStatesFunctionsModel The {@link TechniqueStatesFunctionsModel} */ - public DefaultTechniqueStatesModel(List enable, - TechniqueStatesFunctionsModel techniqueStatesFunctionsModel) - { + public DefaultTechniqueStatesModel(List enable, + TechniqueStatesFunctionsModel techniqueStatesFunctionsModel) { this.enable = Collections.unmodifiableList( - new ArrayList(enable)); + new ArrayList(enable)); this.techniqueStatesFunctionsModel = techniqueStatesFunctionsModel; } @Override - public List getEnable() - { + public List getEnable() { return enable; } @Override - public TechniqueStatesFunctionsModel getTechniqueStatesFunctionsModel() - { + public TechniqueStatesFunctionsModel getTechniqueStatesFunctionsModel() { return techniqueStatesFunctionsModel; } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/TechniqueStatesModels.java b/src/main/java/de/javagl/jgltf/model/gl/impl/TechniqueStatesModels.java index 5c04fad..ecbf0c2 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/TechniqueStatesModels.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/TechniqueStatesModels.java @@ -26,69 +26,65 @@ */ package de.javagl.jgltf.model.gl.impl; -import java.util.Arrays; -import java.util.List; - import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; import de.javagl.jgltf.model.GltfConstants; import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; import de.javagl.jgltf.model.gl.TechniqueStatesModel; import de.javagl.jgltf.model.v1.gl.TechniqueStatesFunctionsModels; +import java.util.Arrays; +import java.util.List; + /** * Methods to create {@link TechniqueStatesModel} instances */ -public class TechniqueStatesModels -{ +public class TechniqueStatesModels { + /** + * Private constructor to prevent instantiation + */ + private TechniqueStatesModels() { + // Private constructor to prevent instantiation + } + /** * Create a default {@link TechniqueStatesModel} - * + * * @return The {@link TechniqueStatesModel} */ - public static TechniqueStatesModel createDefault() - { - TechniqueStatesModel techniqueStatesModel = - new DefaultTechniqueStatesModel( - createDefaultTechniqueStatesEnable(), - createDefaultTechniqueStatesFunctions()); + public static TechniqueStatesModel createDefault() { + TechniqueStatesModel techniqueStatesModel = + new DefaultTechniqueStatesModel( + createDefaultTechniqueStatesEnable(), + createDefaultTechniqueStatesFunctions()); return techniqueStatesModel; } - + /** * Create the default {@link TechniqueStatesFunctionsModel} + * * @return The {@link TechniqueStatesFunctionsModel} */ - public static TechniqueStatesFunctionsModel - createDefaultTechniqueStatesFunctions() - { - TechniqueStatesFunctions functions = - de.javagl.jgltf.model.v1.gl.Techniques - .createDefaultTechniqueStatesFunctions(); + public static TechniqueStatesFunctionsModel + createDefaultTechniqueStatesFunctions() { + TechniqueStatesFunctions functions = + de.javagl.jgltf.model.v1.gl.Techniques + .createDefaultTechniqueStatesFunctions(); TechniqueStatesFunctionsModel techniqueStatesFunctionsModel = - TechniqueStatesFunctionsModels.create(functions); + TechniqueStatesFunctionsModels.create(functions); return techniqueStatesFunctionsModel; } - + /** * Returns the default {@link TechniqueStatesModel#getEnable() enable} - * states - * + * states + * * @return The default enable states */ - public static List createDefaultTechniqueStatesEnable() - { + public static List createDefaultTechniqueStatesEnable() { List enable = Arrays.asList( - GltfConstants.GL_DEPTH_TEST, - GltfConstants.GL_CULL_FACE + GltfConstants.GL_DEPTH_TEST, + GltfConstants.GL_CULL_FACE ); return enable; } - - /** - * Private constructor to prevent instantiation - */ - private TechniqueStatesModels() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/package-info.java b/src/main/java/de/javagl/jgltf/model/gl/impl/package-info.java index 7402989..bb2a352 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/package-info.java @@ -1,6 +1,6 @@ /** * Implementations of the de.javagl.jgltf.model.gl classes.
- *
+ *
* These classes should not be considered to be part of the public API. */ package de.javagl.jgltf.model.gl.impl; diff --git a/src/main/java/de/javagl/jgltf/model/gl/package-info.java b/src/main/java/de/javagl/jgltf/model/gl/package-info.java index e0ddcaf..3f5120f 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/gl/package-info.java @@ -1,5 +1,5 @@ /** - * Classes for modeling OpenGL rendering techniques. + * Classes for modeling OpenGL rendering techniques. */ package de.javagl.jgltf.model.gl; diff --git a/src/main/java/de/javagl/jgltf/model/image/DefaultPixelData.java b/src/main/java/de/javagl/jgltf/model/image/DefaultPixelData.java index 80a1963..752f6ec 100644 --- a/src/main/java/de/javagl/jgltf/model/image/DefaultPixelData.java +++ b/src/main/java/de/javagl/jgltf/model/image/DefaultPixelData.java @@ -31,52 +31,47 @@ /** * Default implementation of a {@link PixelData} */ -final class DefaultPixelData implements PixelData -{ +final class DefaultPixelData implements PixelData { /** * The width */ private final int width; - + /** * The height */ private final int height; - + /** * The pixels, as RGBA values */ private final ByteBuffer pixelsRGBA; - + /** * Creates a new instance - * - * @param width The width - * @param height The height + * + * @param width The width + * @param height The height * @param pixelsRGBA The pixels, as RGBA values */ - DefaultPixelData(int width, int height, ByteBuffer pixelsRGBA) - { + DefaultPixelData(int width, int height, ByteBuffer pixelsRGBA) { this.width = width; this.height = height; this.pixelsRGBA = pixelsRGBA; } - + @Override - public int getWidth() - { + public int getWidth() { return width; } @Override - public int getHeight() - { + public int getHeight() { return height; } @Override - public ByteBuffer getPixelsRGBA() - { + public ByteBuffer getPixelsRGBA() { // The slice is BIG_ENDIAN by default return pixelsRGBA.slice(); } diff --git a/src/main/java/de/javagl/jgltf/model/image/ImageReaders.java b/src/main/java/de/javagl/jgltf/model/image/ImageReaders.java index c2467c0..77dd47b 100644 --- a/src/main/java/de/javagl/jgltf/model/image/ImageReaders.java +++ b/src/main/java/de/javagl/jgltf/model/image/ImageReaders.java @@ -26,16 +26,15 @@ */ package de.javagl.jgltf.model.image; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.Iterator; +import de.javagl.jgltf.model.io.Buffers; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; - -import de.javagl.jgltf.model.io.Buffers; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.util.Iterator; /** * Utility methods to find ImageReader instances for given @@ -44,43 +43,39 @@ * This class should not be considered as part of the public API. It may * change or be omitted in the future. */ -public class ImageReaders -{ +public class ImageReaders { + /** + * Private constructor to prevent instantiation + */ + private ImageReaders() { + // Private constructor to prevent instantiation + } + /** * Tries to find an ImageReader that is capable of reading * the given image data. The returned image reader will be initialized * by passing an ImageInputStream that is created from the given data - * to its setInput method. The caller is responsible for + * to its setInput method. The caller is responsible for * disposing the returned image reader. - * + * * @param imageData The image data * @return The image reader * @throws IOException If no matching image reader can be found */ @SuppressWarnings("resource") - public static ImageReader findImageReader(ByteBuffer imageData) - throws IOException - { - InputStream inputStream = - Buffers.createByteBufferInputStream(imageData.slice()); - ImageInputStream imageInputStream = - ImageIO.createImageInputStream(inputStream); - Iterator imageReaders = - ImageIO.getImageReaders(imageInputStream); - if (imageReaders.hasNext()) - { + public static ImageReader findImageReader(ByteBuffer imageData) + throws IOException { + InputStream inputStream = + Buffers.createByteBufferInputStream(imageData.slice()); + ImageInputStream imageInputStream = + ImageIO.createImageInputStream(inputStream); + Iterator imageReaders = + ImageIO.getImageReaders(imageInputStream); + if (imageReaders.hasNext()) { ImageReader imageReader = imageReaders.next(); imageReader.setInput(imageInputStream); return imageReader; } throw new IOException("Could not find ImageReader for image data"); } - - /** - * Private constructor to prevent instantiation - */ - private ImageReaders() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/image/ImageUtils.java b/src/main/java/de/javagl/jgltf/model/image/ImageUtils.java index c10eead..cfa4cd2 100644 --- a/src/main/java/de/javagl/jgltf/model/image/ImageUtils.java +++ b/src/main/java/de/javagl/jgltf/model/image/ImageUtils.java @@ -26,7 +26,10 @@ */ package de.javagl.jgltf.model.image; -import java.awt.Graphics2D; +import de.javagl.jgltf.model.io.Buffers; + +import javax.imageio.ImageIO; +import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; @@ -38,45 +41,42 @@ import java.nio.IntBuffer; import java.util.logging.Logger; -import javax.imageio.ImageIO; - -import de.javagl.jgltf.model.io.Buffers; - /** * Utility methods related to images.
*
* This class should not be considered to be part of the public API. */ -public class ImageUtils -{ +public class ImageUtils { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(ImageUtils.class.getName()); - + private static final Logger logger = + Logger.getLogger(ImageUtils.class.getName()); + + /** + * Private constructor to prevent instantiation + */ + private ImageUtils() { + // Private constructor to prevent instantiation + } + /** * Returns the contents of the given buffer as a BufferedImage. * Returns null if the given buffer is null. * If the data can not be converted into a buffered image, then an error * message is printed and null is returned. - * + * * @param byteBuffer The byte buffer * @return The buffered image */ - static BufferedImage readAsBufferedImage(ByteBuffer byteBuffer) - { - if (byteBuffer == null) - { + static BufferedImage readAsBufferedImage(ByteBuffer byteBuffer) { + if (byteBuffer == null) { return null; } - try (InputStream inputStream = - Buffers.createByteBufferInputStream(byteBuffer.slice())) - { + try (InputStream inputStream = + Buffers.createByteBufferInputStream(byteBuffer.slice())) { return ImageIO.read(inputStream); - } - catch (IOException e) - { + } catch (IOException e) { logger.severe(e.toString()); return null; } @@ -87,32 +87,29 @@ static BufferedImage readAsBufferedImage(ByteBuffer byteBuffer) * the given image.
*
* The given image might become unmanaged/untrackable by this operation. - * - * @param inputImage The input image + * + * @param inputImage The input image * @param flipVertically Whether the contents of the image should be - * flipped vertically. This is always a hassle. + * flipped vertically. This is always a hassle. * @return The byte buffer containing the ARGB pixel values */ static ByteBuffer getImagePixelsARGB( - BufferedImage inputImage, boolean flipVertically) - { + BufferedImage inputImage, boolean flipVertically) { BufferedImage image = inputImage; - if (flipVertically) - { + if (flipVertically) { image = flipVertically(image); } - if (image.getType() != BufferedImage.TYPE_INT_ARGB) - { + if (image.getType() != BufferedImage.TYPE_INT_ARGB) { image = convertToARGB(image); } IntBuffer imageBuffer = getBuffer(image); - + // Note: The byte order is BIG_ENDIAN by default. This order // is kept here, to keep the ARGB order, and not convert them // to BGRA implicitly. ByteBuffer outputByteBuffer = ByteBuffer - .allocateDirect(imageBuffer.remaining() * Integer.BYTES) - .order(ByteOrder.BIG_ENDIAN); + .allocateDirect(imageBuffer.remaining() * Integer.BYTES) + .order(ByteOrder.BIG_ENDIAN); IntBuffer output = outputByteBuffer.asIntBuffer(); output.put(imageBuffer.slice()); return outputByteBuffer; @@ -121,211 +118,188 @@ static ByteBuffer getImagePixelsARGB( /** * Interpret the given byte buffer as ARGB pixels, and convert it into * a direct byte buffer containing the corresponding RGBA pixels - * + * * @param pixels The input pixels * @return The output pixels */ - static ByteBuffer swizzleARGBtoRGBA(ByteBuffer pixels) - { + static ByteBuffer swizzleARGBtoRGBA(ByteBuffer pixels) { return swizzle(pixels, 16, 8, 0, 24); } /** * Interpret the given byte buffer as RGBA pixels, and convert it into * a direct byte buffer containing the corresponding ARGB pixels - * + * * @param pixels The input pixels * @return The output pixels */ - static ByteBuffer swizzleRGBAtoARGB(ByteBuffer pixels) - { + static ByteBuffer swizzleRGBAtoARGB(ByteBuffer pixels) { return swizzle(pixels, 0, 24, 16, 8); } - + /** * Interpret the given byte buffer as pixels, swizzle the bytes - * of these pixels according to the given shifts, and return a + * of these pixels according to the given shifts, and return a * a direct byte buffer containing the corresponding new pixels - * + * * @param pixels The input pixels - * @param s0 The right-shift for byte 0 - * @param s1 The right-shift for byte 1 - * @param s2 The right-shift for byte 2 - * @param s3 The right-shift for byte 3 + * @param s0 The right-shift for byte 0 + * @param s1 The right-shift for byte 1 + * @param s2 The right-shift for byte 2 + * @param s3 The right-shift for byte 3 * @return The output pixels */ private static ByteBuffer swizzle(ByteBuffer pixels, - int s0, int s1, int s2, int s3) - { + int s0, int s1, int s2, int s3) { IntBuffer iBuffer = pixels.asIntBuffer(); ByteBuffer oByteBuffer = ByteBuffer - .allocateDirect(iBuffer.capacity() * Integer.BYTES) - .order(pixels.order()); + .allocateDirect(iBuffer.capacity() * Integer.BYTES) + .order(pixels.order()); IntBuffer oBuffer = oByteBuffer.asIntBuffer(); - for (int i = 0; i < iBuffer.capacity(); i++) - { + for (int i = 0; i < iBuffer.capacity(); i++) { int input = iBuffer.get(i); int output = swizzle(input, s0, s1, s2, s3); oBuffer.put(i, output); } return oByteBuffer; } - + /** * Swizzle the bytes of the given input according to the given shifts - * - * @param input The input - * @param s0 The right-shift for byte 0 - * @param s1 The right-shift for byte 1 - * @param s2 The right-shift for byte 2 - * @param s3 The right-shift for byte 3 + * + * @param input The input + * @param s0 The right-shift for byte 0 + * @param s1 The right-shift for byte 1 + * @param s2 The right-shift for byte 2 + * @param s3 The right-shift for byte 3 * @return The output */ - private static int swizzle(int input, int s0, int s1, int s2, int s3) - { - int b0 = (input >> s0) & 0xFF; - int b1 = (input >> s1) & 0xFF; - int b2 = (input >> s2) & 0xFF; + private static int swizzle(int input, int s0, int s1, int s2, int s3) { + int b0 = (input >> s0) & 0xFF; + int b1 = (input >> s1) & 0xFF; + int b2 = (input >> s2) & 0xFF; int b3 = (input >> s3) & 0xFF; return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; } - + /** * Convert the given image into a buffered image with the type * TYPE_INT_ARGB. - * + * * @param image The input image * @return The converted image */ - private static BufferedImage convertToARGB(BufferedImage image) - { + private static BufferedImage convertToARGB(BufferedImage image) { BufferedImage newImage = new BufferedImage( - image.getWidth(), image.getHeight(), - BufferedImage.TYPE_INT_ARGB); + image.getWidth(), image.getHeight(), + BufferedImage.TYPE_INT_ARGB); Graphics2D g = newImage.createGraphics(); g.drawImage(image, 0, 0, null); g.dispose(); return newImage; } - + /** - * Create a vertically flipped version of the given image. - * + * Create a vertically flipped version of the given image. + * * @param image The input image * @return The flipped image */ - private static BufferedImage flipVertically(BufferedImage image) - { + private static BufferedImage flipVertically(BufferedImage image) { int w = image.getWidth(); int h = image.getHeight(); BufferedImage newImage = new BufferedImage( - w, h, BufferedImage.TYPE_INT_ARGB); + w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g = newImage.createGraphics(); g.drawImage(image, 0, h, w, -h, null); g.dispose(); return newImage; } - + /** * Returns the data buffer of the given image as an IntBuffer. The given * image will become unmanaged/untrackable by this call. - * + * * @param image The image * @return The data from the image as an IntBuffer * @throws IllegalArgumentException If the given image is not - * backed by a DataBufferInt + * backed by a DataBufferInt */ - private static IntBuffer getBuffer(BufferedImage image) - { + private static IntBuffer getBuffer(BufferedImage image) { DataBuffer dataBuffer = image.getRaster().getDataBuffer(); - if (!(dataBuffer instanceof DataBufferInt)) - { + if (!(dataBuffer instanceof DataBufferInt)) { throw new IllegalArgumentException( - "Invalid buffer type in image, " + - "only TYPE_INT_* is allowed"); + "Invalid buffer type in image, " + + "only TYPE_INT_* is allowed"); } - DataBufferInt dataBufferInt = (DataBufferInt)dataBuffer; + DataBufferInt dataBufferInt = (DataBufferInt) dataBuffer; int data[] = dataBufferInt.getData(); IntBuffer intBuffer = IntBuffer.wrap(data); return intBuffer; } - + /** * Create a buffered image from the given {@link PixelData} - * + * * @param pixelData The {@link PixelData} * @return The buffered image */ - public static BufferedImage createBufferedImage(PixelData pixelData) - { + public static BufferedImage createBufferedImage(PixelData pixelData) { int w = pixelData.getWidth(); int h = pixelData.getHeight(); BufferedImage image = new BufferedImage( - w, h, BufferedImage.TYPE_INT_ARGB); + w, h, BufferedImage.TYPE_INT_ARGB); IntBuffer imageBuffer = getBuffer(image); ByteBuffer pixels = pixelData.getPixelsRGBA(); ByteBuffer argbBytes = swizzleRGBAtoARGB(pixels); imageBuffer.put(argbBytes.asIntBuffer()); return image; } - + /** * Creates the byte buffer containing the image data for the given * pixel data, with the given MIME type.
*
- * The MIME type must be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
+ * The MIME type must be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
*
* If the image data cannot be written, then an error message is * printed and null is returned. - * + * * @param pixelData The {@link PixelData} - * @param mimeType The MIME type + * @param mimeType The MIME type * @return The byte buffer * @throws IllegalArgumentException If the MIME type is not one of the - * types listed above + * types listed above */ public static ByteBuffer createImageDataBuffer( - PixelData pixelData, String mimeType) - { + PixelData pixelData, String mimeType) { String formatName = null; - if ("image/gif".equals(mimeType)) - { + if ("image/gif".equals(mimeType)) { formatName = "gif"; - } - else if ("image/jpeg".equals(mimeType)) - { + } else if ("image/jpeg".equals(mimeType)) { formatName = "jpg"; - } - else if ("image/png".equals(mimeType)) - { + } else if ("image/png".equals(mimeType)) { formatName = "png"; - } - else - { + } else { throw new IllegalArgumentException( - "The MIME type string must be \"image/gif\", " - + "\"image/jpeg\" or \"image/png\", but is " + mimeType); + "The MIME type string must be \"image/gif\", " + + "\"image/jpeg\" or \"image/png\", but is " + mimeType); } BufferedImage image = ImageUtils.createBufferedImage(pixelData); - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) - { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { ImageIO.write(image, formatName, baos); return Buffers.create(baos.toByteArray()); - } - catch (IOException e) - { + } catch (IOException e) { logger.severe(e.toString()); return null; } } - - + // Only a basic test for the swizzling @SuppressWarnings("javadoc") - public static void main(String[] args) - { + public static void main(String[] args) { int input = 0x11223344; ByteBuffer b0 = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN); b0.asIntBuffer().put(input); @@ -333,18 +307,10 @@ public static void main(String[] args) int rgba = b1.asIntBuffer().get(); ByteBuffer b2 = swizzleRGBAtoARGB(b1); int argb = b2.asIntBuffer().get(); - + System.out.println("Input: " + Integer.toHexString(input)); System.out.println("RGBA : " + Integer.toHexString(rgba)); System.out.println("ARGB : " + Integer.toHexString(argb)); } - /** - * Private constructor to prevent instantiation - */ - private ImageUtils() - { - // Private constructor to prevent instantiation - } - } diff --git a/src/main/java/de/javagl/jgltf/model/image/PixelData.java b/src/main/java/de/javagl/jgltf/model/image/PixelData.java index dc2e91b..581e15e 100644 --- a/src/main/java/de/javagl/jgltf/model/image/PixelData.java +++ b/src/main/java/de/javagl/jgltf/model/image/PixelData.java @@ -33,26 +33,25 @@ *
* This class should not be considered to be part of the public API. */ -public interface PixelData -{ +public interface PixelData { /** * Returns the width of the image - * + * * @return The width */ int getWidth(); /** * Returns the height of the image - * + * * @return The height */ int getHeight(); /** - * Returns a new slice of the direct byte buffer containing the pixel + * Returns a new slice of the direct byte buffer containing the pixel * data, as RGBA values - * + * * @return The pixels */ ByteBuffer getPixelsRGBA(); diff --git a/src/main/java/de/javagl/jgltf/model/image/PixelDatas.java b/src/main/java/de/javagl/jgltf/model/image/PixelDatas.java index d754b68..7f11dcf 100644 --- a/src/main/java/de/javagl/jgltf/model/image/PixelDatas.java +++ b/src/main/java/de/javagl/jgltf/model/image/PixelDatas.java @@ -37,54 +37,57 @@ *
* This class should not be considered to be part of the public API. */ -public class PixelDatas -{ +public class PixelDatas { /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(PixelDatas.class.getName()); - + Logger.getLogger(PixelDatas.class.getName()); + + /** + * Private constructor to prevent instantiation + */ + private PixelDatas() { + // Private constructor to prevent instantiation + } + /** * Create a {@link PixelData} from the given image data. The image data * may for example the the raw data of a JPG or PNG or GIF file. The * exact set of supported file formats is not specified. If the given * data can not be read, then a warning is printed and null * is returned. - * + * * @param imageData The image data * @return The {@link PixelData} */ - public static PixelData create(ByteBuffer imageData) - { + public static PixelData create(ByteBuffer imageData) { BufferedImage textureImage = ImageUtils.readAsBufferedImage(imageData); - if (textureImage == null) - { + if (textureImage == null) { logger.warning("Could not read image from image data"); return null; } - - ByteBuffer pixelDataARGB = - ImageUtils.getImagePixelsARGB(textureImage, false); + + ByteBuffer pixelDataARGB = + ImageUtils.getImagePixelsARGB(textureImage, false); ByteBuffer pixelDataRGBA = - ImageUtils.swizzleARGBtoRGBA(pixelDataARGB); + ImageUtils.swizzleARGBtoRGBA(pixelDataARGB); int width = textureImage.getWidth(); int height = textureImage.getHeight(); return new DefaultPixelData(width, height, pixelDataRGBA); } - + /** - * Create an unspecified {@link PixelData} object that may be used as + * Create an unspecified {@link PixelData} object that may be used as * a placeholder for image data that could not be read - * + * * @return The {@link PixelData} object */ - public static PixelData createErrorPixelData() - { + public static PixelData createErrorPixelData() { // Right now, this is a 2x2 checkerboard of red and white pixels ByteBuffer pixelDataRGBA = ByteBuffer.allocateDirect(4 * Integer.SIZE); - IntBuffer intPixelDataRGBA = - pixelDataRGBA.order(ByteOrder.BIG_ENDIAN).asIntBuffer(); + IntBuffer intPixelDataRGBA = + pixelDataRGBA.order(ByteOrder.BIG_ENDIAN).asIntBuffer(); intPixelDataRGBA.put(0, 0xFF0000FF); intPixelDataRGBA.put(1, 0xFFFFFFFF); intPixelDataRGBA.put(2, 0xFF0000FF); @@ -93,13 +96,4 @@ public static PixelData createErrorPixelData() int height = 2; return new DefaultPixelData(width, height, pixelDataRGBA); } - - - /** - * Private constructor to prevent instantiation - */ - private PixelDatas() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/AbstractModelElement.java b/src/main/java/de/javagl/jgltf/model/impl/AbstractModelElement.java index 8e915aa..ae96a25 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/AbstractModelElement.java +++ b/src/main/java/de/javagl/jgltf/model/impl/AbstractModelElement.java @@ -26,51 +26,38 @@ */ package de.javagl.jgltf.model.impl; +import de.javagl.jgltf.model.ModelElement; + import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; -import de.javagl.jgltf.model.ModelElement; - /** * Abstract base implementation of the {@link ModelElement} interface. */ -public class AbstractModelElement implements ModelElement -{ +public class AbstractModelElement implements ModelElement { /** * The extensions */ private Map extensions; - + /** * The extras */ private Object extras; - - /** - * Set the extensions to be a reference to the given map. - * - * @param extensions The extensions - */ - public void setExtensions(Map extensions) - { - this.extensions = extensions; - } - + /** * Add the given extension to this object. - * + *

* This will add the given key-value pair to the extensions map, * creating it if it was null. - * - * @param name The name of the extension + * + * @param name The name of the extension * @param extension The extension object */ - public void addExtension(String name, Object extension) - { + public void addExtension(String name, Object extension) { Objects.requireNonNull(name, "The name may not be null"); - if (this.extensions == null) - { + if (this.extensions == null) { this.extensions = new LinkedHashMap(); } this.extensions.put(name, extension); @@ -78,44 +65,46 @@ public void addExtension(String name, Object extension) /** * Remove the specified extension from this object. - * + *

* If the extension map is empty after this call, then it will be * set to null. - * + * * @param name The name of the extension */ - public void removeExtension(String name) - { - if (this.extensions != null) - { + public void removeExtension(String name) { + if (this.extensions != null) { this.extensions.remove(name); - if (this.extensions.isEmpty()) - { + if (this.extensions.isEmpty()) { this.extensions = null; } } } - - /** - * Set the extras - * - * @param extras The extras - */ - public void setExtras(Object extras) - { - this.extras = extras; - } - @Override - public Map getExtensions() - { + public Map getExtensions() { return extensions; } - + + /** + * Set the extensions to be a reference to the given map. + * + * @param extensions The extensions + */ + public void setExtensions(Map extensions) { + this.extensions = extensions; + } + @Override - public Object getExtras() - { + public Object getExtras() { return extras; } + + /** + * Set the extras + * + * @param extras The extras + */ + public void setExtras(Object extras) { + this.extras = extras; + } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/AbstractNamedModelElement.java b/src/main/java/de/javagl/jgltf/model/impl/AbstractNamedModelElement.java index e8ffe93..7acf52c 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/AbstractNamedModelElement.java +++ b/src/main/java/de/javagl/jgltf/model/impl/AbstractNamedModelElement.java @@ -31,28 +31,25 @@ /** * Abstract base implementation of the {@link NamedModelElement} interface. */ -public class AbstractNamedModelElement extends AbstractModelElement - implements NamedModelElement -{ +public class AbstractNamedModelElement extends AbstractModelElement + implements NamedModelElement { /** * The name */ private String name; - + @Override - public String getName() - { + public String getName() { return name; } - + /** - * Set the name of this model element, or null if this + * Set the name of this model element, or null if this * model element does not have a name. - * + * * @param name The optional name */ - public void setName(String name) - { + public void setName(String name) { this.name = name; } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/Cameras.java b/src/main/java/de/javagl/jgltf/model/impl/Cameras.java index debf755..2e091a0 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/Cameras.java +++ b/src/main/java/de/javagl/jgltf/model/impl/Cameras.java @@ -26,80 +26,72 @@ */ package de.javagl.jgltf.model.impl; -import java.util.logging.Logger; +import de.javagl.jgltf.model.*; -import de.javagl.jgltf.model.CameraModel; -import de.javagl.jgltf.model.CameraOrthographicModel; -import de.javagl.jgltf.model.CameraPerspectiveModel; -import de.javagl.jgltf.model.MathUtils; -import de.javagl.jgltf.model.Utils; +import java.util.logging.Logger; /** * Utility methods related to cameras */ -class Cameras -{ +class Cameras { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(Cameras.class.getName()); - + private static final Logger logger = + Logger.getLogger(Cameras.class.getName()); + + /** + * Private constructor to prevent instantiation + */ + private Cameras() { + // Private constructor to prevent instantiation + } + /** - * Compute the projection matrix for the given {@link CameraModel}. If the - * camera is neither perspective orthographic, then an error message will + * Compute the projection matrix for the given {@link CameraModel}. If the + * camera is neither perspective orthographic, then an error message will * be printed, and the result will be the identity matrix.
*
- * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * * @param cameraModel The {@link CameraModel} - * @param aspectRatio An optional aspect ratio to use. If this is - * null, then the aspect ratio of the camera will be used. - * @param result The array storing the result + * @param aspectRatio An optional aspect ratio to use. If this is + * null, then the aspect ratio of the camera will be used. + * @param result The array storing the result * @return The result array */ static float[] computeProjectionMatrix( - CameraModel cameraModel, Float aspectRatio, float result[]) - { + CameraModel cameraModel, Float aspectRatio, float result[]) { float localResult[] = Utils.validate(result, 16); - - CameraPerspectiveModel cameraPerspective = - cameraModel.getCameraPerspectiveModel(); - CameraOrthographicModel cameraOrthographic = - cameraModel.getCameraOrthographicModel(); - - if (cameraPerspective != null) - { + CameraPerspectiveModel cameraPerspective = + cameraModel.getCameraPerspectiveModel(); + + CameraOrthographicModel cameraOrthographic = + cameraModel.getCameraOrthographicModel(); + + if (cameraPerspective != null) { float fovRad = cameraPerspective.getYfov(); - float fovDeg = (float)Math.toDegrees(fovRad); + float fovDeg = (float) Math.toDegrees(fovRad); float localAspectRatio = 1.0f; - if (aspectRatio != null) - { + if (aspectRatio != null) { localAspectRatio = aspectRatio; - } - else if (cameraPerspective.getAspectRatio() != null) - { + } else if (cameraPerspective.getAspectRatio() != null) { localAspectRatio = cameraPerspective.getAspectRatio(); } float zNear = cameraPerspective.getZnear(); Float zFar = cameraPerspective.getZfar(); - if (zFar == null) - { + if (zFar == null) { MathUtils.infinitePerspective4x4( - fovDeg, localAspectRatio, zNear, localResult); - } - else - { + fovDeg, localAspectRatio, zNear, localResult); + } else { MathUtils.perspective4x4( - fovDeg, localAspectRatio, zNear, zFar, localResult); + fovDeg, localAspectRatio, zNear, zFar, localResult); } - } - else if (cameraOrthographic != null) - { + } else if (cameraOrthographic != null) { float xMag = cameraOrthographic.getXmag(); float yMag = cameraOrthographic.getYmag(); float zNear = cameraOrthographic.getZnear(); @@ -109,20 +101,10 @@ else if (cameraOrthographic != null) localResult[5] = 1.0f / yMag; localResult[10] = 2.0f / (zNear - zFar); localResult[14] = (zFar + zNear) / (zNear - zFar); - } - else - { + } else { logger.severe("Invalid camera type: " + cameraModel); MathUtils.setIdentity4x4(localResult); } return localResult; } - - /** - * Private constructor to prevent instantiation - */ - private Cameras() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultAccessorModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultAccessorModel.java index 947460f..1381898 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultAccessorModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultAccessorModel.java @@ -26,230 +26,195 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.AccessorData; -import de.javagl.jgltf.model.AccessorDatas; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.Accessors; -import de.javagl.jgltf.model.BufferViewModel; -import de.javagl.jgltf.model.ElementType; +import de.javagl.jgltf.model.*; /** * Implementation of an {@link AccessorModel} */ public final class DefaultAccessorModel extends AbstractNamedModelElement - implements AccessorModel -{ + implements AccessorModel { /** * The component type, as a GL constant */ private final int componentType; - + /** + * The {@link ElementType} of this accessor + */ + private final ElementType elementType; + /** + * The number of elements + */ + private final int count; /** * Whether the accessor is normalized */ private boolean normalized; - /** * The offset in bytes, referring to the buffer view */ private int byteOffset; - /** * The {@link BufferViewModel} for this model */ private BufferViewModel bufferViewModel; - - /** - * The {@link ElementType} of this accessor - */ - private final ElementType elementType; - - /** - * The number of elements - */ - private final int count; - /** * The stride between the start of one element and the next */ private int byteStride; - + /** * The {@link AccessorData} */ private AccessorData accessorData; - + /** * The minimum components */ private Number[] max; - + /** * The maximum components */ private Number[] min; - + /** * Creates a new instance - * + * * @param componentType The component type GL constant - * @param count The number of elements - * @param elementType The element type + * @param count The number of elements + * @param elementType The element type */ public DefaultAccessorModel( - int componentType, - int count, - ElementType elementType) - { + int componentType, + int count, + ElementType elementType) { this.componentType = componentType; this.count = count; this.elementType = elementType; this.byteStride = elementType.getByteStride(componentType); } - + + @Override + public BufferViewModel getBufferViewModel() { + return bufferViewModel; + } + /** * Set the {@link BufferViewModel} for this model - * + * * @param bufferViewModel The {@link BufferViewModel} */ - public void setBufferViewModel(BufferViewModel bufferViewModel) - { + public void setBufferViewModel(BufferViewModel bufferViewModel) { this.bufferViewModel = bufferViewModel; } - - /** - * Set the byte offset, referring to the {@link BufferViewModel} - * - * @param byteOffset The byte offset - */ - public void setByteOffset(int byteOffset) - { - this.byteOffset = byteOffset; - } - - /** - * Set the byte stride, indicating the number of bytes between the start - * of one element and the start of the next element. - * - * @param byteStride The byte stride - */ - public void setByteStride(int byteStride) - { - this.byteStride = byteStride; - } @Override - public BufferViewModel getBufferViewModel() - { - return bufferViewModel; - } - - @Override - public int getComponentType() - { + public int getComponentType() { return componentType; } - + @Override - public Class getComponentDataType() - { + public Class getComponentDataType() { return Accessors.getDataTypeForAccessorComponentType( - getComponentType()); + getComponentType()); } - + @Override - public boolean isNormalized() - { + public boolean isNormalized() { return normalized; } - + /** * Set whether the underlying data is normalized - * - * @param normalized Whether the underlying data is normalized + * + * @param normalized Whether the underlying data is normalized */ - public void setNormalized(boolean normalized) - { + public void setNormalized(boolean normalized) { this.normalized = normalized; } - + @Override - public int getComponentSizeInBytes() - { + public int getComponentSizeInBytes() { return Accessors.getNumBytesForAccessorComponentType(componentType); } - + @Override - public int getElementSizeInBytes() - { + public int getElementSizeInBytes() { return elementType.getNumComponents() * getComponentSizeInBytes(); } - + @Override - public int getPaddedElementSizeInBytes() - { + public int getPaddedElementSizeInBytes() { return elementType.getByteStride(componentType); } - + @Override - public int getByteOffset() - { + public int getByteOffset() { return byteOffset; } - + + /** + * Set the byte offset, referring to the {@link BufferViewModel} + * + * @param byteOffset The byte offset + */ + public void setByteOffset(int byteOffset) { + this.byteOffset = byteOffset; + } + @Override - public int getCount() - { + public int getCount() { return count; } - + @Override - public ElementType getElementType() - { + public ElementType getElementType() { return elementType; } - + @Override - public int getByteStride() - { + public int getByteStride() { return byteStride; } - + /** - * Set the {@link AccessorData} for this accessor - * - * @param accessorData The {@link AccessorData} + * Set the byte stride, indicating the number of bytes between the start + * of one element and the start of the next element. + * + * @param byteStride The byte stride */ - public void setAccessorData(AccessorData accessorData) - { - this.accessorData = accessorData; + public void setByteStride(int byteStride) { + this.byteStride = byteStride; } - + @Override - public AccessorData getAccessorData() - { + public AccessorData getAccessorData() { return accessorData; } - - + + /** + * Set the {@link AccessorData} for this accessor + * + * @param accessorData The {@link AccessorData} + */ + public void setAccessorData(AccessorData accessorData) { + this.accessorData = accessorData; + } + @Override - public Number[] getMin() - { - if (min == null) - { + public Number[] getMin() { + if (min == null) { min = AccessorDatas.computeMin(getAccessorData()); } return min.clone(); } - + @Override - public Number[] getMax() - { - if (max == null) - { + public Number[] getMax() { + if (max == null) { max = AccessorDatas.computeMax(getAccessorData()); } return max.clone(); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultAnimationModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultAnimationModel.java index 49dfc04..52a48f9 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultAnimationModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultAnimationModel.java @@ -26,171 +26,157 @@ */ package de.javagl.jgltf.model.impl; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.AnimationModel; +import de.javagl.jgltf.model.NodeModel; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.AnimationModel; -import de.javagl.jgltf.model.NodeModel; - /** * Implementation of an {@link AnimationModel} */ public class DefaultAnimationModel extends AbstractNamedModelElement - implements AnimationModel -{ + implements AnimationModel { + /** + * The {@link Channel} instances + * of this animation + */ + private final List channels; + + /** + * Creates a new instance + */ + public DefaultAnimationModel() { + this.channels = new ArrayList(); + } + + /** + * Add the given {@link Channel} + * + * @param channel The {@link Channel} + */ + public void addChannel(Channel channel) { + Objects.requireNonNull(channel, "The channel may not be null"); + this.channels.add(channel); + } + + @Override + public List getChannels() { + return Collections.unmodifiableList(channels); + } + /** - * Default implementation of a - * {@link de.javagl.jgltf.model.AnimationModel.Sampler} + * Default implementation of a + * {@link Sampler} */ - public static class DefaultSampler implements Sampler - { + public static class DefaultSampler implements Sampler { /** * The input data */ private final AccessorModel input; - + /** * The interpolation method */ private final Interpolation interpolation; - + /** * The output data */ private final AccessorModel output; - + /** * Default constructor - * - * @param input The input + * + * @param input The input * @param interpolation The interpolation - * @param output The output + * @param output The output */ public DefaultSampler( - AccessorModel input, - Interpolation interpolation, - AccessorModel output) - { + AccessorModel input, + Interpolation interpolation, + AccessorModel output) { this.input = Objects.requireNonNull( - input, "The input may not be null"); + input, "The input may not be null"); this.interpolation = Objects.requireNonNull( - interpolation, "The interpolation may not be null"); + interpolation, "The interpolation may not be null"); this.output = Objects.requireNonNull( - output, "The output may not be null"); + output, "The output may not be null"); } - + @Override - public AccessorModel getInput() - { + public AccessorModel getInput() { return input; } @Override - public Interpolation getInterpolation() - { + public Interpolation getInterpolation() { return interpolation; } @Override - public AccessorModel getOutput() - { + public AccessorModel getOutput() { return output; } } - + /** - * Default implementation of a - * {@link de.javagl.jgltf.model.AnimationModel.Channel} + * Default implementation of a + * {@link Channel} */ - public static class DefaultChannel implements Channel - { + public static class DefaultChannel implements Channel { /** * The sampler */ private final Sampler sampler; - + /** * The node model */ private final NodeModel nodeModel; - + /** * The path */ private final String path; - + /** * Default constructor - * - * @param sampler The sampler + * + * @param sampler The sampler * @param nodeModel The node model - * @param path The path + * @param path The path */ public DefaultChannel( - Sampler sampler, - NodeModel nodeModel, - String path) - { + Sampler sampler, + NodeModel nodeModel, + String path) { this.sampler = Objects.requireNonNull( - sampler, "The sampler may not be null"); + sampler, "The sampler may not be null"); this.nodeModel = nodeModel; this.path = Objects.requireNonNull( - path, "The path may not be null"); - + path, "The path may not be null"); + } - + @Override - public Sampler getSampler() - { + public Sampler getSampler() { return sampler; } @Override - public NodeModel getNodeModel() - { + public NodeModel getNodeModel() { return nodeModel; } @Override - public String getPath() - { + public String getPath() { return path; } - - } - - /** - * The {@link de.javagl.jgltf.model.AnimationModel.Channel} instances - * of this animation - */ - private final List channels; - - /** - * Creates a new instance - */ - public DefaultAnimationModel() - { - this.channels = new ArrayList(); - } - - /** - * Add the given {@link de.javagl.jgltf.model.AnimationModel.Channel} - * - * @param channel The {@link de.javagl.jgltf.model.AnimationModel.Channel} - */ - public void addChannel(Channel channel) - { - Objects.requireNonNull(channel, "The channel may not be null"); - this.channels.add(channel); - } - - @Override - public List getChannels() - { - return Collections.unmodifiableList(channels); + } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultAssetModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultAssetModel.java index eccf894..8bf40c8 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultAssetModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultAssetModel.java @@ -32,8 +32,7 @@ * Default implementation of an {@link AssetModel} */ public class DefaultAssetModel extends AbstractNamedModelElement - implements AssetModel -{ + implements AssetModel { /** * The copyright */ @@ -44,35 +43,31 @@ public class DefaultAssetModel extends AbstractNamedModelElement */ private String generator; + @Override + public String getCopyright() { + return copyright; + } + /** * Set the copyright - * + * * @param copyright The copyright */ - public void setCopyright(String copyright) - { + public void setCopyright(String copyright) { this.copyright = copyright; } @Override - public String getCopyright() - { - return copyright; + public String getGenerator() { + return generator; } /** * Set the generator - * + * * @param generator The generator */ - public void setGenerator(String generator) - { + public void setGenerator(String generator) { this.generator = generator; } - - @Override - public String getGenerator() - { - return generator; - } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferModel.java index 62f63e4..087bfd1 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferModel.java @@ -26,71 +26,64 @@ */ package de.javagl.jgltf.model.impl; -import java.nio.ByteBuffer; - import de.javagl.jgltf.model.BufferModel; import de.javagl.jgltf.model.io.Buffers; +import java.nio.ByteBuffer; + /** * Implementation of a {@link BufferModel} */ public final class DefaultBufferModel extends AbstractNamedModelElement - implements BufferModel -{ + implements BufferModel { /** * The URI of the buffer data */ private String uri; - + /** * The actual data of the buffer */ private ByteBuffer bufferData; - + /** * Creates a new instance */ - public DefaultBufferModel() - { + public DefaultBufferModel() { // Default constructor } - + + @Override + public String getUri() { + return uri; + } + /** * Set the URI for the buffer data - * + * * @param uri The URI of the buffer data */ - public void setUri(String uri) - { + public void setUri(String uri) { this.uri = uri; } + @Override + public int getByteLength() { + return bufferData.capacity(); + } + + @Override + public ByteBuffer getBufferData() { + return Buffers.createSlice(bufferData); + } + /** * Set the data of this buffer - * + * * @param bufferData The buffer data */ - public void setBufferData(ByteBuffer bufferData) - { + public void setBufferData(ByteBuffer bufferData) { this.bufferData = bufferData; } - - @Override - public String getUri() - { - return uri; - } - @Override - public int getByteLength() - { - return bufferData.capacity(); - } - - @Override - public ByteBuffer getBufferData() - { - return Buffers.createSlice(bufferData); - } - } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferViewModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferViewModel.java index 4eccc9b..2405fe8 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferViewModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferViewModel.java @@ -26,166 +26,146 @@ */ package de.javagl.jgltf.model.impl; -import java.nio.ByteBuffer; -import java.util.function.Consumer; - import de.javagl.jgltf.model.BufferModel; import de.javagl.jgltf.model.BufferViewModel; import de.javagl.jgltf.model.io.Buffers; +import java.nio.ByteBuffer; +import java.util.function.Consumer; + /** * Implementation of a {@link BufferViewModel} */ public final class DefaultBufferViewModel extends AbstractNamedModelElement - implements BufferViewModel -{ + implements BufferViewModel { + /** + * The optional target + */ + private final Integer target; /** * The {@link BufferModel} for this model */ private BufferModel bufferModel; - /** * The byte offset */ private int byteOffset; - /** * The byte length */ private int byteLength; - /** * The byte stride */ private Integer byteStride; - - /** - * The optional target - */ - private final Integer target; - /** * An optional callback that will be used to perform the - * substitution of sparse accessor data in the + * substitution of sparse accessor data in the * {@link #getBufferViewData() buffer view data} - * when it is obtained for the first time. + * when it is obtained for the first time. */ private Consumer sparseSubstitutionCallback; - + /** * Whether the sparse substitution was already applied */ private boolean sparseSubstitutionApplied; - + /** * Creates a new instance - * + * * @param target The optional target */ - public DefaultBufferViewModel(Integer target) - { + public DefaultBufferViewModel(Integer target) { this.byteOffset = 0; this.byteLength = 0; this.target = target; } - + /** - * Set the callback that will perform the substitution of sparse accessor - * data in the {@link #getBufferViewData() buffer view data} when it is + * Set the callback that will perform the substitution of sparse accessor + * data in the {@link #getBufferViewData() buffer view data} when it is * obtained for the first time. - * + * * @param sparseSubstitutionCallback The callback */ public void setSparseSubstitutionCallback( - Consumer sparseSubstitutionCallback) - { + Consumer sparseSubstitutionCallback) { this.sparseSubstitutionCallback = sparseSubstitutionCallback; } - + + @Override + public ByteBuffer getBufferViewData() { + ByteBuffer bufferData = bufferModel.getBufferData(); + ByteBuffer bufferViewData = + Buffers.createSlice(bufferData, getByteOffset(), getByteLength()); + if (sparseSubstitutionCallback != null && !sparseSubstitutionApplied) { + sparseSubstitutionCallback.accept(bufferViewData); + sparseSubstitutionApplied = true; + } + return bufferViewData; + } + + @Override + public BufferModel getBufferModel() { + return bufferModel; + } + /** * Set the {@link BufferModel} for this model - * + * * @param bufferModel The {@link BufferModel} */ - public void setBufferModel(BufferModel bufferModel) - { + public void setBufferModel(BufferModel bufferModel) { this.bufferModel = bufferModel; } - + + @Override + public int getByteOffset() { + return byteOffset; + } + /** * Set the byte offset of this view referring to its {@link BufferModel} - * + * * @param byteOffset The byte offset */ - public void setByteOffset(int byteOffset) - { + public void setByteOffset(int byteOffset) { this.byteOffset = byteOffset; } + @Override + public int getByteLength() { + return byteLength; + } + /** * Set the byte length of this buffer view - * + * * @param byteLength The byte length */ - public void setByteLength(int byteLength) - { + public void setByteLength(int byteLength) { this.byteLength = byteLength; } + @Override + public Integer getByteStride() { + return byteStride; + } + /** - * Set the optional byte stride. This byte stride must be + * Set the optional byte stride. This byte stride must be * non-null if more than one accessor refers * to this buffer view. - * + * * @param byteStride The byte stride */ - public void setByteStride(Integer byteStride) - { + public void setByteStride(Integer byteStride) { this.byteStride = byteStride; } - - - @Override - public ByteBuffer getBufferViewData() - { - ByteBuffer bufferData = bufferModel.getBufferData(); - ByteBuffer bufferViewData = - Buffers.createSlice(bufferData, getByteOffset(), getByteLength()); - if (sparseSubstitutionCallback != null && !sparseSubstitutionApplied) - { - sparseSubstitutionCallback.accept(bufferViewData); - sparseSubstitutionApplied = true; - } - return bufferViewData; - } - - @Override - public BufferModel getBufferModel() - { - return bufferModel; - } - - @Override - public int getByteOffset() - { - return byteOffset; - } - - @Override - public int getByteLength() - { - return byteLength; - } - - @Override - public Integer getByteStride() - { - return byteStride; - } @Override - public Integer getTarget() - { + public Integer getTarget() { return target; } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraModel.java index b4f21d5..fb446ce 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraModel.java @@ -26,92 +26,83 @@ */ package de.javagl.jgltf.model.impl; -import java.util.function.DoubleSupplier; -import java.util.function.Supplier; - import de.javagl.jgltf.model.CameraModel; import de.javagl.jgltf.model.CameraOrthographicModel; import de.javagl.jgltf.model.CameraPerspectiveModel; import de.javagl.jgltf.model.Suppliers; +import java.util.function.DoubleSupplier; +import java.util.function.Supplier; + /** - * Implementation of a {@link CameraModel} + * Implementation of a {@link CameraModel} */ public final class DefaultCameraModel extends AbstractNamedModelElement - implements CameraModel -{ + implements CameraModel { /** * The {@link CameraOrthographicModel} */ private CameraOrthographicModel cameraOrthographicModel; - + /** * The {@link CameraPerspectiveModel} */ private CameraPerspectiveModel cameraPerspectiveModel; - + /** * Creates a new instance */ - public DefaultCameraModel() - { + public DefaultCameraModel() { // Default constructor } - + + @Override + public CameraOrthographicModel getCameraOrthographicModel() { + return cameraOrthographicModel; + } + /** * Set the {@link CameraOrthographicModel} - * + * * @param cameraOrthographicModel The {@link CameraOrthographicModel} */ public void setCameraOrthographicModel( - CameraOrthographicModel cameraOrthographicModel) - { + CameraOrthographicModel cameraOrthographicModel) { this.cameraOrthographicModel = cameraOrthographicModel; } - + @Override - public CameraOrthographicModel getCameraOrthographicModel() - { - return cameraOrthographicModel; + public CameraPerspectiveModel getCameraPerspectiveModel() { + return cameraPerspectiveModel; } - + /** * Set the {@link CameraPerspectiveModel} - * + * * @param cameraPerspectiveModel The {@link CameraPerspectiveModel} */ public void setCameraPerspectiveModel( - CameraPerspectiveModel cameraPerspectiveModel) - { + CameraPerspectiveModel cameraPerspectiveModel) { this.cameraPerspectiveModel = cameraPerspectiveModel; } - - @Override - public CameraPerspectiveModel getCameraPerspectiveModel() - { - return cameraPerspectiveModel; - } @Override - public float[] computeProjectionMatrix(float result[], Float aspectRatio) - { + public float[] computeProjectionMatrix(float result[], Float aspectRatio) { return Cameras.computeProjectionMatrix(this, aspectRatio, result); } - + @Override public Supplier createProjectionMatrixSupplier( - DoubleSupplier aspectRatioSupplier) - { - return Suppliers.createTransformSupplier(this, (c, t) -> + DoubleSupplier aspectRatioSupplier) { + return Suppliers.createTransformSupplier(this, (c, t) -> { Float aspectRatio = null; - if (aspectRatioSupplier != null) - { - aspectRatio = (float)aspectRatioSupplier.getAsDouble(); + if (aspectRatioSupplier != null) { + aspectRatio = (float) aspectRatioSupplier.getAsDouble(); } computeProjectionMatrix(t, aspectRatio); }); } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraOrthographicModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraOrthographicModel.java index 0f6ced7..c52b1d2 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraOrthographicModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraOrthographicModel.java @@ -31,8 +31,7 @@ /** * Default implementation of a {@link CameraOrthographicModel} */ -public class DefaultCameraOrthographicModel implements CameraOrthographicModel -{ +public class DefaultCameraOrthographicModel implements CameraOrthographicModel { /** * The magnification in x-direction */ @@ -53,69 +52,61 @@ public class DefaultCameraOrthographicModel implements CameraOrthographicModel */ private Float znear; + @Override + public Float getXmag() { + return xmag; + } + /** * Set the magnification in x-direction - * + * * @param xmag The magnification */ - public void setXmag(Float xmag) - { + public void setXmag(Float xmag) { this.xmag = xmag; } + @Override + public Float getYmag() { + return ymag; + } + /** * Set the magnification in y-direction - * + * * @param ymag The magnification */ - public void setYmag(Float ymag) - { + public void setYmag(Float ymag) { this.ymag = ymag; } + @Override + public Float getZfar() { + return zfar; + } + /** * Set the far clipping plane distance - * + * * @param zfar The distance */ - public void setZfar(Float zfar) - { + public void setZfar(Float zfar) { this.zfar = zfar; } + @Override + public Float getZnear() { + return znear; + } + /** * Set the near clipping plane distance - * + * * @param znear The distance */ - public void setZnear(Float znear) - { + public void setZnear(Float znear) { this.znear = znear; } - - @Override - public Float getXmag() - { - return xmag; - } - - @Override - public Float getYmag() - { - return ymag; - } - - @Override - public Float getZfar() - { - return zfar; - } - - @Override - public Float getZnear() - { - return znear; - } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraPerspectiveModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraPerspectiveModel.java index 6fdd0bc..0b190b9 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraPerspectiveModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraPerspectiveModel.java @@ -31,8 +31,7 @@ /** * Default implementation of a {@link CameraPerspectiveModel} */ -public class DefaultCameraPerspectiveModel implements CameraPerspectiveModel -{ +public class DefaultCameraPerspectiveModel implements CameraPerspectiveModel { /** * The aspect ratio */ @@ -53,69 +52,61 @@ public class DefaultCameraPerspectiveModel implements CameraPerspectiveModel */ private Float znear; + @Override + public Float getAspectRatio() { + return aspectRatio; + } + /** * Set the aspect ratio - * + * * @param aspectRatio The aspect ratio */ - public void setAspectRatio(Float aspectRatio) - { + public void setAspectRatio(Float aspectRatio) { this.aspectRatio = aspectRatio; } + @Override + public Float getYfov() { + return yfov; + } + /** * Set the FOV - * + * * @param yfov The FOV */ - public void setYfov(Float yfov) - { + public void setYfov(Float yfov) { this.yfov = yfov; } + @Override + public Float getZfar() { + return zfar; + } + /** * Set the far clipping plane distance - * + * * @param zfar The distance */ - public void setZfar(Float zfar) - { + public void setZfar(Float zfar) { this.zfar = zfar; } + @Override + public Float getZnear() { + return znear; + } + /** * Set the near clipping plane distance - * + * * @param znear The distance */ - public void setZnear(Float znear) - { + public void setZnear(Float znear) { this.znear = znear; } - - @Override - public Float getAspectRatio() - { - return aspectRatio; - } - - @Override - public Float getYfov() - { - return yfov; - } - - @Override - public Float getZfar() - { - return zfar; - } - - @Override - public Float getZnear() - { - return znear; - } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultExtensionsModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultExtensionsModel.java index 9823d9f..ef4e172 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultExtensionsModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultExtensionsModel.java @@ -26,18 +26,13 @@ */ package de.javagl.jgltf.model.impl; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - import de.javagl.jgltf.model.ExtensionsModel; +import java.util.*; + /** * Default implementation of an {@link ExtensionsModel}. - * + *

* This implementation ensures a certain degree of consistency for * the extension information: *

    @@ -52,11 +47,10 @@ * *
* (Of course, adding a "used" extension will not add it as a "required" one, - * and removing a "required" extension will not remove it as - * a "used" extension) + * and removing a "required" extension will not remove it as + * a "used" extension) */ -public class DefaultExtensionsModel implements ExtensionsModel -{ +public class DefaultExtensionsModel implements ExtensionsModel { /** * The used extensions */ @@ -70,43 +64,38 @@ public class DefaultExtensionsModel implements ExtensionsModel /** * Default constructor */ - public DefaultExtensionsModel() - { + public DefaultExtensionsModel() { this.extensionsUsed = new LinkedHashSet(); this.extensionsRequired = new LinkedHashSet(); } /** * Add the given extension name to the "used" extensions. - * + * * @param extension The extension name. */ - public void addExtensionUsed(String extension) - { + public void addExtensionUsed(String extension) { this.extensionsUsed.add(extension); } /** * Remove the given extension name from the "used" extensions and * from the list of "required" extensions. - * + * * @param extension The extension name. */ - public void removeExtensionUsed(String extension) - { + public void removeExtensionUsed(String extension) { this.extensionsUsed.remove(extension); removeExtensionRequired(extension); } /** * Add the given extension names to the "used" extensions. - * + * * @param extensions The extension names */ - public void addExtensionsUsed(Collection extensions) - { - if (extensions != null) - { + public void addExtensionsUsed(Collection extensions) { + if (extensions != null) { this.extensionsUsed.addAll(extensions); } } @@ -114,55 +103,49 @@ public void addExtensionsUsed(Collection extensions) /** * Clear the list of "used" extensions and the list of "required" extensions */ - public void clearExtensionUsed() - { + public void clearExtensionUsed() { this.extensionsUsed.clear(); clearExtensionRequired(); } @Override - public List getExtensionsUsed() - { + public List getExtensionsUsed() { return Collections.unmodifiableList( - new ArrayList(extensionsUsed)); + new ArrayList(extensionsUsed)); } - + /** * Add the given extension name to the "required" extensions and to * the "used" extensions. - * + * * @param extension The extension name. */ - public void addExtensionRequired(String extension) - { + public void addExtensionRequired(String extension) { this.extensionsRequired.add(extension); addExtensionUsed(extension); } /** * Remove the given extension name from the "required" extensions. - * + *

* (Note that this will not remove the given extension name * from the "used" extensions!) - * + * * @param extension The extension name. */ - public void removeExtensionRequired(String extension) - { + public void removeExtensionRequired(String extension) { this.extensionsRequired.remove(extension); } /** * Add the given extension names to the "required" extensions and to * the "used" extensions. - * + * * @param extensions The extension names */ - public void addExtensionsRequired(Collection extensions) - { - if (extensions != null) - { + public void addExtensionsRequired(Collection extensions) { + if (extensions != null) { this.extensionsRequired.addAll(extensions); addExtensionsUsed(extensions); } @@ -171,16 +154,14 @@ public void addExtensionsRequired(Collection extensions) /** * Clear the list of "required" extensions. */ - public void clearExtensionRequired() - { + public void clearExtensionRequired() { this.extensionsRequired.clear(); } - + @Override - public List getExtensionsRequired() - { + public List getExtensionsRequired() { return Collections.unmodifiableList( - new ArrayList(extensionsRequired)); + new ArrayList(extensionsRequired)); } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultGltfModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultGltfModel.java index 9ddd532..4f236e3 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultGltfModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultGltfModel.java @@ -26,32 +26,17 @@ */ package de.javagl.jgltf.model.impl; +import de.javagl.jgltf.model.*; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.AnimationModel; -import de.javagl.jgltf.model.AssetModel; -import de.javagl.jgltf.model.BufferModel; -import de.javagl.jgltf.model.BufferViewModel; -import de.javagl.jgltf.model.CameraModel; -import de.javagl.jgltf.model.ExtensionsModel; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.ImageModel; -import de.javagl.jgltf.model.MaterialModel; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.SceneModel; -import de.javagl.jgltf.model.SkinModel; -import de.javagl.jgltf.model.TextureModel; - /** * Default implementation of a {@link GltfModel}.
*/ -public class DefaultGltfModel extends AbstractModelElement implements GltfModel -{ +public class DefaultGltfModel extends AbstractModelElement implements GltfModel { /** * The {@link AccessorModel} instances */ @@ -61,7 +46,7 @@ public class DefaultGltfModel extends AbstractModelElement implements GltfModel * The {@link AnimationModel} instances */ private final List animationModels; - + /** * The {@link BufferModel} instances */ @@ -71,7 +56,7 @@ public class DefaultGltfModel extends AbstractModelElement implements GltfModel * The {@link BufferViewModel} instances */ private final List bufferViewModels; - + /** * The {@link CameraModel} instances */ @@ -86,7 +71,7 @@ public class DefaultGltfModel extends AbstractModelElement implements GltfModel * The {@link MaterialModel} instances */ private final List materialModels; - + /** * The {@link MeshModel} instances */ @@ -111,22 +96,21 @@ public class DefaultGltfModel extends AbstractModelElement implements GltfModel * The {@link TextureModel} instances */ private final List textureModels; - + /** * The {@link ExtensionsModel} */ private final DefaultExtensionsModel extensionsModel; - + /** * The {@link AssetModel} */ private final DefaultAssetModel assetModel; /** - * Creates a new model + * Creates a new model */ - public DefaultGltfModel() - { + public DefaultGltfModel() { this.accessorModels = new ArrayList(); this.animationModels = new ArrayList(); this.bufferModels = new ArrayList(); @@ -142,37 +126,33 @@ public DefaultGltfModel() this.extensionsModel = new DefaultExtensionsModel(); this.assetModel = new DefaultAssetModel(); } - + /** * Add the given {@link AccessorModel} to this model - * + * * @param accessorModel The object to add */ - public void addAccessorModel(DefaultAccessorModel accessorModel) - { + public void addAccessorModel(DefaultAccessorModel accessorModel) { accessorModels.add(accessorModel); } /** * Remove the given {@link AccessorModel} from this model - * + * * @param accessorModel The object to remove */ - public void removeAccessorModel(DefaultAccessorModel accessorModel) - { + public void removeAccessorModel(DefaultAccessorModel accessorModel) { accessorModels.remove(accessorModel); } /** * Add the given {@link AccessorModel} instances to this model - * + * * @param accessorModels The objects to add */ public void addAccessorModels( - Collection accessorModels) - { - for (DefaultAccessorModel accessorModel : accessorModels) - { + Collection accessorModels) { + for (DefaultAccessorModel accessorModel : accessorModels) { addAccessorModel(accessorModel); } } @@ -183,32 +163,28 @@ public void addAccessorModels( * @param index The index * @return The {@link AccessorModel} */ - public DefaultAccessorModel getAccessorModel(int index) - { + public DefaultAccessorModel getAccessorModel(int index) { return accessorModels.get(index); } /** * Remove all {@link AccessorModel} instances */ - public void clearAccessorModels() - { + public void clearAccessorModels() { accessorModels.clear(); } @Override - public List getAccessorModels() - { + public List getAccessorModels() { return Collections.unmodifiableList(accessorModels); } - + /** * Add the given {@link AnimationModel} to this model * * @param animationModel The instance to add */ - public void addAnimationModel(DefaultAnimationModel animationModel) - { + public void addAnimationModel(DefaultAnimationModel animationModel) { animationModels.add(animationModel); } @@ -217,8 +193,7 @@ public void addAnimationModel(DefaultAnimationModel animationModel) * * @param animationModel The instance to remove */ - public void removeAnimationModel(DefaultAnimationModel animationModel) - { + public void removeAnimationModel(DefaultAnimationModel animationModel) { animationModels.remove(animationModel); } @@ -228,10 +203,8 @@ public void removeAnimationModel(DefaultAnimationModel animationModel) * @param animationModels The instances to add */ public void addAnimationModels( - Collection animationModels) - { - for (DefaultAnimationModel animationModel : animationModels) - { + Collection animationModels) { + for (DefaultAnimationModel animationModel : animationModels) { addAnimationModel(animationModel); } } @@ -242,55 +215,48 @@ public void addAnimationModels( * @param index The index * @return The {@link AnimationModel} */ - public DefaultAnimationModel getAnimationModel(int index) - { + public DefaultAnimationModel getAnimationModel(int index) { return animationModels.get(index); } /** * Remove all {@link AnimationModel} instances */ - public void clearAnimationModels() - { + public void clearAnimationModels() { animationModels.clear(); } @Override - public List getAnimationModels() - { + public List getAnimationModels() { return Collections.unmodifiableList(animationModels); } - + /** * Add the given {@link BufferModel} to this model - * + * * @param bufferModel The instance to add */ - public void addBufferModel(DefaultBufferModel bufferModel) - { + public void addBufferModel(DefaultBufferModel bufferModel) { bufferModels.add(bufferModel); } /** * Remove the given {@link BufferModel} from this model - * + * * @param bufferModel The instance to remove */ - public void removeBufferModel(DefaultBufferModel bufferModel) - { + public void removeBufferModel(DefaultBufferModel bufferModel) { bufferModels.remove(bufferModel); } /** * Add the given {@link BufferModel} instances to this model - * + * * @param bufferModels The instances to add */ public void addBufferModels( - Collection bufferModels) - { - for (DefaultBufferModel bufferModel : bufferModels) - { + Collection bufferModels) { + for (DefaultBufferModel bufferModel : bufferModels) { addBufferModel(bufferModel); } } @@ -301,55 +267,48 @@ public void addBufferModels( * @param index The index * @return The {@link BufferModel} */ - public DefaultBufferModel getBufferModel(int index) - { + public DefaultBufferModel getBufferModel(int index) { return bufferModels.get(index); } /** * Remove all {@link BufferModel} instances */ - public void clearBufferModels() - { + public void clearBufferModels() { bufferModels.clear(); } @Override - public List getBufferModels() - { + public List getBufferModels() { return Collections.unmodifiableList(bufferModels); } - + /** * Add the given {@link BufferViewModel} to this model - * + * * @param bufferViewModel The instance to add */ - public void addBufferViewModel(DefaultBufferViewModel bufferViewModel) - { + public void addBufferViewModel(DefaultBufferViewModel bufferViewModel) { bufferViewModels.add(bufferViewModel); } /** * Remove the given {@link BufferViewModel} from this model - * + * * @param bufferViewModel The instance to remove */ - public void removeBufferViewModel(DefaultBufferViewModel bufferViewModel) - { + public void removeBufferViewModel(DefaultBufferViewModel bufferViewModel) { bufferViewModels.remove(bufferViewModel); } /** * Add the given {@link BufferViewModel} instances to this model - * + * * @param bufferViewModels The instances to add */ public void addBufferViewModels( - Collection bufferViewModels) - { - for (DefaultBufferViewModel bufferViewModel : bufferViewModels) - { + Collection bufferViewModels) { + for (DefaultBufferViewModel bufferViewModel : bufferViewModels) { addBufferViewModel(bufferViewModel); } } @@ -360,55 +319,48 @@ public void addBufferViewModels( * @param index The index * @return The {@link BufferViewModel} */ - public DefaultBufferViewModel getBufferViewModel(int index) - { + public DefaultBufferViewModel getBufferViewModel(int index) { return bufferViewModels.get(index); } /** * Remove all {@link BufferViewModel} instances */ - public void clearBufferViewModels() - { + public void clearBufferViewModels() { bufferViewModels.clear(); } @Override - public List getBufferViewModels() - { + public List getBufferViewModels() { return Collections.unmodifiableList(bufferViewModels); } - + /** * Add the given {@link CameraModel} to this model - * + * * @param cameraModel The instance to add */ - public void addCameraModel(DefaultCameraModel cameraModel) - { + public void addCameraModel(DefaultCameraModel cameraModel) { cameraModels.add(cameraModel); } /** * Remove the given {@link CameraModel} from this model - * + * * @param cameraModel The instance to remove */ - public void removeCameraModel(DefaultCameraModel cameraModel) - { + public void removeCameraModel(DefaultCameraModel cameraModel) { cameraModels.remove(cameraModel); } /** * Add the given {@link CameraModel} instances to this model - * + * * @param cameraModels The instances to add */ public void addCameraModels( - Collection cameraModels) - { - for (DefaultCameraModel cameraModel : cameraModels) - { + Collection cameraModels) { + for (DefaultCameraModel cameraModel : cameraModels) { addCameraModel(cameraModel); } } @@ -419,55 +371,48 @@ public void addCameraModels( * @param index The index * @return The {@link CameraModel} */ - public DefaultCameraModel getCameraModel(int index) - { + public DefaultCameraModel getCameraModel(int index) { return cameraModels.get(index); } /** * Remove all {@link CameraModel} instances */ - public void clearCameraModels() - { + public void clearCameraModels() { cameraModels.clear(); } @Override - public List getCameraModels() - { + public List getCameraModels() { return Collections.unmodifiableList(cameraModels); } - + /** * Add the given {@link ImageModel} to this model - * + * * @param imageModel The instance to add */ - public void addImageModel(DefaultImageModel imageModel) - { + public void addImageModel(DefaultImageModel imageModel) { imageModels.add(imageModel); } /** * Remove the given {@link ImageModel} from this model - * + * * @param imageModel The instance to remove */ - public void removeImageModel(DefaultImageModel imageModel) - { + public void removeImageModel(DefaultImageModel imageModel) { imageModels.remove(imageModel); } /** * Add the given {@link ImageModel} instances to this model - * + * * @param imageModels The instances to add */ public void addImageModels( - Collection imageModels) - { - for (DefaultImageModel imageModel : imageModels) - { + Collection imageModels) { + for (DefaultImageModel imageModel : imageModels) { addImageModel(imageModel); } } @@ -478,55 +423,48 @@ public void addImageModels( * @param index The index * @return The {@link ImageModel} */ - public DefaultImageModel getImageModel(int index) - { + public DefaultImageModel getImageModel(int index) { return imageModels.get(index); } /** * Remove all {@link ImageModel} instances */ - public void clearImageModels() - { + public void clearImageModels() { imageModels.clear(); } @Override - public List getImageModels() - { + public List getImageModels() { return Collections.unmodifiableList(imageModels); } - + /** * Add the given {@link MaterialModel} to this model - * + * * @param materialModel The instance to add */ - public void addMaterialModel(MaterialModel materialModel) - { + public void addMaterialModel(MaterialModel materialModel) { materialModels.add(materialModel); } /** * Remove the given {@link MaterialModel} from this model - * + * * @param materialModel The instance to remove */ - public void removeMaterialModel(MaterialModel materialModel) - { + public void removeMaterialModel(MaterialModel materialModel) { materialModels.remove(materialModel); } /** * Add the given {@link MaterialModel} instances to this model - * + * * @param materialModels The instances to add */ public void addMaterialModels( - Collection materialModels) - { - for (MaterialModel materialModel : materialModels) - { + Collection materialModels) { + for (MaterialModel materialModel : materialModels) { addMaterialModel(materialModel); } } @@ -537,55 +475,48 @@ public void addMaterialModels( * @param index The index * @return The {@link MaterialModel} */ - public MaterialModel getMaterialModel(int index) - { + public MaterialModel getMaterialModel(int index) { return materialModels.get(index); } /** * Remove all {@link MaterialModel} instances */ - public void clearMaterialModels() - { + public void clearMaterialModels() { materialModels.clear(); } @Override - public List getMaterialModels() - { + public List getMaterialModels() { return Collections.unmodifiableList(materialModels); } /** * Add the given {@link MeshModel} to this model - * + * * @param meshModel The instance to add */ - public void addMeshModel(DefaultMeshModel meshModel) - { + public void addMeshModel(DefaultMeshModel meshModel) { meshModels.add(meshModel); } /** * Remove the given {@link MeshModel} from this model - * + * * @param meshModel The instance to remove */ - public void removeMeshModel(DefaultMeshModel meshModel) - { + public void removeMeshModel(DefaultMeshModel meshModel) { meshModels.remove(meshModel); } /** * Add the given {@link MeshModel} instances to this model - * + * * @param meshModels The instances to add */ public void addMeshModels( - Collection meshModels) - { - for (DefaultMeshModel meshModel : meshModels) - { + Collection meshModels) { + for (DefaultMeshModel meshModel : meshModels) { addMeshModel(meshModel); } } @@ -596,55 +527,48 @@ public void addMeshModels( * @param index The index * @return The {@link MeshModel} */ - public DefaultMeshModel getMeshModel(int index) - { + public DefaultMeshModel getMeshModel(int index) { return meshModels.get(index); } /** * Remove all {@link MeshModel} instances */ - public void clearMeshModels() - { + public void clearMeshModels() { meshModels.clear(); } @Override - public List getMeshModels() - { + public List getMeshModels() { return Collections.unmodifiableList(meshModels); } - + /** * Add the given {@link NodeModel} to this model - * + * * @param nodeModel The instance to add */ - public void addNodeModel(DefaultNodeModel nodeModel) - { + public void addNodeModel(DefaultNodeModel nodeModel) { nodeModels.add(nodeModel); } /** * Remove the given {@link NodeModel} from this model - * + * * @param nodeModel The instance to remove */ - public void removeNodeModel(DefaultNodeModel nodeModel) - { + public void removeNodeModel(DefaultNodeModel nodeModel) { nodeModels.remove(nodeModel); } /** * Add the given {@link NodeModel} instances to this model - * + * * @param nodeModels The instances to add */ public void addNodeModels( - Collection nodeModels) - { - for (DefaultNodeModel nodeModel : nodeModels) - { + Collection nodeModels) { + for (DefaultNodeModel nodeModel : nodeModels) { addNodeModel(nodeModel); } } @@ -655,55 +579,48 @@ public void addNodeModels( * @param index The index * @return The {@link NodeModel} */ - public DefaultNodeModel getNodeModel(int index) - { + public DefaultNodeModel getNodeModel(int index) { return nodeModels.get(index); } /** * Remove all {@link NodeModel} instances */ - public void clearNodeModels() - { + public void clearNodeModels() { nodeModels.clear(); } @Override - public List getNodeModels() - { + public List getNodeModels() { return Collections.unmodifiableList(nodeModels); } - + /** * Add the given {@link SceneModel} to this model - * + * * @param sceneModel The instance to add */ - public void addSceneModel(DefaultSceneModel sceneModel) - { + public void addSceneModel(DefaultSceneModel sceneModel) { sceneModels.add(sceneModel); } /** * Remove the given {@link SceneModel} from this model - * + * * @param sceneModel The instance to remove */ - public void removeSceneModel(DefaultSceneModel sceneModel) - { + public void removeSceneModel(DefaultSceneModel sceneModel) { sceneModels.remove(sceneModel); } /** * Add the given {@link SceneModel} instances to this model - * + * * @param sceneModels The instances to add */ public void addSceneModels( - Collection sceneModels) - { - for (DefaultSceneModel sceneModel : sceneModels) - { + Collection sceneModels) { + for (DefaultSceneModel sceneModel : sceneModels) { addSceneModel(sceneModel); } } @@ -714,55 +631,48 @@ public void addSceneModels( * @param index The index * @return The {@link SceneModel} */ - public DefaultSceneModel getSceneModel(int index) - { + public DefaultSceneModel getSceneModel(int index) { return sceneModels.get(index); } /** * Remove all {@link SceneModel} instances */ - public void clearSceneModels() - { + public void clearSceneModels() { sceneModels.clear(); } @Override - public List getSceneModels() - { + public List getSceneModels() { return Collections.unmodifiableList(sceneModels); } /** * Add the given {@link SkinModel} to this model - * + * * @param skinModel The instance to add */ - public void addSkinModel(DefaultSkinModel skinModel) - { + public void addSkinModel(DefaultSkinModel skinModel) { skinModels.add(skinModel); } /** * Remove the given {@link SkinModel} from this model - * + * * @param skinModel The instance to remove */ - public void removeSkinModel(DefaultSkinModel skinModel) - { + public void removeSkinModel(DefaultSkinModel skinModel) { skinModels.remove(skinModel); } /** * Add the given {@link SkinModel} instances to this model - * + * * @param skinModels The instances to add */ public void addSkinModels( - Collection skinModels) - { - for (DefaultSkinModel skinModel : skinModels) - { + Collection skinModels) { + for (DefaultSkinModel skinModel : skinModels) { addSkinModel(skinModel); } } @@ -773,55 +683,48 @@ public void addSkinModels( * @param index The index * @return The {@link SkinModel} */ - public DefaultSkinModel getSkinModel(int index) - { + public DefaultSkinModel getSkinModel(int index) { return skinModels.get(index); } /** * Remove all {@link SkinModel} instances */ - public void clearSkinModels() - { + public void clearSkinModels() { skinModels.clear(); } @Override - public List getSkinModels() - { + public List getSkinModels() { return Collections.unmodifiableList(skinModels); } - + /** * Add the given {@link TextureModel} to this model - * + * * @param textureModel The instance to add */ - public void addTextureModel(DefaultTextureModel textureModel) - { + public void addTextureModel(DefaultTextureModel textureModel) { textureModels.add(textureModel); } /** * Remove the given {@link TextureModel} from this model - * + * * @param textureModel The instance to remove */ - public void removeTextureModel(DefaultTextureModel textureModel) - { + public void removeTextureModel(DefaultTextureModel textureModel) { textureModels.remove(textureModel); } /** * Add the given {@link TextureModel} instances to this model - * + * * @param textureModels The instances to add */ public void addTextureModels( - Collection textureModels) - { - for (DefaultTextureModel textureModel : textureModels) - { + Collection textureModels) { + for (DefaultTextureModel textureModel : textureModels) { addTextureModel(textureModel); } } @@ -832,34 +735,29 @@ public void addTextureModels( * @param index The index * @return The {@link TextureModel} */ - public DefaultTextureModel getTextureModel(int index) - { + public DefaultTextureModel getTextureModel(int index) { return textureModels.get(index); } /** * Remove all {@link TextureModel} instances */ - public void clearTextureModels() - { + public void clearTextureModels() { textureModels.clear(); } @Override - public List getTextureModels() - { + public List getTextureModels() { return Collections.unmodifiableList(textureModels); } - + @Override - public DefaultExtensionsModel getExtensionsModel() - { + public DefaultExtensionsModel getExtensionsModel() { return extensionsModel; } - + @Override - public DefaultAssetModel getAssetModel() - { + public DefaultAssetModel getAssetModel() { return assetModel; } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultImageModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultImageModel.java index 310005e..57d1b46 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultImageModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultImageModel.java @@ -26,113 +26,102 @@ */ package de.javagl.jgltf.model.impl; -import java.nio.ByteBuffer; - import de.javagl.jgltf.model.BufferViewModel; import de.javagl.jgltf.model.ImageModel; import de.javagl.jgltf.model.io.Buffers; +import java.nio.ByteBuffer; + /** * Implementation of a {@link ImageModel} */ public class DefaultImageModel extends AbstractNamedModelElement - implements ImageModel -{ + implements ImageModel { /** * The URI of the image */ private String uri; - + /** * The MIME type of the image data in the buffer view model */ private String mimeType; - + /** * The {@link BufferViewModel} */ private BufferViewModel bufferViewModel; - + /** * The image data */ private ByteBuffer imageData; - + /** * Creates a new instance */ - public DefaultImageModel() - { + public DefaultImageModel() { // Default constructor } - + + @Override + public String getUri() { + return uri; + } + /** * Set the URI - * + * * @param uri The URI */ - public void setUri(String uri) - { + public void setUri(String uri) { this.uri = uri; } - + + @Override + public String getMimeType() { + return mimeType; + } + /** * Set the MIME type - * + * * @param mimeType The MIME type */ - public void setMimeType(String mimeType) - { + public void setMimeType(String mimeType) { this.mimeType = mimeType; } + @Override + public BufferViewModel getBufferViewModel() { + return bufferViewModel; + } + /** - * Set the {@link BufferViewModel} - * + * Set the {@link BufferViewModel} + * * @param bufferViewModel The {@link BufferViewModel} */ - public void setBufferViewModel(BufferViewModel bufferViewModel) - { + public void setBufferViewModel(BufferViewModel bufferViewModel) { this.bufferViewModel = bufferViewModel; } - + + @Override + public ByteBuffer getImageData() { + if (imageData == null) { + return bufferViewModel.getBufferViewData(); + } + return Buffers.createSlice(imageData); + } + /** * Set the image data - * + * * @param imageData The image data */ - public void setImageData(ByteBuffer imageData) - { + public void setImageData(ByteBuffer imageData) { this.imageData = imageData; } - - @Override - public String getUri() - { - return uri; - } - - @Override - public String getMimeType() - { - return mimeType; - } - - @Override - public BufferViewModel getBufferViewModel() - { - return bufferViewModel; - } - - @Override - public ByteBuffer getImageData() - { - if (imageData == null) - { - return bufferViewModel.getBufferViewData(); - } - return Buffers.createSlice(imageData); - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshModel.java index 0b4d725..fb06594 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshModel.java @@ -26,68 +26,62 @@ */ package de.javagl.jgltf.model.impl; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; + import java.util.ArrayList; import java.util.Collections; import java.util.List; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; - /** * Implementation of a {@link MeshModel} */ public class DefaultMeshModel extends AbstractNamedModelElement - implements MeshModel -{ + implements MeshModel { /** - * The {@link MeshPrimitiveModel} instances + * The {@link MeshPrimitiveModel} instances */ private final List meshPrimitiveModels; - + /** * The morph target weights */ private float weights[]; - + /** * Creates a new instance */ - public DefaultMeshModel() - { + public DefaultMeshModel() { this.meshPrimitiveModels = new ArrayList(); } /** * Add the given {@link MeshPrimitiveModel} - * + * * @param meshPrimitiveModel The {@link MeshPrimitiveModel} */ - public void addMeshPrimitiveModel(MeshPrimitiveModel meshPrimitiveModel) - { + public void addMeshPrimitiveModel(MeshPrimitiveModel meshPrimitiveModel) { this.meshPrimitiveModels.add(meshPrimitiveModel); } - - /** - * Set the default morph target weights to be a reference to the - * given array. - * - * @param weights The weights - */ - public void setWeights(float[] weights) - { - this.weights = weights; - } - + @Override - public List getMeshPrimitiveModels() - { + public List getMeshPrimitiveModels() { return Collections.unmodifiableList(meshPrimitiveModels); } - + @Override - public float[] getWeights() - { + public float[] getWeights() { return weights; } + /** + * Set the default morph target weights to be a reference to the + * given array. + * + * @param weights The weights + */ + public void setWeights(float[] weights) { + this.weights = weights; + } + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshPrimitiveModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshPrimitiveModel.java index 16bfe82..256757b 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshPrimitiveModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshPrimitiveModel.java @@ -26,136 +26,115 @@ */ package de.javagl.jgltf.model.impl; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - import de.javagl.jgltf.model.AccessorModel; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.MeshPrimitiveModel; +import java.util.*; + /** * Implementation of a {@link MeshPrimitiveModel} */ -public final class DefaultMeshPrimitiveModel extends AbstractModelElement - implements MeshPrimitiveModel -{ +public final class DefaultMeshPrimitiveModel extends AbstractModelElement + implements MeshPrimitiveModel { /** * The attributes of this mesh primitive model */ private final Map attributes; - - /** - * The {@link AccessorModel} for the indices data - */ - private AccessorModel indices; - - /** - * The {@link MaterialModel} that should be used for rendering - */ - private MaterialModel materialModel; - /** * The rendering mode */ private final int mode; - /** * The morph targets */ private final List> targets; - + /** + * The {@link AccessorModel} for the indices data + */ + private AccessorModel indices; + /** + * The {@link MaterialModel} that should be used for rendering + */ + private MaterialModel materialModel; + /** * Creates a new instance - * + * * @param mode The rendering mode */ - public DefaultMeshPrimitiveModel(int mode) - { + public DefaultMeshPrimitiveModel(int mode) { this.mode = mode; this.attributes = new LinkedHashMap(); - this.targets = new ArrayList>(); + this.targets = new ArrayList>(); } - - + + /** * Put the given {@link AccessorModel} into the attributes, under the * given name - * - * @param name The name + * + * @param name The name * @param accessorModel The {@link AccessorModel} * @return The old value that was stored under the given name */ - public AccessorModel putAttribute(String name, AccessorModel accessorModel) - { + public AccessorModel putAttribute(String name, AccessorModel accessorModel) { Objects.requireNonNull( - accessorModel, "The accessorModel may not be null"); + accessorModel, "The accessorModel may not be null"); return attributes.put(name, accessorModel); } - - /** - * Set the {@link AccessorModel} for the indices - * - * @param indices The indices - */ - public void setIndices(AccessorModel indices) - { - this.indices = indices; - } - - /** - * Set the {@link MaterialModel} - * - * @param materialModel The {@link MaterialModel} - */ - public void setMaterialModel(MaterialModel materialModel) - { - this.materialModel = Objects.requireNonNull( - materialModel, "The materialModel may not be null"); - } - + /** * Add the given morph target. A reference to the given map will be stored. - * + * * @param target The target */ - public void addTarget(Map target) - { + public void addTarget(Map target) { Objects.requireNonNull(target, "The target may not be null"); this.targets.add(target); } - @Override - public Map getAttributes() - { + public Map getAttributes() { return Collections.unmodifiableMap(attributes); } @Override - public AccessorModel getIndices() - { + public AccessorModel getIndices() { return indices; } + /** + * Set the {@link AccessorModel} for the indices + * + * @param indices The indices + */ + public void setIndices(AccessorModel indices) { + this.indices = indices; + } + @Override - public int getMode() - { + public int getMode() { return mode; } @Override - public MaterialModel getMaterialModel() - { + public MaterialModel getMaterialModel() { return materialModel; } - + + /** + * Set the {@link MaterialModel} + * + * @param materialModel The {@link MaterialModel} + */ + public void setMaterialModel(MaterialModel materialModel) { + this.materialModel = Objects.requireNonNull( + materialModel, "The materialModel may not be null"); + } + @Override - public List> getTargets() - { + public List> getTargets() { return Collections.unmodifiableList(targets); } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultNodeModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultNodeModel.java index 25ed9cb..9b1b45d 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultNodeModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultNodeModel.java @@ -26,58 +26,47 @@ */ package de.javagl.jgltf.model.impl; +import de.javagl.jgltf.model.*; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.function.Supplier; -import de.javagl.jgltf.model.CameraModel; -import de.javagl.jgltf.model.MathUtils; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.SkinModel; -import de.javagl.jgltf.model.Suppliers; -import de.javagl.jgltf.model.Utils; - /** - * Implementation of a {@link NodeModel} + * Implementation of a {@link NodeModel} */ public class DefaultNodeModel extends AbstractNamedModelElement - implements NodeModel -{ + implements NodeModel { /** * A thread-local, temporary 16-element matrix */ private static final ThreadLocal TEMP_MATRIX_4x4_IN_LOCAL = - ThreadLocal.withInitial(() -> new float[16]); - + ThreadLocal.withInitial(() -> new float[16]); + /** * A thread-local, temporary 16-element matrix */ private static final ThreadLocal TEMP_MATRIX_4x4_IN_GLOBAL = - ThreadLocal.withInitial(() -> new float[16]); - - /** - * The parent of this node. This is null for the root node. - */ - private NodeModel parent; - + ThreadLocal.withInitial(() -> new float[16]); /** * The children of this node */ private final List children; - /** * The {@link MeshModel} objects that are attached to this node */ private final List meshModels; - + /** + * The parent of this node. This is null for the root node. + */ + private NodeModel parent; /** * The {@link SkinModel} */ private SkinModel skinModel; - + /** * The {@link CameraModel} */ @@ -87,17 +76,17 @@ public class DefaultNodeModel extends AbstractNamedModelElement * The local transform matrix */ private float matrix[]; - + /** * The translation */ private float translation[]; - + /** * The rotation */ private float rotation[]; - + /** * The scale */ @@ -107,25 +96,23 @@ public class DefaultNodeModel extends AbstractNamedModelElement * The weights */ private float weights[]; - + /** - * Creates a new instance + * Creates a new instance */ - public DefaultNodeModel() - { + public DefaultNodeModel() { this.children = new ArrayList(); this.meshModels = new ArrayList(); } - + /** * Copy constructor that creates a shallow copy with references * to the elements of the given model, except for the children and * {@link MeshModel} instances (which will be empty in the copy). - * + * * @param other The other {@link NodeModel} */ - public DefaultNodeModel(NodeModel other) - { + public DefaultNodeModel(NodeModel other) { this.cameraModel = other.getCameraModel(); this.children = new ArrayList(); this.matrix = other.getMatrix(); @@ -137,286 +124,251 @@ public DefaultNodeModel(NodeModel other) this.translation = other.getTranslation(); this.weights = other.getWeights(); } - + /** - * Set the parent of this node - * - * @param parent The parent node + * Compute the local transform of the given node. The transform + * is either taken from the {@link #getMatrix()} (if it is not + * null), or computed from the {@link #getTranslation()}, + * {@link #getRotation()} and {@link #getScale()}, if they + * are not null, respectively.
+ *
+ * The result will be written to the given array, as a 4x4 matrix in + * column major order. If the given array is null or does + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * + * @param nodeModel The node. May not be null. + * @param result The result array + * @return The result array */ - public void setParent(DefaultNodeModel parent) - { - this.parent = parent; + public static float[] computeLocalTransform( + NodeModel nodeModel, float result[]) { + float localResult[] = Utils.validate(result, 16); + if (nodeModel.getMatrix() != null) { + float m[] = nodeModel.getMatrix(); + System.arraycopy(m, 0, localResult, 0, m.length); + return localResult; + } + + MathUtils.setIdentity4x4(localResult); + if (nodeModel.getTranslation() != null) { + float t[] = nodeModel.getTranslation(); + localResult[12] = t[0]; + localResult[13] = t[1]; + localResult[14] = t[2]; + } + if (nodeModel.getRotation() != null) { + float q[] = nodeModel.getRotation(); + float m[] = TEMP_MATRIX_4x4_IN_LOCAL.get(); + MathUtils.quaternionToMatrix4x4(q, m); + MathUtils.mul4x4(localResult, m, localResult); + } + if (nodeModel.getScale() != null) { + float s[] = nodeModel.getScale(); + float m[] = TEMP_MATRIX_4x4_IN_LOCAL.get(); + MathUtils.setIdentity4x4(m); + m[0] = s[0]; + m[5] = s[1]; + m[10] = s[2]; + m[15] = 1.0f; + MathUtils.mul4x4(localResult, m, localResult); + } + return localResult; + } + + /** + * Compute the global transform for the given {@link NodeModel}, + * and store it in the given result. If the given result is + * null or does not have a length of 16, then + * a new array will be created and returned. + * + * @param nodeModel The {@link NodeModel} + * @param result The result + * @return The result + */ + private static float[] computeGlobalTransform( + NodeModel nodeModel, float result[]) { + float localResult[] = Utils.validate(result, 16); + float tempLocalTransform[] = TEMP_MATRIX_4x4_IN_GLOBAL.get(); + NodeModel currentNode = nodeModel; + MathUtils.setIdentity4x4(localResult); + while (currentNode != null) { + currentNode.computeLocalTransform(tempLocalTransform); + MathUtils.mul4x4( + tempLocalTransform, localResult, localResult); + currentNode = currentNode.getParent(); + } + return localResult; + } + + /** + * Check whether the given array has the expected length, and return + * the given array. If the given source array is null, then + * null will be returned. If the given source array does not + * have the expected length, then an IllegalArgumentException + * will be thrown. + * + * @param array The array + * @param expectedLength The expected length + * @return The array + * @throws IllegalArgumentException If the given array does not have + * the expected length + */ + private static float[] check(float array[], int expectedLength) { + if (array == null) { + return null; + } + if (array.length != expectedLength) { + throw new IllegalArgumentException("Expected " + expectedLength + + " array elements, but found " + array.length); + } + return array; } - + /** * Add the given child node - * + * * @param child The child node */ - public void addChild(DefaultNodeModel child) - { + public void addChild(DefaultNodeModel child) { Objects.requireNonNull(child, "The child may not be null"); children.add(child); child.setParent(this); } - + /** - * Add the given {@link MeshModel} - * + * Add the given {@link MeshModel} + * * @param meshModel The {@link MeshModel} */ - public void addMeshModel(MeshModel meshModel) - { + public void addMeshModel(MeshModel meshModel) { Objects.requireNonNull(meshModel, "The meshModel may not be null"); meshModels.add(meshModel); } - - /** - * Set the {@link SkinModel} - * - * @param skinModel The {@link SkinModel} - */ - public void setSkinModel(SkinModel skinModel) - { - this.skinModel = skinModel; + + @Override + public NodeModel getParent() { + return parent; } - + /** - * Set the {@link CameraModel} - * - * @param cameraModel The {@link CameraModel} + * Set the parent of this node + * + * @param parent The parent node */ - public void setCameraModel(CameraModel cameraModel) - { - this.cameraModel = cameraModel; - } - - @Override - public NodeModel getParent() - { - return parent; + public void setParent(DefaultNodeModel parent) { + this.parent = parent; } - + @Override - public List getChildren() - { + public List getChildren() { return Collections.unmodifiableList(children); } - + @Override - public List getMeshModels() - { + public List getMeshModels() { return Collections.unmodifiableList(meshModels); } - + @Override - public SkinModel getSkinModel() - { + public SkinModel getSkinModel() { return skinModel; } - + + /** + * Set the {@link SkinModel} + * + * @param skinModel The {@link SkinModel} + */ + public void setSkinModel(SkinModel skinModel) { + this.skinModel = skinModel; + } + @Override - public CameraModel getCameraModel() - { + public CameraModel getCameraModel() { return cameraModel; } - - @Override - public void setMatrix(float[] matrix) - { - this.matrix = check(matrix, 16); + + /** + * Set the {@link CameraModel} + * + * @param cameraModel The {@link CameraModel} + */ + public void setCameraModel(CameraModel cameraModel) { + this.cameraModel = cameraModel; } - + @Override - public float[] getMatrix() - { + public float[] getMatrix() { return matrix; } @Override - public void setTranslation(float[] translation) - { - this.translation = check(translation, 3); + public void setMatrix(float[] matrix) { + this.matrix = check(matrix, 16); } @Override - public float[] getTranslation() - { + public float[] getTranslation() { return translation; } @Override - public void setRotation(float[] rotation) - { - this.rotation = check(rotation, 4); + public void setTranslation(float[] translation) { + this.translation = check(translation, 3); } @Override - public float[] getRotation() - { + public float[] getRotation() { return rotation; } @Override - public void setScale(float[] scale) - { - this.scale = check(scale, 3); + public void setRotation(float[] rotation) { + this.rotation = check(rotation, 4); } @Override - public float[] getScale() - { + public float[] getScale() { return scale; } @Override - public void setWeights(float[] weights) - { - this.weights = weights; + public void setScale(float[] scale) { + this.scale = check(scale, 3); } @Override - public float[] getWeights() - { + public float[] getWeights() { return weights; } - - + @Override - public float[] computeLocalTransform(float result[]) - { + public void setWeights(float[] weights) { + this.weights = weights; + } + + @Override + public float[] computeLocalTransform(float result[]) { return computeLocalTransform(this, result); } @Override - public float[] computeGlobalTransform(float result[]) - { + public float[] computeGlobalTransform(float result[]) { return computeGlobalTransform(this, result); } - + @Override - public Supplier createGlobalTransformSupplier() - { - return Suppliers.createTransformSupplier(this, - NodeModel::computeGlobalTransform); + public Supplier createGlobalTransformSupplier() { + return Suppliers.createTransformSupplier(this, + NodeModel::computeGlobalTransform); } - + @Override - public Supplier createLocalTransformSupplier() - { - return Suppliers.createTransformSupplier(this, - NodeModel::computeLocalTransform); + public Supplier createLocalTransformSupplier() { + return Suppliers.createTransformSupplier(this, + NodeModel::computeLocalTransform); } - /** - * Compute the local transform of the given node. The transform - * is either taken from the {@link #getMatrix()} (if it is not - * null), or computed from the {@link #getTranslation()}, - * {@link #getRotation()} and {@link #getScale()}, if they - * are not null, respectively.
- *
- * The result will be written to the given array, as a 4x4 matrix in - * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * - * @param nodeModel The node. May not be null. - * @param result The result array - * @return The result array - */ - public static float[] computeLocalTransform( - NodeModel nodeModel, float result[]) - { - float localResult[] = Utils.validate(result, 16); - if (nodeModel.getMatrix() != null) - { - float m[] = nodeModel.getMatrix(); - System.arraycopy(m, 0, localResult, 0, m.length); - return localResult; - } - - MathUtils.setIdentity4x4(localResult); - if (nodeModel.getTranslation() != null) - { - float t[] = nodeModel.getTranslation(); - localResult[12] = t[0]; - localResult[13] = t[1]; - localResult[14] = t[2]; - } - if (nodeModel.getRotation() != null) - { - float q[] = nodeModel.getRotation(); - float m[] = TEMP_MATRIX_4x4_IN_LOCAL.get(); - MathUtils.quaternionToMatrix4x4(q, m); - MathUtils.mul4x4(localResult, m, localResult); - } - if (nodeModel.getScale() != null) - { - float s[] = nodeModel.getScale(); - float m[] = TEMP_MATRIX_4x4_IN_LOCAL.get(); - MathUtils.setIdentity4x4(m); - m[ 0] = s[0]; - m[ 5] = s[1]; - m[10] = s[2]; - m[15] = 1.0f; - MathUtils.mul4x4(localResult, m, localResult); - } - return localResult; - } - - /** - * Compute the global transform for the given {@link NodeModel}, - * and store it in the given result. If the given result is - * null or does not have a length of 16, then - * a new array will be created and returned. - * - * @param nodeModel The {@link NodeModel} - * @param result The result - * @return The result - */ - private static float[] computeGlobalTransform( - NodeModel nodeModel, float result[]) - { - float localResult[] = Utils.validate(result, 16); - float tempLocalTransform[] = TEMP_MATRIX_4x4_IN_GLOBAL.get(); - NodeModel currentNode = nodeModel; - MathUtils.setIdentity4x4(localResult); - while (currentNode != null) - { - currentNode.computeLocalTransform(tempLocalTransform); - MathUtils.mul4x4( - tempLocalTransform, localResult, localResult); - currentNode = currentNode.getParent(); - } - return localResult; - } - - /** - * Check whether the given array has the expected length, and return - * the given array. If the given source array is null, then - * null will be returned. If the given source array does not - * have the expected length, then an IllegalArgumentException - * will be thrown. - * - * @param array The array - * @param expectedLength The expected length - * @return The array - * @throws IllegalArgumentException If the given array does not have - * the expected length - */ - private static float[] check(float array[], int expectedLength) - { - if (array == null) - { - return null; - } - if (array.length != expectedLength) - { - throw new IllegalArgumentException("Expected " + expectedLength - + " array elements, but found " + array.length); - } - return array; - } - - + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultSceneModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultSceneModel.java index 5e1f582..4f09c7f 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultSceneModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultSceneModel.java @@ -26,45 +26,41 @@ */ package de.javagl.jgltf.model.impl; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.SceneModel; + import java.util.ArrayList; import java.util.Collections; import java.util.List; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.SceneModel; - /** - * Implementation of a {@link SceneModel} + * Implementation of a {@link SceneModel} */ public class DefaultSceneModel extends AbstractNamedModelElement - implements SceneModel -{ + implements SceneModel { /** * The list of root nodes */ private final List nodeModels; - + /** * Creates a new instance */ - public DefaultSceneModel() - { + public DefaultSceneModel() { this.nodeModels = new ArrayList(); } - + /** * Add the given (root) {@link NodeModel} to this scene - * + * * @param node The {@link NodeModel} */ - public void addNode(NodeModel node) - { - nodeModels.add(node); + public void addNode(NodeModel node) { + nodeModels.add(node); } - + @Override - public List getNodeModels() - { + public List getNodeModels() { return Collections.unmodifiableList(nodeModels); } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultSkinModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultSkinModel.java index 14fc98a..dcdba05 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultSkinModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultSkinModel.java @@ -26,141 +26,116 @@ */ package de.javagl.jgltf.model.impl; +import de.javagl.jgltf.model.*; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; -import de.javagl.jgltf.model.AccessorDatas; -import de.javagl.jgltf.model.AccessorFloatData; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.MathUtils; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.SkinModel; -import de.javagl.jgltf.model.Utils; - /** * Implementation of a {@link SkinModel} */ public final class DefaultSkinModel extends AbstractNamedModelElement - implements SkinModel -{ - /** - * The bind shape matrix - */ - private float bindShapeMatrix[]; - + implements SkinModel { /** * The joint nodes */ private final List joints; - + /** + * The bind shape matrix + */ + private float bindShapeMatrix[]; /** * The skeleton node */ private NodeModel skeleton; - + /** * The inverse bind matrices */ private AccessorModel inverseBindMatrices; - + /** * Creates a new instance */ - public DefaultSkinModel() - { + public DefaultSkinModel() { this.bindShapeMatrix = MathUtils.createIdentity4x4(); this.joints = new ArrayList(); } - + /** * Set the bind shape matrix - * + * * @param bindShapeMatrix The bind shape matrix. A copy of this array - * will be stored. If it is null, a new array will be - * created, which represents the identity matrix. + * will be stored. If it is null, a new array will be + * created, which represents the identity matrix. */ - public void setBindShapeMatrix(float[] bindShapeMatrix) - { - if (bindShapeMatrix == null) - { + public void setBindShapeMatrix(float[] bindShapeMatrix) { + if (bindShapeMatrix == null) { this.bindShapeMatrix = MathUtils.createIdentity4x4(); - } - else - { + } else { this.bindShapeMatrix = bindShapeMatrix.clone(); } } - + /** - * Add the given joint - * + * Add the given joint + * * @param joint The joint */ - public void addJoint(NodeModel joint) - { + public void addJoint(NodeModel joint) { Objects.requireNonNull(joint, "The joint may not be null"); joints.add(joint); } - - /** - * Set the skeleton root node - * - * @param skeleton The skeleton root node - */ - public void setSkeleton(NodeModel skeleton) - { - this.skeleton = skeleton; - } - - /** - * Set the inverse bind matrices - * - * @param inverseBindMatrices The inverse bind matrices - */ - public void setInverseBindMatrices(AccessorModel inverseBindMatrices) - { - this.inverseBindMatrices = Objects.requireNonNull( - inverseBindMatrices, "The inverseBindMatrices may not be null"); - } - @Override - public float[] getBindShapeMatrix(float[] result) - { + public float[] getBindShapeMatrix(float[] result) { float localResult[] = Utils.validate(result, 16); System.arraycopy(bindShapeMatrix, 0, localResult, 0, 16); return localResult; } - @Override - public List getJoints() - { + public List getJoints() { return Collections.unmodifiableList(joints); } @Override - public NodeModel getSkeleton() - { + public NodeModel getSkeleton() { return skeleton; } + /** + * Set the skeleton root node + * + * @param skeleton The skeleton root node + */ + public void setSkeleton(NodeModel skeleton) { + this.skeleton = skeleton; + } + @Override - public AccessorModel getInverseBindMatrices() - { + public AccessorModel getInverseBindMatrices() { return inverseBindMatrices; } + /** + * Set the inverse bind matrices + * + * @param inverseBindMatrices The inverse bind matrices + */ + public void setInverseBindMatrices(AccessorModel inverseBindMatrices) { + this.inverseBindMatrices = Objects.requireNonNull( + inverseBindMatrices, "The inverseBindMatrices may not be null"); + } + @Override - public float[] getInverseBindMatrix(int index, float[] result) - { + public float[] getInverseBindMatrix(int index, float[] result) { float localResult[] = Utils.validate(result, 16); - AccessorFloatData inverseBindMatricesData = - AccessorDatas.createFloat(inverseBindMatrices); - for (int j = 0; j < 16; j++) - { + AccessorFloatData inverseBindMatricesData = + AccessorDatas.createFloat(inverseBindMatrices); + for (int j = 0; j < 16; j++) { localResult[j] = inverseBindMatricesData.get(index, j); } return localResult; diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultTextureModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultTextureModel.java index 4fc29de..f7aeb2b 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultTextureModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultTextureModel.java @@ -33,8 +33,7 @@ * Implementation of a {@link TextureModel} */ public class DefaultTextureModel extends AbstractNamedModelElement - implements TextureModel -{ + implements TextureModel { /** * The magnification filter constant */ @@ -44,107 +43,96 @@ public class DefaultTextureModel extends AbstractNamedModelElement * The minification filter constant */ private Integer minFilter; - + /** * The wrapping constant for the S-direction */ private Integer wrapS; - + /** * The wrapping constant for the T-direction */ private Integer wrapT; - + /** * The {@link ImageModel} */ private ImageModel imageModel; - + /** * Creates a new instance */ - public DefaultTextureModel() - { + public DefaultTextureModel() { // Default constructor } - - /** - * Set the {@link ImageModel} that backs this texture - * - * @param imageModel The {@link ImageModel} - */ - public void setImageModel(ImageModel imageModel) - { - this.imageModel = imageModel; - } - + @Override - public Integer getMagFilter() - { + public Integer getMagFilter() { return magFilter; } - + /** * Set the magnification filter - * + * * @param magFilter The filter */ - public void setMagFilter(Integer magFilter) - { + public void setMagFilter(Integer magFilter) { this.magFilter = magFilter; } @Override - public Integer getMinFilter() - { + public Integer getMinFilter() { return minFilter; } - + /** * Set the minification filter - * + * * @param minFilter The filter */ - public void setMinFilter(Integer minFilter) - { + public void setMinFilter(Integer minFilter) { this.minFilter = minFilter; } @Override - public Integer getWrapS() - { + public Integer getWrapS() { return wrapS; } - + /** * Set the wrapping behavior in S-direction - * + * * @param wrapS The wrapping mode */ - public void setWrapS(Integer wrapS) - { + public void setWrapS(Integer wrapS) { this.wrapS = wrapS; } @Override - public Integer getWrapT() - { + public Integer getWrapT() { return wrapT; } /** * Set the wrapping behavior in T-direction - * + * * @param wrapT The wrapping mode */ - public void setWrapT(Integer wrapT) - { + public void setWrapT(Integer wrapT) { this.wrapT = wrapT; } - + @Override - public ImageModel getImageModel() - { + public ImageModel getImageModel() { return imageModel; } + + /** + * Set the {@link ImageModel} that backs this texture + * + * @param imageModel The {@link ImageModel} + */ + public void setImageModel(ImageModel imageModel) { + this.imageModel = imageModel; + } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/UriStrings.java b/src/main/java/de/javagl/jgltf/model/impl/UriStrings.java index b5a5605..ca4510a 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/UriStrings.java +++ b/src/main/java/de/javagl/jgltf/model/impl/UriStrings.java @@ -26,69 +26,69 @@ */ package de.javagl.jgltf.model.impl; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.logging.Logger; - import de.javagl.jgltf.model.ImageModel; import de.javagl.jgltf.model.gl.ShaderModel; import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; import de.javagl.jgltf.model.io.MimeTypes; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.logging.Logger; + /** * Utility methods to generate URI strings for buffers, images and shaders.
*
* This class is only intended for internal use! */ -public class UriStrings -{ +public class UriStrings { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(UriStrings.class.getName()); - + private static final Logger logger = + Logger.getLogger(UriStrings.class.getName()); + /** - * Create an unspecified, new URI string that is not yet used as + * Private constructor to prevent instantiation + */ + private UriStrings() { + // Private constructor to prevent instantiation + } + + /** + * Create an unspecified, new URI string that is not yet used as * a URI string. - * + * * @param existingUriStrings The existing URI strings * @return The new URI string */ public static String createBufferUriString( - Collection existingUriStrings) - { + Collection existingUriStrings) { int counter = 0; - while (true) - { + while (true) { String uri = "buffer" + counter + "." + "bin"; - if (!existingUriStrings.contains(uri)) - { + if (!existingUriStrings.contains(uri)) { return uri; } counter++; } } - + /** - * Create an unspecified, new URI string that is not yet used as + * Create an unspecified, new URI string that is not yet used as * a URI string - * - * @param imageModel The {@link ImageModel} to create the string for + * + * @param imageModel The {@link ImageModel} to create the string for * @param existingUriStrings The existing URI strings * @return The new URI string */ public static String createImageUriString(ImageModel imageModel, - Collection existingUriStrings) - { - String extensionWithoutDot = - determineImageFileNameExtension(imageModel); + Collection existingUriStrings) { + String extensionWithoutDot = + determineImageFileNameExtension(imageModel); int counter = 0; - while (true) - { + while (true) { String uri = "image" + counter + "." + extensionWithoutDot; - if (!existingUriStrings.contains(uri)) - { + if (!existingUriStrings.contains(uri)) { return uri; } counter++; @@ -96,87 +96,70 @@ public static String createImageUriString(ImageModel imageModel, } /** - * Determine the extension for an image file name (without the + * Determine the extension for an image file name (without the * "." dot), for the given {@link ImageModel} - * + * * @param imageModel The {@link ImageModel} * @return The file extension */ private static String determineImageFileNameExtension( - ImageModel imageModel) - { + ImageModel imageModel) { // Try to figure out the MIME type String mimeTypeString = imageModel.getMimeType(); - if (mimeTypeString == null) - { + if (mimeTypeString == null) { ByteBuffer imageData = imageModel.getImageData(); - mimeTypeString = - MimeTypes.guessImageMimeTypeStringUnchecked(imageData); + mimeTypeString = + MimeTypes.guessImageMimeTypeStringUnchecked(imageData); } - + // Try to figure out the extension based on the MIME type - if (mimeTypeString != null) - { - String extensionWithoutDot = - MimeTypes.imageFileNameExtensionForMimeTypeString( - mimeTypeString); - if (extensionWithoutDot != null) - { + if (mimeTypeString != null) { + String extensionWithoutDot = + MimeTypes.imageFileNameExtensionForMimeTypeString( + mimeTypeString); + if (extensionWithoutDot != null) { return extensionWithoutDot; } } logger.warning("Could not determine file extension for image URI"); return ""; } - + /** - * Create an unspecified, new URI string that is not yet used as + * Create an unspecified, new URI string that is not yet used as * a URI string - * - * @param shaderModel The {@link ShaderModel} to create the string for + * + * @param shaderModel The {@link ShaderModel} to create the string for * @param existingUriStrings The existing URI strings * @return The new URI string */ public static String createShaderUriString(ShaderModel shaderModel, - Collection existingUriStrings) - { - String extensionWithoutDot = - determineShaderFileNameExtension(shaderModel); + Collection existingUriStrings) { + String extensionWithoutDot = + determineShaderFileNameExtension(shaderModel); int counter = 0; - while (true) - { + while (true) { String uri = "shader" + counter + "." + extensionWithoutDot; - if (!existingUriStrings.contains(uri)) - { + if (!existingUriStrings.contains(uri)) { return uri; } counter++; } } - + /** - * Determine the extension for a shader file name, (without the + * Determine the extension for a shader file name, (without the * "." dot), for the given {@link ShaderModel} - * + * * @param shaderModel The {@link ShaderModel} * @return The file extension */ private static String determineShaderFileNameExtension( - ShaderModel shaderModel) - { - if (shaderModel.getShaderType() == ShaderType.VERTEX_SHADER) - { + ShaderModel shaderModel) { + if (shaderModel.getShaderType() == ShaderType.VERTEX_SHADER) { return "vert"; } return "frag"; } - /** - * Private constructor to prevent instantiation - */ - private UriStrings() - { - // Private constructor to prevent instantiation - } - } diff --git a/src/main/java/de/javagl/jgltf/model/impl/package-info.java b/src/main/java/de/javagl/jgltf/model/impl/package-info.java index 93ac6bc..8c6df71 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/impl/package-info.java @@ -1,6 +1,6 @@ /** * Default implementations of the glTF model interfaces.
- *
+ *
* These classes should not be considered to be part of the public API. */ package de.javagl.jgltf.model.impl; diff --git a/src/main/java/de/javagl/jgltf/model/io/Buffers.java b/src/main/java/de/javagl/jgltf/model/io/Buffers.java index 175ce18..cc8261c 100644 --- a/src/main/java/de/javagl/jgltf/model/io/Buffers.java +++ b/src/main/java/de/javagl/jgltf/model/io/Buffers.java @@ -27,31 +27,31 @@ package de.javagl.jgltf.model.io; import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; +import java.nio.*; import java.util.Collection; /** * Utility methods related to buffers */ -public class Buffers -{ +public class Buffers { + /** + * Private constructor to prevent instantiation + */ + private Buffers() { + // Private constructor to prevent instantiation + } + /** * Returns the contents of the given byte buffer as a string, using - * the platform's default charset, or null if the given + * the platform's default charset, or null if the given * buffer is null. The position and limit of the given * buffer will be unaffected by this call. - * + * * @param byteBuffer The byte buffer * @return The data as a string */ - public static String readAsString(ByteBuffer byteBuffer) - { - if (byteBuffer == null) - { + public static String readAsString(ByteBuffer byteBuffer) { + if (byteBuffer == null) { return null; } byte array[] = new byte[byteBuffer.capacity()]; @@ -64,167 +64,149 @@ public static String readAsString(ByteBuffer byteBuffer) * and limit. The returned slice will have the same byte order as the * given buffer. If the given buffer is null, then * null will be returned. - * + * * @param byteBuffer The byte buffer * @return The slice */ - public static ByteBuffer createSlice(ByteBuffer byteBuffer) - { - if (byteBuffer == null) - { + public static ByteBuffer createSlice(ByteBuffer byteBuffer) { + if (byteBuffer == null) { return null; } return byteBuffer.slice().order(byteBuffer.order()); } - + /** * Create a slice of the given byte buffer, in the specified range. * The returned buffer will have the same byte order as the given * buffer. If the given buffer is null, then * null will be returned. - * + * * @param byteBuffer The byte buffer - * @param position The position where the slice should start - * @param length The length of the slice + * @param position The position where the slice should start + * @param length The length of the slice * @return The slice * @throws IllegalArgumentException If the range that is specified - * by the position and length are not valid for the given buffer + * by the position and length are not valid for the given buffer */ public static ByteBuffer createSlice( - ByteBuffer byteBuffer, int position, int length) - { - if (byteBuffer == null) - { + ByteBuffer byteBuffer, int position, int length) { + if (byteBuffer == null) { return null; } int oldPosition = byteBuffer.position(); int oldLimit = byteBuffer.limit(); - try - { + try { int newLimit = position + length; - if (newLimit > byteBuffer.capacity()) - { + if (newLimit > byteBuffer.capacity()) { throw new IllegalArgumentException( - "The new limit is " + newLimit + ", but the capacity is " - + byteBuffer.capacity()); + "The new limit is " + newLimit + ", but the capacity is " + + byteBuffer.capacity()); } byteBuffer.limit(newLimit); byteBuffer.position(position); ByteBuffer slice = byteBuffer.slice(); slice.order(byteBuffer.order()); return slice; - } - finally - { + } finally { byteBuffer.limit(oldLimit); byteBuffer.position(oldPosition); } } - + /** * Creates a new, direct byte buffer that contains the given data, * with little-endian byte order - * + * * @param data The data * @return The byte buffer */ - public static ByteBuffer create(byte data[]) - { + public static ByteBuffer create(byte data[]) { return create(data, 0, data.length); } - + /** * Creates a new, direct byte buffer that contains the specified range * of the given data, with little-endian byte order - * - * @param data The data + * + * @param data The data * @param offset The offset in the data array * @param length The length of the range * @return The byte buffer */ - public static ByteBuffer create(byte data[], int offset, int length) - { + public static ByteBuffer create(byte data[], int offset, int length) { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(length); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); byteBuffer.put(data, offset, length); byteBuffer.position(0); return byteBuffer; } - + /** * Create a new direct byte buffer with the given size, and little-endian * byte order. - * + * * @param size The size of the buffer * @return The byte buffer * @throws IllegalArgumentException If the given size is negative */ - public static ByteBuffer create(int size) - { + public static ByteBuffer create(int size) { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(size); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); return byteBuffer; } - + /** * Create an input stream from the given byte buffer, starting at its * current position, up to its current limit. Reading the returned - * stream will advance the position of the buffer. If this is not + * stream will advance the position of the buffer. If this is not * desired, a slice of the buffer may be passed to this method. - * + * * @param byteBuffer The buffer * @return The input stream */ - public static InputStream createByteBufferInputStream(ByteBuffer byteBuffer) - { + public static InputStream createByteBufferInputStream(ByteBuffer byteBuffer) { return new ByteBufferInputStream(byteBuffer); } - - + /** * Create a direct byte buffer with native byte order whose contents is * a concatenation of the given byte buffers. If the given collection * is null or empty, then a 0-byte buffer will be created. * The given collection may not contain null elements. - * + * * @param byteBuffers The input byte buffers * @return The concatenated byte buffer */ public static ByteBuffer concat( - Collection byteBuffers) - { - if (byteBuffers == null || byteBuffers.isEmpty()) - { + Collection byteBuffers) { + if (byteBuffers == null || byteBuffers.isEmpty()) { return ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder()); } int resultCapacity = byteBuffers.stream() - .mapToInt(ByteBuffer::capacity) - .reduce(0, (a, b) -> a + b); + .mapToInt(ByteBuffer::capacity) + .reduce(0, (a, b) -> a + b); ByteBuffer newByteBuffer = ByteBuffer - .allocateDirect(resultCapacity) - .order(ByteOrder.nativeOrder()); - for (ByteBuffer byteBuffer : byteBuffers) - { + .allocateDirect(resultCapacity) + .order(ByteOrder.nativeOrder()); + for (ByteBuffer byteBuffer : byteBuffers) { newByteBuffer.put(byteBuffer.slice()); } newByteBuffer.position(0); return newByteBuffer; } - - + /** * Create a new direct byte buffer with native byte order that has the * same contents as the given float buffer. - * + * * @param buffer The input buffer * @return The new byte buffer */ - public static ByteBuffer createByteBufferFrom(FloatBuffer buffer) - { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity() * Float.BYTES); - FloatBuffer floatBuffer = - byteBuffer.order(ByteOrder.nativeOrder()).asFloatBuffer(); + public static ByteBuffer createByteBufferFrom(FloatBuffer buffer) { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity() * Float.BYTES); + FloatBuffer floatBuffer = + byteBuffer.order(ByteOrder.nativeOrder()).asFloatBuffer(); floatBuffer.put(buffer.slice()); return byteBuffer; } @@ -232,16 +214,15 @@ public static ByteBuffer createByteBufferFrom(FloatBuffer buffer) /** * Create a new direct byte buffer with native byte order that has the * same contents as the given int buffer. - * + * * @param buffer The input buffer * @return The new byte buffer */ - public static ByteBuffer createByteBufferFrom(IntBuffer buffer) - { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity() * Integer.BYTES); - IntBuffer intBuffer = - byteBuffer.order(ByteOrder.nativeOrder()).asIntBuffer(); + public static ByteBuffer createByteBufferFrom(IntBuffer buffer) { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity() * Integer.BYTES); + IntBuffer intBuffer = + byteBuffer.order(ByteOrder.nativeOrder()).asIntBuffer(); intBuffer.put(buffer.slice()); return byteBuffer; } @@ -249,118 +230,98 @@ public static ByteBuffer createByteBufferFrom(IntBuffer buffer) /** * Create a new direct byte buffer with native byte order that has the * same contents as the given short buffer. - * + * * @param buffer The input buffer * @return The new byte buffer */ - public static ByteBuffer createByteBufferFrom(ShortBuffer buffer) - { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity() * Short.BYTES); - ShortBuffer shortBuffer = - byteBuffer.order(ByteOrder.nativeOrder()).asShortBuffer(); + public static ByteBuffer createByteBufferFrom(ShortBuffer buffer) { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity() * Short.BYTES); + ShortBuffer shortBuffer = + byteBuffer.order(ByteOrder.nativeOrder()).asShortBuffer(); shortBuffer.put(buffer.slice()); return byteBuffer; } - + /** * Convert the given input buffer into a direct byte buffer with native * byte order, by casting all elements to byte. - * + * * @param buffer The input buffer * @return The byte buffer */ - public static ByteBuffer castToByteBuffer(IntBuffer buffer) - { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity()) - .order(ByteOrder.nativeOrder()); - for (int i = 0; i < buffer.capacity(); i++) - { + public static ByteBuffer castToByteBuffer(IntBuffer buffer) { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity()) + .order(ByteOrder.nativeOrder()); + for (int i = 0; i < buffer.capacity(); i++) { byteBuffer.put(i, (byte) buffer.get(i)); } return byteBuffer; - } - + } + /** * Convert the given input buffer into a direct byte buffer with native * byte order that contains the elements of the given input buffer, * casted to short. - * + * * @param buffer The input buffer * @return The short buffer */ - public static ByteBuffer castToShortByteBuffer(IntBuffer buffer) - { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity() * Short.BYTES); - ShortBuffer shortBuffer = - byteBuffer.order(ByteOrder.nativeOrder()).asShortBuffer(); - for (int i = 0; i < buffer.capacity(); i++) - { + public static ByteBuffer castToShortByteBuffer(IntBuffer buffer) { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity() * Short.BYTES); + ShortBuffer shortBuffer = + byteBuffer.order(ByteOrder.nativeOrder()).asShortBuffer(); + for (int i = 0; i < buffer.capacity(); i++) { shortBuffer.put(i, (short) buffer.get(i)); } return byteBuffer; } - /** - * Creates a copy of the given buffer, as a direct buffer with the + * Creates a copy of the given buffer, as a direct buffer with the * same byte order, and the given capacity. If the given capacity - * is smaller than that of the given buffer, the copy will be - * truncated. If it is larger, the additional bytes will be + * is smaller than that of the given buffer, the copy will be + * truncated. If it is larger, the additional bytes will be * initialized to zero. - * - * @param buffer The input buffer + * + * @param buffer The input buffer * @param newCapacity The new capacity * @return The copy */ - public static ByteBuffer copyOf(ByteBuffer buffer, int newCapacity) - { + public static ByteBuffer copyOf(ByteBuffer buffer, int newCapacity) { ByteBuffer copy = ByteBuffer.allocateDirect(newCapacity); copy.order(buffer.order()); - if (newCapacity < buffer.capacity()) - { + if (newCapacity < buffer.capacity()) { copy.slice().put(createSlice(buffer, 0, newCapacity)); - } - else - { + } else { copy.slice().put(createSlice(buffer)); } return copy; } - + /** - * Perform a copy of the specified buffer range, analogously to + * Perform a copy of the specified buffer range, analogously to * System#arraycopy. - * - * @param src The source buffer + * + * @param src The source buffer * @param srcPos The source position - * @param dst The destination buffer + * @param dst The destination buffer * @param dstPos The destination position * @param length The length * @throws IndexOutOfBoundsException If the indices are invalid. */ public static void bufferCopy( - ByteBuffer src, int srcPos, - ByteBuffer dst, int dstPos, - int length) - { + ByteBuffer src, int srcPos, + ByteBuffer dst, int dstPos, + int length) { // This could be optimized for large lengths, by using bulk operations // on slices of the buffers - for (int i = 0; i < length; i++) - { + for (int i = 0; i < length; i++) { byte b = src.get(srcPos + i); dst.put(dstPos + i, b); } } - - /** - * Private constructor to prevent instantiation - */ - private Buffers() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/io/ByteBufferInputStream.java b/src/main/java/de/javagl/jgltf/model/io/ByteBufferInputStream.java index 3931d36..4a2c246 100644 --- a/src/main/java/de/javagl/jgltf/model/io/ByteBufferInputStream.java +++ b/src/main/java/de/javagl/jgltf/model/io/ByteBufferInputStream.java @@ -34,42 +34,36 @@ /** * Implementation of an input stream that reads from a byte buffer */ -class ByteBufferInputStream extends InputStream -{ +class ByteBufferInputStream extends InputStream { /** * The byte buffer from which this stream is reading */ private final ByteBuffer byteBuffer; - + /** * Creates a new instance that read from the given byte buffer. * Reading from the stream will increase the position of the * given buffer. If this is not desired, a slice of the actual - * buffer may be passed to this constructor. - * + * buffer may be passed to this constructor. + * * @param byteBuffer The byte buffer from which this stream is reading */ - ByteBufferInputStream(ByteBuffer byteBuffer) - { + ByteBufferInputStream(ByteBuffer byteBuffer) { this.byteBuffer = Objects.requireNonNull(byteBuffer, - "The byteBuffer may not be null"); + "The byteBuffer may not be null"); } - + @Override - public int read() throws IOException - { - if (!byteBuffer.hasRemaining()) - { + public int read() throws IOException { + if (!byteBuffer.hasRemaining()) { return -1; } return byteBuffer.get() & 0xFF; } @Override - public int read(byte[] bytes, int off, int len) throws IOException - { - if (!byteBuffer.hasRemaining()) - { + public int read(byte[] bytes, int off, int len) throws IOException { + if (!byteBuffer.hasRemaining()) { return -1; } int readLength = Math.min(len, byteBuffer.remaining()); diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfAsset.java b/src/main/java/de/javagl/jgltf/model/io/GltfAsset.java index 3f694cb..0ac0504 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfAsset.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfAsset.java @@ -31,38 +31,37 @@ import java.util.Map; /** - * Interface for a low-level representation of a glTF asset, consisting of - * the (version-specific) JSON part, optional binary data, and references + * Interface for a low-level representation of a glTF asset, consisting of + * the (version-specific) JSON part, optional binary data, and references * to external data. */ -public interface GltfAsset -{ +public interface GltfAsset { /** - * Returns the version-specific glTF object. This may be a + * Returns the version-specific glTF object. This may be a * {@link de.javagl.jgltf.impl.v1.GlTF version 1.0 glTF} or * or a {@link de.javagl.jgltf.impl.v2.GlTF version 2.0 glTF} - * + * * @return The glTF */ Object getGltf(); - + /** * Returns the binary data of this asset, or null if this * asset does not have associated binary data.
*
- * The returned buffer will be a slice of the data that is stored + * The returned buffer will be a slice of the data that is stored * internally. So changes of the contents of the buffer will affect * this asset, but changes of the limit or position of the buffer * will not affect this asset. - * + * * @return the optional binary data */ ByteBuffer getBinaryData(); - + /** * Return a list of all {@link GltfReference} objects that refer to * external resources for this asset - * + * * @return The {@link GltfReference} objects */ List getReferences(); @@ -72,25 +71,25 @@ public interface GltfAsset * with the given (relative!) URI, or null if there is * no such data.
*
- * The returned buffer will be a slice of the data that is stored + * The returned buffer will be a slice of the data that is stored * internally. So changes of the contents of the buffer will affect * this asset, but changes of the limit or position of the buffer * will not affect this asset. - * + * * @param uriString The URI string * @return The byte buffer */ ByteBuffer getReferenceData(String uriString); - + /** * Returns an unmodifiable view on the mapping from relative URI strings * to the byte buffers containing the data of the external resources.
- *
- * Callers may not modify the values of this map. That is, the + *
+ * Callers may not modify the values of this map. That is, the * positions or limits of the returned buffers may not be modified! - * + * * @return The reference data mapping */ Map getReferenceDatas(); - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfAssetReader.java b/src/main/java/de/javagl/jgltf/model/io/GltfAssetReader.java index e07476e..c8df8a3 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfAssetReader.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfAssetReader.java @@ -26,17 +26,17 @@ */ package de.javagl.jgltf.model.io; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.GltfModels; +import de.javagl.jgltf.model.io.v1.GltfAssetV1; +import de.javagl.jgltf.model.io.v2.GltfAssetV2; + import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.nio.ByteBuffer; import java.nio.file.Path; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.GltfModels; -import de.javagl.jgltf.model.io.v1.GltfAssetV1; -import de.javagl.jgltf.model.io.v2.GltfAssetV2; - /** * A class for reading a glTF asset in a version-agnostic form.
*
@@ -45,9 +45,9 @@ * of the given URI, and loaded automatically. The respective data may * then be obtained with {@link GltfAsset#getReferenceData(String)}.
*
- * The {@link #readWithoutReferences(URI)} and + * The {@link #readWithoutReferences(URI)} and * {@link #readWithoutReferences(InputStream)} methods allow reading an - * asset from a URI or an input stream, without resolving external + * asset from a URI or an input stream, without resolving external * references. This is mainly intended for binary- or embedded glTF assets * that do not have external references, or for cases where the external * references should be resolved manually.
@@ -55,31 +55,27 @@ * Such a {@link GltfAsset} may then be processed further, for example, * by creating a {@link GltfModel} using {@link GltfModels#create(GltfAsset)}. */ -public final class GltfAssetReader -{ +public final class GltfAssetReader { /** * Creates a new instance */ - public GltfAssetReader() - { + public GltfAssetReader() { // Default constructor } - + /** * Read the {@link GltfAsset} from the given URI - * + * * @param uri The URI * @return The {@link GltfAsset} * @throws IOException If an IO error occurs */ - public GltfAsset read(URI uri) throws IOException - { - try (InputStream inputStream = uri.toURL().openStream()) - { + public GltfAsset read(URI uri) throws IOException { + try (InputStream inputStream = uri.toURL().openStream()) { GltfAsset gltfAsset = readWithoutReferences(inputStream); URI baseUri = IO.getParent(uri); GltfReferenceResolver.resolveAll( - gltfAsset.getReferences(), baseUri); + gltfAsset.getReferences(), baseUri); return gltfAsset; } } @@ -91,14 +87,12 @@ public GltfAsset read(URI uri) throws IOException * @return The {@link GltfAsset} * @throws IOException If an IO error occurs */ - public GltfAsset read(Path path) throws IOException - { - try (InputStream inputStream = path.toUri().toURL().openStream()) - { + public GltfAsset read(Path path) throws IOException { + try (InputStream inputStream = path.toUri().toURL().openStream()) { GltfAsset gltfAsset = readWithoutReferences(inputStream); Path basePath = IO.getParent(path); GltfReferenceResolver.resolveAll( - gltfAsset.getReferences(), basePath); + gltfAsset.getReferences(), basePath); return gltfAsset; } } @@ -111,21 +105,19 @@ public GltfAsset read(Path path) throws IOException *
* This is mainly intended for binary- or embedded glTF assets that do not * have external references. - * + * * @param uri The URI * @return The {@link GltfAsset} * @throws IOException If an IO error occurs */ - public GltfAsset readWithoutReferences(URI uri) throws IOException - { - try (InputStream inputStream = uri.toURL().openStream()) - { + public GltfAsset readWithoutReferences(URI uri) throws IOException { + try (InputStream inputStream = uri.toURL().openStream()) { return readWithoutReferences(inputStream); } } - + /** - * Read the glTF asset from the given input stream. The caller is + * Read the glTF asset from the given input stream. The caller is * responsible for closing the given stream.
*
* In contrast to the {@link #read(URI)} method, this method will @@ -134,55 +126,47 @@ public GltfAsset readWithoutReferences(URI uri) throws IOException * This is mainly intended for binary- or embedded glTF assets that do not * have external references, or for cases where the external * references should be resolved manually. - * + * * @param inputStream The input stream * @return The {@link GltfAsset} * @throws IOException If an IO error occurred */ - public GltfAsset readWithoutReferences(InputStream inputStream) - throws IOException - { + public GltfAsset readWithoutReferences(InputStream inputStream) + throws IOException { RawGltfData rawGltfData = RawGltfDataReader.read(inputStream); return read(rawGltfData); } /** * Read the {@link GltfAsset} from the given {@link RawGltfData} - * + * * @param rawGltfData The {@link RawGltfData} * @return The {@link GltfAsset} * @throws IOException If the data cannot be read */ - GltfAsset read(RawGltfData rawGltfData) throws IOException - { - GltfReader gltfReader = new GltfReader(); + GltfAsset read(RawGltfData rawGltfData) throws IOException { + GltfReader gltfReader = new GltfReader(); ByteBuffer jsonData = rawGltfData.getJsonData(); try (InputStream jsonInputStream = - Buffers.createByteBufferInputStream(jsonData)) - { + Buffers.createByteBufferInputStream(jsonData)) { gltfReader.read(jsonInputStream); int majorVersion = gltfReader.getMajorVersion(); - if (majorVersion == 1) - { - de.javagl.jgltf.impl.v1.GlTF gltfV1 = - gltfReader.getAsGltfV1(); - return new GltfAssetV1(gltfV1, - rawGltfData.getBinaryData()); - } - else if (majorVersion == 2) - { - de.javagl.jgltf.impl.v2.GlTF gltfV2 = - gltfReader.getAsGltfV2(); - return new GltfAssetV2(gltfV2, - rawGltfData.getBinaryData()); - } - else - { + if (majorVersion == 1) { + de.javagl.jgltf.impl.v1.GlTF gltfV1 = + gltfReader.getAsGltfV1(); + return new GltfAssetV1(gltfV1, + rawGltfData.getBinaryData()); + } else if (majorVersion == 2) { + de.javagl.jgltf.impl.v2.GlTF gltfV2 = + gltfReader.getAsGltfV2(); + return new GltfAssetV2(gltfV2, + rawGltfData.getBinaryData()); + } else { throw new IOException( - "Unsupported major version: " + majorVersion); + "Unsupported major version: " + majorVersion); } } } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfAssetWriter.java b/src/main/java/de/javagl/jgltf/model/io/GltfAssetWriter.java index 1af68d9..af5798f 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfAssetWriter.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfAssetWriter.java @@ -26,6 +26,11 @@ */ package de.javagl.jgltf.model.io; +import de.javagl.jgltf.model.io.v1.GltfAssetV1; +import de.javagl.jgltf.model.io.v1.GltfAssetWriterV1; +import de.javagl.jgltf.model.io.v2.GltfAssetV2; +import de.javagl.jgltf.model.io.v2.GltfAssetWriterV2; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -35,193 +40,168 @@ import java.nio.channels.WritableByteChannel; import java.util.Map.Entry; -import de.javagl.jgltf.model.io.v1.GltfAssetV1; -import de.javagl.jgltf.model.io.v1.GltfAssetWriterV1; -import de.javagl.jgltf.model.io.v2.GltfAssetV2; -import de.javagl.jgltf.model.io.v2.GltfAssetWriterV2; - /** * A class for writing a {@link GltfAsset} */ -public class GltfAssetWriter -{ +public class GltfAssetWriter { /** * Default constructor */ - public GltfAssetWriter() - { + public GltfAssetWriter() { // Default constructor } /** - * Write the the given {@link GltfAsset} to a file with the given name. + * Write the the given {@link GltfAsset} to a file with the given name. * The {@link GltfAsset#getBinaryData() binary data} will be ignored. - * The {@link GltfAsset#getReferenceDatas() reference data elements} - * will be written to files that are determined by resolving the + * The {@link GltfAsset#getReferenceDatas() reference data elements} + * will be written to files that are determined by resolving the * (relative) URLs of the references against the parent of the specified - * file. - * + * file. + * * @param gltfAsset The {@link GltfAsset} - * @param fileName The file name for the JSON file + * @param fileName The file name for the JSON file * @throws IOException If an IO error occurred */ - public void write(GltfAsset gltfAsset, String fileName) - throws IOException - { + public void write(GltfAsset gltfAsset, String fileName) + throws IOException { write(gltfAsset, new File(fileName)); } - + /** - * Write the the given {@link GltfAsset} to the given file. + * Write the the given {@link GltfAsset} to the given file. * The {@link GltfAsset#getBinaryData() binary data} will be ignored. - * The {@link GltfAsset#getReferenceDatas() reference data elements} - * will be written to files that are determined by resolving the + * The {@link GltfAsset#getReferenceDatas() reference data elements} + * will be written to files that are determined by resolving the * (relative) URLs of the references against the parent of the specified - * file. - * + * file. + * * @param gltfAsset The {@link GltfAsset} - * @param file The file for the JSON part + * @param file The file for the JSON part * @throws IOException If an IO error occurred */ - public void write(GltfAsset gltfAsset, File file) - throws IOException - { - try (OutputStream outputStream = new FileOutputStream(file)) - { + public void write(GltfAsset gltfAsset, File file) + throws IOException { + try (OutputStream outputStream = new FileOutputStream(file)) { writeJson(gltfAsset, outputStream); } - for (Entry entry : - gltfAsset.getReferenceDatas().entrySet()) - { + for (Entry entry : + gltfAsset.getReferenceDatas().entrySet()) { String relativeUrlString = entry.getKey(); ByteBuffer data = entry.getValue(); - - String referenceFileName = - file.toPath().getParent().resolve(relativeUrlString).toString(); + + String referenceFileName = + file.toPath().getParent().resolve(relativeUrlString).toString(); try (@SuppressWarnings("resource") - WritableByteChannel writableByteChannel = - Channels.newChannel(new FileOutputStream(referenceFileName))) - { + WritableByteChannel writableByteChannel = + Channels.newChannel(new FileOutputStream(referenceFileName))) { writableByteChannel.write(data.slice()); } } } - + /** - * Write the JSON part of the given {@link GltfAsset} to a file with + * Write the JSON part of the given {@link GltfAsset} to a file with * the given name. The {@link GltfAsset#getBinaryData() binary data} * and {@link GltfAsset#getReferenceDatas() reference data elements} * will be ignored. - * + * * @param gltfAsset The {@link GltfAsset} - * @param fileName The file name for the JSON file + * @param fileName The file name for the JSON file * @throws IOException If an IO error occurred */ - public void writeJson(GltfAsset gltfAsset, String fileName) - throws IOException - { + public void writeJson(GltfAsset gltfAsset, String fileName) + throws IOException { writeJson(gltfAsset, new File(fileName)); } - + /** - * Write the JSON part of the given {@link GltfAsset} to a file with + * Write the JSON part of the given {@link GltfAsset} to a file with * the given name. The {@link GltfAsset#getBinaryData() binary data} * and {@link GltfAsset#getReferenceDatas() reference data elements} * will be ignored. - * + * * @param gltfAsset The {@link GltfAsset} - * @param file The file for the JSON part + * @param file The file for the JSON part * @throws IOException If an IO error occurred */ - public void writeJson(GltfAsset gltfAsset, File file) - throws IOException - { - try (OutputStream outputStream = new FileOutputStream(file)) - { + public void writeJson(GltfAsset gltfAsset, File file) + throws IOException { + try (OutputStream outputStream = new FileOutputStream(file)) { writeJson(gltfAsset, outputStream); } } - + /** * Write the JSON part of the given {@link GltfAsset} to the given * output stream. The {@link GltfAsset#getBinaryData() binary data} * and {@link GltfAsset#getReferenceDatas() reference data elements} * will be ignored. The caller is responsible for closing the given * stream. - * - * @param gltfAsset The {@link GltfAsset} + * + * @param gltfAsset The {@link GltfAsset} * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void writeJson(GltfAsset gltfAsset, OutputStream outputStream) - throws IOException - { + public void writeJson(GltfAsset gltfAsset, OutputStream outputStream) + throws IOException { Object gltf = gltfAsset.getGltf(); GltfWriter gltfWriter = new GltfWriter(); gltfWriter.write(gltf, outputStream); } - + /** - * Write the given {@link GltfAsset} as a binary glTF asset to file with + * Write the given {@link GltfAsset} as a binary glTF asset to file with * the given name. - * + * * @param gltfAsset The {@link GltfAsset} - * @param fileName The file name for the JSON file + * @param fileName The file name for the JSON file * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAsset gltfAsset, String fileName) - throws IOException - { + public void writeBinary(GltfAsset gltfAsset, String fileName) + throws IOException { writeBinary(gltfAsset, new File(fileName)); } - + /** * Write the given {@link GltfAsset} as a binary glTF asset to the given * file - * + * * @param gltfAsset The {@link GltfAsset} - * @param file The file + * @param file The file * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAsset gltfAsset, File file) - throws IOException - { - try (OutputStream outputStream = new FileOutputStream(file)) - { + public void writeBinary(GltfAsset gltfAsset, File file) + throws IOException { + try (OutputStream outputStream = new FileOutputStream(file)) { writeBinary(gltfAsset, outputStream); } } - + /** - * Write the given {@link GltfAsset} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * Write the given {@link GltfAsset} as a binary glTF asset to the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfAsset The {@link GltfAsset} + * + * @param gltfAsset The {@link GltfAsset} * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAsset gltfAsset, OutputStream outputStream) - throws IOException - { - if (gltfAsset instanceof GltfAssetV1) - { - GltfAssetV1 gltfAssetV1 = (GltfAssetV1)gltfAsset; + public void writeBinary(GltfAsset gltfAsset, OutputStream outputStream) + throws IOException { + if (gltfAsset instanceof GltfAssetV1) { + GltfAssetV1 gltfAssetV1 = (GltfAssetV1) gltfAsset; GltfAssetWriterV1 gltfAssetWriterV1 = new GltfAssetWriterV1(); gltfAssetWriterV1.writeBinary(gltfAssetV1, outputStream); - } - else if (gltfAsset instanceof GltfAssetV2) - { - GltfAssetV2 gltfAssetV2 = (GltfAssetV2)gltfAsset; + } else if (gltfAsset instanceof GltfAssetV2) { + GltfAssetV2 gltfAssetV2 = (GltfAssetV2) gltfAsset; GltfAssetWriterV2 gltfAssetWriterV2 = new GltfAssetWriterV2(); gltfAssetWriterV2.writeBinary(gltfAssetV2, outputStream); - } - else - { + } else { throw new IOException( - "The gltfAsset has an unknown version: " + gltfAsset); + "The gltfAsset has an unknown version: " + gltfAsset); } } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfAssets.java b/src/main/java/de/javagl/jgltf/model/io/GltfAssets.java index 4e30b8d..fe40aed 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfAssets.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfAssets.java @@ -32,144 +32,126 @@ /** * Utility methods related to {@link GltfAsset} instances.
*
- * The methods in this class may be used to check the "nature" of a - * {@link GltfAsset}. A default asset may contain references with - * URIs that refer to a file. An embedded asset may contain + * The methods in this class may be used to check the "nature" of a + * {@link GltfAsset}. A default asset may contain references with + * URIs that refer to a file. An embedded asset may contain * references with URIs that are data URIs. A binary asset may * contain a binary data blob. Mixed forms of assets are possible: * It is possible to create an asset where one URI refers to a file, * and another URI is a data URI. The methods in this class allow - * checking whether an asset is "purely" of one specific type. + * checking whether an asset is "purely" of one specific type. *
* This class should not be considered as part of the public API. It may * change or be omitted in the future. */ -public class GltfAssets -{ +public class GltfAssets { + /** + * Private constructor to prevent instantiation + */ + private GltfAssets() { + // Private constructor to prevent instantiation + } + /** * Returns whether the given {@link GltfAsset} is a default - * asset. This means that it does not contain a (non-empty) + * asset. This means that it does not contain a (non-empty) * {@link GltfAsset#getBinaryData() binary data} blob, and it * does not contain references with (embedded) data URIs. - * + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset is a default asset */ - public static boolean isDefault(GltfAsset gltfAsset) - { + public static boolean isDefault(GltfAsset gltfAsset) { ByteBuffer binaryData = gltfAsset.getBinaryData(); - if (binaryData != null && binaryData.capacity() > 0) - { + if (binaryData != null && binaryData.capacity() > 0) { return false; } - if (containsDataUriReferences(gltfAsset)) - { + if (containsDataUriReferences(gltfAsset)) { return false; } return true; } - + /** * Returns whether the given {@link GltfAsset} is an embedded - * asset. This means that it does not contain a (non-empty) + * asset. This means that it does not contain a (non-empty) * {@link GltfAsset#getBinaryData() binary data} blob, and it * does not contain references that refer to files. - * + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset is an embedded asset */ - public static boolean isEmbedded(GltfAsset gltfAsset) - { + public static boolean isEmbedded(GltfAsset gltfAsset) { ByteBuffer binaryData = gltfAsset.getBinaryData(); - if (binaryData != null && binaryData.capacity() > 0) - { + if (binaryData != null && binaryData.capacity() > 0) { return false; } - if (containsFileUriReferences(gltfAsset)) - { + if (containsFileUriReferences(gltfAsset)) { return false; } return true; } - + /** * Returns whether the given {@link GltfAsset} is binary - * asset. This means that it does does not contain references + * asset. This means that it does does not contain references * that refer to files or have (embedded) data URIs. (Note that - * this method returns true in this case even if + * this method returns true in this case even if * the asset does not have a {@link GltfAsset#getBinaryData() binary data} - * blob) - * + * blob) + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset is a binary asset */ - public static boolean isBinary(GltfAsset gltfAsset) - { - if (containsFileUriReferences(gltfAsset)) - { + public static boolean isBinary(GltfAsset gltfAsset) { + if (containsFileUriReferences(gltfAsset)) { return false; } - if (containsDataUriReferences(gltfAsset)) - { + if (containsDataUriReferences(gltfAsset)) { return false; } return true; } - + /** - * Returns whether the given {@link GltfAsset} contains any + * Returns whether the given {@link GltfAsset} contains any * {@link GltfReference} that has a URI that is not a data URI.
*
- * If the asset does not contain any references, then + * If the asset does not contain any references, then * false is returned.
- * + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset contains (non-data) URI references */ - private static boolean containsFileUriReferences(GltfAsset gltfAsset) - { + private static boolean containsFileUriReferences(GltfAsset gltfAsset) { List references = gltfAsset.getReferences(); - for (GltfReference reference : references) - { + for (GltfReference reference : references) { String uriString = reference.getUri(); - if (!IO.isDataUriString(uriString)) - { + if (!IO.isDataUriString(uriString)) { return true; } } return false; } - + /** - * Returns whether the given {@link GltfAsset} contains any + * Returns whether the given {@link GltfAsset} contains any * {@link GltfReference} that has a URI that is a data URI.
*
- * If the asset does not contain any references, then + * If the asset does not contain any references, then * false is returned.
- * + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset contains data URI references */ - private static boolean containsDataUriReferences(GltfAsset gltfAsset) - { + private static boolean containsDataUriReferences(GltfAsset gltfAsset) { List references = gltfAsset.getReferences(); - for (GltfReference reference : references) - { + for (GltfReference reference : references) { String uriString = reference.getUri(); - if (!IO.isDataUriString(uriString)) - { + if (!IO.isDataUriString(uriString)) { return true; } } return false; } - - - /** - * Private constructor to prevent instantiation - */ - private GltfAssets() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfModelReader.java b/src/main/java/de/javagl/jgltf/model/io/GltfModelReader.java index cf98047..76c6e48 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfModelReader.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfModelReader.java @@ -26,39 +26,56 @@ */ package de.javagl.jgltf.model.io; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.nio.file.Path; - import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.io.v1.GltfAssetV1; import de.javagl.jgltf.model.io.v2.GltfAssetV2; import de.javagl.jgltf.model.v1.GltfModelV1; import de.javagl.jgltf.model.v2.GltfModelCreatorV2; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.Path; + /** * A class for reading a {@link GltfModel} from a URI. */ -public final class GltfModelReader -{ +public final class GltfModelReader { /** * Default constructor */ - public GltfModelReader() - { + public GltfModelReader() { // Default constructor } - + + /** + * Creates a {@link GltfModel} instance from the given {@link GltfAsset} + * + * @param gltfAsset The {@link GltfAsset} + * @return The {@link GltfModel} + * @throws IOException If the given asset has an unknown version + */ + private static GltfModel createModel(GltfAsset gltfAsset) throws IOException { + if (gltfAsset instanceof GltfAssetV1) { + GltfAssetV1 gltfAssetV1 = (GltfAssetV1) gltfAsset; + return new GltfModelV1(gltfAssetV1); + } + if (gltfAsset instanceof GltfAssetV2) { + GltfAssetV2 gltfAssetV2 = (GltfAssetV2) gltfAsset; + return GltfModelCreatorV2.create(gltfAssetV2); + } + throw new IOException( + "The glTF asset has an unknown version: " + gltfAsset); + } + /** * Read the {@link GltfModel} from the given URI - * + * * @param uri The URI * @return The {@link GltfModel} * @throws IOException If an IO error occurs */ - public GltfModel read(URI uri) throws IOException - { + public GltfModel read(URI uri) throws IOException { GltfAssetReader gltfAssetReader = new GltfAssetReader(); GltfAsset gltfAsset = gltfAssetReader.read(uri); return createModel(gltfAsset); @@ -71,76 +88,49 @@ public GltfModel read(URI uri) throws IOException * @return The {@link GltfModel} * @throws IOException If an IO error occurs */ - public GltfModel read(Path path) throws IOException - { + public GltfModel read(Path path) throws IOException { GltfAssetReader gltfAssetReader = new GltfAssetReader(); GltfAsset gltfAsset = gltfAssetReader.read(path); return createModel(gltfAsset); } /** - * Read the {@link GltfModel} from the given URI. In contrast to the - * {@link #read(URI)} method, this method will not resolve any + * Read the {@link GltfModel} from the given URI. In contrast to the + * {@link #read(URI)} method, this method will not resolve any * references that are contained in the {@link GltfModel}.
*
* This is mainly intended for binary- or embedded glTF assets that do not * have external references. - * + * * @param uri The URI * @return The {@link GltfModel} * @throws IOException If an IO error occurs */ - public GltfModel readWithoutReferences(URI uri) throws IOException - { - try (InputStream inputStream = uri.toURL().openStream()) - { + public GltfModel readWithoutReferences(URI uri) throws IOException { + try (InputStream inputStream = uri.toURL().openStream()) { GltfModel gltfModel = readWithoutReferences(inputStream); return gltfModel; } } - + /** * Read the {@link GltfModel} from the given input stream. In contrast - * to the {@link #read(URI)} method, this method will not resolve any + * to the {@link #read(URI)} method, this method will not resolve any * references that are contained in the {@link GltfAsset}.
*
* This is mainly intended for binary- or embedded glTF assets that do not * have external references. - * + * * @param inputStream The input stream to read from * @return The {@link GltfModel} * @throws IOException If an IO error occurs */ - public GltfModel readWithoutReferences(InputStream inputStream) - throws IOException - { + public GltfModel readWithoutReferences(InputStream inputStream) + throws IOException { GltfAssetReader gltfAssetReader = new GltfAssetReader(); - GltfAsset gltfAsset = - gltfAssetReader.readWithoutReferences(inputStream); + GltfAsset gltfAsset = + gltfAssetReader.readWithoutReferences(inputStream); return createModel(gltfAsset); } - - /** - * Creates a {@link GltfModel} instance from the given {@link GltfAsset} - * - * @param gltfAsset The {@link GltfAsset} - * @return The {@link GltfModel} - * @throws IOException If the given asset has an unknown version - */ - private static GltfModel createModel(GltfAsset gltfAsset) throws IOException - { - if (gltfAsset instanceof GltfAssetV1) - { - GltfAssetV1 gltfAssetV1 = (GltfAssetV1)gltfAsset; - return new GltfModelV1(gltfAssetV1); - } - if (gltfAsset instanceof GltfAssetV2) - { - GltfAssetV2 gltfAssetV2 = (GltfAssetV2)gltfAsset; - return GltfModelCreatorV2.create(gltfAssetV2); - } - throw new IOException( - "The glTF asset has an unknown version: " + gltfAsset); - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfModelWriter.java b/src/main/java/de/javagl/jgltf/model/io/GltfModelWriter.java index 4c44855..374e36d 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfModelWriter.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfModelWriter.java @@ -26,158 +26,145 @@ */ package de.javagl.jgltf.model.io; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.io.v1.GltfModelWriterV1; import de.javagl.jgltf.model.io.v2.GltfModelWriterV2; import de.javagl.jgltf.model.v1.GltfModelV1; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + /** * A class for writing a {@link GltfModel}. The model can be written as - * a default glTF, consisting of a JSON file and the files that are + * a default glTF, consisting of a JSON file and the files that are * referred to via URIs, or as a binary file, or an embedded file where * all external references are replaced by data URIs. */ -public class GltfModelWriter -{ +public class GltfModelWriter { /** * Default constructor */ - public GltfModelWriter() - { + public GltfModelWriter() { // Default constructor } /** - * Write the given {@link GltfModel} to a file with the given name. - * External references of buffers or images that are given via the - * respective URI string will be resolved against the parent directory - * of the file, and the corresponding data will be written into the - * corresponding files. - * + * Write the given {@link GltfModel} to a file with the given name. + * External references of buffers or images that are given via the + * respective URI string will be resolved against the parent directory + * of the file, and the corresponding data will be written into the + * corresponding files. + * * @param gltfModel The {@link GltfModel} - * @param fileName The file name + * @param fileName The file name * @throws IOException If an IO error occurs */ - public void write(GltfModel gltfModel, String fileName) - throws IOException - { + public void write(GltfModel gltfModel, String fileName) + throws IOException { write(gltfModel, new File(fileName)); } - + /** * Write the given {@link GltfModel} to the given file. External - * references of buffers or images that are given via the respective - * URI string will be resolved against the parent directory of the - * given file, and the corresponding data will be written into the - * corresponding files. - * + * references of buffers or images that are given via the respective + * URI string will be resolved against the parent directory of the + * given file, and the corresponding data will be written into the + * corresponding files. + * * @param gltfModel The {@link GltfModel} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void write(GltfModel gltfModel, File file) - throws IOException - { - if (gltfModel instanceof GltfModelV1) - { - GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; - GltfModelWriterV1 gltfModelWriterV1 = - new GltfModelWriterV1(); + public void write(GltfModel gltfModel, File file) + throws IOException { + if (gltfModel instanceof GltfModelV1) { + GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; + GltfModelWriterV1 gltfModelWriterV1 = + new GltfModelWriterV1(); gltfModelWriterV1.write(gltfModelV1, file); return; } - GltfModelWriterV2 gltfModelWriterV2 = - new GltfModelWriterV2(); + GltfModelWriterV2 gltfModelWriterV2 = + new GltfModelWriterV2(); gltfModelWriterV2.write(gltfModel, file); } - + /** * Write the given {@link GltfModel} as a binary glTF asset to the * given file - * + * * @param gltfModel The {@link GltfModel} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModel gltfModel, File file) - throws IOException - { - try (OutputStream outputStream = new FileOutputStream(file)) - { + public void writeBinary(GltfModel gltfModel, File file) + throws IOException { + try (OutputStream outputStream = new FileOutputStream(file)) { writeBinary(gltfModel, outputStream); } } - + /** * Write the given {@link GltfModel} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModel gltfModel, OutputStream outputStream) - throws IOException - { - if (gltfModel instanceof GltfModelV1) - { - GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; - GltfModelWriterV1 gltfModelWriterV1 = - new GltfModelWriterV1(); + public void writeBinary(GltfModel gltfModel, OutputStream outputStream) + throws IOException { + if (gltfModel instanceof GltfModelV1) { + GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; + GltfModelWriterV1 gltfModelWriterV1 = + new GltfModelWriterV1(); gltfModelWriterV1.writeBinary(gltfModelV1, outputStream); return; } - GltfModelWriterV2 gltfModelWriterV2 = - new GltfModelWriterV2(); + GltfModelWriterV2 gltfModelWriterV2 = + new GltfModelWriterV2(); gltfModelWriterV2.writeBinary(gltfModel, outputStream); } - + /** * Write the given {@link GltfModel} as an embedded glTF asset to the * given file - * + * * @param gltfModel The {@link GltfModel} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void writeEmbedded(GltfModel gltfModel, File file) - throws IOException - { - try (OutputStream outputStream = new FileOutputStream(file)) - { + public void writeEmbedded(GltfModel gltfModel, File file) + throws IOException { + try (OutputStream outputStream = new FileOutputStream(file)) { writeEmbedded(gltfModel, outputStream); } } - + /** * Write the given {@link GltfModel} as an embedded glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeEmbedded(GltfModel gltfModel, OutputStream outputStream) - throws IOException - { - if (gltfModel instanceof GltfModelV1) - { - GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; - GltfModelWriterV1 gltfModelWriterV1 = - new GltfModelWriterV1(); + public void writeEmbedded(GltfModel gltfModel, OutputStream outputStream) + throws IOException { + if (gltfModel instanceof GltfModelV1) { + GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; + GltfModelWriterV1 gltfModelWriterV1 = + new GltfModelWriterV1(); gltfModelWriterV1.writeEmbedded(gltfModelV1, outputStream); return; } - GltfModelWriterV2 gltfModelWriterV2 = - new GltfModelWriterV2(); + GltfModelWriterV2 gltfModelWriterV2 = + new GltfModelWriterV2(); gltfModelWriterV2.writeEmbedded(gltfModel, outputStream); } } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfReader.java b/src/main/java/de/javagl/jgltf/model/io/GltfReader.java index b92f545..4a89d32 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfReader.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfReader.java @@ -26,145 +26,131 @@ */ package de.javagl.jgltf.model.io; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.logging.Logger; -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; - /** * A class for reading the JSON for a glTF asset in a version-agnostic form. - * It a allows determining the version of the glTF and returning it as + * It a allows determining the version of the glTF and returning it as * a properly typed object - that is, as a {@link de.javagl.jgltf.impl.v1.GlTF} * or a {@link de.javagl.jgltf.impl.v2.GlTF}.
*/ -final class GltfReader -{ +final class GltfReader { /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(GltfReader.class.getName()); + Logger.getLogger(GltfReader.class.getName()); /** * The root node that was read during the last call to {@link #read} */ private JsonElement rootNode; - + + /** + * Tries to obtain the rootNode.asset.version string. If + * either node is null, then "1.0" will be + * returned. + * + * @param rootNode The root node + * @return The version + */ + private static String getVersion(JsonElement rootNode) { + JsonElement assetNode = rootNode.getAsJsonObject().get("asset"); + if (assetNode == null) { + return "1.0"; + } + JsonElement versionNode = assetNode.getAsJsonObject().get("version"); + if (versionNode == null) { + return "1.0"; + } + if (!versionNode.isJsonPrimitive()) { + logger.warning("No valid 'version' property in 'asset'. " + + "Assuming version 1.0"); + return "1.0"; + } + return versionNode.getAsString(); + } + /** - * Read the JSON data from the given input stream. The caller is + * Read the JSON data from the given input stream. The caller is * responsible for closing the given stream. After this method * has been called, the version of the glTF may be obtained with * {@link #getVersion()}, and the actual asset may be obtained * with {@link #getAsGltfV1()} or {@link #getAsGltfV2()}. - * + * * @param inputStream The input stream * @throws IOException If an IO error occurred */ - void read(InputStream inputStream) throws IOException - { - InputStreamReader reader = new InputStreamReader(inputStream); - rootNode = JsonParser.parseReader(reader); - reader.close(); + void read(InputStream inputStream) throws IOException { + InputStreamReader reader = new InputStreamReader(inputStream); + rootNode = JsonParser.parseReader(reader); + reader.close(); } - + /** * Returns the version of the glTF, or null * if no glTF was read yet - * + * * @return The version string */ - String getVersion() - { - if (rootNode == null) - { + String getVersion() { + if (rootNode == null) { return null; } return getVersion(rootNode); } - + /** * Returns the major version of the glTF, or 0 of no glTF was read yet. - * + * * @return The major version number */ - int getMajorVersion() - { - if (rootNode == null) - { + int getMajorVersion() { + if (rootNode == null) { return 0; } int version[] = VersionUtils.computeMajorMinorPatch(getVersion()); return version[0]; } - + /** - * Obtain the glTF as a {@link de.javagl.jgltf.impl.v1.GlTF}, + * Obtain the glTF as a {@link de.javagl.jgltf.impl.v1.GlTF}, * or null if no glTF was read yet. - * + * * @return The glTF. * @throws IllegalArgumentException If the glTF that was read is not - * a valid glTF 1.0 + * a valid glTF 1.0 */ - de.javagl.jgltf.impl.v1.GlTF getAsGltfV1() - { - if (rootNode == null) - { + de.javagl.jgltf.impl.v1.GlTF getAsGltfV1() { + if (rootNode == null) { return null; } - return new Gson().fromJson(rootNode, - de.javagl.jgltf.impl.v1.GlTF.class); + return new Gson().fromJson(rootNode, + de.javagl.jgltf.impl.v1.GlTF.class); } - + /** - * Obtain the glTF as a {@link de.javagl.jgltf.impl.v2.GlTF}, + * Obtain the glTF as a {@link de.javagl.jgltf.impl.v2.GlTF}, * or null if no glTF was read yet. - * + * * @return The glTF. * @throws IllegalArgumentException If the glTF that was read is not - * a valid glTF 2.0 + * a valid glTF 2.0 */ - de.javagl.jgltf.impl.v2.GlTF getAsGltfV2() - { - if (rootNode == null) - { + de.javagl.jgltf.impl.v2.GlTF getAsGltfV2() { + if (rootNode == null) { return null; } - return new Gson().fromJson(rootNode, - de.javagl.jgltf.impl.v2.GlTF.class); + return new Gson().fromJson(rootNode, + de.javagl.jgltf.impl.v2.GlTF.class); } - - /** - * Tries to obtain the rootNode.asset.version string. If - * either node is null, then "1.0" will be - * returned. - * - * @param rootNode The root node - * @return The version - */ - private static String getVersion(JsonElement rootNode) - { - JsonElement assetNode = rootNode.getAsJsonObject().get("asset"); - if (assetNode == null) - { - return "1.0"; - } - JsonElement versionNode = assetNode.getAsJsonObject().get("version"); - if (versionNode == null) - { - return "1.0"; - } - if (!versionNode.isJsonPrimitive()) - { - logger.warning("No valid 'version' property in 'asset'. " + - "Assuming version 1.0"); - return "1.0"; - } - return versionNode.getAsString(); - } - - + + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfReference.java b/src/main/java/de/javagl/jgltf/model/io/GltfReference.java index be72717..7eabd97 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfReference.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfReference.java @@ -33,70 +33,65 @@ /** * A reference to an external resource that belongs to a {@link GltfAsset}. */ -public final class GltfReference -{ +public final class GltfReference { /** * The name of the external resource */ private final String name; - + /** * The (relative) URI of the reference */ private final String uri; - + /** * The target that is supposed to receive the binary data that was * read from the external resource */ private final Consumer target; - + /** * Default constructor - * - * @param name The name of the external resource - * @param uri The (relative) URI of the reference + * + * @param name The name of the external resource + * @param uri The (relative) URI of the reference * @param target The target that is supposed to receive the binary - * data that was read from the external resource + * data that was read from the external resource */ - public GltfReference(String name, String uri, Consumer target) - { + public GltfReference(String name, String uri, Consumer target) { this.name = Objects.requireNonNull( - name, "The name may not be null"); + name, "The name may not be null"); this.uri = Objects.requireNonNull( - uri, "The uri may not be null"); + uri, "The uri may not be null"); this.target = Objects.requireNonNull( - target, "The target may not be null"); + target, "The target may not be null"); } - + /** * Returns the name of the external resource - * + * * @return The name */ - public String getName() - { + public String getName() { return name; } - + /** * Returns the (relative) URI of the reference - * + * * @return The URI */ - public String getUri() - { + public String getUri() { return uri; } - + /** * Returns the target that is supposed to receive the binary * data that was read from the external resource - * + * * @return The target */ - public Consumer getTarget() - { + public Consumer getTarget() { return target; } } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfReferenceResolver.java b/src/main/java/de/javagl/jgltf/model/io/GltfReferenceResolver.java index 56e596b..a7697e2 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfReferenceResolver.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfReferenceResolver.java @@ -38,29 +38,34 @@ * A class for resolving the external data of {@link GltfReference} objects * that are obtained from a {@link GltfAsset} */ -public class GltfReferenceResolver -{ +public class GltfReferenceResolver { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfReferenceResolver.class.getName()); + private static final Logger logger = + Logger.getLogger(GltfReferenceResolver.class.getName()); /** - * Calls {@link #resolve(GltfReference, Function)} with each + * Private constructor to prevent instantiation + */ + private GltfReferenceResolver() { + // Private constructor to prevent instantiation + } + + /** + * Calls {@link #resolve(GltfReference, Function)} with each * {@link GltfReference} of the given list, resolving the * URIs of the references against the given base URI - * + * * @param references The {@link GltfReference} objects - * @param baseUri The base URI that references will be resolved against + * @param baseUri The base URI that references will be resolved against */ public static void resolveAll( - Iterable references, URI baseUri) - { + Iterable references, URI baseUri) { Objects.requireNonNull(references, "The references may not be null"); Objects.requireNonNull(baseUri, "The baseUri may not be null"); - Function uriResolver = - UriResolvers.createBaseUriResolver(baseUri); + Function uriResolver = + UriResolvers.createBaseUriResolver(baseUri); resolveAll(references, uriResolver); } @@ -70,72 +75,59 @@ public static void resolveAll( * Paths of the references against the given base Path * * @param references The {@link GltfReference} objects - * @param basePath The base Path that references will be resolved against + * @param basePath The base Path that references will be resolved against */ public static void resolveAll( - Iterable references, Path basePath) - { + Iterable references, Path basePath) { Objects.requireNonNull(references, "The references may not be null"); Objects.requireNonNull(basePath, "The basePath may not be null"); Function uriResolver = - UriResolvers.createBasePathResolver(basePath); + UriResolvers.createBasePathResolver(basePath); resolveAll(references, uriResolver); } /** - * Calls {@link #resolve(GltfReference, Function)} with each + * Calls {@link #resolve(GltfReference, Function)} with each * {@link GltfReference} of the given list - * - * @param references The {@link GltfReference} objects + * + * @param references The {@link GltfReference} objects * @param uriResolver The function for resolving a URI string - * into a byte buffer + * into a byte buffer */ public static void resolveAll( - Iterable references, - Function uriResolver) - { + Iterable references, + Function uriResolver) { Objects.requireNonNull(references, "The references may not be null"); Objects.requireNonNull(uriResolver, "The uriResolver may not be null"); - for (GltfReference reference : references) - { + for (GltfReference reference : references) { resolve(reference, uriResolver); } } - + /** - * Pass the {@link GltfReference#getUri() URI} of the given - * {@link GltfReference} to the given resolver function, - * and and pass the resulting byte buffer to the + * Pass the {@link GltfReference#getUri() URI} of the given + * {@link GltfReference} to the given resolver function, + * and and pass the resulting byte buffer to the * {@link GltfReference#getTarget() target} of the reference. If * a URI cannot be resolved, a warning will be printed. - * - * @param reference The {@link GltfReference} + * + * @param reference The {@link GltfReference} * @param uriResolver The function for resolving a URI string - * into an byte buffer + * into an byte buffer */ - public static void resolve(GltfReference reference, - Function uriResolver) - { + public static void resolve(GltfReference reference, + Function uriResolver) { Objects.requireNonNull(reference, "The reference may not be null"); Objects.requireNonNull(uriResolver, "The uriResolver may not be null"); String uri = reference.getUri(); ByteBuffer byteBuffer = uriResolver.apply(uri); - if (byteBuffer == null) - { + if (byteBuffer == null) { logger.warning("Could not resolve URI " + uri); } Consumer target = reference.getTarget(); target.accept(byteBuffer); } - - /** - * Private constructor to prevent instantiation - */ - private GltfReferenceResolver() - { - // Private constructor to prevent instantiation - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfWriter.java b/src/main/java/de/javagl/jgltf/model/io/GltfWriter.java index 5befb1c..87ed1f9 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfWriter.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfWriter.java @@ -26,72 +26,66 @@ */ package de.javagl.jgltf.model.io; +import com.google.gson.GsonBuilder; + import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; -import com.google.gson.GsonBuilder; - /** * A class for writing a glTF as JSON */ -public final class GltfWriter -{ +public final class GltfWriter { /** * Whether the JSON output should be indented */ private boolean indenting; - + /** * Creates a new glTF writer. By default, the output written by this class * will be indented. */ - public GltfWriter() - { + public GltfWriter() { this.indenting = true; } - - /** - * Set whether the JSON output should be indented - * - * @param indenting whether the JSON output should be indented - */ - public void setIndenting(boolean indenting) - { - this.indenting = indenting; - } - + /** * Returns whether the JSON output will be indented - * + * * @return Whether the JSON output will be indented */ - public boolean isIndenting() - { + public boolean isIndenting() { return indenting; } - + + /** + * Set whether the JSON output should be indented + * + * @param indenting whether the JSON output should be indented + */ + public void setIndenting(boolean indenting) { + this.indenting = indenting; + } + /** * Write the given glTF to the given output stream. The caller * is responsible for closing the stream. - * - * @param gltf The glTF + * + * @param gltf The glTF * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void write(Object gltf, OutputStream outputStream) - throws IOException - { - GsonBuilder gsonBuilder = new GsonBuilder(); - if (indenting) - { - gsonBuilder.setPrettyPrinting(); + public void write(Object gltf, OutputStream outputStream) + throws IOException { + GsonBuilder gsonBuilder = new GsonBuilder(); + if (indenting) { + gsonBuilder.setPrettyPrinting(); } OutputStreamWriter writer = new OutputStreamWriter(outputStream); gsonBuilder.create().toJson(gsonBuilder, writer); writer.close(); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/IO.java b/src/main/java/de/javagl/jgltf/model/io/IO.java index 8571952..7cb5a07 100644 --- a/src/main/java/de/javagl/jgltf/model/io/IO.java +++ b/src/main/java/de/javagl/jgltf/model/io/IO.java @@ -26,17 +26,8 @@ */ package de.javagl.jgltf.model.io; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; +import java.io.*; +import java.net.*; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; @@ -44,79 +35,73 @@ /** * IO utility methods */ -public class IO -{ +public class IO { + /** + * Private constructor to prevent instantiation + */ + private IO() { + // Private constructor to prevent instantiation + } + /** * Convert the given URI string into an absolute URI, resolving it * against the given base URI if necessary - * - * @param baseUri The base URI + * + * @param baseUri The base URI * @param uriString The URI string * @return The absolute URI * @throws IOException If the URI string is not valid */ - public static URI makeAbsolute(URI baseUri, String uriString) - throws IOException - { - try - { + public static URI makeAbsolute(URI baseUri, String uriString) + throws IOException { + try { String escapedUriString = uriString.replaceAll(" ", "%20"); URI uri = new URI(escapedUriString); - if (uri.isAbsolute()) - { + if (uri.isAbsolute()) { return uri; } return baseUri.resolve(escapedUriString); - } - catch (URISyntaxException e) - { + } catch (URISyntaxException e) { throw new IOException("Invalid URI string: " + uriString, e); } } - + /** * Convert the given URI string into an absolute path, resolving it * against the given base path if necessary * - * @param basePath The base path + * @param basePath The base path * @param uriString The URI string * @return The absolute path * @throws IOException If the URI string is not valid */ public static Path makeAbsolute(Path basePath, String uriString) - throws IOException - { - try - { + throws IOException { + try { String escapedUriString = uriString.replaceAll(" ", "%20"); URI uri = new URI(escapedUriString); - if (uri.isAbsolute()) - { + if (uri.isAbsolute()) { return Paths.get(uri).toAbsolutePath(); } return basePath.resolve(escapedUriString).toAbsolutePath(); - } - catch (URISyntaxException e) - { + } catch (URISyntaxException e) { throw new IOException("Invalid URI string: " + uriString, e); } } /** - * Returns the URI describing the parent of the given URI. If the - * given URI describes a file, this will return the URI of the + * Returns the URI describing the parent of the given URI. If the + * given URI describes a file, this will return the URI of the * directory. If the given URI describes a directory, this will * return the URI of the parent directory - * + * * @param uri The URI * @return The parent URI */ - public static URI getParent(URI uri) - { - if (uri.getPath().endsWith("/")) - { - return uri.resolve(".."); + public static URI getParent(URI uri) { + if (uri.getPath().endsWith("/")) { + return uri.resolve(".."); } return uri.resolve("."); } @@ -130,103 +115,88 @@ public static URI getParent(URI uri) * @param path The path * @return The parent path */ - public static Path getParent(Path path) - { + public static Path getParent(Path path) { return path.getParent(); } /** - * Returns whether the given URI is a data URI. - * + * Returns whether the given URI is a data URI. + * * @param uri The URI * @return Whether the string is a data URI */ - public static boolean isDataUri(URI uri) - { + public static boolean isDataUri(URI uri) { return "data".equalsIgnoreCase(uri.getScheme()); } - + /** * Returns whether the given string is a data URI. If the given string - * is null, then false will be returned. - * + * is null, then false will be returned. + * * @param uriString The URI string * @return Whether the string is a data URI */ - public static boolean isDataUriString(String uriString) - { - if (uriString == null) - { + public static boolean isDataUriString(String uriString) { + if (uriString == null) { return false; } - try - { + try { URI uri = new URI(uriString); return isDataUri(uri); - } - catch (URISyntaxException e) - { + } catch (URISyntaxException e) { return false; } } - + /** - * Tries to extract the "file name" that is referred to with the + * Tries to extract the "file name" that is referred to with the * given URI. This is the part behind the last "/" slash - * that appears in the string representation of the given URI. If no - * file name can be extracted, then the string representation of the + * that appears in the string representation of the given URI. If no + * file name can be extracted, then the string representation of the * URI is returned. - * + * * @param uri The URI * @return The file name */ - public static String extractFileName(URI uri) - { + public static String extractFileName(URI uri) { String s = uri.toString(); int lastSlashIndex = s.lastIndexOf('/'); - if (lastSlashIndex != -1) - { + if (lastSlashIndex != -1) { return s.substring(lastSlashIndex + 1); } return s; } - + /** * Returns whether the resource that is described with the given URI * exists. If an IO exception occurs during this check, this method - * will simply return false. - * + * will simply return false. + * * @param uri The URI * @return Whether the resource exists */ - public static boolean existsUnchecked(URI uri) - { - try - { + public static boolean existsUnchecked(URI uri) { + try { return exists(uri); - } - catch (IOException e) - { + } catch (IOException e) { return false; } } - + /** * Returns whether the resource that is described with the given URI * exists - * + * * @param uri The URI * @return Whether the resource exists * @throws IOException If an IO error occurs. This usually implies that - * the return value would be false... + * the return value would be false... */ - private static boolean exists(URI uri) throws IOException - { + private static boolean exists(URI uri) throws IOException { URL url = uri.toURL(); URLConnection connection = url.openConnection(); - if (connection instanceof HttpURLConnection) - { - HttpURLConnection httpConnection = (HttpURLConnection)connection; + if (connection instanceof HttpURLConnection) { + HttpURLConnection httpConnection = (HttpURLConnection) connection; httpConnection.setRequestMethod("HEAD"); int responseCode = httpConnection.getResponseCode(); return responseCode == HttpURLConnection.HTTP_OK; @@ -234,49 +204,39 @@ private static boolean exists(URI uri) throws IOException String path = uri.getPath(); return new File(path).exists(); } - - + /** * Try to obtain the content length from the given URI. Returns -1 * if the content length can not be determined. - * + * * @param uri The URI * @return The content length */ - public static long getContentLength(URI uri) - { - try - { + public static long getContentLength(URI uri) { + try { URLConnection connection = uri.toURL().openConnection(); return connection.getContentLengthLong(); - } - catch (IOException e) - { + } catch (IOException e) { return -1; } } - + /** * Creates an input stream from the given URI, which may either be * an actual (absolute) URI, or a data URI with base64 encoded data - * + * * @param uri The URI * @return The input stream * @throws IOException If the stream can not be opened */ - public static InputStream createInputStream(URI uri) throws IOException - { - if ("data".equalsIgnoreCase(uri.getScheme())) - { + public static InputStream createInputStream(URI uri) throws IOException { + if ("data".equalsIgnoreCase(uri.getScheme())) { byte data[] = readDataUri(uri.toString()); return new ByteArrayInputStream(data); } - try - { + try { return uri.toURL().openStream(); - } - catch (MalformedURLException e) - { + } catch (MalformedURLException e) { throw new IOException(e); } } @@ -289,19 +249,14 @@ public static InputStream createInputStream(URI uri) throws IOException * @return The input stream * @throws IOException If the stream can not be opened */ - public static InputStream createInputStream(Path path) throws IOException - { - if ("data".equalsIgnoreCase(path.toUri().getScheme())) - { + public static InputStream createInputStream(Path path) throws IOException { + if ("data".equalsIgnoreCase(path.toUri().getScheme())) { byte data[] = readDataUri(path.toUri().toString()); return new ByteArrayInputStream(data); } - try - { + try { return path.toUri().toURL().openStream(); - } - catch (MalformedURLException e) - { + } catch (MalformedURLException e) { throw new IOException(e); } } @@ -309,152 +264,127 @@ public static InputStream createInputStream(Path path) throws IOException /** * Read the data from the given URI as a byte array. The data may either * be an actual URI, or a data URI with base64 encoded data. - * + * * @param uri The URI * @return The byte array * @throws IOException If an IO error occurs */ - public static byte[] read(URI uri) - throws IOException - { - try (InputStream inputStream = createInputStream(uri)) - { + public static byte[] read(URI uri) + throws IOException { + try (InputStream inputStream = createInputStream(uri)) { byte data[] = readStream(inputStream); return data; } } - /** * Read the base 64 encoded data from the given data URI string. * The data is assumed to start after the base64, part - * of the URI string, which must have the form + * of the URI string, which must have the form * data:...;base64,... - * + * * @param uriString The URI string * @return The data * @throws IllegalArgumentException If the given string is not a valid - * Base64 encoded data URI string + * Base64 encoded data URI string */ - public static byte[] readDataUri(String uriString) - { + public static byte[] readDataUri(String uriString) { String encoding = "base64,"; int encodingIndex = uriString.indexOf(encoding); - if (encodingIndex < 0) - { + if (encodingIndex < 0) { throw new IllegalArgumentException( - "The given URI string is not a base64 encoded " - + "data URI string: " + uriString); + "The given URI string is not a base64 encoded " + + "data URI string: " + uriString); } int contentStartIndex = encodingIndex + encoding.length(); byte data[] = Base64.getDecoder().decode( - uriString.substring(contentStartIndex)); + uriString.substring(contentStartIndex)); return data; } - + /** * Reads the data from the given inputStream and returns it as * a byte array. The caller is responsible for closing the stream. - * + * * @param inputStream The input stream to read * @return The data from the inputStream * @throws IOException If an IO error occurs, or if the thread that - * executes this method is interrupted. + * executes this method is interrupted. */ - public static byte[] readStream(InputStream inputStream) throws IOException - { + public static byte[] readStream(InputStream inputStream) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte buffer[] = new byte[16384]; - while (true) - { + while (true) { int read = inputStream.read(buffer); - if (read == -1) - { + if (read == -1) { break; } baos.write(buffer, 0, read); - if (Thread.currentThread().isInterrupted()) - { + if (Thread.currentThread().isInterrupted()) { throw new IOException("Interrupted while reading stream", - new InterruptedException()); + new InterruptedException()); } } baos.flush(); return baos.toByteArray(); } - + /** - * Read the specified number of bytes from the given input stream, + * Read the specified number of bytes from the given input stream, * writing them into the given array at the given offset - * - * @param inputStream The input stream - * @param data The array to write the data to - * @param offset The offset inside the target array - * @param numBytesToRead The number of bytes to read - * @throws IOException If an IO error occurs, or the end of the input - * stream was encountered before the requested number of bytes have - * been read + * + * @param inputStream The input stream + * @param data The array to write the data to + * @param offset The offset inside the target array + * @param numBytesToRead The number of bytes to read + * @throws IOException If an IO error occurs, or the end of the input + * stream was encountered before the requested number of bytes have + * been read * @throws IllegalArgumentException If the given offset is negative, or - * the sum of the given offset and the number of bytes to read is larger - * than the length of the given array + * the sum of the given offset and the number of bytes to read is larger + * than the length of the given array */ - static void read(InputStream inputStream, byte data[], int offset, - int numBytesToRead) throws IOException - { - if (offset < 0) - { + static void read(InputStream inputStream, byte data[], int offset, + int numBytesToRead) throws IOException { + if (offset < 0) { throw new IllegalArgumentException( - "Array offset is negative: " + offset); + "Array offset is negative: " + offset); } - if (offset + numBytesToRead > data.length) - { + if (offset + numBytesToRead > data.length) { throw new IllegalArgumentException( - "Cannot write " + numBytesToRead - + " bytes into an array of length " + data.length - + " with an offset of " + offset); + "Cannot write " + numBytesToRead + + " bytes into an array of length " + data.length + + " with an offset of " + offset); } int totalNumBytesRead = 0; - while (true) - { + while (true) { int read = inputStream.read( - data, offset + totalNumBytesRead, - numBytesToRead - totalNumBytesRead); - if (read == -1) - { + data, offset + totalNumBytesRead, + numBytesToRead - totalNumBytesRead); + if (read == -1) { throw new IOException( - "Could not read " + numBytesToRead + " bytes"); + "Could not read " + numBytesToRead + " bytes"); } totalNumBytesRead += read; - if (totalNumBytesRead == numBytesToRead) - { + if (totalNumBytesRead == numBytesToRead) { break; } } } - + /** * Read from the given input stream, writing into the given array, * until the array is filled. - * + * * @param inputStream The input stream - * @param data The array to write the data to + * @param data The array to write the data to * @throws IOException If an IO error occurs, or the end of the input - * stream was encountered before the requested number of bytes have - * been read + * stream was encountered before the requested number of bytes have + * been read */ - public static void read(InputStream inputStream, byte data[]) - throws IOException - { + public static void read(InputStream inputStream, byte data[]) + throws IOException { read(inputStream, data, 0, data.length); } - - - /** - * Private constructor to prevent instantiation - */ - private IO() - { - // Private constructor to prevent instantiation - } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/io/MimeTypes.java b/src/main/java/de/javagl/jgltf/model/io/MimeTypes.java index 80858cc..95eae3b 100644 --- a/src/main/java/de/javagl/jgltf/model/io/MimeTypes.java +++ b/src/main/java/de/javagl/jgltf/model/io/MimeTypes.java @@ -26,183 +26,165 @@ */ package de.javagl.jgltf.model.io; +import de.javagl.jgltf.model.image.ImageReaders; + +import javax.imageio.ImageReader; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.util.logging.Logger; -import javax.imageio.ImageReader; - -import de.javagl.jgltf.model.image.ImageReaders; - /** * Utility methods to related to the MIME type from data URLs or image data */ -public class MimeTypes -{ +public class MimeTypes { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(MimeTypes.class.getName()); - + private static final Logger logger = + Logger.getLogger(MimeTypes.class.getName()); + + /** + * Private constructor to prevent instantiation + */ + private MimeTypes() { + // Private constructor to prevent instantiation + } + /** - * Tries to detect the format of the image data from the given URI, and + * Tries to detect the format of the image data from the given URI, and * return the corresponding MIME type string.
*
- * This may, for example, be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
+ * This may, for example, be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
*
- * + * * @param uriString The image data * @return The image format string, or null if it can not * be detected. */ - private static String guessImageMimeTypeString(String uriString) - { - try - { + private static String guessImageMimeTypeString(String uriString) { + try { URI uri = new URI(uriString); - if ("data".equalsIgnoreCase(uri.getScheme())) - { + if ("data".equalsIgnoreCase(uri.getScheme())) { String raw = uri.getRawSchemeSpecificPart().toLowerCase(); String type = getStringBetween(raw, "image/", ";base64"); return "image/" + type.toLowerCase(); } - } - catch (URISyntaxException e) - { + } catch (URISyntaxException e) { return null; } int lastDotIndex = uriString.lastIndexOf('.'); - if (lastDotIndex == -1) - { + if (lastDotIndex == -1) { return null; } String end = uriString.substring(lastDotIndex + 1).toLowerCase(); - if (end.equalsIgnoreCase("jpg") || end.equalsIgnoreCase("jpeg")) - { + if (end.equalsIgnoreCase("jpg") || end.equalsIgnoreCase("jpeg")) { return "image/jpeg"; } return "image/" + end.toLowerCase(); } - + /** * Returns the part of the input string between the given "before" and * "after" part, or null if either of the given parts are - * not contained in the input string, or the "after" part appears + * not contained in the input string, or the "after" part appears * before the "before" part. - * - * @param input The input string + * + * @param input The input string * @param before The "before" part - * @param after The "after" part + * @param after The "after" part * @return The string between "before" and "after" */ private static String getStringBetween( - String input, String before, String after) - { + String input, String before, String after) { int beforeIndex = input.indexOf(before); - if (beforeIndex < 0) - { + if (beforeIndex < 0) { return null; } int afterIndex = input.indexOf(after); - if (afterIndex < beforeIndex) - { + if (afterIndex < beforeIndex) { return null; } return input.substring(beforeIndex + before.length(), afterIndex); } - - + /** * Tries to detect the format of the given image data, and return the * corresponding MIME type string.
*
- * This may, for example, be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
+ * This may, for example, be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
*
- * + * * @param imageData The image data * @return The image format string * @throws IOException If the image format can not be detected */ - private static String guessImageMimeTypeString(ByteBuffer imageData) - throws IOException - { + private static String guessImageMimeTypeString(ByteBuffer imageData) + throws IOException { ImageReader imageReader = null; - try - { + try { imageReader = ImageReaders.findImageReader(imageData); return "image/" + imageReader.getFormatName().toLowerCase(); - } - finally - { - if (imageReader != null) - { + } finally { + if (imageReader != null) { imageReader.dispose(); } } } - + /** * Tries to detect the format of the given image data, and return the * corresponding MIME type string.
*
- * This may, for example, be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
- *
+ * This may, for example, be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
+ *
+ * * @param imageData The image data * @return The image format string */ - public static String guessImageMimeTypeStringUnchecked(ByteBuffer imageData) - { - try - { + public static String guessImageMimeTypeStringUnchecked(ByteBuffer imageData) { + try { return guessImageMimeTypeString(imageData); - } - catch (IOException e) - { + } catch (IOException e) { return null; } } - + /** - * Tries to detect the format of the given image URI and its data and - * return the corresponding MIME type string.
+ * Tries to detect the format of the given image URI and its data and + * return the corresponding MIME type string.
*
- * This may, for example, be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
+ * This may, for example, be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
*
- * This method will do an (unspecified) best-effort approach to detect + * This method will do an (unspecified) best-effort approach to detect * the mime type, either from the image or from the image data (which - * are both optional). If the type can not be determined, then - * null will be returned. - * + * are both optional). If the type can not be determined, then + * null will be returned. + * * @param uriString The URI string * @param imageData The image data * @return The image format string, or null if it can not * be detected. */ public static String guessImageMimeTypeString( - String uriString, ByteBuffer imageData) - { - if (uriString != null) - { - String imageMimeTypeString = - MimeTypes.guessImageMimeTypeString(uriString); - if (imageMimeTypeString != null) - { + String uriString, ByteBuffer imageData) { + if (uriString != null) { + String imageMimeTypeString = + MimeTypes.guessImageMimeTypeString(uriString); + if (imageMimeTypeString != null) { return imageMimeTypeString; } } - if (imageData != null) - { + if (imageData != null) { return guessImageMimeTypeStringUnchecked(imageData); } return null; @@ -219,35 +201,22 @@ public static String guessImageMimeTypeString( * * For other inputs, a warning will be printed, and null will * be returned. - * + * * @param mimeTypeString The MIME type string * @return The file extension */ public static String imageFileNameExtensionForMimeTypeString( - String mimeTypeString) - { - if ("image/jpeg".equals(mimeTypeString)) - { + String mimeTypeString) { + if ("image/jpeg".equals(mimeTypeString)) { return "jpg"; } - if ("image/png".equals(mimeTypeString)) - { + if ("image/png".equals(mimeTypeString)) { return "png"; } - if ("image/gif".equals(mimeTypeString)) - { + if ("image/gif".equals(mimeTypeString)) { return "gif"; } logger.warning("Invalid MIME type string: " + mimeTypeString); return null; } - - - /** - * Private constructor to prevent instantiation - */ - private MimeTypes() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/io/ProgressInputStream.java b/src/main/java/de/javagl/jgltf/model/io/ProgressInputStream.java index fd9d996..9554961 100644 --- a/src/main/java/de/javagl/jgltf/model/io/ProgressInputStream.java +++ b/src/main/java/de/javagl/jgltf/model/io/ProgressInputStream.java @@ -39,21 +39,20 @@ * An input stream that informs property change listeners and consumers * about the number of bytes that are read. */ -public final class ProgressInputStream extends FilterInputStream -{ +public final class ProgressInputStream extends FilterInputStream { // Originally based on http://stackoverflow.com/a/1339589, heavily modified /** * The property change support */ private final PropertyChangeSupport propertyChangeSupport; - + /** - * The consumers that will be informed about the total number of + * The consumers that will be informed about the total number of * bytes that have been read */ private final List totalNumBytesReadConsumers; - + /** * The total number of bytes that have been read */ @@ -62,137 +61,120 @@ public final class ProgressInputStream extends FilterInputStream /** * Creates a new progress input stream that reads from the given input * stream - * + * * @param inputStream The input stream */ - public ProgressInputStream(InputStream inputStream) - { + public ProgressInputStream(InputStream inputStream) { super(inputStream); this.propertyChangeSupport = new PropertyChangeSupport(this); - this.totalNumBytesReadConsumers = - new CopyOnWriteArrayList(); + this.totalNumBytesReadConsumers = + new CopyOnWriteArrayList(); } - + /** * Returns the total number of bytes that already have been read * from the stream - * + * * @return The number of bytes read */ - long getTotalNumBytesRead() - { + long getTotalNumBytesRead() { return totalNumBytesRead; } /** * Add the given listener to be informed when the number of bytes * that have been read from this stream changes - * + * * @param listener The listener to add */ - void addPropertyChangeListener(PropertyChangeListener listener) - { + void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(listener); } /** * Remove the given listener from this stream - * + * * @param listener The listener to remove */ - void removePropertyChangeListener(PropertyChangeListener listener) - { + void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); } - + /** - * Add the given consumer to be informed about the total number of + * Add the given consumer to be informed about the total number of * bytes that have been read - * + * * @param consumer The consumer */ - public void addTotalNumBytesReadConsumer(LongConsumer consumer) - { + public void addTotalNumBytesReadConsumer(LongConsumer consumer) { totalNumBytesReadConsumers.add(consumer); } /** * Remove the given consumer - * + * * @param consumer The consumer */ - public void removeTotalNumBytesReadConsumer(LongConsumer consumer) - { + public void removeTotalNumBytesReadConsumer(LongConsumer consumer) { totalNumBytesReadConsumers.remove(consumer); } @Override - public int read() throws IOException - { + public int read() throws IOException { int b = super.read(); - if (b != -1) - { + if (b != -1) { updateProgress(1); } return b; } @Override - public int read(byte[] b) throws IOException - { + public int read(byte[] b) throws IOException { return read(b, 0, b.length); } @Override - public int read(byte[] b, int off, int len) throws IOException - { + public int read(byte[] b, int off, int len) throws IOException { int read = super.read(b, off, len); - if (read == -1) - { + if (read == -1) { return -1; } return (int) updateProgress(read); } @Override - public long skip(long n) throws IOException - { + public long skip(long n) throws IOException { return updateProgress(super.skip(n)); } @Override - public void mark(int readlimit) - { + public void mark(int readlimit) { throw new UnsupportedOperationException(); } @Override - public void reset() throws IOException - { + public void reset() throws IOException { throw new UnsupportedOperationException(); } @Override - public boolean markSupported() - { + public boolean markSupported() { return false; } /** * Update the progress of this stream, based on the given number of * bytes that have been read, and inform all registered listeners - * - * @param numBytesRead The number of bytes that have been read + * + * @param numBytesRead The number of bytes that have been read * @return The number of bytes read */ - private long updateProgress(long numBytesRead) - { - if (numBytesRead > 0) - { + private long updateProgress(long numBytesRead) { + if (numBytesRead > 0) { long oldTotalNumBytesRead = this.totalNumBytesRead; this.totalNumBytesRead += numBytesRead; propertyChangeSupport.firePropertyChange("totalNumBytesRead", - oldTotalNumBytesRead, this.totalNumBytesRead); + oldTotalNumBytesRead, this.totalNumBytesRead); fireTotalNumBytesRead(); } return numBytesRead; @@ -202,10 +184,8 @@ private long updateProgress(long numBytesRead) * Forward the information about the total number of bytes that have * been read to the consumers */ - private void fireTotalNumBytesRead() - { - for (LongConsumer consumer : totalNumBytesReadConsumers) - { + private void fireTotalNumBytesRead() { + for (LongConsumer consumer : totalNumBytesReadConsumers) { consumer.accept(totalNumBytesRead); } } diff --git a/src/main/java/de/javagl/jgltf/model/io/RawGltfData.java b/src/main/java/de/javagl/jgltf/model/io/RawGltfData.java index b9a6a94..bbb09c1 100644 --- a/src/main/java/de/javagl/jgltf/model/io/RawGltfData.java +++ b/src/main/java/de/javagl/jgltf/model/io/RawGltfData.java @@ -32,80 +32,75 @@ /** * The raw data of a glTF asset, consisting of the raw JSON data and the binary - * data. This data is still independent of the actual glTF version, and covers + * data. This data is still independent of the actual glTF version, and covers * both standard (JSON) and binary glTF.
*
* Instances of this class are returned by the {@link RawGltfDataReader}. - * Clients will usually not use this class directly. + * Clients will usually not use this class directly. */ -public final class RawGltfData -{ +public final class RawGltfData { /** * The JSON data */ private final ByteBuffer jsonData; - + /** * The optional binary data */ private final ByteBuffer binaryData; - + /** * Default constructor. References to the buffers will be stored. * So they should have their position and limit set accordingly, * and may not be modified after being passed to this constructor. - * - * @param jsonData The JSON data + * + * @param jsonData The JSON data * @param binaryData The optional binary data */ - public RawGltfData(ByteBuffer jsonData, ByteBuffer binaryData) - { + public RawGltfData(ByteBuffer jsonData, ByteBuffer binaryData) { this.jsonData = Objects.requireNonNull( - jsonData, "The jsonData may not be null"); + jsonData, "The jsonData may not be null"); this.binaryData = binaryData; } - + /** * Returns the JSON string from this data - * + * * @return The JSON string */ - public String getJsonString() - { + public String getJsonString() { byte jsonDataArray[] = new byte[jsonData.capacity()]; jsonData.slice().get(jsonDataArray); String jsonString = new String(jsonDataArray, Charset.forName("UTF-8")); return jsonString; } - + /** * Returns the JSON data.
*
- * The returned buffer will be a slice of the data that is stored + * The returned buffer will be a slice of the data that is stored * internally. This means that changes of the data will affect this * instance, but changes of the position or limit of the returned - * buffer will not affect this instance. - * + * buffer will not affect this instance. + * * @return The JSON data */ - public ByteBuffer getJsonData() - { + public ByteBuffer getJsonData() { return Buffers.createSlice(jsonData); } - + /** * Returns the binary data. This may be null if the asset * was created from a JSON string only.
*
- * The returned buffer will be a slice of the data that is stored + * The returned buffer will be a slice of the data that is stored * internally. This means that changes of the data will affect this * instance, but changes of the position or limit of the returned * buffer will not affect this instance. - * + * * @return The binary data */ - public ByteBuffer getBinaryData() - { + public ByteBuffer getBinaryData() { return Buffers.createSlice(binaryData); } } diff --git a/src/main/java/de/javagl/jgltf/model/io/RawGltfDataReader.java b/src/main/java/de/javagl/jgltf/model/io/RawGltfDataReader.java index 46bd327..b032706 100644 --- a/src/main/java/de/javagl/jgltf/model/io/RawGltfDataReader.java +++ b/src/main/java/de/javagl/jgltf/model/io/RawGltfDataReader.java @@ -26,15 +26,15 @@ */ package de.javagl.jgltf.model.io; +import de.javagl.jgltf.model.io.v1.RawBinaryGltfDataReaderV1; +import de.javagl.jgltf.model.io.v2.RawBinaryGltfDataReaderV2; + import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; -import de.javagl.jgltf.model.io.v1.RawBinaryGltfDataReaderV1; -import de.javagl.jgltf.model.io.v2.RawBinaryGltfDataReaderV2; - /** * A class for reading the raw data of a glTF asset from an input stream. * The given stream may provide any form of glTF data: @@ -50,68 +50,61 @@ *
* Clients will usually not use this class directly. */ -public class RawGltfDataReader -{ +public class RawGltfDataReader { /** * The magic binary glTF header. * This is an integer corresponding to the ASCII string "glTF" */ private static final int MAGIC_BINARY_GLTF_HEADER = 0x46546C67; - + /** * The version number indicating glTF 1.0 */ private static final int BINARY_GLTF_VERSION_1 = 1; - + /** * The version number indicating glTF 2.0 */ private static final int BINARY_GLTF_VERSION_2 = 2; + /** + * Private constructor to prevent instantiation + */ + private RawGltfDataReader() { + // Private constructor to prevent instantiation + } + /** * Read the raw glTF data from the given input stream. The caller is * responsible for closing the given stream. - * + * * @param inputStream The input stream * @return The {@link RawGltfData} * @throws IOException If an IO error occurs */ - public static RawGltfData read(InputStream inputStream) throws IOException - { + public static RawGltfData read(InputStream inputStream) throws IOException { byte rawData[] = IO.readStream(inputStream); - if (rawData.length >= 8) - { - ByteBuffer data = - ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN); + if (rawData.length >= 8) { + ByteBuffer data = + ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN); IntBuffer intData = data.asIntBuffer(); int magic = intData.get(0); - if (magic == MAGIC_BINARY_GLTF_HEADER) - { + if (magic == MAGIC_BINARY_GLTF_HEADER) { int version = intData.get(1); - if (version == BINARY_GLTF_VERSION_1) - { + if (version == BINARY_GLTF_VERSION_1) { return RawBinaryGltfDataReaderV1.readBinaryGltf(data); } - if (version == BINARY_GLTF_VERSION_2) - { + if (version == BINARY_GLTF_VERSION_2) { return RawBinaryGltfDataReaderV2.readBinaryGltf(data); } throw new IOException( - "Unknown binary glTF version: " + version); + "Unknown binary glTF version: " + version); } } ByteBuffer jsonData = Buffers.create(rawData); return new RawGltfData(jsonData, null); } - - /** - * Private constructor to prevent instantiation - */ - private RawGltfDataReader() - { - // Private constructor to prevent instantiation - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/UriResolvers.java b/src/main/java/de/javagl/jgltf/model/io/UriResolvers.java index c7936d8..0e55e0f 100644 --- a/src/main/java/de/javagl/jgltf/model/io/UriResolvers.java +++ b/src/main/java/de/javagl/jgltf/model/io/UriResolvers.java @@ -38,50 +38,50 @@ /** * Methods for creating functions that resolve URI to byte buffers */ -public class UriResolvers -{ +public class UriResolvers { /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(UriResolvers.class.getName()); + Logger.getLogger(UriResolvers.class.getName()); /** - * Creates a function that resolves URI strings against the given - * base URI, and returns a byte buffer containing the data from + * Private constructor to prevent instantiation + */ + private UriResolvers() { + // Private constructor to prevent instantiation + } + + /** + * Creates a function that resolves URI strings against the given + * base URI, and returns a byte buffer containing the data from * the resulting URI.
*
* The given URI strings may either be standard URI or data URI.
*
* If the returned function cannot read the data, then it will print a * warning and return null. - * + * * @param baseUri The base URI to resolve against * @return The function */ public static Function createBaseUriResolver( - URI baseUri) - { + URI baseUri) { Objects.requireNonNull(baseUri, "The baseUri may not be null"); - Function inputStreamFunction = - new Function() - { - @Override - public InputStream apply(String uriString) - { - try - { - URI absoluteUri = IO.makeAbsolute(baseUri, uriString); - return IO.createInputStream(absoluteUri); - } - catch (IOException e) - { - logger.warning("Could not open input stream for URI " - + uriString + ": " + e.getMessage()); - return null; - } - } - }; + Function inputStreamFunction = + new Function() { + @Override + public InputStream apply(String uriString) { + try { + URI absoluteUri = IO.makeAbsolute(baseUri, uriString); + return IO.createInputStream(absoluteUri); + } catch (IOException e) { + logger.warning("Could not open input stream for URI " + + uriString + ": " + e.getMessage()); + return null; + } + } + }; return reading(inputStreamFunction); } @@ -100,66 +100,55 @@ public InputStream apply(String uriString) * @return The function */ public static Function createBasePathResolver( - Path basePath) - { + Path basePath) { Objects.requireNonNull(basePath, "The basePath may not be null"); Function inputStreamFunction = - new Function() - { - @Override - public InputStream apply(String uriString) - { - try - { - if (IO.isDataUriString(uriString)) - { - return IO.createInputStream(URI.create(uriString)); + new Function() { + @Override + public InputStream apply(String uriString) { + try { + if (IO.isDataUriString(uriString)) { + return IO.createInputStream(URI.create(uriString)); + } + Path absolutePath = IO.makeAbsolute(basePath, uriString); + return IO.createInputStream(absolutePath); + } catch (IOException e) { + logger.warning("Could not open input stream for URI " + + uriString + ": " + e.getMessage()); + return null; + } } - Path absolutePath = IO.makeAbsolute(basePath, uriString); - return IO.createInputStream(absolutePath); - } - catch (IOException e) - { - logger.warning("Could not open input stream for URI " - + uriString + ": " + e.getMessage()); - return null; - } - } - }; + }; return reading(inputStreamFunction); } /** * Create a function that maps a string to the input stream of a resource * of the given class. - * + * * @param c The class * @return The resolving function */ public static Function createResourceUriResolver( - Class c) - { + Class c) { Objects.requireNonNull(c, "The class may not be null"); Function inputStreamFunction = - new Function() - { - @Override - public InputStream apply(String uriString) - { - InputStream inputStream = - c.getResourceAsStream("/" + uriString); - if (inputStream == null) - { - logger.warning( - "Could not obtain input stream for resource " - + "with URI " + uriString); - } - return inputStream; - } - }; + new Function() { + @Override + public InputStream apply(String uriString) { + InputStream inputStream = + c.getResourceAsStream("/" + uriString); + if (inputStream == null) { + logger.warning( + "Could not obtain input stream for resource " + + "with URI " + uriString); + } + return inputStream; + } + }; return reading(inputStreamFunction); } - + /** * Returns a function that reads the data from the input stream that is * provided by the given delegate, and returns this data as a direct @@ -168,45 +157,30 @@ public InputStream apply(String uriString) * If the delegate returns null, or an input stream that * cannot be read, then the function will print a warning and return * null. - * + * * @param inputStreamFunction The input stream function * @return The function for reading the input stream data */ private static Function reading( - Function inputStreamFunction) - { - return new Function() - { + Function inputStreamFunction) { + return new Function() { @Override - public ByteBuffer apply(T t) - { - try (InputStream inputStream = inputStreamFunction.apply(t)) - { - if (inputStream == null) - { + public ByteBuffer apply(T t) { + try (InputStream inputStream = inputStreamFunction.apply(t)) { + if (inputStream == null) { logger.warning("The input stream was null"); return null; } byte data[] = IO.readStream(inputStream); return Buffers.create(data); - } - catch (IOException e) - { + } catch (IOException e) { logger.warning("Could not read from input stream: " - + e.getMessage()); + + e.getMessage()); return null; } } - - }; - } - /** - * Private constructor to prevent instantiation - */ - private UriResolvers() - { - // Private constructor to prevent instantiation + }; } } diff --git a/src/main/java/de/javagl/jgltf/model/io/VersionUtils.java b/src/main/java/de/javagl/jgltf/model/io/VersionUtils.java index ded34a4..ab6ee96 100644 --- a/src/main/java/de/javagl/jgltf/model/io/VersionUtils.java +++ b/src/main/java/de/javagl/jgltf/model/io/VersionUtils.java @@ -29,32 +29,28 @@ /** * Utility methods related to version strings */ -public class VersionUtils -{ +public class VersionUtils { /** * Compare the given semantic version numbers. - * + * * @param v0 The first version number * @param v1 The second version number * @return A value that is smaller than, equal to or greater than 0, * indicating whether the first version is smaller than, equal to * or greater than the second version. */ - public static int compareVersions(String v0, String v1) - { + public static int compareVersions(String v0, String v1) { int[] sv0 = computeMajorMinorPatch(v0); int[] sv1 = computeMajorMinorPatch(v1); - for (int i = 0; i < 3; i++) - { + for (int i = 0; i < 3; i++) { int c = Integer.compare(sv0[i], sv1[i]); - if (c != 0) - { + if (c != 0) { return c; } } return 0; } - + /** * Compute the semantic version numbers from the given string. The * string is assumed to be a semantic version number, consisting @@ -62,58 +58,48 @@ public static int compareVersions(String v0, String v1) * is allowed to have a non-numeric suffix, which will be ignored * here. Any element of this pattern that is not present or cannot * be parsed will be assumed to be 0. - * + * * @param v The version string * @return An array containing 3 values: The major, minor and patch version */ - static int[] computeMajorMinorPatch(String v) - { + static int[] computeMajorMinorPatch(String v) { int result[] = new int[3]; String tokens[] = v.split("\\."); int n = Math.min(tokens.length, 3); - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { String token = tokens[i]; result[i] = parseIntPrefix(token); } return result; } - + /** * Try to parse an integer value from the start of the given string. * For example, for the string "23a-beta", this will * return 23. If no valid number can be parsed, then * 0 is returned. - * + * * @param s The input string - * @return The integer + * @return The integer */ - private static int parseIntPrefix(String s) - { + private static int parseIntPrefix(String s) { String number = ""; - for (int j = 0; j < s.length(); j++) - { + for (int j = 0; j < s.length(); j++) { char c = s.charAt(j); - if (Character.isDigit(c)) - { + if (Character.isDigit(c)) { number += c; - } - else - { + } else { break; } } - try - { + try { return Integer.parseInt(number); - } - catch (NumberFormatException e) - { + } catch (NumberFormatException e) { return 0; } } - - + + // public static void main(String[] args) // { // String s = "1.2.0"; diff --git a/src/main/java/de/javagl/jgltf/model/io/package-info.java b/src/main/java/de/javagl/jgltf/model/io/package-info.java index 78a1a26..1602246 100644 --- a/src/main/java/de/javagl/jgltf/model/io/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/io/package-info.java @@ -1,5 +1,5 @@ /** - * Classes for reading and writing glTF data + * Classes for reading and writing glTF data */ package de.javagl.jgltf.model.io; diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/BinaryAssetCreatorV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/BinaryAssetCreatorV1.java index 4a67239..e869bd9 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/BinaryAssetCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/BinaryAssetCreatorV1.java @@ -26,6 +26,14 @@ */ package de.javagl.jgltf.model.io.v1; +import de.javagl.jgltf.impl.v1.*; +import de.javagl.jgltf.model.BufferModel; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.ImageModel; +import de.javagl.jgltf.model.gl.ShaderModel; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.v1.*; + import java.nio.ByteBuffer; import java.util.Collections; import java.util.LinkedHashMap; @@ -33,67 +41,115 @@ import java.util.Map.Entry; import java.util.function.Function; -import de.javagl.jgltf.impl.v1.Buffer; -import de.javagl.jgltf.impl.v1.BufferView; -import de.javagl.jgltf.impl.v1.GlTF; -import de.javagl.jgltf.impl.v1.Image; -import de.javagl.jgltf.impl.v1.Shader; -import de.javagl.jgltf.model.BufferModel; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.ImageModel; -import de.javagl.jgltf.model.gl.ShaderModel; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.v1.BinaryGltfV1; -import de.javagl.jgltf.model.v1.GltfCreatorV1; -import de.javagl.jgltf.model.v1.GltfExtensionsV1; -import de.javagl.jgltf.model.v1.GltfIds; -import de.javagl.jgltf.model.v1.GltfModelV1; - /** - * A class for creating a binary {@link GltfAssetV1} from a + * A class for creating a binary {@link GltfAssetV1} from a * {@link GltfModelV1}.
*
*/ -final class BinaryAssetCreatorV1 -{ +final class BinaryAssetCreatorV1 { /** * Creates a new asset creator */ - BinaryAssetCreatorV1() - { + BinaryAssetCreatorV1() { // Default constructor } - + + /** + * Compute the total size that is required for the binary glTF buffer + * for the given {@link GltfModel}, which is the sum of all buffer + * sizes of all buffers, images and shaders. + * + * @param gltfModel The {@link GltfModel} + * @return The total size for the binary glTF buffer + */ + private static int computeBinaryGltfBufferSize(GltfModelV1 gltfModel) { + int binaryGltfBufferSize = 0; + for (BufferModel bufferModel : gltfModel.getBufferModels()) { + ByteBuffer bufferData = bufferModel.getBufferData(); + binaryGltfBufferSize += bufferData.capacity(); + } + for (ImageModel imageModel : gltfModel.getImageModels()) { + ByteBuffer imageData = imageModel.getImageData(); + binaryGltfBufferSize += imageData.capacity(); + } + for (ShaderModel shaderModel : gltfModel.getShaderModels()) { + ByteBuffer shaderData = shaderModel.getShaderData(); + binaryGltfBufferSize += shaderData.capacity(); + } + return binaryGltfBufferSize; + } + + /** + * Put the contents of all byte buffers that are associated with the + * given keys into the given target buffer. This method assumes + * that the target buffer has a sufficient capacity to hold all + * buffers. + * + * @param The key type + * @param keys The mapping keys + * @param keyToByteBuffer The function that provides the byte buffer + * based on the key of the element + * @param targetBuffer The target buffer + * @return A mapping from each key to the offset inside the target buffer + */ + private static Map concatBuffers( + Iterable keys, + Function keyToByteBuffer, + ByteBuffer targetBuffer) { + Map offsets = new LinkedHashMap(); + for (K key : keys) { + ByteBuffer oldByteBuffer = keyToByteBuffer.apply(key); + int offset = targetBuffer.position(); + offsets.put(key, offset); + targetBuffer.put(oldByteBuffer.slice()); + } + return offsets; + } + + /** + * Creates a copy of the given map, as a linked hash map. If the given + * map is null, then an unmodifiable empty map will be + * returned + * + * @param map The input map + * @return The copy + */ + private static Map copy(Map map) { + if (map == null) { + return Collections.emptyMap(); + } + return new LinkedHashMap(map); + } + /** * Create a binary {@link GltfAssetV1} from the given {@link GltfModelV1}. * The resulting asset will have a {@link GlTF} that uses the binary * glTF extension objects in its {@link Buffer}, {@link Image} and - * {@link Shader} elements, to refer to the - * {@link GltfAssetV1#getBinaryData() binary data} of the asset. - * + * {@link Shader} elements, to refer to the + * {@link GltfAssetV1#getBinaryData() binary data} of the asset. + * * @param gltfModel The {@link GltfModelV1} * @return The {@link GltfAssetV1} */ - GltfAssetV1 create(GltfModelV1 gltfModel) - { + GltfAssetV1 create(GltfModelV1 gltfModel) { GlTF outputGltf = GltfCreatorV1.create(gltfModel); - + // Create the new byte buffer for the data of the "binary_glTF" Buffer - int binaryGltfBufferSize = - computeBinaryGltfBufferSize(gltfModel); - ByteBuffer binaryGltfByteBuffer = - Buffers.create(binaryGltfBufferSize); + int binaryGltfBufferSize = + computeBinaryGltfBufferSize(gltfModel); + ByteBuffer binaryGltfByteBuffer = + Buffers.create(binaryGltfBufferSize); - // Create the "binary_glTF" Buffer, - GltfExtensionsV1.addExtensionUsed(outputGltf, - BinaryGltfV1.getBinaryGltfExtensionName()); + // Create the "binary_glTF" Buffer, + GltfExtensionsV1.addExtensionUsed(outputGltf, + BinaryGltfV1.getBinaryGltfExtensionName()); Buffer binaryGltfBuffer = new Buffer(); binaryGltfBuffer.setType("arraybuffer"); binaryGltfBuffer.setUri( - BinaryGltfV1.getBinaryGltfBufferId() + ".bin"); + BinaryGltfV1.getBinaryGltfBufferId() + ".bin"); binaryGltfBuffer.setByteLength(binaryGltfBufferSize); Map newBuffers = Collections.singletonMap( - BinaryGltfV1.getBinaryGltfBufferId(), binaryGltfBuffer); + BinaryGltfV1.getBinaryGltfBufferId(), binaryGltfBuffer); // Create defensive copies of the original maps, as linked maps // with a fixed iteration order (!). If the input maps are null, @@ -103,44 +159,43 @@ GltfAssetV1 create(GltfModelV1 gltfModel) Map oldImages = copy(outputGltf.getImages()); Map oldShaders = copy(outputGltf.getShaders()); - // TODO This is not solved very elegantly, due to the + // TODO This is not solved very elegantly, due to the // transition of glTF 1.0 to glTF 2.0 - refactor this! - + // Create mappings from the IDs to the corresponding model elements. // This assumes that they are in the same order. Map bufferIdToBuffer = GltfUtilsV1.createMap( - oldBuffers, gltfModel.getBufferModels()); + oldBuffers, gltfModel.getBufferModels()); Map imageIdToImage = GltfUtilsV1.createMap( - oldImages, gltfModel.getImageModels()); + oldImages, gltfModel.getImageModels()); Map shaderIdToShader = GltfUtilsV1.createMap( - oldShaders, gltfModel.getShaderModels()); - + oldShaders, gltfModel.getShaderModels()); + // Place the data from buffers, images and shaders into the - // new binary glTF buffer. The mappings from IDs to offsets + // new binary glTF buffer. The mappings from IDs to offsets // inside the resulting buffer will be used to compute the // offsets for the buffer views Map bufferOffsets = concatBuffers( - oldBuffers.keySet(), - id -> bufferIdToBuffer.get(id).getBufferData(), - binaryGltfByteBuffer); + oldBuffers.keySet(), + id -> bufferIdToBuffer.get(id).getBufferData(), + binaryGltfByteBuffer); Map imageOffsets = concatBuffers( - oldImages.keySet(), - id -> imageIdToImage.get(id).getImageData(), - binaryGltfByteBuffer); + oldImages.keySet(), + id -> imageIdToImage.get(id).getImageData(), + binaryGltfByteBuffer); Map shaderOffsets = concatBuffers( - oldShaders.keySet(), - id -> shaderIdToShader.get(id).getShaderData(), - binaryGltfByteBuffer); + oldShaders.keySet(), + id -> shaderIdToShader.get(id).getShaderData(), + binaryGltfByteBuffer); binaryGltfByteBuffer.position(0); - // For all existing BufferViews, create new ones that are updated to + // For all existing BufferViews, create new ones that are updated to // refer to the new binary glTF buffer, with the appropriate offset - Map oldBufferViews = - copy(outputGltf.getBufferViews()); - Map newBufferViews = - new LinkedHashMap(); - for (Entry oldEntry : oldBufferViews.entrySet()) - { + Map oldBufferViews = + copy(outputGltf.getBufferViews()); + Map newBufferViews = + new LinkedHashMap(); + for (Entry oldEntry : oldBufferViews.entrySet()) { String id = oldEntry.getKey(); BufferView oldBufferView = oldEntry.getValue(); BufferView newBufferView = GltfUtilsV1.copy(oldBufferView); @@ -155,21 +210,20 @@ GltfAssetV1 create(GltfModelV1 gltfModel) newBufferViews.put(id, newBufferView); } - // For all existing Images, create new ones that are updated to + // For all existing Images, create new ones that are updated to // refer to the new binary glTF buffer, using a bufferView ID // (in the binary_glTF extension object) that refers to a newly // created BufferView - Map newImages = - new LinkedHashMap(); - for (Entry oldEntry : oldImages.entrySet()) - { + Map newImages = + new LinkedHashMap(); + for (Entry oldEntry : oldImages.entrySet()) { String id = oldEntry.getKey(); Image oldImage = oldEntry.getValue(); Image newImage = GltfUtilsV1.copy(oldImage); // Create the BufferView for the image - ByteBuffer imageData = - imageIdToImage.get(id).getImageData(); + ByteBuffer imageData = + imageIdToImage.get(id).getImageData(); int byteLength = imageData.capacity(); int byteOffset = imageOffsets.get(id); BufferView imageBufferView = new BufferView(); @@ -178,14 +232,14 @@ GltfAssetV1 create(GltfModelV1 gltfModel) imageBufferView.setByteLength(byteLength); // Store the BufferView under a newly generated ID - String generatedBufferViewId = - GltfIds.generateId("bufferView_for_image_" + id, - oldBufferViews.keySet()); + String generatedBufferViewId = + GltfIds.generateId("bufferView_for_image_" + id, + oldBufferViews.keySet()); newBufferViews.put(generatedBufferViewId, imageBufferView); // Let the image refer to the BufferView via its extension object BinaryGltfV1.setBinaryGltfBufferViewId( - newImage, generatedBufferViewId); + newImage, generatedBufferViewId); // Set the width, height and mimeType properties for the // extension object @@ -194,21 +248,20 @@ GltfAssetV1 create(GltfModelV1 gltfModel) newImages.put(id, newImage); } - // For all existing Shaders, create new ones that are updated to + // For all existing Shaders, create new ones that are updated to // refer to the new binary glTF buffer using a bufferView ID // (in the binary_glTF extension object) that refers to a newly // created BufferView - Map newShaders = - new LinkedHashMap(); - for (Entry oldEntry : oldShaders.entrySet()) - { + Map newShaders = + new LinkedHashMap(); + for (Entry oldEntry : oldShaders.entrySet()) { String id = oldEntry.getKey(); Shader oldShader = oldEntry.getValue(); Shader newShader = GltfUtilsV1.copy(oldShader); // Create the BufferView for the shader - ByteBuffer shaderData = - shaderIdToShader.get(id).getShaderData(); + ByteBuffer shaderData = + shaderIdToShader.get(id).getShaderData(); int byteLength = shaderData.capacity(); int byteOffset = shaderOffsets.get(id); BufferView shaderBufferView = new BufferView(); @@ -218,115 +271,33 @@ GltfAssetV1 create(GltfModelV1 gltfModel) // Store the BufferView under a newly generated ID String generatedBufferViewId = - GltfIds.generateId("bufferView_for_shader_" + id, - oldBufferViews.keySet()); + GltfIds.generateId("bufferView_for_shader_" + id, + oldBufferViews.keySet()); newBufferViews.put(generatedBufferViewId, shaderBufferView); // Let the shader refer to the BufferView via its extension object BinaryGltfV1.setBinaryGltfBufferViewId( - newShader, generatedBufferViewId); + newShader, generatedBufferViewId); newShaders.put(id, newShader); } // Place the newly created mappings into the output glTF, // if there have been non-null mappings for them in the input - if (!newBuffers.isEmpty()) - { + if (!newBuffers.isEmpty()) { outputGltf.setBuffers(newBuffers); } - if (!newImages.isEmpty()) - { + if (!newImages.isEmpty()) { outputGltf.setImages(newImages); } - if (!newShaders.isEmpty()) - { + if (!newShaders.isEmpty()) { outputGltf.setShaders(newShaders); } - if (!newBufferViews.isEmpty()) - { + if (!newBufferViews.isEmpty()) { outputGltf.setBufferViews(newBufferViews); } return new GltfAssetV1(outputGltf, binaryGltfByteBuffer); } - /** - * Compute the total size that is required for the binary glTF buffer - * for the given {@link GltfModel}, which is the sum of all buffer - * sizes of all buffers, images and shaders. - * - * @param gltfModel The {@link GltfModel} - * @return The total size for the binary glTF buffer - */ - private static int computeBinaryGltfBufferSize(GltfModelV1 gltfModel) - { - int binaryGltfBufferSize = 0; - for (BufferModel bufferModel : gltfModel.getBufferModels()) - { - ByteBuffer bufferData = bufferModel.getBufferData(); - binaryGltfBufferSize += bufferData.capacity(); - } - for (ImageModel imageModel : gltfModel.getImageModels()) - { - ByteBuffer imageData = imageModel.getImageData(); - binaryGltfBufferSize += imageData.capacity(); - } - for (ShaderModel shaderModel : gltfModel.getShaderModels()) - { - ByteBuffer shaderData = shaderModel.getShaderData(); - binaryGltfBufferSize += shaderData.capacity(); - } - return binaryGltfBufferSize; - } - - - /** - * Put the contents of all byte buffers that are associated with the - * given keys into the given target buffer. This method assumes - * that the target buffer has a sufficient capacity to hold all - * buffers. - * - * @param The key type - * - * @param keys The mapping keys - * @param keyToByteBuffer The function that provides the byte buffer - * based on the key of the element - * @param targetBuffer The target buffer - * @return A mapping from each key to the offset inside the target buffer - */ - private static Map concatBuffers( - Iterable keys, - Function keyToByteBuffer, - ByteBuffer targetBuffer) - { - Map offsets = new LinkedHashMap(); - for (K key : keys) - { - ByteBuffer oldByteBuffer = keyToByteBuffer.apply(key); - int offset = targetBuffer.position(); - offsets.put(key, offset); - targetBuffer.put(oldByteBuffer.slice()); - } - return offsets; - } - - /** - * Creates a copy of the given map, as a linked hash map. If the given - * map is null, then an unmodifiable empty map will be - * returned - * - * @param map The input map - * @return The copy - */ - private static Map copy(Map map) - { - if (map == null) - { - return Collections.emptyMap(); - } - return new LinkedHashMap(map); - } - - } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/DefaultAssetCreatorV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/DefaultAssetCreatorV1.java index 3df30c5..342b661 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/DefaultAssetCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/DefaultAssetCreatorV1.java @@ -26,14 +26,6 @@ */ package de.javagl.jgltf.model.io.v1; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - import de.javagl.jgltf.impl.v1.Buffer; import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Image; @@ -51,22 +43,29 @@ import de.javagl.jgltf.model.v1.GltfExtensionsV1; import de.javagl.jgltf.model.v1.GltfModelV1; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + /** - * A class for creating a {@link GltfAssetV1} with a default data + * A class for creating a {@link GltfAssetV1} with a default data * representation from a {@link GltfModelV1}.
*
- * In the default data representation, elements are referred to via URIs. + * In the default data representation, elements are referred to via URIs. * Data elements like {@link Buffer}, {@link Image} or {@link Shader} - * objects that used the binary glTF extension or data URIs will be + * objects that used the binary glTF extension or data URIs will be * converted to refer to their data using URIs. */ -final class DefaultAssetCreatorV1 -{ +final class DefaultAssetCreatorV1 { /** * The {@link GltfAssetV1} that is currently being created */ private GltfAssetV1 gltfAsset; - + /** * The set of {@link Buffer} URI strings that are already used */ @@ -81,121 +80,115 @@ final class DefaultAssetCreatorV1 * The set of {@link Shader} URI strings that are already used */ private Set existingShaderUriStrings; - + /** * Creates a new asset creator */ - DefaultAssetCreatorV1() - { + DefaultAssetCreatorV1() { // Default constructor } + /** + * Collect all strings that are obtained from the given elements by + * applying the given function, if these strings are not null + * and no data URI strings + * + * @param elements The elements + * @param uriFunction The function to obtain the string + * @return The strings + */ + private static Set collectUriStrings(Collection elements, + Function uriFunction) { + return elements.stream() + .map(uriFunction) + .filter(Objects::nonNull) + .filter(uriString -> !IO.isDataUriString(uriString)) + .collect(Collectors.toSet()); + } + /** * Create a default {@link GltfAssetV1} from the given {@link GltfModelV1}. - * + * * @param gltfModel The input {@link GltfModelV1} * @return The default {@link GltfAssetV1} */ - GltfAssetV1 create(GltfModelV1 gltfModel) - { + GltfAssetV1 create(GltfModelV1 gltfModel) { GlTF outputGltf = GltfCreatorV1.create(gltfModel); - + // Remove the binary glTF extension, if it was used - GltfExtensionsV1.removeExtensionUsed(outputGltf, - BinaryGltfV1.getBinaryGltfExtensionName()); + GltfExtensionsV1.removeExtensionUsed(outputGltf, + BinaryGltfV1.getBinaryGltfExtensionName()); existingBufferUriStrings = collectUriStrings( - Optionals.of(outputGltf.getBuffers()).values(), - Buffer::getUri); + Optionals.of(outputGltf.getBuffers()).values(), + Buffer::getUri); existingImageUriStrings = collectUriStrings( - Optionals.of(outputGltf.getImages()).values(), - Image::getUri); + Optionals.of(outputGltf.getImages()).values(), + Image::getUri); existingShaderUriStrings = collectUriStrings( - Optionals.of(outputGltf.getShaders()).values(), - Shader::getUri); + Optionals.of(outputGltf.getShaders()).values(), + Shader::getUri); this.gltfAsset = new GltfAssetV1(outputGltf, null); - - // TODO This is not solved very elegantly, due to the + + // TODO This is not solved very elegantly, due to the // transition of glTF 1.0 to glTF 2.0 - refactor this! - + // Create mappings from the IDs to the corresponding model elements. // This assumes that they are in the same order. Map bufferIdToBuffer = GltfUtilsV1.createMap( - outputGltf.getBuffers(), - gltfModel.getBufferModels()); + outputGltf.getBuffers(), + gltfModel.getBufferModels()); Map imageIdToImage = GltfUtilsV1.createMap( - outputGltf.getImages(), - gltfModel.getImageModels()); + outputGltf.getImages(), + gltfModel.getImageModels()); Map shaderIdToShader = GltfUtilsV1.createMap( - outputGltf.getShaders(), - gltfModel.getShaderModels()); - - Optionals.of(outputGltf.getBuffers()).forEach((id, value) -> - storeBufferAsDefault(gltfModel, id, value, bufferIdToBuffer::get)); - Optionals.of(outputGltf.getImages()).forEach((id, value) -> - storeImageAsDefault(gltfModel, id, value, imageIdToImage::get)); - Optionals.of(outputGltf.getShaders()).forEach((id, value) -> - storeShaderAsDefault(gltfModel, id, value, shaderIdToShader::get)); + outputGltf.getShaders(), + gltfModel.getShaderModels()); - return gltfAsset; - } + Optionals.of(outputGltf.getBuffers()).forEach((id, value) -> + storeBufferAsDefault(gltfModel, id, value, bufferIdToBuffer::get)); + Optionals.of(outputGltf.getImages()).forEach((id, value) -> + storeImageAsDefault(gltfModel, id, value, imageIdToImage::get)); + Optionals.of(outputGltf.getShaders()).forEach((id, value) -> + storeShaderAsDefault(gltfModel, id, value, shaderIdToShader::get)); - /** - * Collect all strings that are obtained from the given elements by - * applying the given function, if these strings are not null - * and no data URI strings - * - * @param elements The elements - * @param uriFunction The function to obtain the string - * @return The strings - */ - private static Set collectUriStrings(Collection elements, - Function uriFunction) - { - return elements.stream() - .map(uriFunction) - .filter(Objects::nonNull) - .filter(uriString -> !IO.isDataUriString(uriString)) - .collect(Collectors.toSet()); + return gltfAsset; } - /** - * Store the given {@link Buffer} with the given ID in the current + * Store the given {@link Buffer} with the given ID in the current * output asset.
*
- * If the {@link Buffer#getUri() buffer URI} is null or a - * data URI, it will receive a new URI, which refers to the buffer data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Buffer#getUri() buffer URI} is null or a + * data URI, it will receive a new URI, which refers to the buffer data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
* If the given ID is the binary glTF buffer ID, "binary_glTF", - * then the buffer will also receive a new URI. + * then the buffer will also receive a new URI. *
- * The given {@link Buffer} object will be modified accordingly, if + * The given {@link Buffer} object will be modified accordingly, if * necessary: Its URI will be set to be the new URI. - * - * @param gltfModel The {@link GltfModelV1} - * @param id The ID of the {@link Buffer} - * @param buffer The {@link Buffer} - * @param lookup The lookup from ID to model + * + * @param gltfModel The {@link GltfModelV1} + * @param id The ID of the {@link Buffer} + * @param buffer The {@link Buffer} + * @param lookup The lookup from ID to model */ private void storeBufferAsDefault( - GltfModelV1 gltfModel, String id, Buffer buffer, - Function lookup) - { + GltfModelV1 gltfModel, String id, Buffer buffer, + Function lookup) { BufferModel bufferModel = lookup.apply(id); ByteBuffer bufferData = bufferModel.getBufferData(); - + String oldUriString = buffer.getUri(); String newUriString = oldUriString; if (oldUriString == null || - IO.isDataUriString(oldUriString) || - BinaryGltfV1.isBinaryGltfBufferId(id)) - { + IO.isDataUriString(oldUriString) || + BinaryGltfV1.isBinaryGltfBufferId(id)) { newUriString = UriStrings.createBufferUriString( - existingBufferUriStrings); + existingBufferUriStrings); buffer.setUri(newUriString); existingBufferUriStrings.add(newUriString); } @@ -203,88 +196,84 @@ private void storeBufferAsDefault( } /** - * Store the given {@link Image} with the given ID in the current + * Store the given {@link Image} with the given ID in the current * output asset.
*
- * If the {@link Image#getUri() image URI} is null or a - * data URI, it will receive a new URI, which refers to the image data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Image#getUri() image URI} is null or a + * data URI, it will receive a new URI, which refers to the image data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
- * The given {@link Image} object will be modified accordingly, if + * The given {@link Image} object will be modified accordingly, if * necessary: Its URI will be set to be the new URI. If it referred * to a buffer view, using the binary glTF extension, then this - * reference will be removed. - * - * @param gltfModel The {@link GltfModelV1} - * @param id The id of the {@link Image} - * @param image The {@link Image} - * @param lookup The lookup from ID to model + * reference will be removed. + * + * @param gltfModel The {@link GltfModelV1} + * @param id The id of the {@link Image} + * @param image The {@link Image} + * @param lookup The lookup from ID to model * @throws GltfException If the image format (and thus, the MIME type) - * can not be determined from the image data + * can not be determined from the image data */ private void storeImageAsDefault( - GltfModelV1 gltfModel, String id, Image image, - Function lookup) - { + GltfModelV1 gltfModel, String id, Image image, + Function lookup) { ImageModel imageModel = lookup.apply(id); ByteBuffer imageData = imageModel.getImageData(); String oldUriString = image.getUri(); String newUriString = oldUriString; if (oldUriString == null || - IO.isDataUriString(oldUriString) || - BinaryGltfV1.hasBinaryGltfExtension(image)) - { + IO.isDataUriString(oldUriString) || + BinaryGltfV1.hasBinaryGltfExtension(image)) { newUriString = UriStrings.createImageUriString( - imageModel, existingImageUriStrings); + imageModel, existingImageUriStrings); image.setUri(newUriString); existingImageUriStrings.add(newUriString); - + // Remove the extension object, if necessary image.removeExtensions(BinaryGltfV1.getBinaryGltfExtensionName()); } gltfAsset.putReferenceData(newUriString, imageData); } - + /** - * Store the given {@link Shader} with the given ID in the current + * Store the given {@link Shader} with the given ID in the current * output asset.
*
- * If the {@link Shader#getUri() shader URI} is null or a - * data URI, it will receive a new URI, which refers to the shader data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Shader#getUri() shader URI} is null or a + * data URI, it will receive a new URI, which refers to the shader data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
- * The given {@link Shader} object will be modified accordingly, if + * The given {@link Shader} object will be modified accordingly, if * necessary: Its URI will be set to be the new URI. If it referred * to a buffer view, using the binary glTF extension, then this - * reference will be removed. - * - * @param gltfModel The {@link GltfModelV1} - * @param id The id of the {@link Shader} - * @param shader The {@link Shader} - * @param lookup The lookup from ID to model + * reference will be removed. + * + * @param gltfModel The {@link GltfModelV1} + * @param id The id of the {@link Shader} + * @param shader The {@link Shader} + * @param lookup The lookup from ID to model */ private void storeShaderAsDefault( - GltfModelV1 gltfModel, String id, Shader shader, - Function lookup) - { + GltfModelV1 gltfModel, String id, Shader shader, + Function lookup) { ShaderModel shaderModel = lookup.apply(id); ByteBuffer shaderData = shaderModel.getShaderData(); String oldUriString = shader.getUri(); String newUriString = oldUriString; if (oldUriString == null || - IO.isDataUriString(oldUriString) || - BinaryGltfV1.hasBinaryGltfExtension(shader)) - { + IO.isDataUriString(oldUriString) || + BinaryGltfV1.hasBinaryGltfExtension(shader)) { newUriString = UriStrings.createShaderUriString( - shaderModel, existingShaderUriStrings); + shaderModel, existingShaderUriStrings); shader.setUri(newUriString); existingShaderUriStrings.add(newUriString); - + // Remove the extension object, if necessary shader.removeExtensions(BinaryGltfV1.getBinaryGltfExtensionName()); } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/EmbeddedAssetCreatorV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/EmbeddedAssetCreatorV1.java index afc8280..30ad207 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/EmbeddedAssetCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/EmbeddedAssetCreatorV1.java @@ -26,11 +26,6 @@ */ package de.javagl.jgltf.model.io.v1; -import java.nio.ByteBuffer; -import java.util.Base64; -import java.util.Map; -import java.util.function.Function; - import de.javagl.jgltf.impl.v1.Buffer; import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Image; @@ -47,172 +42,167 @@ import de.javagl.jgltf.model.v1.GltfCreatorV1; import de.javagl.jgltf.model.v1.GltfModelV1; +import java.nio.ByteBuffer; +import java.util.Base64; +import java.util.Map; +import java.util.function.Function; + /** - * A class for creating a {@link GltfAssetV1} with an "embedded" data + * A class for creating a {@link GltfAssetV1} with an "embedded" data * representation from a {@link GltfModelV1}.
*
- * In the "embedded" data representation, the data of elements like - * {@link Buffer}, {@link Image} or {@link Shader} objects is stored + * In the "embedded" data representation, the data of elements like + * {@link Buffer}, {@link Image} or {@link Shader} objects is stored * in data URIs. */ -final class EmbeddedAssetCreatorV1 -{ +final class EmbeddedAssetCreatorV1 { /** * Creates a new asset creator */ - EmbeddedAssetCreatorV1() - { + EmbeddedAssetCreatorV1() { // Default constructor } /** - * Create a {@link GltfAssetV1} with "embedded" data representation from - * the given {@link GltfModelV1}.
- *
- * The returned {@link GltfAssetV1} will contain a {@link GlTF} where the - * the URIs that appear in {@link Buffer}, {@link Image} or {@link Shader} - * instances are replaced with data URIs that contain the corresponding - * data. Its {@link GltfAsset#getBinaryData() binary data} will be - * null, and its {@link GltfAsset#getReferenceDatas() - * reference data elements} will be empty. - * - * @param gltfModel The input {@link GltfModelV1} - * @return The embedded {@link GltfAssetV1} - */ - GltfAssetV1 create(GltfModelV1 gltfModel) - { - GlTF outputGltf = GltfCreatorV1.create(gltfModel); - - // TODO This is not solved very elegantly, due to the - // transition of glTF 1.0 to glTF 2.0 - refactor this! - - // Create mappings from the IDs to the corresponding model elements. - // This assumes that they are in the same order. - Map bufferIdToBuffer = GltfUtilsV1.createMap( - outputGltf.getBuffers(), - gltfModel.getBufferModels()); - Map imageIdToImage = GltfUtilsV1.createMap( - outputGltf.getImages(), - gltfModel.getImageModels()); - Map shaderIdToShader = GltfUtilsV1.createMap( - outputGltf.getShaders(), - gltfModel.getShaderModels()); - - Optionals.of(outputGltf.getBuffers()).forEach((id, value) -> - convertBufferToEmbedded( - gltfModel, id, value, bufferIdToBuffer::get)); - Optionals.of(outputGltf.getImages()).forEach((id, value) -> - convertImageToEmbedded( - gltfModel, id, value, imageIdToImage::get)); - Optionals.of(outputGltf.getShaders()).forEach((id, value) -> - convertShaderToEmbedded( - gltfModel, id, value, shaderIdToShader::get)); - - return new GltfAssetV1(outputGltf, null); - } - - /** - * Convert the given {@link Buffer} into an embedded buffer, by replacing + * Convert the given {@link Buffer} into an embedded buffer, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModelV1} - * @param id The ID of the {@link Buffer} - * @param buffer The {@link Buffer} - * @param lookup The lookup from ID to model + * @param id The ID of the {@link Buffer} + * @param buffer The {@link Buffer} + * @param lookup The lookup from ID to model */ private static void convertBufferToEmbedded( - GltfModelV1 gltfModel, String id, Buffer buffer, - Function lookup) - { + GltfModelV1 gltfModel, String id, Buffer buffer, + Function lookup) { String uriString = buffer.getUri(); - if (IO.isDataUriString(uriString)) - { + if (IO.isDataUriString(uriString)) { return; } BufferModel bufferModel = lookup.apply(id); ByteBuffer bufferData = bufferModel.getBufferData(); - + byte data[] = new byte[bufferData.capacity()]; bufferData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); - String dataUriString = - "data:application/gltf-buffer;base64," + encodedData; - + String dataUriString = + "data:application/gltf-buffer;base64," + encodedData; + buffer.setUri(dataUriString); } /** - * Convert the given {@link Image} into an embedded image, by replacing + * Convert the given {@link Image} into an embedded image, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModelV1} - * @param id The ID of the {@link Image} - * @param image The {@link Image} - * @param lookup The lookup from ID to model + * @param id The ID of the {@link Image} + * @param image The {@link Image} + * @param lookup The lookup from ID to model * @throws GltfException If the image format (and thus, the MIME type) - * can not be determined from the image data + * can not be determined from the image data */ private static void convertImageToEmbedded( - GltfModelV1 gltfModel, String id, Image image, - Function lookup) - { + GltfModelV1 gltfModel, String id, Image image, + Function lookup) { String uriString = image.getUri(); - if (IO.isDataUriString(uriString)) - { + if (IO.isDataUriString(uriString)) { return; } ImageModel imageModel = lookup.apply(id); ByteBuffer imageData = imageModel.getImageData(); - + String uri = image.getUri(); String imageMimeTypeString = - MimeTypes.guessImageMimeTypeString(uri, imageData); - if (imageMimeTypeString == null) - { + MimeTypes.guessImageMimeTypeString(uri, imageData); + if (imageMimeTypeString == null) { throw new GltfException( - "Could not detect MIME type of image " + id); + "Could not detect MIME type of image " + id); } byte data[] = new byte[imageData.capacity()]; imageData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); String dataUriString = - "data:" + imageMimeTypeString + ";base64," + encodedData; - + "data:" + imageMimeTypeString + ";base64," + encodedData; + image.removeExtensions(BinaryGltfV1.getBinaryGltfExtensionName()); image.setUri(dataUriString); } /** - * Convert the given {@link Shader} into an embedded shader, by replacing + * Convert the given {@link Shader} into an embedded shader, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModelV1} - * @param id The ID of the {@link Shader} - * @param shader The {@link Shader} - * @param lookup The lookup from ID to model + * @param id The ID of the {@link Shader} + * @param shader The {@link Shader} + * @param lookup The lookup from ID to model */ private static void convertShaderToEmbedded( - GltfModelV1 gltfModel, String id, Shader shader, - Function lookup) - { + GltfModelV1 gltfModel, String id, Shader shader, + Function lookup) { String uriString = shader.getUri(); - if (IO.isDataUriString(uriString)) - { + if (IO.isDataUriString(uriString)) { return; } ShaderModel shaderModel = lookup.apply(id); ByteBuffer shaderData = shaderModel.getShaderData(); - + byte data[] = new byte[shaderData.capacity()]; shaderData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); - String dataUriString = - "data:text/plain;base64," + encodedData; - + String dataUriString = + "data:text/plain;base64," + encodedData; + shader.removeExtensions(BinaryGltfV1.getBinaryGltfExtensionName()); shader.setUri(dataUriString); } + /** + * Create a {@link GltfAssetV1} with "embedded" data representation from + * the given {@link GltfModelV1}.
+ *
+ * The returned {@link GltfAssetV1} will contain a {@link GlTF} where the + * the URIs that appear in {@link Buffer}, {@link Image} or {@link Shader} + * instances are replaced with data URIs that contain the corresponding + * data. Its {@link GltfAsset#getBinaryData() binary data} will be + * null, and its {@link GltfAsset#getReferenceDatas() + * reference data elements} will be empty. + * + * @param gltfModel The input {@link GltfModelV1} + * @return The embedded {@link GltfAssetV1} + */ + GltfAssetV1 create(GltfModelV1 gltfModel) { + GlTF outputGltf = GltfCreatorV1.create(gltfModel); + + // TODO This is not solved very elegantly, due to the + // transition of glTF 1.0 to glTF 2.0 - refactor this! + + // Create mappings from the IDs to the corresponding model elements. + // This assumes that they are in the same order. + Map bufferIdToBuffer = GltfUtilsV1.createMap( + outputGltf.getBuffers(), + gltfModel.getBufferModels()); + Map imageIdToImage = GltfUtilsV1.createMap( + outputGltf.getImages(), + gltfModel.getImageModels()); + Map shaderIdToShader = GltfUtilsV1.createMap( + outputGltf.getShaders(), + gltfModel.getShaderModels()); + + Optionals.of(outputGltf.getBuffers()).forEach((id, value) -> + convertBufferToEmbedded( + gltfModel, id, value, bufferIdToBuffer::get)); + Optionals.of(outputGltf.getImages()).forEach((id, value) -> + convertImageToEmbedded( + gltfModel, id, value, imageIdToImage::get)); + Optionals.of(outputGltf.getShaders()).forEach((id, value) -> + convertShaderToEmbedded( + gltfModel, id, value, shaderIdToShader::get)); + + return new GltfAssetV1(outputGltf, null); + } + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetV1.java index f148f07..1403e25 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetV1.java @@ -26,16 +26,6 @@ */ package de.javagl.jgltf.model.io.v1; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - import de.javagl.jgltf.impl.v1.Buffer; import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Image; @@ -47,166 +37,151 @@ import de.javagl.jgltf.model.io.IO; import de.javagl.jgltf.model.v1.BinaryGltfV1; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + /** * Implementation of the {@link GltfAsset} interface for glTF 1.0. */ -public final class GltfAssetV1 implements GltfAsset -{ +public final class GltfAssetV1 implements GltfAsset { /** * The {@link GlTF} */ private final GlTF gltf; - + /** * The optional binary data */ private final ByteBuffer binaryData; - + /** * The mapping from (relative) URI strings to the associated external data */ private final Map referenceDatas; - + /** * Creates a new instance - * - * @param gltf The {@link GlTF} + * + * @param gltf The {@link GlTF} * @param binaryData The optional binary data */ - public GltfAssetV1(GlTF gltf, ByteBuffer binaryData) - { + public GltfAssetV1(GlTF gltf, ByteBuffer binaryData) { this.gltf = Objects.requireNonNull(gltf, "The gltf may not be null"); this.binaryData = binaryData; this.referenceDatas = new ConcurrentHashMap(); } - + /** * Store the given byte buffer under the given (relative) URI string - * - * @param uriString The URI string + * + * @param uriString The URI string * @param byteBuffer The byte buffer */ - void putReferenceData(String uriString, ByteBuffer byteBuffer) - { - if (byteBuffer == null) - { + void putReferenceData(String uriString, ByteBuffer byteBuffer) { + if (byteBuffer == null) { referenceDatas.remove(uriString); - } - else - { + } else { referenceDatas.put(uriString, byteBuffer); } } - + @Override - public GlTF getGltf() - { + public GlTF getGltf() { return gltf; } - + @Override - public ByteBuffer getBinaryData() - { + public ByteBuffer getBinaryData() { return Buffers.createSlice(binaryData); } - + @Override - public List getReferences() - { + public List getReferences() { List references = new ArrayList(); references.addAll(getBufferReferences()); references.addAll(getImageReferences()); references.addAll(getShaderReferences()); return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * buffers that are contained in this model. - * + * * @return The references */ - public List getBufferReferences() - { + public List getBufferReferences() { List references = new ArrayList(); Map buffers = Optionals.of(gltf.getBuffers()); - for (Entry entry : buffers.entrySet()) - { + for (Entry entry : buffers.entrySet()) { String bufferId = entry.getKey(); - if (BinaryGltfV1.isBinaryGltfBufferId(bufferId)) - { + if (BinaryGltfV1.isBinaryGltfBufferId(bufferId)) { continue; } Buffer buffer = buffers.get(bufferId); String uri = buffer.getUri(); - if (!IO.isDataUriString(uri)) - { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); - GltfReference reference = - new GltfReference(bufferId, uri, target); + if (!IO.isDataUriString(uri)) { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); + GltfReference reference = + new GltfReference(bufferId, uri, target); references.add(reference); } } return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * images that are contained in this model. - * + * * @return The references */ - public List getImageReferences() - { + public List getImageReferences() { List references = new ArrayList(); Map images = Optionals.of(gltf.getImages()); - for (Entry entry : images.entrySet()) - { + for (Entry entry : images.entrySet()) { String imageId = entry.getKey(); Image image = entry.getValue(); - if (BinaryGltfV1.hasBinaryGltfExtension(image)) - { + if (BinaryGltfV1.hasBinaryGltfExtension(image)) { continue; } String uri = image.getUri(); - if (!IO.isDataUriString(uri)) - { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); - GltfReference reference = - new GltfReference(imageId, uri, target); + if (!IO.isDataUriString(uri)) { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); + GltfReference reference = + new GltfReference(imageId, uri, target); references.add(reference); } } return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * shaders that are contained in this model. - * + * * @return The references */ - public List getShaderReferences() - { + public List getShaderReferences() { List references = new ArrayList(); Map shaders = Optionals.of(gltf.getShaders()); - for (Entry entry : shaders.entrySet()) - { + for (Entry entry : shaders.entrySet()) { String shaderId = entry.getKey(); Shader shader = entry.getValue(); - if (BinaryGltfV1.hasBinaryGltfExtension(shader)) - { + if (BinaryGltfV1.hasBinaryGltfExtension(shader)) { continue; } String uri = shader.getUri(); - if (!IO.isDataUriString(uri)) - { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); - GltfReference reference = - new GltfReference(shaderId, uri, target); + if (!IO.isDataUriString(uri)) { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); + GltfReference reference = + new GltfReference(shaderId, uri, target); references.add(reference); } } @@ -214,15 +189,13 @@ public List getShaderReferences() } @Override - public ByteBuffer getReferenceData(String uriString) - { + public ByteBuffer getReferenceData(String uriString) { return Buffers.createSlice(referenceDatas.get(uriString)); } - + @Override - public Map getReferenceDatas() - { + public Map getReferenceDatas() { return Collections.unmodifiableMap(referenceDatas); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetWriterV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetWriterV1.java index 13d4c48..7c547a2 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetWriterV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetWriterV1.java @@ -26,6 +26,10 @@ */ package de.javagl.jgltf.model.io.v1; +import de.javagl.jgltf.impl.v1.GlTF; +import de.javagl.jgltf.model.io.GltfAssetWriter; +import de.javagl.jgltf.model.io.GltfWriter; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -35,24 +39,19 @@ import java.nio.channels.Channels; import java.nio.channels.WritableByteChannel; -import de.javagl.jgltf.impl.v1.GlTF; -import de.javagl.jgltf.model.io.GltfAssetWriter; -import de.javagl.jgltf.model.io.GltfWriter; - /** * A class for writing a glTF 1.0 asset in binary format to an output stream. - * This class contains implementations for the methods of the - * {@link GltfAssetWriter}, for glTF 1.0 assets. Clients should not use this + * This class contains implementations for the methods of the + * {@link GltfAssetWriter}, for glTF 1.0 assets. Clients should not use this * class directly, but only the {@link GltfAssetWriter}. */ -public class GltfAssetWriterV1 -{ +public class GltfAssetWriterV1 { /** * The magic binary glTF header. * This is an integer corresponding to the ASCII string "glTF" */ private static final int MAGIC_BINARY_GLTF_HEADER = 0x46546C67; - + /** * The binary glTF version that is written by this writer */ @@ -62,42 +61,38 @@ public class GltfAssetWriterV1 * The constant indicating JSON content format for glTF 1.0 */ private static final int CONTENT_FORMAT_JSON = 0; - + /** * Default constructor */ - public GltfAssetWriterV1() - { + public GltfAssetWriterV1() { // Default constructor } /** - * Write the given {@link GltfAssetV1} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * Write the given {@link GltfAssetV1} as a binary glTF asset to the + * given output stream. The caller is responsible for closing the * given stream.
*
- * - * @param gltfAsset The {@link GltfAssetV1} + * + * @param gltfAsset The {@link GltfAssetV1} * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAssetV1 gltfAsset, OutputStream outputStream) - throws IOException - { + public void writeBinary(GltfAssetV1 gltfAsset, OutputStream outputStream) + throws IOException { // Write the JSON representation of the glTF, creating the scene data GlTF gltf = gltfAsset.getGltf(); byte sceneData[]; - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) - { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { GltfWriter gltfWriter = new GltfWriter(); gltfWriter.setIndenting(false); gltfWriter.write(gltf, baos); sceneData = baos.toByteArray(); } - + ByteBuffer binaryData = gltfAsset.getBinaryData(); - if (binaryData == null) - { + if (binaryData == null) { binaryData = ByteBuffer.wrap(new byte[0]); } @@ -105,26 +100,26 @@ public void writeBinary(GltfAssetV1 gltfAsset, OutputStream outputStream) byte headerData[] = new byte[20]; int magic = MAGIC_BINARY_GLTF_HEADER; int version = BINARY_GLTF_VERSION; - int length = - headerData.length + sceneData.length + binaryData.capacity(); + int length = + headerData.length + sceneData.length + binaryData.capacity(); int contentLength = sceneData.length; int contentFormat = CONTENT_FORMAT_JSON; - + IntBuffer headerBuffer = ByteBuffer.wrap(headerData) - .order(ByteOrder.LITTLE_ENDIAN).asIntBuffer(); + .order(ByteOrder.LITTLE_ENDIAN).asIntBuffer(); headerBuffer.put(magic); headerBuffer.put(version); headerBuffer.put(length); headerBuffer.put(contentLength); headerBuffer.put(contentFormat); - + // Finally, write the header, scene and binary glTF buffer @SuppressWarnings("resource") - WritableByteChannel writableByteChannel = - Channels.newChannel(outputStream); + WritableByteChannel writableByteChannel = + Channels.newChannel(outputStream); writableByteChannel.write(ByteBuffer.wrap(headerData)); writableByteChannel.write(ByteBuffer.wrap(sceneData)); writableByteChannel.write(binaryData.slice()); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetsV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetsV1.java index 5a3205b..a924945 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetsV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetsV1.java @@ -35,59 +35,52 @@ * This class should not be considered as part of the public API. It may * change or be omitted in the future. */ -public class GltfAssetsV1 -{ +public class GltfAssetsV1 { /** - * Create a new default {@link GltfAssetV1} from the given + * Private constructor to prevent instantiation + */ + private GltfAssetsV1() { + // Private constructor to prevent instantiation + } + + /** + * Create a new default {@link GltfAssetV1} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV1} */ - public static GltfAssetV1 createDefault(GltfModelV1 gltfModel) - { + public static GltfAssetV1 createDefault(GltfModelV1 gltfModel) { DefaultAssetCreatorV1 assetCreator = new DefaultAssetCreatorV1(); GltfAssetV1 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - + /** - * Create a new binary {@link GltfAssetV1} from the given + * Create a new binary {@link GltfAssetV1} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV1} */ - public static GltfAssetV1 createBinary(GltfModelV1 gltfModel) - { + public static GltfAssetV1 createBinary(GltfModelV1 gltfModel) { BinaryAssetCreatorV1 assetCreator = new BinaryAssetCreatorV1(); GltfAssetV1 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - + /** - * Create a new embedded {@link GltfAssetV1} from the given + * Create a new embedded {@link GltfAssetV1} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV1} */ - public static GltfAssetV1 createEmbedded(GltfModelV1 gltfModel) - { + public static GltfAssetV1 createEmbedded(GltfModelV1 gltfModel) { EmbeddedAssetCreatorV1 assetCreator = new EmbeddedAssetCreatorV1(); GltfAssetV1 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - - - - /** - * Private constructor to prevent instantiation - */ - private GltfAssetsV1() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfModelWriterV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfModelWriterV1.java index 53fe3b0..df27f93 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfModelWriterV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfModelWriterV1.java @@ -26,98 +26,91 @@ */ package de.javagl.jgltf.model.io.v1; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.model.io.GltfAssetWriter; import de.javagl.jgltf.model.io.GltfModelWriter; import de.javagl.jgltf.model.io.GltfWriter; import de.javagl.jgltf.model.v1.GltfModelV1; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + /** - * A class for writing a {@link GltfModelV1}. This class contains + * A class for writing a {@link GltfModelV1}. This class contains * implementations for the methods of the {@link GltfModelWriter}, * for glTF 1.0 assets. Clients should not use this class directly, * but only the {@link GltfModelWriter}. */ -public final class GltfModelWriterV1 -{ +public final class GltfModelWriterV1 { /** * Default constructor */ - public GltfModelWriterV1() - { + public GltfModelWriterV1() { // Default constructor } - + /** * Write the given {@link GltfModelV1} to the given file. External - * references of buffers, images and shaders that are given via - * the respective URI string will be resolved against the parent - * directory of the given file, and the corresponding data will - * be written into the corresponding files. - * + * references of buffers, images and shaders that are given via + * the respective URI string will be resolved against the parent + * directory of the given file, and the corresponding data will + * be written into the corresponding files. + * * @param gltfModel The {@link GltfModelV1} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void write(GltfModelV1 gltfModel, File file) - throws IOException - { + public void write(GltfModelV1 gltfModel, File file) + throws IOException { GltfAssetV1 gltfAsset = GltfAssetsV1.createDefault(gltfModel); GltfAssetWriter gltfAssetWriter = new GltfAssetWriter(); gltfAssetWriter.write(gltfAsset, file); } - + /** * Write the given {@link GltfModelV1} as a binary glTF asset to the * given file - * + * * @param gltfModel The {@link GltfModelV1} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModelV1 gltfModel, File file) - throws IOException - { - try (OutputStream outputStream = new FileOutputStream(file)) - { + public void writeBinary(GltfModelV1 gltfModel, File file) + throws IOException { + try (OutputStream outputStream = new FileOutputStream(file)) { writeBinary(gltfModel, outputStream); } } - + /** * Write the given {@link GltfModelV1} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModelV1} + * + * @param gltfModel The {@link GltfModelV1} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModelV1 gltfModel, OutputStream outputStream) - throws IOException - { + public void writeBinary(GltfModelV1 gltfModel, OutputStream outputStream) + throws IOException { GltfAssetV1 gltfAsset = GltfAssetsV1.createBinary(gltfModel); GltfAssetWriterV1 gltfAssetWriter = new GltfAssetWriterV1(); gltfAssetWriter.writeBinary(gltfAsset, outputStream); } - + /** * Write the given {@link GltfModelV1} as an embedded glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModelV1} + * + * @param gltfModel The {@link GltfModelV1} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeEmbedded(GltfModelV1 gltfModel, OutputStream outputStream) - throws IOException - { + public void writeEmbedded(GltfModelV1 gltfModel, OutputStream outputStream) + throws IOException { GltfAssetV1 gltfAsset = GltfAssetsV1.createEmbedded(gltfModel); GltfWriter gltfWriter = new GltfWriter(); GlTF gltf = gltfAsset.getGltf(); diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfReaderV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfReaderV1.java index f77c7d1..d590f18 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfReaderV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfReaderV1.java @@ -26,44 +26,40 @@ */ package de.javagl.jgltf.model.io.v1; +import com.google.gson.Gson; +import de.javagl.jgltf.impl.v1.GlTF; + import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import com.google.gson.Gson; - -import de.javagl.jgltf.impl.v1.GlTF; - /** * A class for reading a version 1.0 {@link GlTF} from an input stream */ -public final class GltfReaderV1 -{ +public final class GltfReaderV1 { // Note: This class could use GltfReader as a delegate, and could // then verify that the glTF has the right version. Right now, it // assumes that it is only used for glTF 1.0 inputs. - + /** * Creates a new glTF reader */ - public GltfReaderV1() - { + public GltfReaderV1() { // Default constructor } - + /** * Read the {@link GlTF} from the given stream - * + * * @param inputStream The input stream * @return The {@link GlTF} * @throws IOException If an IO error occurs */ - public GlTF read(InputStream inputStream) throws IOException - { - InputStreamReader reader = new InputStreamReader(inputStream); - GlTF gltf = new Gson().fromJson(reader, GlTF.class); - reader.close(); + public GlTF read(InputStream inputStream) throws IOException { + InputStreamReader reader = new InputStreamReader(inputStream); + GlTF gltf = new Gson().fromJson(reader, GlTF.class); + reader.close(); return gltf; } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfUtilsV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfUtilsV1.java index e2b2ee7..b344545 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfUtilsV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfUtilsV1.java @@ -26,25 +26,26 @@ */ package de.javagl.jgltf.model.io.v1; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - import com.google.gson.Gson; - import de.javagl.jgltf.impl.v1.BufferView; import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Image; import de.javagl.jgltf.impl.v1.Shader; import de.javagl.jgltf.model.GltfException; +import java.util.*; + /** * Utility methods related to {@link GlTF}s */ -class GltfUtilsV1 -{ +class GltfUtilsV1 { + /** + * Private constructor to prevent instantiation + */ + private GltfUtilsV1() { + // Private constructor to prevent instantiation + } + /** * Creates a deep copy of the given {@link GlTF}.
*
@@ -53,25 +54,23 @@ class GltfUtilsV1 * in the copy. The goal of this method is to create a copy that is, * as far as reasonably possible, "structurally equivalent" to the * given input. - * - * @param gltf The input + * + * @param gltf The input * @return The copy * @throws GltfException If the copy can not be created */ - static GlTF copy(GlTF gltf) - { - Gson gson = new Gson(); - return gson.fromJson(gson.toJsonTree(gltf, GlTF.class), GlTF.class); + static GlTF copy(GlTF gltf) { + Gson gson = new Gson(); + return gson.fromJson(gson.toJsonTree(gltf, GlTF.class), GlTF.class); } /** * Creates a shallow copy of the given {@link BufferView} - * + * * @param bufferView The {@link BufferView} * @return The copy */ - static BufferView copy(BufferView bufferView) - { + static BufferView copy(BufferView bufferView) { BufferView copy = new BufferView(); copy.setExtensions(bufferView.getExtensions()); copy.setExtras(bufferView.getExtras()); @@ -82,16 +81,14 @@ static BufferView copy(BufferView bufferView) copy.setTarget(bufferView.getTarget()); return copy; } - - + /** * Creates a shallow copy of the given {@link Image} - * + * * @param image The {@link Image} * @return The copy */ - static Image copy(Image image) - { + static Image copy(Image image) { Image copy = new Image(); copy.setExtensions(image.getExtensions()); copy.setExtras(image.getExtras()); @@ -99,15 +96,14 @@ static Image copy(Image image) copy.setUri(image.getUri()); return copy; } - + /** * Creates a shallow copy of the given {@link Shader} - * + * * @param shader The {@link Shader} * @return The copy */ - static Shader copy(Shader shader) - { + static Shader copy(Shader shader) { Shader copy = new Shader(); copy.setExtensions(shader.getExtensions()); copy.setExtras(shader.getExtras()); @@ -116,47 +112,35 @@ static Shader copy(Shader shader) copy.setUri(shader.getUri()); return copy; } - + /** * Combine the keys of the given map with the elements of the given * collection, in iteration order. - * - * @param map The map + * + * @param map The map * @param collection The collection * @return The resulting map * @throws IllegalArgumentException If the inputs have different sizes */ static Map createMap( - Map map, - Collection collection) - { - if (map == null) - { + Map map, + Collection collection) { + if (map == null) { return Collections.emptyMap(); } - if (map.size() != collection.size()) - { + if (map.size() != collection.size()) { throw new IllegalArgumentException( - "The inputs must have the same size, but the sizes are " - + map.size() + " and " + collection.size()); + "The inputs must have the same size, but the sizes are " + + map.size() + " and " + collection.size()); } Iterator iterator0 = map.keySet().iterator(); Iterator iterator1 = collection.iterator(); Map result = new LinkedHashMap(); - while (iterator0.hasNext()) - { + while (iterator0.hasNext()) { K k = iterator0.next(); V v = iterator1.next(); result.put(k, v); } return result; } - - /** - * Private constructor to prevent instantiation - */ - private GltfUtilsV1() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/RawBinaryGltfDataReaderV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/RawBinaryGltfDataReaderV1.java index 50a0817..ea96401 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/RawBinaryGltfDataReaderV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/RawBinaryGltfDataReaderV1.java @@ -26,80 +26,73 @@ */ package de.javagl.jgltf.model.io.v1; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.io.RawGltfData; + import java.io.IOException; import java.nio.ByteBuffer; import java.nio.IntBuffer; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.io.RawGltfData; - /** * A class for reading a {@link RawGltfData} from a buffer that contains * binary glTF 1.0 data */ -public class RawBinaryGltfDataReaderV1 -{ +public class RawBinaryGltfDataReaderV1 { /** * The length of the binary glTF header for glTF 1.0, in bytes */ private static final int BINARY_GLTF_VERSION_1_HEADER_LENGTH_IN_BYTES = 20; - + /** * The constant indicating JSON content format for glTF 1.0 */ private static final int CONTENT_FORMAT_JSON = 0; - + + /** + * Private constructor to prevent instantiation + */ + private RawBinaryGltfDataReaderV1() { + // Private constructor to prevent instantiation + } + /** * Read the {@link RawGltfData} from the given buffer, which contains * the binary glTF 1.0 data - * + * * @param data The input data * @return The {@link RawGltfData} * @throws IOException If an IO error occurs */ - public static RawGltfData readBinaryGltf(ByteBuffer data) - throws IOException - { + public static RawGltfData readBinaryGltf(ByteBuffer data) + throws IOException { int headerLength = BINARY_GLTF_VERSION_1_HEADER_LENGTH_IN_BYTES; - if (data.capacity() < headerLength) - { + if (data.capacity() < headerLength) { throw new IOException("Expected header of size " + headerLength - + ", but only found " + data.capacity() + " bytes"); + + ", but only found " + data.capacity() + " bytes"); } IntBuffer intData = data.asIntBuffer(); int length = intData.get(2); - if (length != data.capacity()) - { + if (length != data.capacity()) { throw new IOException( - "Data length is " + data.capacity() + ", expected " + length); + "Data length is " + data.capacity() + ", expected " + length); } - - int contentLength = intData.get(3); + + int contentLength = intData.get(3); int contentFormat = intData.get(4); - if (contentFormat != CONTENT_FORMAT_JSON) - { + if (contentFormat != CONTENT_FORMAT_JSON) { throw new IOException("Expected content format to be JSON (" - + CONTENT_FORMAT_JSON + "), but found " + contentFormat); + + CONTENT_FORMAT_JSON + "), but found " + contentFormat); } ByteBuffer contentData = Buffers.createSlice( - data, headerLength, contentLength); + data, headerLength, contentLength); int bodyByteOffset = headerLength + contentLength; int bodyByteLength = length - bodyByteOffset; ByteBuffer bodyData = null; - if (bodyByteLength > 0) - { - bodyData = Buffers.create(bodyByteLength); - Buffers.bufferCopy(data, bodyByteOffset, bodyData, 0, bodyByteLength); + if (bodyByteLength > 0) { + bodyData = Buffers.create(bodyByteLength); + Buffers.bufferCopy(data, bodyByteOffset, bodyData, 0, bodyByteLength); } - + return new RawGltfData(contentData, bodyData); } - - /** - * Private constructor to prevent instantiation - */ - private RawBinaryGltfDataReaderV1() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/BinaryAssetCreatorV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/BinaryAssetCreatorV2.java index 6f210c9..aebf7c9 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/BinaryAssetCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/BinaryAssetCreatorV2.java @@ -26,15 +26,6 @@ */ package de.javagl.jgltf.model.io.v2; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Logger; -import java.util.stream.Collectors; - import de.javagl.jgltf.impl.v2.Buffer; import de.javagl.jgltf.impl.v2.BufferView; import de.javagl.jgltf.impl.v2.GlTF; @@ -47,47 +38,105 @@ import de.javagl.jgltf.model.io.MimeTypes; import de.javagl.jgltf.model.v2.GltfCreatorV2; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.logging.Logger; +import java.util.stream.Collectors; + /** - * A class for creating a binary {@link GltfAssetV2} from a + * A class for creating a binary {@link GltfAssetV2} from a * {@link GltfModel}.
*
*/ -final class BinaryAssetCreatorV2 -{ +final class BinaryAssetCreatorV2 { /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(BinaryAssetCreatorV2.class.getName()); - + Logger.getLogger(BinaryAssetCreatorV2.class.getName()); + /** * Creates a new asset creator */ - BinaryAssetCreatorV2() - { + BinaryAssetCreatorV2() { // Default constructor } - + + /** + * Compute the total size that is required for the binary glTF buffer + * for the given {@link GltfModel}, which is the sum of all buffer + * sizes of all buffers and images + * + * @param gltfModel The {@link GltfModel} + * @return The total size for the binary glTF buffer + */ + private static int computeBinaryGltfBufferSize(GltfModel gltfModel) { + int binaryGltfBufferSize = 0; + for (BufferModel bufferModel : gltfModel.getBufferModels()) { + ByteBuffer bufferData = bufferModel.getBufferData(); + binaryGltfBufferSize += bufferData.capacity(); + } + for (ImageModel imageModel : gltfModel.getImageModels()) { + ByteBuffer imageData = imageModel.getImageData(); + binaryGltfBufferSize += imageData.capacity(); + } + return binaryGltfBufferSize; + } + + /** + * Put the contents of all byte buffers of the given list into the given + * target buffer. This method assumes that the target buffer has a + * sufficient capacity to hold all buffers. + * + * @param buffers The buffers + * @param targetBuffer The target buffer + * @return A mapping from each key to the offset inside the target buffer + */ + private static Map concatBuffers( + List buffers, ByteBuffer targetBuffer) { + Map offsets = new LinkedHashMap(); + for (int i = 0; i < buffers.size(); i++) { + ByteBuffer oldByteBuffer = buffers.get(i); + int offset = targetBuffer.position(); + offsets.put(i, offset); + targetBuffer.put(oldByteBuffer.slice()); + } + return offsets; + } + + /** + * Creates a copy of the given list. If the given list is null, + * then an unmodifiable empty list will be returned + * + * @param list The input list + * @return The copy + */ + private static List copy(List list) { + if (list == null) { + return Collections.emptyList(); + } + return new ArrayList(list); + } + /** * Create a binary {@link GltfAssetV2} from the given {@link GltfModel}. * The resulting asset will have a {@link GlTF} that uses references to * {@link BufferView} objects in its {@link Buffer} and {@link Image} - * elements. - * + * elements. + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV2} */ - GltfAssetV2 create(GltfModel gltfModel) - { + GltfAssetV2 create(GltfModel gltfModel) { GlTF outputGltf = GltfCreatorV2.create(gltfModel); - + // Create the new byte buffer for the data of the "binary_glTF" Buffer - int binaryGltfBufferSize = - computeBinaryGltfBufferSize(gltfModel); - ByteBuffer binaryGltfByteBuffer = - Buffers.create(binaryGltfBufferSize); + int binaryGltfBufferSize = + computeBinaryGltfBufferSize(gltfModel); + ByteBuffer binaryGltfByteBuffer = + Buffers.create(binaryGltfBufferSize); - // Create the binary Buffer, + // Create the binary Buffer, Buffer binaryGltfBuffer = new Buffer(); binaryGltfBuffer.setByteLength(binaryGltfBufferSize); outputGltf.setBuffers(Collections.singletonList(binaryGltfBuffer)); @@ -95,31 +144,30 @@ GltfAssetV2 create(GltfModel gltfModel) // Create a defensive copy of the original image list List oldImages = copy(outputGltf.getImages()); - // Place the data from buffers and images into the new binary glTF - // buffer. The mappings from IDs to offsets inside the resulting + // Place the data from buffers and images into the new binary glTF + // buffer. The mappings from IDs to offsets inside the resulting // buffer will be used to compute the offsets for the buffer views - List bufferDatas = - gltfModel.getBufferModels().stream() - .map(BufferModel::getBufferData) - .collect(Collectors.toList()); + List bufferDatas = + gltfModel.getBufferModels().stream() + .map(BufferModel::getBufferData) + .collect(Collectors.toList()); Map bufferOffsets = concatBuffers( - bufferDatas, binaryGltfByteBuffer); - List imageDatas = - gltfModel.getImageModels().stream() - .map(ImageModel::getImageData) - .collect(Collectors.toList()); + bufferDatas, binaryGltfByteBuffer); + List imageDatas = + gltfModel.getImageModels().stream() + .map(ImageModel::getImageData) + .collect(Collectors.toList()); Map imageOffsets = concatBuffers( - imageDatas, binaryGltfByteBuffer); + imageDatas, binaryGltfByteBuffer); binaryGltfByteBuffer.position(0); - // For all existing BufferViews, create new ones that are updated to + // For all existing BufferViews, create new ones that are updated to // refer to the new binary glTF buffer, with the appropriate offset - List oldBufferViews = - copy(outputGltf.getBufferViews()); - List newBufferViews = - new ArrayList(); - for (int i = 0; i < oldBufferViews.size(); i++) - { + List oldBufferViews = + copy(outputGltf.getBufferViews()); + List newBufferViews = + new ArrayList(); + for (int i = 0; i < oldBufferViews.size(); i++) { BufferView oldBufferView = oldBufferViews.get(i); BufferView newBufferView = GltfUtilsV2.copy(oldBufferView); @@ -133,12 +181,11 @@ GltfAssetV2 create(GltfModel gltfModel) newBufferViews.add(newBufferView); } - // For all existing Images, create new ones that are updated to - // refer to the new binary glTF buffer, using a bufferView + // For all existing Images, create new ones that are updated to + // refer to the new binary glTF buffer, using a bufferView // index that refers to a newly created BufferView List newImages = new ArrayList(); - for (int i = 0; i < oldImages.size(); i++) - { + for (int i = 0; i < oldImages.size(); i++) { Image oldImage = oldImages.get(i); Image newImage = GltfUtilsV2.copy(oldImage); @@ -155,100 +202,30 @@ GltfAssetV2 create(GltfModel gltfModel) int newBufferViewIndex = newBufferViews.size(); newImage.setBufferView(newBufferViewIndex); newImage.setUri(null); - + String imageMimeTypeString = - MimeTypes.guessImageMimeTypeString( - oldImage.getUri(), imageData); - if (imageMimeTypeString == null) - { + MimeTypes.guessImageMimeTypeString( + oldImage.getUri(), imageData); + if (imageMimeTypeString == null) { logger.warning("Could not detect MIME type of image"); - } - else - { + } else { newImage.setMimeType(imageMimeTypeString); } - + newBufferViews.add(imageBufferView); newImages.add(newImage); } // Place the newly created lists into the output glTF, // if there have been non-null lists for them in the input - if (!oldImages.isEmpty()) - { + if (!oldImages.isEmpty()) { outputGltf.setImages(newImages); } - if (!newBufferViews.isEmpty()) - { + if (!newBufferViews.isEmpty()) { outputGltf.setBufferViews(newBufferViews); } return new GltfAssetV2(outputGltf, binaryGltfByteBuffer); } - /** - * Compute the total size that is required for the binary glTF buffer - * for the given {@link GltfModel}, which is the sum of all buffer - * sizes of all buffers and images - * - * @param gltfModel The {@link GltfModel} - * @return The total size for the binary glTF buffer - */ - private static int computeBinaryGltfBufferSize(GltfModel gltfModel) - { - int binaryGltfBufferSize = 0; - for (BufferModel bufferModel : gltfModel.getBufferModels()) - { - ByteBuffer bufferData = bufferModel.getBufferData(); - binaryGltfBufferSize += bufferData.capacity(); - } - for (ImageModel imageModel : gltfModel.getImageModels()) - { - ByteBuffer imageData = imageModel.getImageData(); - binaryGltfBufferSize += imageData.capacity(); - } - return binaryGltfBufferSize; - } - - /** - * Put the contents of all byte buffers of the given list into the given - * target buffer. This method assumes that the target buffer has a - * sufficient capacity to hold all buffers. - * - * @param buffers The buffers - * @param targetBuffer The target buffer - * @return A mapping from each key to the offset inside the target buffer - */ - private static Map concatBuffers( - List buffers, ByteBuffer targetBuffer) - { - Map offsets = new LinkedHashMap(); - for (int i = 0; i < buffers.size(); i++) - { - ByteBuffer oldByteBuffer = buffers.get(i); - int offset = targetBuffer.position(); - offsets.put(i, offset); - targetBuffer.put(oldByteBuffer.slice()); - } - return offsets; - } - - - /** - * Creates a copy of the given list. If the given list is null, - * then an unmodifiable empty list will be returned - * - * @param list The input list - * @return The copy - */ - private static List copy(List list) - { - if (list == null) - { - return Collections.emptyList(); - } - return new ArrayList(list); - } - - } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/DefaultAssetCreatorV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/DefaultAssetCreatorV2.java index e50759f..953a7e4 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/DefaultAssetCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/DefaultAssetCreatorV2.java @@ -26,14 +26,6 @@ */ package de.javagl.jgltf.model.io.v2; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - import de.javagl.jgltf.impl.v2.Buffer; import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.impl.v2.Image; @@ -46,22 +38,29 @@ import de.javagl.jgltf.model.io.IO; import de.javagl.jgltf.model.v2.GltfCreatorV2; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + /** - * A class for creating a {@link GltfAssetV2} with a default data + * A class for creating a {@link GltfAssetV2} with a default data * representation from a {@link GltfModel}.
*
- * In the default data representation, elements are referred to via URIs. + * In the default data representation, elements are referred to via URIs. * Data elements like {@link Buffer} or {@link Image} - * objects that used the binary glTF extension or data URIs will be + * objects that used the binary glTF extension or data URIs will be * converted to refer to their data using URIs. */ -final class DefaultAssetCreatorV2 -{ +final class DefaultAssetCreatorV2 { /** * The {@link GltfAssetV2} that is currently being created */ private GltfAssetV2 gltfAsset; - + /** * The set of {@link Buffer} URI strings that are already used */ @@ -75,36 +74,50 @@ final class DefaultAssetCreatorV2 /** * Creates a new asset creator */ - DefaultAssetCreatorV2() - { + DefaultAssetCreatorV2() { // Default constructor } + /** + * Collect all strings that are obtained from the given elements by + * applying the given function, if these strings are not null + * and no data URI strings + * + * @param elements The elements + * @param uriFunction The function to obtain the string + * @return The strings + */ + private static Set collectUriStrings(Collection elements, + Function uriFunction) { + return elements.stream() + .map(uriFunction) + .filter(Objects::nonNull) + .filter(uriString -> !IO.isDataUriString(uriString)) + .collect(Collectors.toSet()); + } + /** * Create a default {@link GltfAssetV2} from the given {@link GltfModel}. - * + * * @param gltfModel The input {@link GltfModel} * @return The default {@link GltfAssetV2} */ - GltfAssetV2 create(GltfModel gltfModel) - { + GltfAssetV2 create(GltfModel gltfModel) { GlTF outputGltf = GltfCreatorV2.create(gltfModel); List buffers = Optionals.of(outputGltf.getBuffers()); List images = Optionals.of(outputGltf.getImages()); - + existingBufferUriStrings = collectUriStrings(buffers, Buffer::getUri); existingImageUriStrings = collectUriStrings(images, Image::getUri); this.gltfAsset = new GltfAssetV2(outputGltf, null); - - for (int i = 0; i < buffers.size(); i++) - { + + for (int i = 0; i < buffers.size(); i++) { Buffer buffer = buffers.get(i); storeBufferAsDefault(gltfModel, i, buffer); } - for (int i = 0; i < images.size(); i++) - { + for (int i = 0; i < images.size(); i++) { Image image = images.get(i); storeImageAsDefault(gltfModel, i, image); } @@ -113,99 +126,75 @@ GltfAssetV2 create(GltfModel gltfModel) } /** - * Collect all strings that are obtained from the given elements by - * applying the given function, if these strings are not null - * and no data URI strings - * - * @param elements The elements - * @param uriFunction The function to obtain the string - * @return The strings - */ - private static Set collectUriStrings(Collection elements, - Function uriFunction) - { - return elements.stream() - .map(uriFunction) - .filter(Objects::nonNull) - .filter(uriString -> !IO.isDataUriString(uriString)) - .collect(Collectors.toSet()); - } - - /** - * Store the given {@link Buffer} with the given index in the current + * Store the given {@link Buffer} with the given index in the current * output asset.
*
- * If the {@link Buffer#getUri() buffer URI} is null or a - * data URI, it will receive a new URI, which refers to the buffer data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Buffer#getUri() buffer URI} is null or a + * data URI, it will receive a new URI, which refers to the buffer data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
- * The given {@link Buffer} object will be modified accordingly, if - * necessary: Its URI will be set to be the new URI. - * - * @param gltfModel The {@link GltfModel} - * @param index The index of the {@link Buffer} - * @param buffer The {@link Buffer} + * The given {@link Buffer} object will be modified accordingly, if + * necessary: Its URI will be set to be the new URI. + * + * @param gltfModel The {@link GltfModel} + * @param index The index of the {@link Buffer} + * @param buffer The {@link Buffer} */ private void storeBufferAsDefault( - GltfModel gltfModel, int index, Buffer buffer) - { + GltfModel gltfModel, int index, Buffer buffer) { BufferModel bufferModel = gltfModel.getBufferModels().get(index); ByteBuffer bufferData = bufferModel.getBufferData(); String oldUriString = buffer.getUri(); String newUriString = oldUriString; - if (oldUriString == null || IO.isDataUriString(oldUriString)) - { + if (oldUriString == null || IO.isDataUriString(oldUriString)) { newUriString = UriStrings.createBufferUriString( - existingBufferUriStrings); + existingBufferUriStrings); buffer.setUri(newUriString); existingBufferUriStrings.add(newUriString); } - + gltfAsset.putReferenceData(newUriString, bufferData); } - + /** - * Store the given {@link Image} with the given index in the current + * Store the given {@link Image} with the given index in the current * output asset.
*
- * If the {@link Image#getUri() image URI} is null or a - * data URI, it will receive a new URI, which refers to the image data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Image#getUri() image URI} is null or a + * data URI, it will receive a new URI, which refers to the image data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
- * The given {@link Image} object will be modified accordingly, if + * The given {@link Image} object will be modified accordingly, if * necessary: Its URI will be set to be the new URI. If it referred * to a {@link Image#getBufferView() image buffer view}, then this * reference will be set to be null. - * - * @param gltfModel The {@link GltfModel} - * @param index The index of the {@link Image} - * @param image The {@link Image} + * + * @param gltfModel The {@link GltfModel} + * @param index The index of the {@link Image} + * @param image The {@link Image} */ private void storeImageAsDefault( - GltfModel gltfModel, int index, Image image) - { + GltfModel gltfModel, int index, Image image) { ImageModel imageModel = gltfModel.getImageModels().get(index); ByteBuffer imageData = imageModel.getImageData(); String oldUriString = image.getUri(); String newUriString = oldUriString; - if (oldUriString == null || IO.isDataUriString(oldUriString)) - { + if (oldUriString == null || IO.isDataUriString(oldUriString)) { newUriString = UriStrings.createImageUriString( - imageModel, existingImageUriStrings); + imageModel, existingImageUriStrings); image.setUri(newUriString); existingImageUriStrings.add(newUriString); } - - if (image.getBufferView() != null) - { + + if (image.getBufferView() != null) { image.setBufferView(null); } - + gltfAsset.putReferenceData(newUriString, imageData); } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/EmbeddedAssetCreatorV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/EmbeddedAssetCreatorV2.java index f09f961..5e41d68 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/EmbeddedAssetCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/EmbeddedAssetCreatorV2.java @@ -26,141 +26,127 @@ */ package de.javagl.jgltf.model.io.v2; -import java.nio.ByteBuffer; -import java.util.Base64; -import java.util.List; - import de.javagl.jgltf.impl.v2.Buffer; import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.impl.v2.Image; -import de.javagl.jgltf.model.BufferModel; -import de.javagl.jgltf.model.GltfException; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.ImageModel; -import de.javagl.jgltf.model.Optionals; +import de.javagl.jgltf.model.*; import de.javagl.jgltf.model.io.GltfAsset; import de.javagl.jgltf.model.io.IO; import de.javagl.jgltf.model.io.MimeTypes; import de.javagl.jgltf.model.v2.GltfCreatorV2; +import java.nio.ByteBuffer; +import java.util.Base64; +import java.util.List; + /** - * A class for creating a {@link GltfAssetV2} with an "embedded" data + * A class for creating a {@link GltfAssetV2} with an "embedded" data * representation from a {@link GltfModel}.
*
- * In the "embedded" data representation, the data of elements like + * In the "embedded" data representation, the data of elements like * {@link Buffer} or {@link Image} objects is stored in data URIs. */ -final class EmbeddedAssetCreatorV2 -{ +final class EmbeddedAssetCreatorV2 { /** * Creates a new asset creator */ - EmbeddedAssetCreatorV2() - { + EmbeddedAssetCreatorV2() { // Default constructor } /** - * Create a {@link GltfAssetV2} with "embedded" data representation from - * the given {@link GltfModel}.
- *
- * The returned {@link GltfAssetV2} will contain a {@link GlTF} where the - * the URIs that appear in {@link Buffer} and {@link Image} instances are - * replaced with data URIs that contain the corresponding data. - * Its {@link GltfAsset#getBinaryData() binary data} will be - * null, and its {@link GltfAsset#getReferenceDatas() - * reference data elements} will be empty. - * - * @param gltfModel The input {@link GltfModel} - * @return The embedded {@link GltfAssetV2} - */ - GltfAssetV2 create(GltfModel gltfModel) - { - GlTF outputGltf = GltfCreatorV2.create(gltfModel); - - List buffers = Optionals.of(outputGltf.getBuffers()); - for (int i = 0; i < buffers.size(); i++) - { - Buffer buffer = buffers.get(i); - convertBufferToEmbedded(gltfModel, i, buffer); - } - - List images = Optionals.of(outputGltf.getImages()); - for (int i = 0; i < images.size(); i++) - { - Image image = images.get(i); - convertImageToEmbedded(gltfModel, i, image); - } - - return new GltfAssetV2(outputGltf, null); - } - - /** - * Convert the given {@link Buffer} into an embedded buffer, by replacing + * Convert the given {@link Buffer} into an embedded buffer, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModel} - * @param index The index of the {@link Buffer} - * @param buffer The {@link Buffer} + * @param index The index of the {@link Buffer} + * @param buffer The {@link Buffer} */ private static void convertBufferToEmbedded( - GltfModel gltfModel, int index, Buffer buffer) - { + GltfModel gltfModel, int index, Buffer buffer) { String uriString = buffer.getUri(); - if (IO.isDataUriString(uriString)) - { + if (IO.isDataUriString(uriString)) { return; } BufferModel bufferModel = gltfModel.getBufferModels().get(index); ByteBuffer bufferData = bufferModel.getBufferData(); - + byte data[] = new byte[bufferData.capacity()]; bufferData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); - String dataUriString = - "data:application/gltf-buffer;base64," + encodedData; - + String dataUriString = + "data:application/gltf-buffer;base64," + encodedData; + buffer.setUri(dataUriString); } /** - * Convert the given {@link Image} into an embedded image, by replacing + * Convert the given {@link Image} into an embedded image, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModel} - * @param index The index of the {@link Image} - * @param image The {@link Image} + * @param index The index of the {@link Image} + * @param image The {@link Image} * @throws GltfException If the image format (and thus, the MIME type) - * can not be determined from the image data + * can not be determined from the image data */ private static void convertImageToEmbedded( - GltfModel gltfModel, int index, Image image) - { + GltfModel gltfModel, int index, Image image) { String uriString = image.getUri(); - if (IO.isDataUriString(uriString)) - { + if (IO.isDataUriString(uriString)) { return; } ImageModel imageModel = gltfModel.getImageModels().get(index); ByteBuffer imageData = imageModel.getImageData(); - + String uri = image.getUri(); String imageMimeTypeString = - MimeTypes.guessImageMimeTypeString(uri, imageData); - if (imageMimeTypeString == null) - { + MimeTypes.guessImageMimeTypeString(uri, imageData); + if (imageMimeTypeString == null) { throw new GltfException( - "Could not detect MIME type of image " + index); + "Could not detect MIME type of image " + index); } byte data[] = new byte[imageData.capacity()]; imageData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); String dataUriString = - "data:" + imageMimeTypeString + ";base64," + encodedData; - + "data:" + imageMimeTypeString + ";base64," + encodedData; + image.setUri(dataUriString); } + /** + * Create a {@link GltfAssetV2} with "embedded" data representation from + * the given {@link GltfModel}.
+ *
+ * The returned {@link GltfAssetV2} will contain a {@link GlTF} where the + * the URIs that appear in {@link Buffer} and {@link Image} instances are + * replaced with data URIs that contain the corresponding data. + * Its {@link GltfAsset#getBinaryData() binary data} will be + * null, and its {@link GltfAsset#getReferenceDatas() + * reference data elements} will be empty. + * + * @param gltfModel The input {@link GltfModel} + * @return The embedded {@link GltfAssetV2} + */ + GltfAssetV2 create(GltfModel gltfModel) { + GlTF outputGltf = GltfCreatorV2.create(gltfModel); + + List buffers = Optionals.of(outputGltf.getBuffers()); + for (int i = 0; i < buffers.size(); i++) { + Buffer buffer = buffers.get(i); + convertBufferToEmbedded(gltfModel, i, buffer); + } + + List images = Optionals.of(outputGltf.getImages()); + for (int i = 0; i < images.size(); i++) { + Image image = images.get(i); + convertImageToEmbedded(gltfModel, i, image); + } + + return new GltfAssetV2(outputGltf, null); + } + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetV2.java index e5914b2..94c7e32 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetV2.java @@ -26,15 +26,6 @@ */ package de.javagl.jgltf.model.io.v2; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - import de.javagl.jgltf.impl.v2.Buffer; import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.impl.v2.Image; @@ -44,16 +35,20 @@ import de.javagl.jgltf.model.io.GltfReference; import de.javagl.jgltf.model.io.IO; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + /** * Implementation of the {@link GltfAsset} interface for glTF 2.0. */ -public final class GltfAssetV2 implements GltfAsset -{ +public final class GltfAssetV2 implements GltfAsset { /** * The {@link GlTF} */ private final GlTF gltf; - + /** * The optional binary data */ @@ -63,132 +58,114 @@ public final class GltfAssetV2 implements GltfAsset * The mapping from (relative) URI strings to the associated external data */ private final Map referenceDatas; - + /** * Creates a new instance - * - * @param gltf The {@link GlTF} + * + * @param gltf The {@link GlTF} * @param binaryData The optional binary data */ - public GltfAssetV2(GlTF gltf, ByteBuffer binaryData) - { + public GltfAssetV2(GlTF gltf, ByteBuffer binaryData) { this.gltf = Objects.requireNonNull(gltf, "The gltf may not be null"); this.binaryData = binaryData; this.referenceDatas = new ConcurrentHashMap(); } - + /** * Store the given byte buffer under the given (relative) URI string - * - * @param uriString The URI string + * + * @param uriString The URI string * @param byteBuffer The byte buffer */ - void putReferenceData(String uriString, ByteBuffer byteBuffer) - { - if (byteBuffer == null) - { + void putReferenceData(String uriString, ByteBuffer byteBuffer) { + if (byteBuffer == null) { referenceDatas.remove(uriString); - } - else - { + } else { referenceDatas.put(uriString, byteBuffer); } } - + @Override - public GlTF getGltf() - { + public GlTF getGltf() { return gltf; } - + @Override - public ByteBuffer getBinaryData() - { + public ByteBuffer getBinaryData() { return Buffers.createSlice(binaryData); } - + @Override - public List getReferences() - { + public List getReferences() { List references = new ArrayList(); references.addAll(getBufferReferences()); references.addAll(getImageReferences()); return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * buffers that are contained in this model. - * + * * @return The references */ - public List getBufferReferences() - { + public List getBufferReferences() { List references = new ArrayList(); List buffers = Optionals.of(gltf.getBuffers()); - for (int i = 0; i < buffers.size(); i++) - { + for (int i = 0; i < buffers.size(); i++) { Buffer buffer = buffers.get(i); - if (buffer.getUri() == null) - { + if (buffer.getUri() == null) { // This is the binary glTF buffer continue; } String uri = buffer.getUri(); - if (!IO.isDataUriString(uri)) - { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); + if (!IO.isDataUriString(uri)) { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); GltfReference reference = - new GltfReference("buffer " + i, uri, target); + new GltfReference("buffer " + i, uri, target); references.add(reference); } } return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * images that are contained in this model. - * + * * @return The references */ - public List getImageReferences() - { + public List getImageReferences() { List references = new ArrayList(); List images = Optionals.of(gltf.getImages()); - for (int i = 0; i < images.size(); i++) - { + for (int i = 0; i < images.size(); i++) { Image image = images.get(i); - if (image.getBufferView() != null) - { + if (image.getBufferView() != null) { // This is an image that refers to a buffer view continue; } String uri = image.getUri(); - if (!IO.isDataUriString(uri)) - { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); - GltfReference reference = - new GltfReference("image " + i, uri, target); + if (!IO.isDataUriString(uri)) { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); + GltfReference reference = + new GltfReference("image " + i, uri, target); references.add(reference); } } return references; } - + @Override - public ByteBuffer getReferenceData(String uriString) - { + public ByteBuffer getReferenceData(String uriString) { return Buffers.createSlice(referenceDatas.get(uriString)); } @Override - public Map getReferenceDatas() - { + public Map getReferenceDatas() { return Collections.unmodifiableMap(referenceDatas); } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetWriterV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetWriterV2.java index 231f1bb..89f1ec5 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetWriterV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetWriterV2.java @@ -26,6 +26,11 @@ */ package de.javagl.jgltf.model.io.v2; +import de.javagl.jgltf.impl.v2.GlTF; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.io.GltfAssetWriter; +import de.javagl.jgltf.model.io.GltfWriter; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -34,25 +39,19 @@ import java.nio.channels.WritableByteChannel; import java.util.Arrays; -import de.javagl.jgltf.impl.v2.GlTF; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.io.GltfAssetWriter; -import de.javagl.jgltf.model.io.GltfWriter; - /** * A class for writing a glTF 2.0 asset in binary format to an output stream. - * This class contains implementations for the methods of the - * {@link GltfAssetWriter}, for glTF 2.0 assets. Clients should not use this + * This class contains implementations for the methods of the + * {@link GltfAssetWriter}, for glTF 2.0 assets. Clients should not use this * class directly, but only the {@link GltfAssetWriter}. */ -public final class GltfAssetWriterV2 -{ +public final class GltfAssetWriterV2 { /** * The magic binary glTF header. * This is an integer corresponding to the ASCII string "glTF" */ private static final int MAGIC_BINARY_GLTF_HEADER = 0x46546C67; - + /** * The binary glTF version that is written by this writer */ @@ -63,67 +62,60 @@ public final class GltfAssetWriterV2 * This is an integer corresponding to the ASCII string "JSON" */ private static final int CHUNK_TYPE_JSON = 0x4E4F534A; - + /** * The constant indicating BIN chunk type for glTF 2.0 * This is an integer corresponding to the ASCII string "BIN" */ private static final int CHUNK_TYPE_BIN = 0x004E4942; - + /** * Default constructor */ - public GltfAssetWriterV2() - { + public GltfAssetWriterV2() { // Default constructor } - + /** - * Write the given {@link GltfAssetV2} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * Write the given {@link GltfAssetV2} as a binary glTF asset to the + * given output stream. The caller is responsible for closing the * given stream.
*
- * - * @param gltfAsset The {@link GltfAssetV2} + * + * @param gltfAsset The {@link GltfAssetV2} * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAssetV2 gltfAsset, OutputStream outputStream) - throws IOException - { + public void writeBinary(GltfAssetV2 gltfAsset, OutputStream outputStream) + throws IOException { // Write the JSON representation of the glTF GlTF gltf = gltfAsset.getGltf(); byte jsonData[]; - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) - { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { GltfWriter gltfWriter = new GltfWriter(); gltfWriter.setIndenting(false); gltfWriter.write(gltf, baos); jsonData = baos.toByteArray(); } // Ensure 4-byte-alignment for the jsonData - if (jsonData.length % 4 != 0) - { + if (jsonData.length % 4 != 0) { int oldLength = jsonData.length; int padding = 4 - (oldLength % 4); jsonData = Arrays.copyOf(jsonData, oldLength + padding); - for (int i = 0; i < padding; i++) - { + for (int i = 0; i < padding; i++) { jsonData[oldLength + i] = ' '; } } - + // Obtain the binary data, and ensure it's 4-byte aligned ByteBuffer binaryData = gltfAsset.getBinaryData(); - if (binaryData == null) - { + if (binaryData == null) { binaryData = ByteBuffer.wrap(new byte[0]); } - if (binaryData.capacity() % 4 != 0) - { + if (binaryData.capacity() % 4 != 0) { int padding = 4 - (binaryData.capacity() % 4); - binaryData = - Buffers.copyOf(binaryData, binaryData.capacity() + padding); + binaryData = + Buffers.copyOf(binaryData, binaryData.capacity() + padding); } // Create the JSON chunk data @@ -131,24 +123,24 @@ public void writeBinary(GltfAssetV2 gltfAsset, OutputStream outputStream) jsonChunkData.append(jsonData.length); jsonChunkData.append(CHUNK_TYPE_JSON); jsonChunkData.append(ByteBuffer.wrap(jsonData)); - + // Create the BIN chunk data ChunkData binChunkData = new ChunkData(); binChunkData.append(binaryData.capacity()); binChunkData.append(CHUNK_TYPE_BIN); binChunkData.append(binaryData); - + // Create the header data ChunkData headerData = new ChunkData(); headerData.append(MAGIC_BINARY_GLTF_HEADER); headerData.append(BINARY_GLTF_VERSION); int length = 12 + jsonData.length + 8 + binaryData.capacity() + 8; headerData.append(length); - + // Finally, write the header, JSON and BIN data to the output stream @SuppressWarnings("resource") - WritableByteChannel writableByteChannel = - Channels.newChannel(outputStream); + WritableByteChannel writableByteChannel = + Channels.newChannel(outputStream); writableByteChannel.write(headerData.get()); writableByteChannel.write(jsonChunkData.get()); writableByteChannel.write(binChunkData.get()); @@ -157,61 +149,55 @@ public void writeBinary(GltfAssetV2 gltfAsset, OutputStream outputStream) /** * Utility class for collecting the data of one binary glTF 2.0 chunk */ - private static class ChunkData - { + private static class ChunkData { /** * The stream that will collect the data */ private ByteArrayOutputStream baos; - + /** * Default constructor */ - ChunkData() - { + ChunkData() { baos = new ByteArrayOutputStream(); } - + /** * Append the given value to this data - * + * * @param value The value * @throws IOException If an IO error occurs */ - void append(int value) throws IOException - { + void append(int value) throws IOException { baos.write((value >> 0) & 0xFF); baos.write((value >> 8) & 0xFF); baos.write((value >> 16) & 0xFF); baos.write((value >> 24) & 0xFF); } - + /** * Append the given buffer to this data - * + * * @param buffer The buffer * @throws IOException If an IO error occurs */ - void append(ByteBuffer buffer) throws IOException - { + void append(ByteBuffer buffer) throws IOException { @SuppressWarnings("resource") - WritableByteChannel writableByteChannel = - Channels.newChannel(baos); + WritableByteChannel writableByteChannel = + Channels.newChannel(baos); writableByteChannel.write(buffer.slice()); } - + /** * Returns the chunk data as a (non-direct!) buffer - * + * * @return The chunk data */ - ByteBuffer get() - { + ByteBuffer get() { return ByteBuffer.wrap(baos.toByteArray()); } - + } - - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetsV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetsV2.java index 2f5cd50..485fcc1 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetsV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetsV2.java @@ -34,59 +34,52 @@ * This class should not be considered as part of the public API. It may * change or be omitted in the future. */ -public class GltfAssetsV2 -{ +public class GltfAssetsV2 { /** - * Create a new default {@link GltfAssetV2} from the given + * Private constructor to prevent instantiation + */ + private GltfAssetsV2() { + // Private constructor to prevent instantiation + } + + /** + * Create a new default {@link GltfAssetV2} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV2} */ - public static GltfAssetV2 createDefault(GltfModel gltfModel) - { + public static GltfAssetV2 createDefault(GltfModel gltfModel) { DefaultAssetCreatorV2 assetCreator = new DefaultAssetCreatorV2(); GltfAssetV2 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - + /** - * Create a new binary {@link GltfAssetV2} from the given + * Create a new binary {@link GltfAssetV2} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV2} */ - public static GltfAssetV2 createBinary(GltfModel gltfModel) - { + public static GltfAssetV2 createBinary(GltfModel gltfModel) { BinaryAssetCreatorV2 assetCreator = new BinaryAssetCreatorV2(); GltfAssetV2 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - + /** - * Create a new embedded {@link GltfAssetV2} from the given + * Create a new embedded {@link GltfAssetV2} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV2} */ - public static GltfAssetV2 createEmbedded(GltfModel gltfModel) - { + public static GltfAssetV2 createEmbedded(GltfModel gltfModel) { EmbeddedAssetCreatorV2 assetCreator = new EmbeddedAssetCreatorV2(); GltfAssetV2 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - - - - /** - * Private constructor to prevent instantiation - */ - private GltfAssetsV2() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfModelWriterV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfModelWriterV2.java index 1d88259..4deb205 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfModelWriterV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfModelWriterV2.java @@ -26,80 +26,75 @@ */ package de.javagl.jgltf.model.io.v2; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; - import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.io.GltfAssetWriter; import de.javagl.jgltf.model.io.GltfModelWriter; import de.javagl.jgltf.model.io.GltfWriter; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + /** - * A class for writing a {@link GltfModel}. This class contains + * A class for writing a {@link GltfModel}. This class contains * implementations for the methods of the {@link GltfModelWriter}, * for glTF 2.0 assets. Clients should not use this class directly, * but only the {@link GltfModelWriter}. */ -public final class GltfModelWriterV2 -{ +public final class GltfModelWriterV2 { /** * Default constructor */ - public GltfModelWriterV2() - { + public GltfModelWriterV2() { // Default constructor } - + /** * Write the given {@link GltfModel} to the given file. External - * references of buffers and images that are given via the respective - * URI string will be resolved against the parent directory of the - * given file, and the corresponding data will be written into - * the corresponding files. - * + * references of buffers and images that are given via the respective + * URI string will be resolved against the parent directory of the + * given file, and the corresponding data will be written into + * the corresponding files. + * * @param gltfModel The {@link GltfModel} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void write(GltfModel gltfModel, File file) - throws IOException - { + public void write(GltfModel gltfModel, File file) + throws IOException { GltfAssetV2 gltfAsset = GltfAssetsV2.createDefault(gltfModel); GltfAssetWriter gltfAssetWriter = new GltfAssetWriter(); gltfAssetWriter.write(gltfAsset, file); } - + /** * Write the given {@link GltfModel} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModel gltfModel, OutputStream outputStream) - throws IOException - { + public void writeBinary(GltfModel gltfModel, OutputStream outputStream) + throws IOException { GltfAssetV2 gltfAsset = GltfAssetsV2.createBinary(gltfModel); GltfAssetWriterV2 gltfAssetWriter = new GltfAssetWriterV2(); gltfAssetWriter.writeBinary(gltfAsset, outputStream); } - + /** * Write the given {@link GltfModel} as an embedded glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeEmbedded(GltfModel gltfModel, OutputStream outputStream) - throws IOException - { + public void writeEmbedded(GltfModel gltfModel, OutputStream outputStream) + throws IOException { GltfAssetV2 gltfAsset = GltfAssetsV2.createEmbedded(gltfModel); GltfWriter gltfWriter = new GltfWriter(); GlTF gltf = gltfAsset.getGltf(); diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfReaderV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfReaderV2.java index 7c49229..6180e57 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfReaderV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfReaderV2.java @@ -26,44 +26,40 @@ */ package de.javagl.jgltf.model.io.v2; +import com.google.gson.Gson; +import de.javagl.jgltf.impl.v2.GlTF; + import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import com.google.gson.Gson; - -import de.javagl.jgltf.impl.v2.GlTF; - /** * A class for reading a version 2.0 {@link GlTF} from an input stream */ -public final class GltfReaderV2 -{ +public final class GltfReaderV2 { // Note: This class could use GltfReader as a delegate, and could // then verify that the glTF has the right version. Right now, it // assumes that it is only used for glTF 2.0 inputs. - + /** * Creates a new glTF reader */ - public GltfReaderV2() - { + public GltfReaderV2() { // Default constructor } - + /** * Read the {@link GlTF} from the given stream - * + * * @param inputStream The input stream * @return The {@link GlTF} * @throws IOException If an IO error occurs */ - public GlTF read(InputStream inputStream) throws IOException - { - InputStreamReader reader = new InputStreamReader(inputStream); - GlTF gltf = new Gson().fromJson(reader, GlTF.class); - reader.close(); + public GlTF read(InputStream inputStream) throws IOException { + InputStreamReader reader = new InputStreamReader(inputStream); + GlTF gltf = new Gson().fromJson(reader, GlTF.class); + reader.close(); return gltf; } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfUtilsV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfUtilsV2.java index f0a0934..fb2863b 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfUtilsV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfUtilsV2.java @@ -27,7 +27,6 @@ package de.javagl.jgltf.model.io.v2; import com.google.gson.Gson; - import de.javagl.jgltf.impl.v2.BufferView; import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.impl.v2.Image; @@ -36,8 +35,14 @@ /** * Utility methods related to {@link GlTF}s */ -class GltfUtilsV2 -{ +class GltfUtilsV2 { + /** + * Private constructor to prevent instantiation + */ + private GltfUtilsV2() { + // Private constructor to prevent instantiation + } + /** * Creates a deep copy of the given {@link GlTF}.
*
@@ -46,25 +51,23 @@ class GltfUtilsV2 * in the copy. The goal of this method is to create a copy that is, * as far as reasonably possible, "structurally equivalent" to the * given input. - * - * @param gltf The input + * + * @param gltf The input * @return The copy * @throws GltfException If the copy can not be created */ - static GlTF copy(GlTF gltf) - { - Gson gson = new Gson(); - return gson.fromJson(gson.toJsonTree(gltf, GlTF.class), GlTF.class); + static GlTF copy(GlTF gltf) { + Gson gson = new Gson(); + return gson.fromJson(gson.toJsonTree(gltf, GlTF.class), GlTF.class); } /** * Creates a shallow copy of the given {@link BufferView} - * + * * @param bufferView The {@link BufferView} * @return The copy */ - static BufferView copy(BufferView bufferView) - { + static BufferView copy(BufferView bufferView) { BufferView copy = new BufferView(); copy.setExtensions(bufferView.getExtensions()); copy.setExtras(bufferView.getExtras()); @@ -76,16 +79,14 @@ static BufferView copy(BufferView bufferView) copy.setByteStride(bufferView.getByteStride()); return copy; } - - + /** * Creates a shallow copy of the given {@link Image} - * + * * @param image The {@link Image} * @return The copy */ - static Image copy(Image image) - { + static Image copy(Image image) { Image copy = new Image(); copy.setExtensions(image.getExtensions()); copy.setExtras(image.getExtras()); @@ -95,12 +96,4 @@ static Image copy(Image image) copy.setMimeType(image.getMimeType()); return copy; } - - /** - * Private constructor to prevent instantiation - */ - private GltfUtilsV2() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/RawBinaryGltfDataReaderV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/RawBinaryGltfDataReaderV2.java index f885c15..96eb258 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/RawBinaryGltfDataReaderV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/RawBinaryGltfDataReaderV2.java @@ -26,20 +26,19 @@ */ package de.javagl.jgltf.model.io.v2; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.io.RawGltfData; + import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.io.RawGltfData; - /** * A class for reading a {@link RawGltfData} from a buffer that contains * binary glTF 2.0 data. */ -public class RawBinaryGltfDataReaderV2 -{ +public class RawBinaryGltfDataReaderV2 { /** * The length of the binary glTF header for glTF 2.0, in bytes */ @@ -50,119 +49,93 @@ public class RawBinaryGltfDataReaderV2 * This is an integer corresponding to the ASCII string "JSON" */ private static final int CHUNK_TYPE_JSON = 0x4E4F534A; - + /** * The constant indicating BIN chunk type for glTF 2.0 * This is an integer corresponding to the ASCII string "BIN" */ private static final int CHUNK_TYPE_BIN = 0x004E4942; - + + /** + * Private constructor to prevent instantiation + */ + private RawBinaryGltfDataReaderV2() { + // Private constructor to prevent instantiation + } + /** * Read the {@link RawGltfData} from the given buffer, which contains * the binary glTF 2.0 data - * + * * @param data The input data * @return The {@link RawGltfData} * @throws IOException If an IO error occurs */ - public static RawGltfData readBinaryGltf(ByteBuffer data) - throws IOException - { + public static RawGltfData readBinaryGltf(ByteBuffer data) + throws IOException { int headerLength = BINARY_GLTF_VERSION_2_HEADER_LENGTH_IN_BYTES; - if (data.capacity() < headerLength) - { + if (data.capacity() < headerLength) { throw new IOException("Expected header of size " + headerLength - + ", but only found " + data.capacity() + " bytes"); + + ", but only found " + data.capacity() + " bytes"); } int length = data.getInt(8); - if (length != data.capacity()) - { + if (length != data.capacity()) { throw new IOException( - "Data length is " + data.capacity() + ", expected " + length); + "Data length is " + data.capacity() + ", expected " + length); } - + List chunks = readChunks(data); - if (chunks.isEmpty()) - { + if (chunks.isEmpty()) { throw new IOException( - "Found no chunks in binary glTF data"); + "Found no chunks in binary glTF data"); } Chunk jsonChunk = chunks.get(0); - if (jsonChunk.type != CHUNK_TYPE_JSON) - { + if (jsonChunk.type != CHUNK_TYPE_JSON) { throw new IOException("First chunk must be of type JSON (" - + CHUNK_TYPE_JSON + "), but found " + jsonChunk.type); + + CHUNK_TYPE_JSON + "), but found " + jsonChunk.type); } ByteBuffer jsonData = jsonChunk.data; ByteBuffer binData = null; - if (chunks.size() > 1) - { + if (chunks.size() > 1) { Chunk binChunk = chunks.get(1); - if (binChunk.type != CHUNK_TYPE_BIN) - { + if (binChunk.type != CHUNK_TYPE_BIN) { throw new IOException("Second chunk must be of type BIN (" - + CHUNK_TYPE_BIN + "), but found " + jsonChunk.type); + + CHUNK_TYPE_BIN + "), but found " + jsonChunk.type); } binData = binChunk.data; } return new RawGltfData(jsonData, binData); } - - /** - * A class representing a chunk in binary glTF 2.0 - */ - private static class Chunk - { - /** - * The length - */ - int length; - - /** - * The type - */ - int type; - - /** - * The actual chunk data - */ - ByteBuffer data; - } - + /** * Read the {@link Chunk} objects from the given binary glTF 2.0 data - * + * * @param data The input data * @return The chunks * @throws IOException If an IO error occurs */ - private static List readChunks(ByteBuffer data) throws IOException - { + private static List readChunks(ByteBuffer data) throws IOException { int headerLength = BINARY_GLTF_VERSION_2_HEADER_LENGTH_IN_BYTES; List chunks = new ArrayList(); int offset = headerLength; - while (offset < data.capacity()) - { + while (offset < data.capacity()) { Chunk chunk = new Chunk(); chunk.length = data.getInt(offset); offset += 4; chunk.type = data.getInt(offset); offset += 4; - if (offset + chunk.length > data.capacity()) - { + if (offset + chunk.length > data.capacity()) { throw new IOException("The offset for the data of chunk " - + chunks.size() + " is " + offset + ", its length is " - + chunk.length + ", but " + (offset + chunk.length) - + " is larger than capacity of the buffer, which is only " - + data.capacity()); + + chunks.size() + " is " + offset + ", its length is " + + chunk.length + ", but " + (offset + chunk.length) + + " is larger than capacity of the buffer, which is only " + + data.capacity()); } - if (chunk.length > 0) - { - if(chunk.type == CHUNK_TYPE_BIN) { - chunk.data = Buffers.create(chunk.length); - Buffers.bufferCopy(data, offset, chunk.data, 0, chunk.length); - } - else chunk.data = Buffers.createSlice(data, offset, chunk.length); + if (chunk.length > 0) { + if (chunk.type == CHUNK_TYPE_BIN) { + chunk.data = Buffers.create(chunk.length); + Buffers.bufferCopy(data, offset, chunk.data, 0, chunk.length); + } else chunk.data = Buffers.createSlice(data, offset, chunk.length); } offset += chunk.length; chunks.add(chunk); @@ -171,10 +144,22 @@ private static List readChunks(ByteBuffer data) throws IOException } /** - * Private constructor to prevent instantiation + * A class representing a chunk in binary glTF 2.0 */ - private RawBinaryGltfDataReaderV2() - { - // Private constructor to prevent instantiation + private static class Chunk { + /** + * The length + */ + int length; + + /** + * The type + */ + int type; + + /** + * The actual chunk data + */ + ByteBuffer data; } } diff --git a/src/main/java/de/javagl/jgltf/model/package-info.java b/src/main/java/de/javagl/jgltf/model/package-info.java index 0458925..e476c70 100644 --- a/src/main/java/de/javagl/jgltf/model/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/package-info.java @@ -1,7 +1,7 @@ /** * Classes for loading and accessing glTF data. These are basic utility * classes that offer "convenience" access to the glTF data in a form - * that is specific for Java, but not specific for the application. + * that is specific for Java, but not specific for the application. */ package de.javagl.jgltf.model; diff --git a/src/main/java/de/javagl/jgltf/model/v1/BinaryGltfV1.java b/src/main/java/de/javagl/jgltf/model/v1/BinaryGltfV1.java index 361a155..000fff1 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/BinaryGltfV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/BinaryGltfV1.java @@ -26,30 +26,24 @@ */ package de.javagl.jgltf.model.v1; -import java.io.IOException; -import java.nio.ByteBuffer; - -import javax.imageio.ImageReader; - -import de.javagl.jgltf.impl.v1.Buffer; -import de.javagl.jgltf.impl.v1.BufferView; -import de.javagl.jgltf.impl.v1.GlTFProperty; -import de.javagl.jgltf.impl.v1.Image; -import de.javagl.jgltf.impl.v1.Shader; +import de.javagl.jgltf.impl.v1.*; import de.javagl.jgltf.model.GltfException; import de.javagl.jgltf.model.image.ImageReaders; +import javax.imageio.ImageReader; +import java.io.IOException; +import java.nio.ByteBuffer; + /** * Utility methods related to the binary glTF extension of glTF 1.0 */ -public class BinaryGltfV1 -{ +public class BinaryGltfV1 { /** * The name of the KHR_binary_glTF extension */ - private static final String KHRONOS_BINARY_GLTF_EXTENSION_NAME = - "KHR_binary_glTF"; - + private static final String KHRONOS_BINARY_GLTF_EXTENSION_NAME = + "KHR_binary_glTF"; + /** * The unique, universal buffer ID for the binary data that is stored * in a binary glTF file @@ -57,145 +51,130 @@ public class BinaryGltfV1 private static final String BINARY_GLTF_BUFFER_ID = "binary_glTF"; /** - * Returns whether the given {@link GlTFProperty} has the + * Private constructor to prevent instantiation + */ + private BinaryGltfV1() { + // Private constructor to prevent instantiation + } + + /** + * Returns whether the given {@link GlTFProperty} has the * "KHR_binary_glTF" extension. This is applicable * to {@link Image} and {@link Shader} objects that may contain - * an extension object with a {@link BufferView} ID instead of - * a URI. The {@link BufferView} ID may be obtained with + * an extension object with a {@link BufferView} ID instead of + * a URI. The {@link BufferView} ID may be obtained with * {@link BinaryGltfV1#getBinaryGltfBufferViewId(GlTFProperty)}. - * + * * @param gltfProperty The {@link GlTFProperty} * @return Whether the extension exists */ - public static boolean hasBinaryGltfExtension(GlTFProperty gltfProperty) - { - return GltfExtensionsV1.hasExtension(gltfProperty, - KHRONOS_BINARY_GLTF_EXTENSION_NAME); + public static boolean hasBinaryGltfExtension(GlTFProperty gltfProperty) { + return GltfExtensionsV1.hasExtension(gltfProperty, + KHRONOS_BINARY_GLTF_EXTENSION_NAME); } /** - * Returns the value of the "bufferView" property in + * Returns the value of the "bufferView" property in * the "KHR_binary_glTF" extension object of the * given {@link GlTFProperty}, or null if either the - * extension object or the property does not exist. - * + * extension object or the property does not exist. + * * @param gltfProperty The {@link GlTFProperty} * @return The property value */ - static String getBinaryGltfBufferViewId(GlTFProperty gltfProperty) - { + static String getBinaryGltfBufferViewId(GlTFProperty gltfProperty) { return GltfExtensionsV1.getExtensionPropertyValueAsString( - gltfProperty, KHRONOS_BINARY_GLTF_EXTENSION_NAME, "bufferView"); + gltfProperty, KHRONOS_BINARY_GLTF_EXTENSION_NAME, "bufferView"); } /** - * Set the value of the "bufferView" property in + * Set the value of the "bufferView" property in * the "KHR_binary_glTF" extension object of the * given {@link GlTFProperty}. If no (or an invalid) extension * object already existed, it will be created or overwritten, - * respectively. - * + * respectively. + * * @param gltfProperty The {@link GlTFProperty} * @param bufferViewId The {@link BufferView} ID */ public static void setBinaryGltfBufferViewId( - GlTFProperty gltfProperty, String bufferViewId) - { + GlTFProperty gltfProperty, String bufferViewId) { GltfExtensionsV1.setExtensionPropertyValue( - gltfProperty, KHRONOS_BINARY_GLTF_EXTENSION_NAME, - "bufferView", bufferViewId); + gltfProperty, KHRONOS_BINARY_GLTF_EXTENSION_NAME, + "bufferView", bufferViewId); } - + /** - * Set the properties for the given {@link Image} that is stored + * Set the properties for the given {@link Image} that is stored * as a "KHR_binary_glTF" image. These properties * are - *

    + *
      *
    • The image width
    • *
    • The image height
    • *
    • The image mimeType
    • *
    - * (Note that the buffer view ID is set explicitly with + * (Note that the buffer view ID is set explicitly with * {@link #setBinaryGltfBufferViewId(GlTFProperty, String)}) - * - * @param image The image + * + * @param image The image * @param imageData The raw image data * @throws GltfException If the image data cannot be analyzed to derive - * the required information + * the required information */ public static void setBinaryGltfImageProperties( - Image image, ByteBuffer imageData) - { + Image image, ByteBuffer imageData) { ImageReader imageReader = null; - try - { + try { imageReader = ImageReaders.findImageReader(imageData); int width = imageReader.getWidth(0); int height = imageReader.getHeight(0); String mimeType = "image/" + imageReader.getFormatName(); GltfExtensionsV1.setExtensionPropertyValue(image, - KHRONOS_BINARY_GLTF_EXTENSION_NAME, "width", width); + KHRONOS_BINARY_GLTF_EXTENSION_NAME, "width", width); GltfExtensionsV1.setExtensionPropertyValue(image, - KHRONOS_BINARY_GLTF_EXTENSION_NAME, "height", height); + KHRONOS_BINARY_GLTF_EXTENSION_NAME, "height", height); GltfExtensionsV1.setExtensionPropertyValue(image, - KHRONOS_BINARY_GLTF_EXTENSION_NAME, "mimeType", mimeType); - } - catch (IOException e) - { + KHRONOS_BINARY_GLTF_EXTENSION_NAME, "mimeType", mimeType); + } catch (IOException e) { throw new GltfException( - "Could not derive image properties for binary glTF", e); - } - finally - { - if (imageReader != null) - { + "Could not derive image properties for binary glTF", e); + } finally { + if (imageReader != null) { imageReader.dispose(); } } } - /** * Returns the name of the Khronos binary glTF extension * ("KHR_binary_glTF") - * + * * @return The name of the Khronos binary glTF extension */ - public static String getBinaryGltfExtensionName() - { + public static String getBinaryGltfExtensionName() { return KHRONOS_BINARY_GLTF_EXTENSION_NAME; } /** - * Returns unique ID of the binary glTF {@link Buffer} + * Returns unique ID of the binary glTF {@link Buffer} * ("binary_glTF") - * + * * @return The binary glTF {@link Buffer} ID */ - public static String getBinaryGltfBufferId() - { + public static String getBinaryGltfBufferId() { return BINARY_GLTF_BUFFER_ID; } /** * Returns whether the given ID is the unique ID of the binary glTF * {@link Buffer} ("binary_glTF") - * + * * @param id The ID * @return Whether the given ID is the binary glTF {@link Buffer} ID */ - public static boolean isBinaryGltfBufferId(String id) - { + public static boolean isBinaryGltfBufferId(String id) { return BINARY_GLTF_BUFFER_ID.equals(id); } - - /** - * Private constructor to prevent instantiation - */ - private BinaryGltfV1() - { - // Private constructor to prevent instantiation - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfCreatorV1.java b/src/main/java/de/javagl/jgltf/model/v1/GltfCreatorV1.java index d03d2eb..8092091 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfCreatorV1.java @@ -26,962 +26,905 @@ */ package de.javagl.jgltf.model.v1; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import de.javagl.jgltf.impl.v1.*; +import de.javagl.jgltf.model.*; +import de.javagl.jgltf.model.AnimationModel.Channel; +import de.javagl.jgltf.model.AnimationModel.Sampler; +import de.javagl.jgltf.model.gl.*; +import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; + +import java.util.*; import java.util.Map.Entry; -import java.util.Objects; import java.util.function.Function; import java.util.logging.Logger; import java.util.stream.Collectors; -import de.javagl.jgltf.impl.v1.Accessor; -import de.javagl.jgltf.impl.v1.Animation; -import de.javagl.jgltf.impl.v1.AnimationChannel; -import de.javagl.jgltf.impl.v1.AnimationChannelTarget; -import de.javagl.jgltf.impl.v1.AnimationSampler; -import de.javagl.jgltf.impl.v1.Asset; -import de.javagl.jgltf.impl.v1.Buffer; -import de.javagl.jgltf.impl.v1.BufferView; -import de.javagl.jgltf.impl.v1.Camera; -import de.javagl.jgltf.impl.v1.CameraOrthographic; -import de.javagl.jgltf.impl.v1.CameraPerspective; -import de.javagl.jgltf.impl.v1.GlTF; -import de.javagl.jgltf.impl.v1.GlTFChildOfRootProperty; -import de.javagl.jgltf.impl.v1.GlTFProperty; -import de.javagl.jgltf.impl.v1.Image; -import de.javagl.jgltf.impl.v1.Material; -import de.javagl.jgltf.impl.v1.Mesh; -import de.javagl.jgltf.impl.v1.MeshPrimitive; -import de.javagl.jgltf.impl.v1.Node; -import de.javagl.jgltf.impl.v1.Program; -import de.javagl.jgltf.impl.v1.Scene; -import de.javagl.jgltf.impl.v1.Shader; -import de.javagl.jgltf.impl.v1.Skin; -import de.javagl.jgltf.impl.v1.Technique; -import de.javagl.jgltf.impl.v1.TechniqueParameters; -import de.javagl.jgltf.impl.v1.TechniqueStates; -import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; -import de.javagl.jgltf.impl.v1.Texture; -import de.javagl.jgltf.model.AccessorData; -import de.javagl.jgltf.model.AccessorDatas; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.AnimationModel; -import de.javagl.jgltf.model.AnimationModel.Channel; -import de.javagl.jgltf.model.AnimationModel.Sampler; -import de.javagl.jgltf.model.AssetModel; -import de.javagl.jgltf.model.BufferModel; -import de.javagl.jgltf.model.BufferViewModel; -import de.javagl.jgltf.model.CameraModel; -import de.javagl.jgltf.model.CameraOrthographicModel; -import de.javagl.jgltf.model.CameraPerspectiveModel; -import de.javagl.jgltf.model.ExtensionsModel; -import de.javagl.jgltf.model.GltfConstants; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.ImageModel; -import de.javagl.jgltf.model.MaterialModel; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; -import de.javagl.jgltf.model.ModelElement; -import de.javagl.jgltf.model.NamedModelElement; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.Optionals; -import de.javagl.jgltf.model.SceneModel; -import de.javagl.jgltf.model.SkinModel; -import de.javagl.jgltf.model.TextureModel; -import de.javagl.jgltf.model.gl.ProgramModel; -import de.javagl.jgltf.model.gl.ShaderModel; -import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; -import de.javagl.jgltf.model.gl.TechniqueModel; -import de.javagl.jgltf.model.gl.TechniqueParametersModel; -import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; -import de.javagl.jgltf.model.gl.TechniqueStatesModel; - /** - * A class for creating the {@link GlTF version 1.0 glTF} from a + * A class for creating the {@link GlTF version 1.0 glTF} from a * {@link GltfModel}.
    *
    - * TODO: Not all features that could be supported are supported yet. + * TODO: Not all features that could be supported are supported yet. */ -public class GltfCreatorV1 -{ +public class GltfCreatorV1 { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfCreatorV1.class.getName()); - - /** - * Creates a {@link GlTF} from the given {@link GltfModel} - * - * @param gltfModel The {@link GltfModel} - * @return The {@link GlTF} - */ - public static GlTF create(GltfModel gltfModel) - { - GltfCreatorV1 creator = new GltfCreatorV1(gltfModel); - return creator.create(); - } - - /** - * Inner class containing the information that is necessary to define - * a glTF {@link de.javagl.jgltf.impl.v1.Sampler} - */ - @SuppressWarnings("javadoc") - private static class SamplerInfo - { - final Integer magFilter; - final Integer minFilter; - final Integer wrapS; - final Integer wrapT; - - SamplerInfo(TextureModel textureModel) - { - this.magFilter = textureModel.getMagFilter(); - this.minFilter = textureModel.getMinFilter(); - this.wrapS = textureModel.getWrapS(); - this.wrapT = textureModel.getWrapT(); - } - - @Override - public int hashCode() - { - return Objects.hash(magFilter, minFilter, wrapS, wrapT); - } - - @Override - public boolean equals(Object object) - { - if (this == object) - { - return true; - } - if (object == null) - { - return false; - } - if (getClass() != object.getClass()) - { - return false; - } - SamplerInfo other = (SamplerInfo) object; - if (!Objects.equals(magFilter, other.magFilter)) - { - return false; - } - if (!Objects.equals(minFilter, other.minFilter)) - { - return false; - } - if (!Objects.equals(wrapS, other.wrapS)) - { - return false; - } - if (!Objects.equals(wrapT, other.wrapT)) - { - return false; - } - return true; - } - } - + private static final Logger logger = + Logger.getLogger(GltfCreatorV1.class.getName()); /** * The {@link GltfModel} that this instance operates on */ private final GltfModel gltfModel; - /** * A map from {@link AccessorModel} objects to their IDs */ private final Map accessorIds; - /** * A map from {@link BufferModel} objects to their IDs */ private final Map bufferIds; - /** * A map from {@link BufferViewModel} objects to their IDs */ private final Map bufferViewIds; - /** * A map from {@link CameraModel} objects to their IDs */ private final Map cameraIds; - /** * A map from {@link ImageModel} objects to their IDs */ private final Map imageIds; - /** * A map from {@link MaterialModel} objects to their IDs */ private final Map materialIds; - /** * A map from {@link MeshModel} objects to their IDs */ private final Map meshIds; - /** * A map from {@link NodeModel} objects to their IDs */ private final Map nodeIds; - /** * A map from {@link ProgramModel} objects to their IDs */ private final Map programIds; - /** * A map from {@link ShaderModel} objects to their IDs */ private final Map shaderIds; - /** * A map from {@link SkinModel} objects to their IDs */ private final Map skinIds; - /** * A map from {@link TechniqueModel} objects to their IDs */ private final Map techniqueIds; - /** * A map from {@link TextureModel} objects to their IDs */ private final Map textureIds; - /** * A map from {@link SamplerInfo} objects to their IDs */ private final Map samplerIds; - + /** * Creates a new instance with the given {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} */ - private GltfCreatorV1(GltfModel gltfModel) - { + private GltfCreatorV1(GltfModel gltfModel) { this.gltfModel = Objects.requireNonNull( - gltfModel, "The gltfModel may not be null"); - + gltfModel, "The gltfModel may not be null"); + accessorIds = computeIdMap( - "accessor", gltfModel.getAccessorModels()); + "accessor", gltfModel.getAccessorModels()); bufferIds = computeIdMap( - "buffer", gltfModel.getBufferModels()); + "buffer", gltfModel.getBufferModels()); bufferViewIds = computeIdMap( - "bufferView", gltfModel.getBufferViewModels()); + "bufferView", gltfModel.getBufferViewModels()); cameraIds = computeIdMap( - "camera", gltfModel.getCameraModels()); + "camera", gltfModel.getCameraModels()); imageIds = computeIdMap( - "image", gltfModel.getImageModels()); + "image", gltfModel.getImageModels()); materialIds = computeIdMap( - "material", gltfModel.getMaterialModels()); + "material", gltfModel.getMaterialModels()); meshIds = computeIdMap( - "mesh", gltfModel.getMeshModels()); + "mesh", gltfModel.getMeshModels()); nodeIds = computeIdMap( - "node", gltfModel.getNodeModels()); + "node", gltfModel.getNodeModels()); skinIds = computeIdMap( - "skin", gltfModel.getSkinModels()); + "skin", gltfModel.getSkinModels()); textureIds = computeIdMap( - "texture", gltfModel.getTextureModels()); - - if (gltfModel instanceof GltfModelV1) - { - GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; + "texture", gltfModel.getTextureModels()); + + if (gltfModel instanceof GltfModelV1) { + GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; programIds = computeIdMap( - "program", gltfModelV1.getProgramModels()); + "program", gltfModelV1.getProgramModels()); shaderIds = computeIdMap( - "shader", gltfModelV1.getShaderModels()); + "shader", gltfModelV1.getShaderModels()); techniqueIds = computeIdMap( - "technique", gltfModelV1.getTechniqueModels()); - } - else - { + "technique", gltfModelV1.getTechniqueModels()); + } else { programIds = Collections.emptyMap(); shaderIds = Collections.emptyMap(); techniqueIds = Collections.emptyMap(); } - + samplerIds = createSamplerIds(gltfModel.getTextureModels()); } - + + /** + * Creates a {@link GlTF} from the given {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} + * @return The {@link GlTF} + */ + public static GlTF create(GltfModel gltfModel) { + GltfCreatorV1 creator = new GltfCreatorV1(gltfModel); + return creator.create(); + } + + /** + * Create the {@link Accessor} for the given {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewId The ID of the {@link BufferViewModel} + * that the {@link AccessorModel} refers to + * @return The {@link Accessor} + */ + public static Accessor createAccessor( + AccessorModel accessorModel, String bufferViewId) { + Accessor accessor = new Accessor(); + transferGltfChildOfRootPropertyElements(accessorModel, accessor); + + accessor.setBufferView(bufferViewId); + + accessor.setByteOffset(accessorModel.getByteOffset()); + accessor.setComponentType(accessorModel.getComponentType()); + accessor.setCount(accessorModel.getCount()); + accessor.setType(accessorModel.getElementType().toString()); + accessor.setByteStride(accessorModel.getByteStride()); + + AccessorData accessorData = accessorModel.getAccessorData(); + accessor.setMax(AccessorDatas.computeMax(accessorData)); + accessor.setMin(AccessorDatas.computeMin(accessorData)); + + return accessor; + } + + /** + * Create the {@link Buffer} for the given {@link BufferModel} + * + * @param bufferModel The {@link BufferModel} + * @return The {@link Buffer} + */ + public static Buffer createBuffer(BufferModel bufferModel) { + Buffer buffer = new Buffer(); + transferGltfChildOfRootPropertyElements(bufferModel, buffer); + + buffer.setUri(bufferModel.getUri()); + buffer.setByteLength(bufferModel.getByteLength()); + return buffer; + } + + /** + * Create the {@link BufferView} for the given {@link BufferViewModel} + * + * @param bufferViewModel The {@link BufferViewModel} + * @param bufferId The ID of the {@link BufferModel} that the + * {@link BufferViewModel} refers to + * @return The {@link BufferView} + */ + public static BufferView createBufferView( + BufferViewModel bufferViewModel, String bufferId) { + BufferView bufferView = new BufferView(); + transferGltfChildOfRootPropertyElements(bufferViewModel, bufferView); + + bufferView.setBuffer(bufferId); + bufferView.setByteOffset(bufferViewModel.getByteOffset()); + bufferView.setByteLength(bufferViewModel.getByteLength()); + bufferView.setTarget(bufferViewModel.getTarget()); + + return bufferView; + } + + /** + * Create a {@link de.javagl.jgltf.impl.v1.Sampler} from the given + * {@link SamplerInfo} + * + * @param samplerInfo The {@link SamplerInfo} + * @return The {@link de.javagl.jgltf.impl.v1.Sampler} + */ + private static de.javagl.jgltf.impl.v1.Sampler createSampler( + SamplerInfo samplerInfo) { + de.javagl.jgltf.impl.v1.Sampler sampler = + new de.javagl.jgltf.impl.v1.Sampler(); + sampler.setMagFilter(samplerInfo.magFilter); + sampler.setMinFilter(samplerInfo.minFilter); + sampler.setWrapS(samplerInfo.wrapS); + sampler.setWrapT(samplerInfo.wrapT); + return sampler; + } + + /** + * Transfer the extensions and extras from the given model element to + * the given property + * + * @param modelElement The model element + * @param property The property + */ + private static void transferGltfPropertyElements( + ModelElement modelElement, GlTFProperty property) { + property.setExtensions(modelElement.getExtensions()); + property.setExtras(modelElement.getExtras()); + } + + /** + * Transfer the name and extensions and extras from the given model + * element to the given property + * + * @param modelElement The model element + * @param property The property + */ + private static void transferGltfChildOfRootPropertyElements( + NamedModelElement modelElement, + GlTFChildOfRootProperty property) { + property.setName(modelElement.getName()); + transferGltfPropertyElements(modelElement, property); + } + + /** + * Creates a map that maps (unspecified) strings starting with the + * given prefix to the results of applying the given mapper to the + * given elements, or null if the given collection is + * empty + * + * @param prefix The prefix + * @param elements The elements + * @param mapper The mapper + * @return The map + */ + private static Map map( + String prefix, + Collection elements, + Function mapper) { + return map(prefix, map(elements, mapper)); + } + + /** + * Creates a map that maps (unspecified) strings starting with the + * given prefix to the given elements, or null if the + * given collection is null or empty + * + * @param prefix The prefix + * @param elements The elements + * @return The map + */ + private static Map map( + String prefix, Collection elements) { + if (elements == null || elements.isEmpty()) { + return null; + } + Map map = new LinkedHashMap(); + int index = 0; + for (T element : elements) { + map.put(prefix + "_" + index, element); + index++; + } + return map; + } + + /** + * Returns a list containing the result of mapping the given elements with + * the given function, or null if the given collection is + * empty + * + * @param collection The collection + * @param mapper The mapper + * @return The list + */ + private static List map( + Collection collection, + Function mapper) { + if (collection.isEmpty()) { + return null; + } + return collection.stream().map(mapper).collect(Collectors.toList()); + } + + /** + * Creates a map that has the same keys as the given map, mapped to + * the IDs that are looked up for the respective values, using + * the given function + * + * @param map The map + * @param idLookup The index lookup + * @return The index map + */ + private static Map resolveIds( + Map map, + Function idLookup) { + Map result = new LinkedHashMap(); + for (Entry entry : map.entrySet()) { + K key = entry.getKey(); + T value = entry.getValue(); + String id = idLookup.apply(value); + result.put(key, id); + } + return result; + } + + /** + * Create an ordered map that contains a mapping of the given elements + * to IDs that start with the given prefix + * + * @param prefix The prefix + * @param elements The elements + * @return The ID map + */ + private static Map computeIdMap( + String prefix, Collection elements) { + Map ids = new LinkedHashMap(); + int index = 0; + for (T element : elements) { + ids.put(element, prefix + "_" + index); + index++; + } + return ids; + } + /** * Create the {@link GlTF} instance from the {@link GltfModel} - * + * * @return The {@link GlTF} instance */ - public GlTF create() - { + public GlTF create() { GlTF gltf = new GlTF(); transferGltfPropertyElements(gltfModel, gltf); - + gltf.setAccessors(map("accessor", - gltfModel.getAccessorModels(), - this::createAccessor)); + gltfModel.getAccessorModels(), + this::createAccessor)); gltf.setAnimations(map("animation", - gltfModel.getAnimationModels(), - this::createAnimation)); + gltfModel.getAnimationModels(), + this::createAnimation)); gltf.setBuffers(map("buffer", - gltfModel.getBufferModels(), - GltfCreatorV1::createBuffer)); + gltfModel.getBufferModels(), + GltfCreatorV1::createBuffer)); gltf.setBufferViews(map("bufferView", - gltfModel.getBufferViewModels(), - this::createBufferView)); - gltf.setCameras(map("camera", - gltfModel.getCameraModels(), - this::createCamera)); + gltfModel.getBufferViewModels(), + this::createBufferView)); + gltf.setCameras(map("camera", + gltfModel.getCameraModels(), + this::createCamera)); gltf.setImages(map("image", - gltfModel.getImageModels(), - this::createImage)); - gltf.setMaterials(map("material", - gltfModel.getMaterialModels(), - this::createMaterial)); - gltf.setMeshes(map("mesh", - gltfModel.getMeshModels(), - this::createMesh)); + gltfModel.getImageModels(), + this::createImage)); + gltf.setMaterials(map("material", + gltfModel.getMaterialModels(), + this::createMaterial)); + gltf.setMeshes(map("mesh", + gltfModel.getMeshModels(), + this::createMesh)); gltf.setNodes(map("node", - gltfModel.getNodeModels(), - this::createNode)); + gltfModel.getNodeModels(), + this::createNode)); gltf.setScenes(map("scene", - gltfModel.getSceneModels(), - this::createScene)); - gltf.setSkins(map("skin", - gltfModel.getSkinModels(), - this::createSkin)); - + gltfModel.getSceneModels(), + this::createScene)); + gltf.setSkins(map("skin", + gltfModel.getSkinModels(), + this::createSkin)); + gltf.setSamplers(createSamplers()); - + gltf.setTextures(map("texture", - gltfModel.getTextureModels(), - this::createTexture)); - - - if (gltfModel instanceof GltfModelV1) - { - GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; - gltf.setPrograms(map("program", - gltfModelV1.getProgramModels(), - this::createProgram)); - gltf.setShaders(map("shader", - gltfModelV1.getShaderModels(), - this::createShader)); - gltf.setTechniques(map("technique", - gltfModelV1.getTechniqueModels(), - this::createTechnique)); + gltfModel.getTextureModels(), + this::createTexture)); + + + if (gltfModel instanceof GltfModelV1) { + GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; + gltf.setPrograms(map("program", + gltfModelV1.getProgramModels(), + this::createProgram)); + gltf.setShaders(map("shader", + gltfModelV1.getShaderModels(), + this::createShader)); + gltf.setTechniques(map("technique", + gltfModelV1.getTechniqueModels(), + this::createTechnique)); } - - if (gltf.getScenes() != null && !gltf.getScenes().isEmpty()) - { + + if (gltf.getScenes() != null && !gltf.getScenes().isEmpty()) { gltf.setScene(gltf.getScenes().keySet().iterator().next()); } - + ExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); List extensionsUsed = extensionsModel.getExtensionsUsed(); - if (!extensionsUsed.isEmpty()) - { + if (!extensionsUsed.isEmpty()) { gltf.setExtensionsUsed(extensionsUsed); } - + Asset asset = createAsset(gltfModel.getAssetModel()); gltf.setAsset(asset); - + return gltf; } - + /** * Create the {@link Accessor} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link Accessor} */ - private Accessor createAccessor(AccessorModel accessorModel) - { - String bufferViewId = - bufferViewIds.get(accessorModel.getBufferViewModel()); + private Accessor createAccessor(AccessorModel accessorModel) { + String bufferViewId = + bufferViewIds.get(accessorModel.getBufferViewModel()); return createAccessor(accessorModel, bufferViewId); } - - /** - * Create the {@link Accessor} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewId The ID of the {@link BufferViewModel} - * that the {@link AccessorModel} refers to - * @return The {@link Accessor} - */ - public static Accessor createAccessor( - AccessorModel accessorModel, String bufferViewId) - { - Accessor accessor = new Accessor(); - transferGltfChildOfRootPropertyElements(accessorModel, accessor); - - accessor.setBufferView(bufferViewId); - - accessor.setByteOffset(accessorModel.getByteOffset()); - accessor.setComponentType(accessorModel.getComponentType()); - accessor.setCount(accessorModel.getCount()); - accessor.setType(accessorModel.getElementType().toString()); - accessor.setByteStride(accessorModel.getByteStride()); - - AccessorData accessorData = accessorModel.getAccessorData(); - accessor.setMax(AccessorDatas.computeMax(accessorData)); - accessor.setMin(AccessorDatas.computeMin(accessorData)); - - return accessor; - } - + /** * Create the {@link Animation} for the given {@link AnimationModel} - * + * * @param animationModel The {@link AnimationModel} * @return The {@link Animation} */ - private Animation createAnimation(AnimationModel animationModel) - { + private Animation createAnimation(AnimationModel animationModel) { Animation animation = new Animation(); transferGltfChildOfRootPropertyElements(animationModel, animation); - + Map samplers = new LinkedHashMap(); List channels = animationModel.getChannels(); int counter = 0; - for (Channel channel : channels) - { + for (Channel channel : channels) { String id = "sampler_" + counter; samplers.put(channel.getSampler(), id); counter++; } - - List animationChannels = - new ArrayList(); - for (Channel channel : channels) - { + + List animationChannels = + new ArrayList(); + for (Channel channel : channels) { AnimationChannel animationChannel = new AnimationChannel(); - + AnimationChannelTarget target = new AnimationChannelTarget(); NodeModel nodeModel = channel.getNodeModel(); target.setId(nodeIds.get(nodeModel)); target.setPath(channel.getPath()); animationChannel.setTarget(target); - + Sampler sampler = channel.getSampler(); animationChannel.setSampler(samplers.get(sampler)); - + animationChannels.add(animationChannel); } animation.setChannels(animationChannels); - - Map animationSamplers = - new LinkedHashMap(); - for (Sampler sampler : samplers.keySet()) - { + + Map animationSamplers = + new LinkedHashMap(); + for (Sampler sampler : samplers.keySet()) { AnimationSampler animationSampler = new AnimationSampler(); animationSampler.setInput( - accessorIds.get(sampler.getInput())); + accessorIds.get(sampler.getInput())); animationSampler.setInterpolation( - sampler.getInterpolation().name()); + sampler.getInterpolation().name()); animationSampler.setOutput( - accessorIds.get(sampler.getOutput())); + accessorIds.get(sampler.getOutput())); String key = samplers.get(sampler); animationSamplers.put(key, animationSampler); } animation.setSamplers(animationSamplers); - + return animation; } - - - /** - * Create the {@link Buffer} for the given {@link BufferModel} - * - * @param bufferModel The {@link BufferModel} - * @return The {@link Buffer} - */ - public static Buffer createBuffer(BufferModel bufferModel) - { - Buffer buffer = new Buffer(); - transferGltfChildOfRootPropertyElements(bufferModel, buffer); - buffer.setUri(bufferModel.getUri()); - buffer.setByteLength(bufferModel.getByteLength()); - return buffer; - } - /** * Create the {@link BufferView} for the given {@link BufferViewModel} - * + * * @param bufferViewModel The {@link BufferViewModel} * @return The {@link BufferView} */ - private BufferView createBufferView(BufferViewModel bufferViewModel) - { - String bufferId = - bufferIds.get(bufferViewModel.getBufferModel()); + private BufferView createBufferView(BufferViewModel bufferViewModel) { + String bufferId = + bufferIds.get(bufferViewModel.getBufferModel()); return createBufferView(bufferViewModel, bufferId); } - - /** - * Create the {@link BufferView} for the given {@link BufferViewModel} - * - * @param bufferViewModel The {@link BufferViewModel} - * @param bufferId The ID of the {@link BufferModel} that the - * {@link BufferViewModel} refers to - * @return The {@link BufferView} - */ - public static BufferView createBufferView( - BufferViewModel bufferViewModel, String bufferId) - { - BufferView bufferView = new BufferView(); - transferGltfChildOfRootPropertyElements(bufferViewModel, bufferView); - - bufferView.setBuffer(bufferId); - bufferView.setByteOffset(bufferViewModel.getByteOffset()); - bufferView.setByteLength(bufferViewModel.getByteLength()); - bufferView.setTarget(bufferViewModel.getTarget()); - - return bufferView; - } - /** * Create the {@link Camera} for the given {@link CameraModel} - * + * * @param cameraModel The {@link CameraModel} * @return The {@link Camera} */ - private Camera createCamera(CameraModel cameraModel) - { + private Camera createCamera(CameraModel cameraModel) { Camera camera = new Camera(); transferGltfChildOfRootPropertyElements(cameraModel, camera); - - CameraPerspectiveModel cameraPerspectiveModel = - cameraModel.getCameraPerspectiveModel(); - CameraOrthographicModel cameraOrthographicModel = - cameraModel.getCameraOrthographicModel(); - if (cameraPerspectiveModel != null) - { + + CameraPerspectiveModel cameraPerspectiveModel = + cameraModel.getCameraPerspectiveModel(); + CameraOrthographicModel cameraOrthographicModel = + cameraModel.getCameraOrthographicModel(); + if (cameraPerspectiveModel != null) { CameraPerspective cameraPerspective = new CameraPerspective(); cameraPerspective.setAspectRatio( - cameraPerspectiveModel.getAspectRatio()); + cameraPerspectiveModel.getAspectRatio()); cameraPerspective.setYfov( - cameraPerspectiveModel.getYfov()); + cameraPerspectiveModel.getYfov()); cameraPerspective.setZfar( - cameraPerspectiveModel.getZfar()); + cameraPerspectiveModel.getZfar()); cameraPerspective.setZnear( - cameraPerspectiveModel.getZnear()); + cameraPerspectiveModel.getZnear()); camera.setPerspective(cameraPerspective); camera.setType("perspective"); - } - else if (cameraOrthographicModel != null) - { + } else if (cameraOrthographicModel != null) { CameraOrthographic cameraOrthographic = new CameraOrthographic(); cameraOrthographic.setXmag( - cameraOrthographicModel.getXmag()); + cameraOrthographicModel.getXmag()); cameraOrthographic.setYmag( - cameraOrthographicModel.getYmag()); + cameraOrthographicModel.getYmag()); cameraOrthographic.setZfar( - cameraOrthographicModel.getZfar()); + cameraOrthographicModel.getZfar()); cameraOrthographic.setZnear( - cameraOrthographicModel.getZnear()); + cameraOrthographicModel.getZnear()); camera.setOrthographic(cameraOrthographic); camera.setType("orthographic"); - } - else - { + } else { logger.severe("Camera is neither perspective nor orthographic"); } return camera; } - + /** * Create the {@link Image} for the given {@link ImageModel} - * + * * @param imageModel The {@link ImageModel} * @return The {@link Image} */ - private Image createImage(ImageModel imageModel) - { + private Image createImage(ImageModel imageModel) { Image image = new Image(); transferGltfChildOfRootPropertyElements(imageModel, image); - - String bufferView = - bufferViewIds.get(imageModel.getBufferViewModel()); - if (bufferView != null) - { + + String bufferView = + bufferViewIds.get(imageModel.getBufferViewModel()); + if (bufferView != null) { logger.severe( - "Images with BufferView are not supported in glTF 1.0"); + "Images with BufferView are not supported in glTF 1.0"); } image.setUri(imageModel.getUri()); - + return image; } - + /** * Create the {@link Material} for the given {@link MaterialModel}. * If the given {@link MaterialModel} is not a {@link MaterialModelV1}, * then a warning is printed and null is returned. - * + * * @param materialModel The {@link MaterialModel} * @return The {@link Material} */ - private Material createMaterial(MaterialModel materialModel) - { - if (materialModel instanceof MaterialModelV1) - { - MaterialModelV1 materialModelV1 = (MaterialModelV1)materialModel; + private Material createMaterial(MaterialModel materialModel) { + if (materialModel instanceof MaterialModelV1) { + MaterialModelV1 materialModelV1 = (MaterialModelV1) materialModel; return createMaterialV1(materialModelV1); } // TODO It should be possible to use a glTF 2.0 material model here logger.severe("Cannot store glTF 2.0 material in glTF 1.0"); return null; } - + /** * Create the {@link Material} for the given {@link MaterialModelV1} - * + * * @param materialModel The {@link MaterialModelV1} * @return The {@link Material} */ - private Material createMaterialV1(MaterialModelV1 materialModel) - { + private Material createMaterialV1(MaterialModelV1 materialModel) { Material material = new Material(); transferGltfChildOfRootPropertyElements(materialModel, material); - + TechniqueModel techniqueModel = materialModel.getTechniqueModel(); material.setTechnique(techniqueIds.get(techniqueModel)); - + Map modelValues = materialModel.getValues(); Map values = new LinkedHashMap(); - for (Entry valueEntry : modelValues.entrySet()) - { + for (Entry valueEntry : modelValues.entrySet()) { String parameterName = valueEntry.getKey(); Object value = valueEntry.getValue(); - if (value instanceof TextureModel) - { - TextureModel textureModel = (TextureModel)value; + if (value instanceof TextureModel) { + TextureModel textureModel = (TextureModel) value; String textureId = textureIds.get(textureModel); values.put(parameterName, textureId); - } - else - { + } else { values.put(parameterName, value); } } material.setValues(values); return material; } - + /** * Create the {@link Program} for the given {@link ProgramModel} - * + * * @param programModel The {@link ProgramModel} * @return The {@link Program} */ - private Program createProgram(ProgramModel programModel) - { + private Program createProgram(ProgramModel programModel) { Program program = new Program(); transferGltfChildOfRootPropertyElements(programModel, program); - - ShaderModel vertexShaderModel = - programModel.getVertexShaderModel(); + + ShaderModel vertexShaderModel = + programModel.getVertexShaderModel(); program.setVertexShader(shaderIds.get(vertexShaderModel)); - - ShaderModel fragmentShaderModel = - programModel.getFragmentShaderModel(); + + ShaderModel fragmentShaderModel = + programModel.getFragmentShaderModel(); program.setFragmentShader(shaderIds.get(fragmentShaderModel)); - + List modelAttributes = programModel.getAttributes(); - if (!modelAttributes.isEmpty()) - { + if (!modelAttributes.isEmpty()) { List attributes = new ArrayList(modelAttributes); program.setAttributes(attributes); } return program; } - + /** * Create the {@link Shader} for the given {@link ShaderModel} - * + * * @param shaderModel The {@link ShaderModel} * @return The {@link Shader} */ - private Shader createShader(ShaderModel shaderModel) - { + private Shader createShader(ShaderModel shaderModel) { Shader shader = new Shader(); transferGltfChildOfRootPropertyElements(shaderModel, shader); - + ShaderType shaderType = shaderModel.getShaderType(); - if (shaderType == ShaderType.VERTEX_SHADER) - { + if (shaderType == ShaderType.VERTEX_SHADER) { shader.setType(GltfConstants.GL_VERTEX_SHADER); - } - else if (shaderType == ShaderType.FRAGMENT_SHADER) - { + } else if (shaderType == ShaderType.FRAGMENT_SHADER) { shader.setType(GltfConstants.GL_FRAGMENT_SHADER); - } - else - { + } else { logger.severe("Invalid shader type: " + shaderType); } shader.setUri(shaderModel.getUri()); return shader; } - + /** * Create the {@link Technique} for the given {@link TechniqueModel} - * + * * @param techniqueModel The {@link TechniqueModel} * @return The {@link Technique} */ - private Technique createTechnique(TechniqueModel techniqueModel) - { + private Technique createTechnique(TechniqueModel techniqueModel) { Technique technique = new Technique(); transferGltfChildOfRootPropertyElements(techniqueModel, technique); - + ProgramModel programModel = techniqueModel.getProgramModel(); technique.setProgram(programIds.get(programModel)); Map uniforms = techniqueModel.getUniforms(); technique.setUniforms(new LinkedHashMap(uniforms)); - + Map attributes = techniqueModel.getAttributes(); technique.setAttributes(new LinkedHashMap(attributes)); - - Map parametersModel = - techniqueModel.getParameters(); - if (!parametersModel.isEmpty()) - { - Map parameters = - new LinkedHashMap(); - - for (Entry entry : - parametersModel.entrySet()) - { + + Map parametersModel = + techniqueModel.getParameters(); + if (!parametersModel.isEmpty()) { + Map parameters = + new LinkedHashMap(); + + for (Entry entry : + parametersModel.entrySet()) { String key = entry.getKey(); - TechniqueParametersModel techniqueParametersModel = - entry.getValue(); - + TechniqueParametersModel techniqueParametersModel = + entry.getValue(); + TechniqueParameters techniqueParameters = - createTechniqueParameters(techniqueParametersModel); - + createTechniqueParameters(techniqueParametersModel); + parameters.put(key, techniqueParameters); } technique.setParameters(parameters); } technique.setStates(createTechniqueStates( - techniqueModel.getTechniqueStatesModel())); - + techniqueModel.getTechniqueStatesModel())); + return technique; } - + /** * Returns the {@link TechniqueParameters} object for the given * {@link TechniqueParametersModel} - * + * * @param techniqueParametersModel The {@link TechniqueParametersModel} * @return The {@link TechniqueParameters} */ private TechniqueParameters createTechniqueParameters( - TechniqueParametersModel techniqueParametersModel) - { + TechniqueParametersModel techniqueParametersModel) { TechniqueParameters techniqueParameters = new TechniqueParameters(); - + techniqueParameters.setSemantic(techniqueParametersModel.getSemantic()); techniqueParameters.setType(techniqueParametersModel.getType()); techniqueParameters.setCount(techniqueParametersModel.getCount()); techniqueParameters.setValue(techniqueParametersModel.getValue()); - + NodeModel nodeModel = techniqueParametersModel.getNodeModel(); techniqueParameters.setNode(nodeIds.get(nodeModel)); - + return techniqueParameters; } - + /** * Returns the {@link TechniqueStates} object for the given * {@link TechniqueStatesModel} - * + * * @param techniqueStatesModel The {@link TechniqueStatesModel} * @return The {@link TechniqueStates} */ private TechniqueStates createTechniqueStates( - TechniqueStatesModel techniqueStatesModel) - { - if (techniqueStatesModel == null) - { + TechniqueStatesModel techniqueStatesModel) { + if (techniqueStatesModel == null) { return null; } TechniqueStates techniqueStates = new TechniqueStates(); - + List enable = techniqueStatesModel.getEnable(); - if (enable != null) - { + if (enable != null) { techniqueStates.setEnable(new ArrayList(enable)); } - + techniqueStates.setFunctions(createTechniqueStatesFunctions( - techniqueStatesModel.getTechniqueStatesFunctionsModel())); - + techniqueStatesModel.getTechniqueStatesFunctionsModel())); + return techniqueStates; } - + /** * Returns the {@link TechniqueStatesFunctions} object for the given * {@link TechniqueStatesFunctionsModel} - * - * @param techniqueStatesFunctionsModel The - * {@link TechniqueStatesFunctionsModel} + * + * @param techniqueStatesFunctionsModel The + * {@link TechniqueStatesFunctionsModel} * @return The {@link TechniqueStatesFunctions} */ private TechniqueStatesFunctions createTechniqueStatesFunctions( - TechniqueStatesFunctionsModel techniqueStatesFunctionsModel) - { - if (techniqueStatesFunctionsModel == null) - { + TechniqueStatesFunctionsModel techniqueStatesFunctionsModel) { + if (techniqueStatesFunctionsModel == null) { return null; } - TechniqueStatesFunctions techniqueStatesFunctions = - new TechniqueStatesFunctions(); - + TechniqueStatesFunctions techniqueStatesFunctions = + new TechniqueStatesFunctions(); + techniqueStatesFunctions.setBlendColor(Optionals.clone( - techniqueStatesFunctionsModel.getBlendColor())); + techniqueStatesFunctionsModel.getBlendColor())); techniqueStatesFunctions.setBlendEquationSeparate(Optionals.clone( - techniqueStatesFunctionsModel.getBlendEquationSeparate())); + techniqueStatesFunctionsModel.getBlendEquationSeparate())); techniqueStatesFunctions.setBlendFuncSeparate(Optionals.clone( - techniqueStatesFunctionsModel.getBlendFuncSeparate())); + techniqueStatesFunctionsModel.getBlendFuncSeparate())); techniqueStatesFunctions.setColorMask(Optionals.clone( - techniqueStatesFunctionsModel.getColorMask())); + techniqueStatesFunctionsModel.getColorMask())); techniqueStatesFunctions.setCullFace(Optionals.clone( - techniqueStatesFunctionsModel.getCullFace())); + techniqueStatesFunctionsModel.getCullFace())); techniqueStatesFunctions.setDepthFunc(Optionals.clone( - techniqueStatesFunctionsModel.getDepthFunc())); + techniqueStatesFunctionsModel.getDepthFunc())); techniqueStatesFunctions.setDepthMask(Optionals.clone( - techniqueStatesFunctionsModel.getDepthMask())); + techniqueStatesFunctionsModel.getDepthMask())); techniqueStatesFunctions.setDepthRange(Optionals.clone( - techniqueStatesFunctionsModel.getDepthRange())); + techniqueStatesFunctionsModel.getDepthRange())); techniqueStatesFunctions.setFrontFace(Optionals.clone( - techniqueStatesFunctionsModel.getFrontFace())); + techniqueStatesFunctionsModel.getFrontFace())); techniqueStatesFunctions.setLineWidth(Optionals.clone( - techniqueStatesFunctionsModel.getLineWidth())); + techniqueStatesFunctionsModel.getLineWidth())); techniqueStatesFunctions.setPolygonOffset(Optionals.clone( - techniqueStatesFunctionsModel.getPolygonOffset())); - + techniqueStatesFunctionsModel.getPolygonOffset())); + return techniqueStatesFunctions; } - - + /** * Create the {@link Mesh} for the given {@link MeshModel} - * + * * @param meshModel The {@link MeshModel} * @return The {@link Mesh} */ - private Mesh createMesh(MeshModel meshModel) - { + private Mesh createMesh(MeshModel meshModel) { Mesh mesh = new Mesh(); transferGltfChildOfRootPropertyElements(meshModel, mesh); - + List meshPrimitives = new ArrayList(); - List meshPrimitiveModels = - meshModel.getMeshPrimitiveModels(); - for (MeshPrimitiveModel meshPrimitiveModel : meshPrimitiveModels) - { - MeshPrimitive meshPrimitive = - createMeshPrimitive(meshPrimitiveModel); + List meshPrimitiveModels = + meshModel.getMeshPrimitiveModels(); + for (MeshPrimitiveModel meshPrimitiveModel : meshPrimitiveModels) { + MeshPrimitive meshPrimitive = + createMeshPrimitive(meshPrimitiveModel); meshPrimitives.add(meshPrimitive); } mesh.setPrimitives(meshPrimitives); - - if (meshModel.getWeights() != null) - { + + if (meshModel.getWeights() != null) { logger.severe("Morph target weights are not supported in glTF 1.0"); } return mesh; } - + /** * Create the {@link MeshPrimitive} for the given {@link MeshPrimitiveModel} - * + * * @param meshPrimitiveModel The {@link MeshPrimitiveModel} * @return The {@link MeshPrimitive} */ private MeshPrimitive createMeshPrimitive( - MeshPrimitiveModel meshPrimitiveModel) - { + MeshPrimitiveModel meshPrimitiveModel) { MeshPrimitive meshPrimitive = new MeshPrimitive(); transferGltfPropertyElements(meshPrimitiveModel, meshPrimitive); meshPrimitive.setMode(meshPrimitiveModel.getMode()); - + Map attributes = resolveIds( - meshPrimitiveModel.getAttributes(), - accessorIds::get); + meshPrimitiveModel.getAttributes(), + accessorIds::get); meshPrimitive.setAttributes(attributes); AccessorModel Ids = meshPrimitiveModel.getIndices(); meshPrimitive.setIndices(accessorIds.get(Ids)); - - List> modelTargetsList = - meshPrimitiveModel.getTargets(); - if (!modelTargetsList.isEmpty()) - { + + List> modelTargetsList = + meshPrimitiveModel.getTargets(); + if (!modelTargetsList.isEmpty()) { logger.severe("Morph targets are not supported in glTF 1.0"); } - + String material = materialIds.get( - meshPrimitiveModel.getMaterialModel()); + meshPrimitiveModel.getMaterialModel()); meshPrimitive.setMaterial(material); - + return meshPrimitive; } /** * Create the {@link Node} for the given {@link NodeModel} - * + * * @param nodeModel The {@link NodeModel} * @return The {@link Node} */ - private Node createNode(NodeModel nodeModel) - { + private Node createNode(NodeModel nodeModel) { Node node = new Node(); transferGltfChildOfRootPropertyElements(nodeModel, node); - - if (!nodeModel.getChildren().isEmpty()) - { + + if (!nodeModel.getChildren().isEmpty()) { node.setChildren(map( - nodeModel.getChildren(), nodeIds::get)); + nodeModel.getChildren(), nodeIds::get)); } node.setTranslation(Optionals.clone(nodeModel.getTranslation())); node.setRotation(Optionals.clone(nodeModel.getRotation())); node.setScale(Optionals.clone(nodeModel.getScale())); node.setMatrix(Optionals.clone(nodeModel.getMatrix())); - + String camera = cameraIds.get(nodeModel.getCameraModel()); node.setCamera(camera); - + String skin = skinIds.get(nodeModel.getSkinModel()); node.setSkin(skin); - - if (nodeModel.getWeights() != null) - { + + if (nodeModel.getWeights() != null) { logger.severe("Morph target weights are not supported in glTF 1.0"); } - + List nodeMeshModels = nodeModel.getMeshModels(); - if (!nodeMeshModels.isEmpty()) - { + if (!nodeMeshModels.isEmpty()) { List meshes = new ArrayList(); - for (MeshModel meshModel : nodeMeshModels) - { + for (MeshModel meshModel : nodeMeshModels) { String id = meshIds.get(meshModel); meshes.add(id); } @@ -989,295 +932,175 @@ private Node createNode(NodeModel nodeModel) } return node; } - + /** * Create the {@link Scene} for the given {@link SceneModel} - * + * * @param sceneModel The {@link SceneModel} * @return The {@link Scene} */ - private Scene createScene(SceneModel sceneModel) - { + private Scene createScene(SceneModel sceneModel) { Scene scene = new Scene(); transferGltfChildOfRootPropertyElements(sceneModel, scene); - + scene.setNodes(map( - sceneModel.getNodeModels(), nodeIds::get)); + sceneModel.getNodeModels(), nodeIds::get)); return scene; } - + /** * Create the {@link Skin} for the given {@link SkinModel} - * + * * @param skinModel The {@link SkinModel} * @return The {@link Skin} */ - private Skin createSkin(SkinModel skinModel) - { + private Skin createSkin(SkinModel skinModel) { Skin skin = new Skin(); transferGltfChildOfRootPropertyElements(skinModel, skin); - - String inverseBindMatrices = - accessorIds.get(skinModel.getInverseBindMatrices()); + + String inverseBindMatrices = + accessorIds.get(skinModel.getInverseBindMatrices()); skin.setInverseBindMatrices(inverseBindMatrices); - + // TODO Not implemented yet logger.severe("Skins are not yet fully supported"); - + return skin; } - + /** * Create a mapping from {@link SamplerInfo} objects to IDs, - * based on the {@link SamplerInfo} objects that are + * based on the {@link SamplerInfo} objects that are * created from the given {@link TextureModel} objects - * + * * @param textureModels The {@link TextureModel} objects * @return The IDs */ private Map createSamplerIds( - List textureModels) - { - Map samplerIndices = - new LinkedHashMap(); - for (TextureModel textureModel : textureModels) - { + List textureModels) { + Map samplerIndices = + new LinkedHashMap(); + for (TextureModel textureModel : textureModels) { SamplerInfo samplerInfo = new SamplerInfo(textureModel); - if (!samplerIndices.containsKey(samplerInfo)) - { - samplerIndices.put(samplerInfo, - "sampler_" + samplerIndices.size()); + if (!samplerIndices.containsKey(samplerInfo)) { + samplerIndices.put(samplerInfo, + "sampler_" + samplerIndices.size()); } } return samplerIndices; } - + /** * Create the {@link de.javagl.jgltf.impl.v1.Sampler} objects for * the current glTF model, returning null if there * are no samplers. - * + * * @return The samplers */ - private Map createSamplers() - { - if (samplerIds.isEmpty()) - { + private Map createSamplers() { + if (samplerIds.isEmpty()) { return null; } - Map samplers = - new LinkedHashMap(); - for (SamplerInfo samplerInfo : samplerIds.keySet()) - { - de.javagl.jgltf.impl.v1.Sampler sampler = - createSampler(samplerInfo); + Map samplers = + new LinkedHashMap(); + for (SamplerInfo samplerInfo : samplerIds.keySet()) { + de.javagl.jgltf.impl.v1.Sampler sampler = + createSampler(samplerInfo); String key = samplerIds.get(samplerInfo); samplers.put(key, sampler); } return samplers; } - - /** - * Create a {@link de.javagl.jgltf.impl.v1.Sampler} from the given - * {@link SamplerInfo} - * - * @param samplerInfo The {@link SamplerInfo} - * @return The {@link de.javagl.jgltf.impl.v1.Sampler} - */ - private static de.javagl.jgltf.impl.v1.Sampler createSampler( - SamplerInfo samplerInfo) - { - de.javagl.jgltf.impl.v1.Sampler sampler = - new de.javagl.jgltf.impl.v1.Sampler(); - sampler.setMagFilter(samplerInfo.magFilter); - sampler.setMinFilter(samplerInfo.minFilter); - sampler.setWrapS(samplerInfo.wrapS); - sampler.setWrapT(samplerInfo.wrapT); - return sampler; - } - /** * Creates a texture for the given {@link TextureModel} - * + * * @param textureModel The {@link TextureModel} * @return The {@link Texture} */ - private Texture createTexture(TextureModel textureModel) - { + private Texture createTexture(TextureModel textureModel) { Texture texture = new Texture(); transferGltfChildOfRootPropertyElements(textureModel, texture); - + SamplerInfo samplerInfo = new SamplerInfo(textureModel); String id = samplerIds.get(samplerInfo); texture.setSampler(id); - + texture.setSource(imageIds.get(textureModel.getImageModel())); - + return texture; } - + /** * Creates an asset for the given {@link AssetModel} - * + * * @param assetModel The {@link AssetModel} * @return The {@link Asset} */ - private Asset createAsset(AssetModel assetModel) - { + private Asset createAsset(AssetModel assetModel) { Asset asset = new Asset(); asset.setVersion("1.0"); asset.setGenerator("JglTF from https://github.com/javagl/JglTF"); - + transferGltfPropertyElements(assetModel, asset); - - if (assetModel.getCopyright() != null) - { + + if (assetModel.getCopyright() != null) { asset.setCopyright(assetModel.getCopyright()); } - if (assetModel.getGenerator() != null) - { + if (assetModel.getGenerator() != null) { asset.setGenerator(assetModel.getGenerator()); } return asset; } /** - * Transfer the extensions and extras from the given model element to - * the given property - * - * @param modelElement The model element - * @param property The property - */ - private static void transferGltfPropertyElements( - ModelElement modelElement, GlTFProperty property) - { - property.setExtensions(modelElement.getExtensions()); - property.setExtras(modelElement.getExtras()); - } - - /** - * Transfer the name and extensions and extras from the given model - * element to the given property - * - * @param modelElement The model element - * @param property The property - */ - private static void transferGltfChildOfRootPropertyElements( - NamedModelElement modelElement, - GlTFChildOfRootProperty property) - { - property.setName(modelElement.getName()); - transferGltfPropertyElements(modelElement, property); - } - - /** - * Creates a map that maps (unspecified) strings starting with the - * given prefix to the results of applying the given mapper to the - * given elements, or null if the given collection is - * empty - * - * @param prefix The prefix - * @param elements The elements - * @param mapper The mapper - * @return The map + * Inner class containing the information that is necessary to define + * a glTF {@link de.javagl.jgltf.impl.v1.Sampler} */ - private static Map map( - String prefix, - Collection elements, - Function mapper) - { - return map(prefix, map(elements, mapper)); - } + @SuppressWarnings("javadoc") + private static class SamplerInfo { + final Integer magFilter; + final Integer minFilter; + final Integer wrapS; + final Integer wrapT; - /** - * Creates a map that maps (unspecified) strings starting with the - * given prefix to the given elements, or null if the - * given collection is null or empty - * - * @param prefix The prefix - * @param elements The elements - * @return The map - */ - private static Map map( - String prefix, Collection elements) - { - if (elements == null || elements.isEmpty()) - { - return null; - } - Map map = new LinkedHashMap(); - int index = 0; - for (T element : elements) - { - map.put(prefix + "_" + index, element); - index++; - } - return map; - } - - /** - * Returns a list containing the result of mapping the given elements with - * the given function, or null if the given collection is - * empty - * - * @param collection The collection - * @param mapper The mapper - * @return The list - */ - private static List map( - Collection collection, - Function mapper) - { - if (collection.isEmpty()) - { - return null; + SamplerInfo(TextureModel textureModel) { + this.magFilter = textureModel.getMagFilter(); + this.minFilter = textureModel.getMinFilter(); + this.wrapS = textureModel.getWrapS(); + this.wrapT = textureModel.getWrapT(); } - return collection.stream().map(mapper).collect(Collectors.toList()); - } - /** - * Creates a map that has the same keys as the given map, mapped to - * the IDs that are looked up for the respective values, using - * the given function - * - * @param map The map - * @param idLookup The index lookup - * @return The index map - */ - private static Map resolveIds( - Map map, - Function idLookup) - { - Map result = new LinkedHashMap(); - for (Entry entry : map.entrySet()) - { - K key = entry.getKey(); - T value = entry.getValue(); - String id = idLookup.apply(value); - result.put(key, id); + @Override + public int hashCode() { + return Objects.hash(magFilter, minFilter, wrapS, wrapT); } - return result; - } - - /** - * Create an ordered map that contains a mapping of the given elements - * to IDs that start with the given prefix - * - * @param prefix The prefix - * @param elements The elements - * @return The ID map - */ - private static Map computeIdMap( - String prefix, Collection elements) - { - Map ids = new LinkedHashMap(); - int index = 0; - for (T element : elements) - { - ids.put(element, prefix + "_" + index); - index++; + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null) { + return false; + } + if (getClass() != object.getClass()) { + return false; + } + SamplerInfo other = (SamplerInfo) object; + if (!Objects.equals(magFilter, other.magFilter)) { + return false; + } + if (!Objects.equals(minFilter, other.minFilter)) { + return false; + } + if (!Objects.equals(wrapS, other.wrapS)) { + return false; + } + if (!Objects.equals(wrapT, other.wrapT)) { + return false; + } + return true; } - return ids; } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfExtensionsV1.java b/src/main/java/de/javagl/jgltf/model/v1/GltfExtensionsV1.java index 7080784..9d60978 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfExtensionsV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfExtensionsV1.java @@ -26,201 +26,178 @@ */ package de.javagl.jgltf.model.v1; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - import com.google.gson.Gson; - import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.GlTFProperty; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + /** * Utility methods related to glTF extensions for glTF 1.0 */ -public class GltfExtensionsV1 -{ +public class GltfExtensionsV1 { /** - * If the {@link GlTF#getExtensionsUsed() used extensions} of the given + * Private constructor to prevent instantiation + */ + private GltfExtensionsV1() { + // Private constructor to prevent instantiation + } + + /** + * If the {@link GlTF#getExtensionsUsed() used extensions} of the given * {@link GlTF} is null or does not contain the given * extension name, then it will be set to a new list that contains all * previous extension names, and the given one. - * - * @param gltf The {@link GlTF} + * + * @param gltf The {@link GlTF} * @param extensionName The name of the extension to add */ - public static void addExtensionUsed(GlTF gltf, String extensionName) - { + public static void addExtensionUsed(GlTF gltf, String extensionName) { List oldExtensionsUsed = gltf.getExtensionsUsed(); - if (oldExtensionsUsed == null || - !oldExtensionsUsed.contains(extensionName)) - { + if (oldExtensionsUsed == null || + !oldExtensionsUsed.contains(extensionName)) { gltf.addExtensionsUsed(extensionName); } } - + /** - * If the {@link GlTF#getExtensionsUsed() used extensions} of the given - * {@link GlTF} contains the given extension name, then it will be set + * If the {@link GlTF#getExtensionsUsed() used extensions} of the given + * {@link GlTF} contains the given extension name, then it will be set * to a new list that contains all previous extension names, except * for the given one. - * - * @param gltf The {@link GlTF} + * + * @param gltf The {@link GlTF} * @param extensionName The name of the extension to remove */ - public static void removeExtensionUsed(GlTF gltf, String extensionName) - { + public static void removeExtensionUsed(GlTF gltf, String extensionName) { List oldExtensionsUsed = gltf.getExtensionsUsed(); - if (oldExtensionsUsed != null && - oldExtensionsUsed.contains(extensionName)) - { + if (oldExtensionsUsed != null && + oldExtensionsUsed.contains(extensionName)) { gltf.removeExtensionsUsed(extensionName); } } - + /** - * Return the key-value mapping that is stored as the - * {@link GlTFProperty#getExtensions() extension} with the given name - * in the given {@link GlTFProperty}, or null if no such + * Return the key-value mapping that is stored as the + * {@link GlTFProperty#getExtensions() extension} with the given name + * in the given {@link GlTFProperty}, or null if no such * entry can be found. - * - * @param gltfProperty The {@link GlTFProperty} + * + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name * @return The extension property mapping, or null */ private static Map getExtensionMap( - GlTFProperty gltfProperty, String extensionName) - { + GlTFProperty gltfProperty, String extensionName) { Map extensions = gltfProperty.getExtensions(); - if (extensions == null) - { + if (extensions == null) { return null; } Object value = extensions.get(extensionName); - if (value == null) - { + if (value == null) { return null; } - if (value instanceof Map) - { - Map map = (Map)value; + if (value instanceof Map) { + Map map = (Map) value; @SuppressWarnings("unchecked") - Map result = (Map)map; - return result; + Map result = (Map) map; + return result; } return null; } - - + /** - * Returns whether a non-null key-value mapping is stored + * Returns whether a non-null key-value mapping is stored * as the {@link GlTFProperty#getExtensions() extension} with the * given name in the given glTF property. - - * @param gltfProperty The {@link GlTFProperty} + * + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name * @return Whether the specified extension mapping exists */ static boolean hasExtension( - GlTFProperty gltfProperty, String extensionName) - { + GlTFProperty gltfProperty, String extensionName) { return getExtensionMap(gltfProperty, extensionName) != null; } - + /** - * Returns the value of the specified property in the key-value mapping - * that is stored as the {@link GlTFProperty#getExtensions() extension} + * Returns the value of the specified property in the key-value mapping + * that is stored as the {@link GlTFProperty#getExtensions() extension} * with the given name in the given glTF property. If the specified * extension does not exist, or does not have the specified property, * then null is returned. - * - * @param gltfProperty The {@link GlTFProperty} + * + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name - * @param propertyName The property name + * @param propertyName The property name * @return The value, as a string. */ static String getExtensionPropertyValueAsString( - GlTFProperty gltfProperty, String extensionName, String propertyName) - { - Map extensionMap = - getExtensionMap(gltfProperty, extensionName); - if (extensionMap == null) - { + GlTFProperty gltfProperty, String extensionName, String propertyName) { + Map extensionMap = + getExtensionMap(gltfProperty, extensionName); + if (extensionMap == null) { return null; } Object value = extensionMap.get(propertyName); - if (value == null) - { + if (value == null) { return null; } return String.valueOf(value); } - + /** * Stores the given property value under the given property key in the * key-value mapping that is stored under the given extension name in - * the {@link GlTFProperty#getExtensions() extensions} of the given + * the {@link GlTFProperty#getExtensions() extensions} of the given * {@link GlTFProperty}. If the mapping for the given extension name * did not exist, it will be created. If it already existed but was * no key-value mapping, then its old value will be overwritten. - * - * @param gltfProperty The {@link GlTFProperty} + * + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name - * @param propertyName The property name + * @param propertyName The property name * @param propertyValue The value */ static void setExtensionPropertyValue( - GlTFProperty gltfProperty, String extensionName, - String propertyName, Object propertyValue) - { - Map extensionMap = - getExtensionMap(gltfProperty, extensionName); - if (extensionMap == null) - { + GlTFProperty gltfProperty, String extensionName, + String propertyName, Object propertyValue) { + Map extensionMap = + getExtensionMap(gltfProperty, extensionName); + if (extensionMap == null) { extensionMap = new LinkedHashMap(); gltfProperty.addExtensions(extensionName, extensionMap); } extensionMap.put(propertyName, propertyValue); } - - + /** * Fetch the value of the specified extension object from the given - * {@link GlTFProperty}, converted into the given target type. + * {@link GlTFProperty}, converted into the given target type. * Returns null if the given {@link GlTFProperty} does * not have the specified extension. - * - * @param gltfProperty The {@link GlTFProperty} + * + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name - * @param type The type to convert the object to + * @param type The type to convert the object to * @return The object * @throws IllegalArgumentException If the specified extension object - * cannot be converted to the desired target type + * cannot be converted to the desired target type */ static T fetchExtensionObject( - GlTFProperty gltfProperty, String extensionName, Class type) - { + GlTFProperty gltfProperty, String extensionName, Class type) { Map extensions = gltfProperty.getExtensions(); - if (extensions == null) - { + if (extensions == null) { return null; } Object extensionObject = extensions.get(extensionName); - if (extensionObject == null) - { + if (extensionObject == null) { return null; } Gson gson = new Gson(); return gson.fromJson(gson.toJsonTree(extensionObject), type); } - - - /** - * Private constructor to prevent instantiation - */ - private GltfExtensionsV1() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfIds.java b/src/main/java/de/javagl/jgltf/model/v1/GltfIds.java index 50f5597..c6c4f12 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfIds.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfIds.java @@ -26,31 +26,35 @@ */ package de.javagl.jgltf.model.v1; +import de.javagl.jgltf.impl.v1.GlTF; + import java.util.Collections; import java.util.Map; import java.util.Set; -import de.javagl.jgltf.impl.v1.GlTF; - /** * Utility methods for generating IDs for {@link GlTF} objects */ -public class GltfIds -{ +public class GltfIds { + /** + * Private constructor to prevent instantiation + */ + private GltfIds() { + // Private constructor to prevent instantiation + } + /** * Generate an unspecified ID string with the given prefix that is not * yet contained in the key set of the given map - * + * * @param prefix The prefix for the ID string - * @param map The map from the existing IDs. This may be null. + * @param map The map from the existing IDs. This may be null. * @return The new ID */ public static String generateId( - String prefix, Map map) - { + String prefix, Map map) { Set set = Collections.emptySet(); - if (map != null) - { + if (map != null) { set = map.keySet(); } return generateId(prefix, set); @@ -59,37 +63,25 @@ public static String generateId( /** * Generate an unspecified ID string with the given prefix that is not * yet contained in the given set - * + * * @param prefix The prefix for the ID string - * @param set The set of the existing IDs. This may be null. + * @param set The set of the existing IDs. This may be null. * @return The new ID */ public static String generateId( - String prefix, Set set) - { + String prefix, Set set) { Set localSet = Collections.emptySet(); - if (set != null) - { + if (set != null) { localSet = set; } int counter = localSet.size(); - while (true) - { + while (true) { String id = prefix + counter; - if (!localSet.contains(id)) - { + if (!localSet.contains(id)) { return id; } counter++; } } - /** - * Private constructor to prevent instantiation - */ - private GltfIds() - { - // Private constructor to prevent instantiation - } - } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfModelCreatorV1.java b/src/main/java/de/javagl/jgltf/model/v1/GltfModelCreatorV1.java index bf2bfa0..875fa17 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfModelCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfModelCreatorV1.java @@ -26,106 +26,19 @@ */ package de.javagl.jgltf.model.v1; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.function.Function; -import java.util.function.IntFunction; -import java.util.logging.Logger; - import com.google.gson.Gson; import com.google.gson.JsonElement; import com.modularmods.mcgltf.MCglTF; - -import de.javagl.jgltf.impl.v1.Accessor; -import de.javagl.jgltf.impl.v1.Animation; -import de.javagl.jgltf.impl.v1.AnimationChannel; -import de.javagl.jgltf.impl.v1.AnimationChannelTarget; -import de.javagl.jgltf.impl.v1.AnimationSampler; -import de.javagl.jgltf.impl.v1.Asset; -import de.javagl.jgltf.impl.v1.Buffer; -import de.javagl.jgltf.impl.v1.BufferView; -import de.javagl.jgltf.impl.v1.Camera; -import de.javagl.jgltf.impl.v1.CameraOrthographic; -import de.javagl.jgltf.impl.v1.CameraPerspective; -import de.javagl.jgltf.impl.v1.GlTF; -import de.javagl.jgltf.impl.v1.GlTFChildOfRootProperty; -import de.javagl.jgltf.impl.v1.GlTFProperty; -import de.javagl.jgltf.impl.v1.Image; -import de.javagl.jgltf.impl.v1.Material; -import de.javagl.jgltf.impl.v1.Mesh; -import de.javagl.jgltf.impl.v1.MeshPrimitive; -import de.javagl.jgltf.impl.v1.Node; -import de.javagl.jgltf.impl.v1.Program; -import de.javagl.jgltf.impl.v1.Sampler; -import de.javagl.jgltf.impl.v1.Scene; -import de.javagl.jgltf.impl.v1.Shader; -import de.javagl.jgltf.impl.v1.Skin; -import de.javagl.jgltf.impl.v1.Technique; -import de.javagl.jgltf.impl.v1.TechniqueParameters; -import de.javagl.jgltf.impl.v1.TechniqueStates; -import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; -import de.javagl.jgltf.impl.v1.Texture; -import de.javagl.jgltf.model.AccessorDatas; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.Accessors; -import de.javagl.jgltf.model.AnimationModel; +import de.javagl.jgltf.impl.v1.*; +import de.javagl.jgltf.model.*; import de.javagl.jgltf.model.AnimationModel.Channel; import de.javagl.jgltf.model.AnimationModel.Interpolation; -import de.javagl.jgltf.model.AssetModel; -import de.javagl.jgltf.model.BufferModel; -import de.javagl.jgltf.model.BufferViewModel; -import de.javagl.jgltf.model.CameraModel; -import de.javagl.jgltf.model.ElementType; -import de.javagl.jgltf.model.ExtensionsModel; -import de.javagl.jgltf.model.GltfConstants; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.ImageModel; -import de.javagl.jgltf.model.MaterialModel; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.Optionals; -import de.javagl.jgltf.model.SceneModel; -import de.javagl.jgltf.model.SkinModel; -import de.javagl.jgltf.model.TextureModel; -import de.javagl.jgltf.model.gl.ProgramModel; -import de.javagl.jgltf.model.gl.ShaderModel; +import de.javagl.jgltf.model.gl.*; import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; -import de.javagl.jgltf.model.gl.TechniqueModel; -import de.javagl.jgltf.model.gl.TechniqueParametersModel; -import de.javagl.jgltf.model.gl.TechniqueStatesModel; -import de.javagl.jgltf.model.gl.impl.DefaultProgramModel; -import de.javagl.jgltf.model.gl.impl.DefaultShaderModel; -import de.javagl.jgltf.model.gl.impl.DefaultTechniqueModel; -import de.javagl.jgltf.model.gl.impl.DefaultTechniqueParametersModel; -import de.javagl.jgltf.model.gl.impl.DefaultTechniqueStatesFunctionsModel; -import de.javagl.jgltf.model.gl.impl.DefaultTechniqueStatesModel; -import de.javagl.jgltf.model.impl.AbstractModelElement; -import de.javagl.jgltf.model.impl.AbstractNamedModelElement; -import de.javagl.jgltf.model.impl.DefaultAccessorModel; -import de.javagl.jgltf.model.impl.DefaultAnimationModel; +import de.javagl.jgltf.model.gl.impl.*; +import de.javagl.jgltf.model.impl.*; import de.javagl.jgltf.model.impl.DefaultAnimationModel.DefaultChannel; import de.javagl.jgltf.model.impl.DefaultAnimationModel.DefaultSampler; -import de.javagl.jgltf.model.impl.DefaultAssetModel; -import de.javagl.jgltf.model.impl.DefaultBufferModel; -import de.javagl.jgltf.model.impl.DefaultBufferViewModel; -import de.javagl.jgltf.model.impl.DefaultCameraModel; -import de.javagl.jgltf.model.impl.DefaultCameraOrthographicModel; -import de.javagl.jgltf.model.impl.DefaultCameraPerspectiveModel; -import de.javagl.jgltf.model.impl.DefaultExtensionsModel; -import de.javagl.jgltf.model.impl.DefaultGltfModel; -import de.javagl.jgltf.model.impl.DefaultImageModel; -import de.javagl.jgltf.model.impl.DefaultMeshModel; -import de.javagl.jgltf.model.impl.DefaultMeshPrimitiveModel; -import de.javagl.jgltf.model.impl.DefaultNodeModel; -import de.javagl.jgltf.model.impl.DefaultSceneModel; -import de.javagl.jgltf.model.impl.DefaultSkinModel; -import de.javagl.jgltf.model.impl.DefaultTextureModel; import de.javagl.jgltf.model.io.Buffers; import de.javagl.jgltf.model.io.GltfAsset; import de.javagl.jgltf.model.io.IO; @@ -135,77 +48,323 @@ import de.javagl.jgltf.model.v1.gl.TechniqueStatesFunctionsModels; import net.minecraft.resources.ResourceLocation; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.Map.Entry; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.logging.Logger; + /** * A class that is responsible for filling a {@link DefaultGltfModel} with * the model instances that are created from a {@link GltfAssetV1} */ -public class GltfModelCreatorV1 -{ +public class GltfModelCreatorV1 { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfModelCreatorV1.class.getName()); - - /** - * Create the {@link GltfModel} for the given {@link GltfAssetV1} - * - * @param gltfAsset The {@link GltfAssetV1} - * @return The {@link GltfModel} - */ - public static GltfModelV1 create(GltfAssetV1 gltfAsset) - { - GltfModelV1 gltfModel = new GltfModelV1(); - GltfModelCreatorV1 creator = - new GltfModelCreatorV1(gltfAsset, gltfModel); - creator.create(); - return gltfModel; - } - + private static final Logger logger = + Logger.getLogger(GltfModelCreatorV1.class.getName()); /** * The {@link IndexMappingSet} */ private final IndexMappingSet indexMappingSet; - /** * The {@link GltfAsset} of this model */ private final GltfAsset gltfAsset; - /** * The {@link GlTF} of this model */ private final GlTF gltf; - /** * The {@link GltfModel} that is built */ private final GltfModelV1 gltfModel; - + /** * Creates a new model for the given glTF - * + * * @param gltfAsset The {@link GltfAssetV1} * @param gltfModel The {@link GltfModel} */ GltfModelCreatorV1( - GltfAssetV1 gltfAsset, GltfModelV1 gltfModel) - { - this.gltfAsset = Objects.requireNonNull(gltfAsset, - "The gltfAsset may not be null"); + GltfAssetV1 gltfAsset, GltfModelV1 gltfModel) { + this.gltfAsset = Objects.requireNonNull(gltfAsset, + "The gltfAsset may not be null"); this.gltf = gltfAsset.getGltf(); - this.gltfModel = Objects.requireNonNull(gltfModel, - "The gltfModel may not be null"); + this.gltfModel = Objects.requireNonNull(gltfModel, + "The gltfModel may not be null"); this.indexMappingSet = IndexMappingSets.create(gltfAsset.getGltf()); } - + + /** + * Create the {@link GltfModel} for the given {@link GltfAssetV1} + * + * @param gltfAsset The {@link GltfAssetV1} + * @return The {@link GltfModel} + */ + public static GltfModelV1 create(GltfAssetV1 gltfAsset) { + GltfModelV1 gltfModel = new GltfModelV1(); + GltfModelCreatorV1 creator = + new GltfModelCreatorV1(gltfAsset, gltfModel); + creator.create(); + return gltfModel; + } + + /** + * Create a {@link DefaultAccessorModel} for the given {@link Accessor} + * + * @param accessor The {@link Accessor} + * @return The {@link AccessorModel} + */ + private static DefaultAccessorModel createAccessorModel(Accessor accessor) { + Integer componentType = accessor.getComponentType(); + Integer byteOffset = accessor.getByteOffset(); + Integer count = accessor.getCount(); + ElementType elementType = ElementType.forString(accessor.getType()); + Integer byteStride = accessor.getByteStride(); + if (byteStride == null) { + byteStride = elementType.getNumComponents() * + Accessors.getNumBytesForAccessorComponentType( + componentType); + } + DefaultAccessorModel accessorModel = new DefaultAccessorModel( + componentType, count, elementType); + accessorModel.setByteOffset(byteOffset); + accessorModel.setByteStride(byteStride); + return accessorModel; + } + + /** + * Create a {@link DefaultBufferViewModel} for the given {@link BufferView} + * + * @param bufferView The {@link BufferView} + * @return The {@link BufferViewModel} + */ + private static DefaultBufferViewModel createBufferViewModel( + BufferView bufferView) { + int byteOffset = bufferView.getByteOffset(); + Integer byteLength = bufferView.getByteLength(); + if (byteLength == null) { + logger.warning("No byteLength found in BufferView"); + byteLength = 0; + } + Integer target = bufferView.getTarget(); + DefaultBufferViewModel bufferViewModel = + new DefaultBufferViewModel(target); + bufferViewModel.setByteOffset(byteOffset); + bufferViewModel.setByteLength(byteLength); + return bufferViewModel; + } + + /** + * Computes the {@link AccessorModel#getByteStride() byte stride} of + * the given {@link AccessorModel} instances. If the given instances + * do not have the same byte stride, then a warning will be printed. + * + * @param accessorModels The {@link AccessorModel} instances + * @return The common byte stride + */ + private static int computeCommonByteStride( + Iterable accessorModels) { + int commonByteStride = -1; + for (AccessorModel accessorModel : accessorModels) { + int byteStride = accessorModel.getByteStride(); + if (commonByteStride == -1) { + commonByteStride = byteStride; + } else { + if (commonByteStride != byteStride) { + logger.warning("The accessor models do not have the " + + "same byte stride: " + commonByteStride + + " and " + byteStride); + } + } + } + return commonByteStride; + } + + /** + * Compute the mapping from joint names to the ID of the {@link Node} with + * the respective {@link Node#getJointName() joint name} + * + * @param gltf The {@link GlTF} + * @return The mapping + */ + private static Map computeJointNameToNodeIdMap(GlTF gltf) { + Map map = new LinkedHashMap(); + Map nodes = Optionals.of(gltf.getNodes()); + for (Entry entry : nodes.entrySet()) { + String nodeId = entry.getKey(); + Node node = entry.getValue(); + if (node.getJointName() != null) { + String oldNodeId = map.put(node.getJointName(), nodeId); + if (oldNodeId != null) { + logger.warning("Joint name " + node.getJointName() + + " is mapped to nodes with IDs " + nodeId + " and " + + oldNodeId); + } + } + } + return map; + } + + /** + * Add all {@link TechniqueParametersModel} instances for the + * attributes of the given {@link Technique} to the given + * {@link TechniqueModel} + * + * @param technique The {@link Technique} + * @param techniqueModel The {@link TechniqueModel} + * @param nodeLookup The function for looking up the {@link NodeModel} + * for a given node ID. This may be null, but if its is + * null and there is a non-null node ID + * in the technique parameters, then an error message will be + * printed. + */ + private static void addParameters(Technique technique, + DefaultTechniqueModel techniqueModel, + Function nodeLookup) { + Map parameters = + Optionals.of(technique.getParameters()); + for (Entry entry : parameters.entrySet()) { + String parameterName = entry.getKey(); + TechniqueParameters parameter = entry.getValue(); + + int type = parameter.getType(); + int count = Optionals.of(parameter.getCount(), 1); + String semantic = parameter.getSemantic(); + Object value = parameter.getValue(); + String nodeId = parameter.getNode(); + NodeModel nodeModel = null; + if (nodeId != null) { + if (nodeLookup == null) { + logger.severe("No lookup function found for the nodes"); + } else { + nodeModel = nodeLookup.apply(nodeId); + } + } + + TechniqueParametersModel techniqueParametersModel = + new DefaultTechniqueParametersModel( + type, count, semantic, value, nodeModel); + techniqueModel.addParameter( + parameterName, techniqueParametersModel); + } + } + + /** + * Add all attribute entries of the given {@link Technique} to the given + * {@link TechniqueModel} + * + * @param technique The {@link Technique} + * @param techniqueModel The {@link TechniqueModel} + */ + private static void addAttributes(Technique technique, + DefaultTechniqueModel techniqueModel) { + Map attributes = + Optionals.of(technique.getAttributes()); + for (Entry entry : attributes.entrySet()) { + String attributeName = entry.getKey(); + String parameterName = entry.getValue(); + techniqueModel.addAttribute(attributeName, parameterName); + } + } + + /** + * Add all uniform entries of the given {@link Technique} to the given + * {@link TechniqueModel} + * + * @param technique The {@link Technique} + * @param techniqueModel The {@link TechniqueModel} + */ + private static void addUniforms(Technique technique, + DefaultTechniqueModel techniqueModel) { + Map uniforms = + Optionals.of(technique.getUniforms()); + for (Entry entry : uniforms.entrySet()) { + String uniformName = entry.getKey(); + String parameterName = entry.getValue(); + techniqueModel.addUniform(uniformName, parameterName); + } + } + + /** + * Initialize the given {@link TechniqueModel} with the values that are + * obtained from the given {@link Technique} + * + * @param techniqueModel The {@link TechniqueModel} + * @param technique The {@link Technique} + * @param nodeLookup The function for looking up the {@link NodeModel} + * for a given node ID. This may be null, but if its is + * null and there is a non-null node ID + * in the technique parameters, then an error message will be + * printed. + */ + public static void initTechniqueModel( + DefaultTechniqueModel techniqueModel, Technique technique, + Function nodeLookup) { + transferGltfChildOfRootPropertyElements(technique, techniqueModel); + + addParameters(technique, techniqueModel, nodeLookup); + addAttributes(technique, techniqueModel); + addUniforms(technique, techniqueModel); + + List enableModel = null; + DefaultTechniqueStatesFunctionsModel techniqueStatesFunctionsModel = + null; + TechniqueStates states = technique.getStates(); + if (states != null) { + List enable = states.getEnable(); + if (enable != null) { + enableModel = new ArrayList(enable); + } + TechniqueStatesFunctions functions = states.getFunctions(); + if (functions != null) { + techniqueStatesFunctionsModel = + TechniqueStatesFunctionsModels.create(functions); + } + + TechniqueStatesModel techniqueStatesModel = + new DefaultTechniqueStatesModel( + enableModel, techniqueStatesFunctionsModel); + techniqueModel.setTechniqueStatesModel(techniqueStatesModel); + } + } + + /** + * Transfer the extensions and extras from the given property to + * the given target + * + * @param property The property + * @param modelElement The target + */ + private static void transferGltfPropertyElements( + GlTFProperty property, AbstractModelElement modelElement) { + modelElement.setExtensions(property.getExtensions()); + modelElement.setExtras(property.getExtras()); + } + + /** + * Transfer the name and extensions and extras from the given property to + * the given target + * + * @param property The property + * @param modelElement The target + */ + private static void transferGltfChildOfRootPropertyElements( + GlTFChildOfRootProperty property, + AbstractNamedModelElement modelElement) { + modelElement.setName(property.getName()); + transferGltfPropertyElements(property, modelElement); + } + /** * Create and initialize all models */ - void create() - { + void create() { transferGltfPropertyElements(gltf, gltfModel); - + createAccessorModels(); createAnimationModels(); createBufferModels(); @@ -221,14 +380,14 @@ void create() createShaderModels(); createProgramModels(); createTechniqueModels(); - + initBufferModels(); initBufferViewModels(); - + initAccessorModels(); - + assignBufferViewByteStrides(); - + initAnimationModels(); initImageModels(); initTechniqueModels(); @@ -240,206 +399,135 @@ void create() initTextureModels(); initShaderModels(); initProgramModels(); - + initExtensionsModel(); initAssetModel(); } - + /** * Create the {@link AccessorModel} instances */ - private void createAccessorModels() - { + private void createAccessorModels() { Map accessors = Optionals.of(gltf.getAccessors()); - for (Accessor accessor : accessors.values()) - { + for (Accessor accessor : accessors.values()) { DefaultAccessorModel accessorModel = createAccessorModel(accessor); gltfModel.addAccessorModel(accessorModel); } } - /** - * Create a {@link DefaultAccessorModel} for the given {@link Accessor} - * - * @param accessor The {@link Accessor} - * @return The {@link AccessorModel} - */ - private static DefaultAccessorModel createAccessorModel(Accessor accessor) - { - Integer componentType = accessor.getComponentType(); - Integer byteOffset = accessor.getByteOffset(); - Integer count = accessor.getCount(); - ElementType elementType = ElementType.forString(accessor.getType()); - Integer byteStride = accessor.getByteStride(); - if (byteStride == null) - { - byteStride = elementType.getNumComponents() * - Accessors.getNumBytesForAccessorComponentType( - componentType); - } - DefaultAccessorModel accessorModel = new DefaultAccessorModel( - componentType, count, elementType); - accessorModel.setByteOffset(byteOffset); - accessorModel.setByteStride(byteStride); - return accessorModel; - } - /** * Create the {@link AnimationModel} instances */ - private void createAnimationModels() - { + private void createAnimationModels() { Map animations = Optionals.of(gltf.getAnimations()); - for (int i = 0; i < animations.size(); i++) - { + for (int i = 0; i < animations.size(); i++) { gltfModel.addAnimationModel(new DefaultAnimationModel()); } } - + /** * Create the {@link BufferModel} instances */ - private void createBufferModels() - { + private void createBufferModels() { Map buffers = Optionals.of(gltf.getBuffers()); - for (Buffer buffer : buffers.values()) - { + for (Buffer buffer : buffers.values()) { DefaultBufferModel bufferModel = new DefaultBufferModel(); bufferModel.setUri(buffer.getUri()); gltfModel.addBufferModel(bufferModel); } } - + /** * Create the {@link BufferViewModel} instances */ - private void createBufferViewModels() - { - Map bufferViews = - Optionals.of(gltf.getBufferViews()); - for (BufferView bufferView : bufferViews.values()) - { - DefaultBufferViewModel bufferViewModel = - createBufferViewModel(bufferView); + private void createBufferViewModels() { + Map bufferViews = + Optionals.of(gltf.getBufferViews()); + for (BufferView bufferView : bufferViews.values()) { + DefaultBufferViewModel bufferViewModel = + createBufferViewModel(bufferView); gltfModel.addBufferViewModel(bufferViewModel); } } - + /** * Create the {@link CameraModel} instances */ - private void createCameraModels() - { - Map cameras = - Optionals.of(gltf.getCameras()); - for (Camera camera : cameras.values()) - { + private void createCameraModels() { + Map cameras = + Optionals.of(gltf.getCameras()); + for (Camera camera : cameras.values()) { String type = camera.getType(); - if ("perspective".equals(type)) - { + if ("perspective".equals(type)) { CameraPerspective cameraPerspective = camera.getPerspective(); - DefaultCameraPerspectiveModel cameraPerspectiveModel = - new DefaultCameraPerspectiveModel(); + DefaultCameraPerspectiveModel cameraPerspectiveModel = + new DefaultCameraPerspectiveModel(); cameraPerspectiveModel.setAspectRatio( - cameraPerspective.getAspectRatio()); + cameraPerspective.getAspectRatio()); cameraPerspectiveModel.setYfov( - cameraPerspective.getYfov()); + cameraPerspective.getYfov()); cameraPerspectiveModel.setZfar( - cameraPerspective.getZfar()); + cameraPerspective.getZfar()); cameraPerspectiveModel.setZnear( - cameraPerspective.getZnear()); - DefaultCameraModel cameraModel = - new DefaultCameraModel(); + cameraPerspective.getZnear()); + DefaultCameraModel cameraModel = + new DefaultCameraModel(); cameraModel.setCameraPerspectiveModel(cameraPerspectiveModel); gltfModel.addCameraModel(cameraModel); - } - else if ("orthographic".equals(type)) - { - CameraOrthographic cameraOrthographic = - camera.getOrthographic(); - DefaultCameraOrthographicModel cameraOrthographicModel = - new DefaultCameraOrthographicModel(); + } else if ("orthographic".equals(type)) { + CameraOrthographic cameraOrthographic = + camera.getOrthographic(); + DefaultCameraOrthographicModel cameraOrthographicModel = + new DefaultCameraOrthographicModel(); cameraOrthographicModel.setXmag( - cameraOrthographic.getXmag()); + cameraOrthographic.getXmag()); cameraOrthographicModel.setYmag( - cameraOrthographic.getYmag()); + cameraOrthographic.getYmag()); cameraOrthographicModel.setZfar( - cameraOrthographic.getZfar()); + cameraOrthographic.getZfar()); cameraOrthographicModel.setZnear( - cameraOrthographic.getZnear()); - DefaultCameraModel cameraModel = - new DefaultCameraModel(); + cameraOrthographic.getZnear()); + DefaultCameraModel cameraModel = + new DefaultCameraModel(); cameraModel.setCameraOrthographicModel(cameraOrthographicModel); gltfModel.addCameraModel(cameraModel); - } - else - { + } else { logger.severe("Invalid camera type: " + type); } } } - /** - * Create a {@link DefaultBufferViewModel} for the given {@link BufferView} - * - * @param bufferView The {@link BufferView} - * @return The {@link BufferViewModel} - */ - private static DefaultBufferViewModel createBufferViewModel( - BufferView bufferView) - { - int byteOffset = bufferView.getByteOffset(); - Integer byteLength = bufferView.getByteLength(); - if (byteLength == null) - { - logger.warning("No byteLength found in BufferView"); - byteLength = 0; - } - Integer target = bufferView.getTarget(); - DefaultBufferViewModel bufferViewModel = - new DefaultBufferViewModel(target); - bufferViewModel.setByteOffset(byteOffset); - bufferViewModel.setByteLength(byteLength); - return bufferViewModel; - } - /** * Create the {@link ImageModel} instances */ - private void createImageModels() - { - Map images = - Optionals.of(gltf.getImages()); - for (Image image : images.values()) - { - DefaultImageModel imageModel = - new DefaultImageModel(); + private void createImageModels() { + Map images = + Optionals.of(gltf.getImages()); + for (Image image : images.values()) { + DefaultImageModel imageModel = + new DefaultImageModel(); String uri = image.getUri(); imageModel.setUri(uri); gltfModel.addImageModel(imageModel); } } - + /** * Create the {@link MaterialModel} instances */ - private void createMaterialModels() - { + private void createMaterialModels() { Map materials = Optionals.of(gltf.getMaterials()); - for (int i = 0; i < materials.size(); i++) - { + for (int i = 0; i < materials.size(); i++) { gltfModel.addMaterialModel(new MaterialModelV1()); } } - + /** * Create the {@link MeshModel} instances */ - private void createMeshModels() - { + private void createMeshModels() { Map meshes = Optionals.of(gltf.getMeshes()); - for (int i = 0; i < meshes.size(); i++) - { + for (int i = 0; i < meshes.size(); i++) { gltfModel.addMeshModel(new DefaultMeshModel()); } } @@ -447,11 +535,9 @@ private void createMeshModels() /** * Create the {@link NodeModel} instances */ - private void createNodeModels() - { + private void createNodeModels() { Map nodes = Optionals.of(gltf.getNodes()); - for (int i = 0; i < nodes.size(); i++) - { + for (int i = 0; i < nodes.size(); i++) { gltfModel.addNodeModel(new DefaultNodeModel()); } } @@ -459,23 +545,19 @@ private void createNodeModels() /** * Create the {@link SceneModel} instances */ - private void createSceneModels() - { + private void createSceneModels() { Map scenes = Optionals.of(gltf.getScenes()); - for (int i = 0; i < scenes.size(); i++) - { + for (int i = 0; i < scenes.size(); i++) { gltfModel.addSceneModel(new DefaultSceneModel()); } } - + /** * Create the {@link SkinModel} instances */ - private void createSkinModels() - { + private void createSkinModels() { Map skins = Optionals.of(gltf.getSkins()); - for (Entry entry : skins.entrySet()) - { + for (Entry entry : skins.entrySet()) { Skin skin = entry.getValue(); float[] bindShapeMatrix = skin.getBindShapeMatrix(); DefaultSkinModel skinModel = new DefaultSkinModel(); @@ -487,25 +569,23 @@ private void createSkinModels() /** * Create the {@link TextureModel} instances */ - private void createTextureModels() - { + private void createTextureModels() { Map textures = Optionals.of(gltf.getTextures()); Map samplers = Optionals.of(gltf.getSamplers()); - for (Entry entry : textures.entrySet()) - { + for (Entry entry : textures.entrySet()) { Texture texture = entry.getValue(); String samplerId = texture.getSampler(); Sampler sampler = samplers.get(samplerId); - + int magFilter = Optionals.of( - sampler.getMagFilter(), sampler.defaultMagFilter()); + sampler.getMagFilter(), sampler.defaultMagFilter()); int minFilter = Optionals.of( - sampler.getMinFilter(), sampler.defaultMinFilter()); + sampler.getMinFilter(), sampler.defaultMinFilter()); int wrapS = Optionals.of( - sampler.getWrapS(), sampler.defaultWrapS()); + sampler.getWrapS(), sampler.defaultWrapS()); int wrapT = Optionals.of( - sampler.getWrapT(), sampler.defaultWrapT()); - + sampler.getWrapT(), sampler.defaultWrapT()); + DefaultTextureModel textureModel = new DefaultTextureModel(); textureModel.setMagFilter(magFilter); textureModel.setMinFilter(minFilter); @@ -514,28 +594,23 @@ private void createTextureModels() gltfModel.addTextureModel(textureModel); } } - + /** * Create the {@link ShaderModel} instances */ - private void createShaderModels() - { + private void createShaderModels() { Map shaders = Optionals.of(gltf.getShaders()); - for (Entry entry : shaders.entrySet()) - { + for (Entry entry : shaders.entrySet()) { Shader shader = entry.getValue(); Integer type = shader.getType(); ShaderType shaderType = null; - if (type == GltfConstants.GL_VERTEX_SHADER) - { + if (type == GltfConstants.GL_VERTEX_SHADER) { shaderType = ShaderType.VERTEX_SHADER; - } - else - { + } else { shaderType = ShaderType.FRAGMENT_SHADER; } DefaultShaderModel shaderModel = - new DefaultShaderModel(shader.getUri(), shaderType); + new DefaultShaderModel(shader.getUri(), shaderType); gltfModel.addShaderModel(shaderModel); } } @@ -543,46 +618,39 @@ private void createShaderModels() /** * Create the {@link ProgramModel} instances */ - private void createProgramModels() - { + private void createProgramModels() { Map programs = Optionals.of(gltf.getPrograms()); - for (int i = 0; i < programs.size(); i++) - { + for (int i = 0; i < programs.size(); i++) { gltfModel.addProgramModel(new DefaultProgramModel()); } } - + /** * Create the {@link TechniqueModel} instances */ - private void createTechniqueModels() - { + private void createTechniqueModels() { Map techniques = Optionals.of(gltf.getTechniques()); - for (int i = 0; i < techniques.size(); i++) - { + for (int i = 0; i < techniques.size(); i++) { gltfModel.addTechniqueModel(new DefaultTechniqueModel()); } } - /** * Initialize the {@link AccessorModel} instances */ - private void initAccessorModels() - { + private void initAccessorModels() { Map accessors = Optionals.of(gltf.getAccessors()); - for (Entry entry : accessors.entrySet()) - { + for (Entry entry : accessors.entrySet()) { String accessorId = entry.getKey(); Accessor accessor = entry.getValue(); String bufferViewId = accessor.getBufferView(); - BufferViewModel bufferViewModel = - get("bufferViews", bufferViewId, - gltfModel::getBufferViewModel); + BufferViewModel bufferViewModel = + get("bufferViews", bufferViewId, + gltfModel::getBufferViewModel); DefaultAccessorModel accessorModel = - get("accessors", accessorId, - gltfModel::getAccessorModel); - + get("accessors", accessorId, + gltfModel::getAccessorModel); + transferGltfChildOfRootPropertyElements(accessor, accessorModel); accessorModel.setBufferViewModel(bufferViewModel); accessorModel.setAccessorData(AccessorDatas.create(accessorModel)); @@ -592,433 +660,352 @@ private void initAccessorModels() /** * Initialize the {@link AnimationModel} instances */ - private void initAnimationModels() - { + private void initAnimationModels() { Map animations = Optionals.of(gltf.getAnimations()); - for (Entry entry : animations.entrySet()) - { + for (Entry entry : animations.entrySet()) { String animationId = entry.getKey(); Animation animation = entry.getValue(); DefaultAnimationModel animationModel = - get("animations", animationId, - gltfModel::getAnimationModel); + get("animations", animationId, + gltfModel::getAnimationModel); transferGltfChildOfRootPropertyElements(animation, animationModel); - List channels = - Optionals.of(animation.getChannels()); - for (AnimationChannel animationChannel : channels) - { + List channels = + Optionals.of(animation.getChannels()); + for (AnimationChannel animationChannel : channels) { Channel channel = createChannel(animation, animationChannel); animationModel.addChannel(channel); } } } - + /** * Initialize the {@link ImageModel} instances */ - private void initImageModels() - { + private void initImageModels() { Map images = Optionals.of(gltf.getImages()); - for (Entry entry : images.entrySet()) - { + for (Entry entry : images.entrySet()) { String imageId = entry.getKey(); Image image = entry.getValue(); DefaultImageModel imageModel = - get("images", imageId, gltfModel::getImageModel); + get("images", imageId, gltfModel::getImageModel); transferGltfChildOfRootPropertyElements(image, imageModel); - + Object extras = image.getExtras(); - if(extras != null) { - JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); - if(extra != null) { - imageModel.setImageData(MCglTF.getInstance().getImageResource(new ResourceLocation(extra.getAsString()))); - continue; - } - } - - if (BinaryGltfV1.hasBinaryGltfExtension(image)) - { - String bufferViewId = - BinaryGltfV1.getBinaryGltfBufferViewId(image); + if (extras != null) { + JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); + if (extra != null) { + imageModel.setImageData(MCglTF.getInstance().getImageResource(new ResourceLocation(extra.getAsString()))); + continue; + } + } + + if (BinaryGltfV1.hasBinaryGltfExtension(image)) { + String bufferViewId = + BinaryGltfV1.getBinaryGltfBufferViewId(image); BufferViewModel bufferViewModel = - get("bufferViews", bufferViewId, - gltfModel::getBufferViewModel); + get("bufferViews", bufferViewId, + gltfModel::getBufferViewModel); imageModel.setBufferViewModel(bufferViewModel); - } - else - { + } else { String uri = image.getUri(); - if (IO.isDataUriString(uri)) - { + if (IO.isDataUriString(uri)) { byte data[] = IO.readDataUri(uri); ByteBuffer imageData = Buffers.create(data); imageModel.setImageData(imageData); - } - else - { + } else { ByteBuffer imageData = gltfAsset.getReferenceData(uri); imageModel.setImageData(imageData); } } } } - + /** * Create the {@link Channel} object for the given animation and animation * channel - * - * @param animation The {@link Animation} + * + * @param animation The {@link Animation} * @param animationChannel The {@link AnimationChannel} * @return The {@link Channel} */ private Channel createChannel( - Animation animation, AnimationChannel animationChannel) - { - Map parameters = - Optionals.of(animation.getParameters()); - Map samplers = - Optionals.of(animation.getSamplers()); + Animation animation, AnimationChannel animationChannel) { + Map parameters = + Optionals.of(animation.getParameters()); + Map samplers = + Optionals.of(animation.getSamplers()); String samplerId = animationChannel.getSampler(); AnimationSampler animationSampler = samplers.get(samplerId); - + String inputParameterId = animationSampler.getInput(); String inputAccessorId = parameters.get(inputParameterId); - if (inputAccessorId == null) - { - // This was valid for a short time, when glTF 2.0 was still - // called glTF 1.1. The check here is not perfectly reliable, - // but there should be a decreasing number of glTF 1.0 models + if (inputAccessorId == null) { + // This was valid for a short time, when glTF 2.0 was still + // called glTF 1.1. The check here is not perfectly reliable, + // but there should be a decreasing number of glTF 1.0 models // out there, and even fewer glTF 1.1 ones. logger.warning( - "Assuming " + inputParameterId + " to be an accessor ID"); + "Assuming " + inputParameterId + " to be an accessor ID"); inputAccessorId = inputParameterId; } - AccessorModel inputAccessorModel = - get("accessors", inputAccessorId, gltfModel::getAccessorModel); - + AccessorModel inputAccessorModel = + get("accessors", inputAccessorId, gltfModel::getAccessorModel); + String outputParameterId = animationSampler.getOutput(); String outputAccessorId = parameters.get(outputParameterId); - if (outputAccessorId == null) - { - // This was valid for a short time, when glTF 2.0 was still - // called glTF 1.1. The check here is not perfectly reliable, - // but there should be a decreasing number of glTF 1.0 models + if (outputAccessorId == null) { + // This was valid for a short time, when glTF 2.0 was still + // called glTF 1.1. The check here is not perfectly reliable, + // but there should be a decreasing number of glTF 1.0 models // out there, and even fewer glTF 1.1 ones. logger.warning( - "Assuming " + outputParameterId + " to be an accessor ID"); + "Assuming " + outputParameterId + " to be an accessor ID"); outputAccessorId = outputParameterId; } - AccessorModel outputAccessorModel = - get("accessors", outputAccessorId, gltfModel::getAccessorModel); - - String interpolationString = - animationSampler.getInterpolation(); - Interpolation interpolation = - interpolationString == null ? Interpolation.LINEAR : - Interpolation.valueOf(interpolationString); - + AccessorModel outputAccessorModel = + get("accessors", outputAccessorId, gltfModel::getAccessorModel); + + String interpolationString = + animationSampler.getInterpolation(); + Interpolation interpolation = + interpolationString == null ? Interpolation.LINEAR : + Interpolation.valueOf(interpolationString); + AnimationModel.Sampler sampler = new DefaultSampler( - inputAccessorModel, interpolation, outputAccessorModel); - - AnimationChannelTarget animationChannelTarget = - animationChannel.getTarget(); + inputAccessorModel, interpolation, outputAccessorModel); + + AnimationChannelTarget animationChannelTarget = + animationChannel.getTarget(); String nodeId = animationChannelTarget.getId(); String path = animationChannelTarget.getPath(); - + NodeModel nodeModel = get("nodes", nodeId, gltfModel::getNodeModel); - - AnimationModel.Channel channel = - new DefaultChannel(sampler, nodeModel, path); + + Channel channel = + new DefaultChannel(sampler, nodeModel, path); return channel; } /** * Initialize the {@link BufferModel} instances */ - private void initBufferModels() - { + private void initBufferModels() { ByteBuffer binaryData = null; ByteBuffer b = gltfAsset.getBinaryData(); - if (b != null && b.capacity() > 0) - { + if (b != null && b.capacity() > 0) { binaryData = b; } - + Map buffers = Optionals.of(gltf.getBuffers()); - for (Entry entry : buffers.entrySet()) - { + for (Entry entry : buffers.entrySet()) { String bufferId = entry.getKey(); Buffer buffer = entry.getValue(); - DefaultBufferModel bufferModel = - get("buffers", bufferId, gltfModel::getBufferModel); + DefaultBufferModel bufferModel = + get("buffers", bufferId, gltfModel::getBufferModel); transferGltfChildOfRootPropertyElements(buffer, bufferModel); - + Object extras = buffer.getExtras(); - if(extras != null) { - JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); - if(extra != null) { - bufferModel.setBufferData(MCglTF.getInstance().getBufferResource(new ResourceLocation(extra.getAsString()))); - continue; - } - } - - if (BinaryGltfV1.isBinaryGltfBufferId(bufferId)) - { - if (binaryData == null) - { + if (extras != null) { + JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); + if (extra != null) { + bufferModel.setBufferData(MCglTF.getInstance().getBufferResource(new ResourceLocation(extra.getAsString()))); + continue; + } + } + + if (BinaryGltfV1.isBinaryGltfBufferId(bufferId)) { + if (binaryData == null) { logger.severe("The glTF contains a buffer with the binary" - + " buffer ID, but no binary data has been given"); + + " buffer ID, but no binary data has been given"); continue; } bufferModel.setBufferData(binaryData); - } - else - { + } else { String uri = buffer.getUri(); - if (IO.isDataUriString(uri)) - { + if (IO.isDataUriString(uri)) { byte data[] = IO.readDataUri(uri); ByteBuffer bufferData = Buffers.create(data); bufferModel.setBufferData(bufferData); - } - else - { + } else { ByteBuffer bufferData = gltfAsset.getReferenceData(uri); bufferModel.setBufferData(bufferData); } } } } - - + /** * Initialize the {@link BufferViewModel} instances */ - private void initBufferViewModels() - { - Map bufferViews = - Optionals.of(gltf.getBufferViews()); - for (Entry entry : bufferViews.entrySet()) - { + private void initBufferViewModels() { + Map bufferViews = + Optionals.of(gltf.getBufferViews()); + for (Entry entry : bufferViews.entrySet()) { String bufferViewId = entry.getKey(); BufferView bufferView = entry.getValue(); - + String bufferId = bufferView.getBuffer(); - BufferModel bufferModel = - get("buffers", bufferId, gltfModel::getBufferModel); - DefaultBufferViewModel bufferViewModel = - get("bufferViews", bufferViewId, gltfModel::getBufferViewModel); + BufferModel bufferModel = + get("buffers", bufferId, gltfModel::getBufferModel); + DefaultBufferViewModel bufferViewModel = + get("bufferViews", bufferViewId, gltfModel::getBufferViewModel); transferGltfChildOfRootPropertyElements( - bufferView, bufferViewModel); + bufferView, bufferViewModel); bufferViewModel.setBufferModel(bufferModel); } } - + /** * Compute all {@link AccessorModel} instances that refer to the * given {@link BufferViewModel} - * + * * @param bufferViewModel The {@link BufferViewModel} * @return The list of {@link AccessorModel} instances */ private List computeAccessorModelsOf( - BufferViewModel bufferViewModel) - { - List result = - new ArrayList(); + BufferViewModel bufferViewModel) { + List result = + new ArrayList(); int n = gltfModel.getAccessorModels().size(); - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { DefaultAccessorModel accessorModel = gltfModel.getAccessorModel(i); BufferViewModel b = accessorModel.getBufferViewModel(); - if (bufferViewModel.equals(b)) - { + if (bufferViewModel.equals(b)) { result.add(accessorModel); } } return result; } - - /** - * Computes the {@link AccessorModel#getByteStride() byte stride} of - * the given {@link AccessorModel} instances. If the given instances - * do not have the same byte stride, then a warning will be printed. - * - * @param accessorModels The {@link AccessorModel} instances - * @return The common byte stride - */ - private static int computeCommonByteStride( - Iterable accessorModels) - { - int commonByteStride = -1; - for (AccessorModel accessorModel : accessorModels) - { - int byteStride = accessorModel.getByteStride(); - if (commonByteStride == -1) - { - commonByteStride = byteStride; - } - else - { - if (commonByteStride != byteStride) - { - logger.warning("The accessor models do not have the " - + "same byte stride: " + commonByteStride - + " and " + byteStride); - } - } - } - return commonByteStride; - } - /** * Set the {@link BufferViewModel#getByteStride() byte strides} of all - * {@link BufferViewModel} instances, depending on the + * {@link BufferViewModel} instances, depending on the * {@link AccessorModel} instances that refer to them */ - private void assignBufferViewByteStrides() - { + private void assignBufferViewByteStrides() { int n = gltfModel.getBufferModels().size(); - for (int i = 0; i < n; i++) - { - DefaultBufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(i); - List accessorModelsOfBufferView = - computeAccessorModelsOf(bufferViewModel); - if (accessorModelsOfBufferView.size() > 1) - { - int byteStride = - computeCommonByteStride(accessorModelsOfBufferView); + for (int i = 0; i < n; i++) { + DefaultBufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(i); + List accessorModelsOfBufferView = + computeAccessorModelsOf(bufferViewModel); + if (accessorModelsOfBufferView.size() > 1) { + int byteStride = + computeCommonByteStride(accessorModelsOfBufferView); bufferViewModel.setByteStride(byteStride); } } } - + /** * Initialize the {@link MeshModel} instances */ - private void initMeshModels() - { - Map meshes = - Optionals.of(gltf.getMeshes()); - for (Entry entry : meshes.entrySet()) - { + private void initMeshModels() { + Map meshes = + Optionals.of(gltf.getMeshes()); + for (Entry entry : meshes.entrySet()) { String meshId = entry.getKey(); Mesh mesh = entry.getValue(); - List primitives = - Optionals.of(mesh.getPrimitives()); - DefaultMeshModel meshModel = - get("meshes", meshId, gltfModel::getMeshModel); + List primitives = + Optionals.of(mesh.getPrimitives()); + DefaultMeshModel meshModel = + get("meshes", meshId, gltfModel::getMeshModel); transferGltfChildOfRootPropertyElements(mesh, meshModel); - for (MeshPrimitive meshPrimitive : primitives) - { - MeshPrimitiveModel meshPrimitiveModel = - createMeshPrimitiveModel(meshPrimitive); + for (MeshPrimitive meshPrimitive : primitives) { + MeshPrimitiveModel meshPrimitiveModel = + createMeshPrimitiveModel(meshPrimitive); meshModel.addMeshPrimitiveModel(meshPrimitiveModel); } } } - + /** * Create a {@link MeshPrimitiveModel} for the given {@link MeshPrimitive} - * + * * @param meshPrimitive The {@link MeshPrimitive} * @return The {@link MeshPrimitiveModel} */ private DefaultMeshPrimitiveModel createMeshPrimitiveModel( - MeshPrimitive meshPrimitive) - { + MeshPrimitive meshPrimitive) { Integer mode = Optionals.of( - meshPrimitive.getMode(), - meshPrimitive.defaultMode()); - DefaultMeshPrimitiveModel meshPrimitiveModel = - new DefaultMeshPrimitiveModel(mode); + meshPrimitive.getMode(), + meshPrimitive.defaultMode()); + DefaultMeshPrimitiveModel meshPrimitiveModel = + new DefaultMeshPrimitiveModel(mode); transferGltfPropertyElements(meshPrimitive, meshPrimitiveModel); - + String indicesId = meshPrimitive.getIndices(); - if (indicesId != null) - { - AccessorModel indices = - get("accessors", indicesId, gltfModel::getAccessorModel); + if (indicesId != null) { + AccessorModel indices = + get("accessors", indicesId, gltfModel::getAccessorModel); meshPrimitiveModel.setIndices(indices); } - Map attributes = - Optionals.of(meshPrimitive.getAttributes()); - for (Entry entry : attributes.entrySet()) - { + Map attributes = + Optionals.of(meshPrimitive.getAttributes()); + for (Entry entry : attributes.entrySet()) { String attributeName = entry.getKey(); String attributeId = entry.getValue(); - - AccessorModel attribute = - get("accessors", attributeId, gltfModel::getAccessorModel); + + AccessorModel attribute = + get("accessors", attributeId, gltfModel::getAccessorModel); meshPrimitiveModel.putAttribute(attributeName, attribute); } - + String materialId = meshPrimitive.getMaterial(); if (materialId == null || - GltfDefaults.isDefaultMaterialId(materialId)) - { + GltfDefaults.isDefaultMaterialId(materialId)) { meshPrimitiveModel.setMaterialModel( - DefaultModels.getDefaultMaterialModel()); - } - else - { - MaterialModel materialModel = - get("materials", materialId, gltfModel::getMaterialModel); + DefaultModels.getDefaultMaterialModel()); + } else { + MaterialModel materialModel = + get("materials", materialId, gltfModel::getMaterialModel); meshPrimitiveModel.setMaterialModel(materialModel); } - + return meshPrimitiveModel; } /** * Initialize the {@link NodeModel} instances */ - private void initNodeModels() - { + private void initNodeModels() { Map nodes = Optionals.of(gltf.getNodes()); - for (Entry entry : nodes.entrySet()) - { + for (Entry entry : nodes.entrySet()) { String nodeId = entry.getKey(); Node node = entry.getValue(); - - DefaultNodeModel nodeModel = - get("nodes", nodeId, gltfModel::getNodeModel); + + DefaultNodeModel nodeModel = + get("nodes", nodeId, gltfModel::getNodeModel); transferGltfChildOfRootPropertyElements(node, nodeModel); - + List childIds = Optionals.of(node.getChildren()); - for (String childId : childIds) - { - DefaultNodeModel child = - get("nodes", childId, gltfModel::getNodeModel); + for (String childId : childIds) { + DefaultNodeModel child = + get("nodes", childId, gltfModel::getNodeModel); nodeModel.addChild(child); } List meshIds = Optionals.of(node.getMeshes()); - for (String meshId : meshIds) - { - MeshModel meshModel = - get("meshes", meshId, gltfModel::getMeshModel); + for (String meshId : meshIds) { + MeshModel meshModel = + get("meshes", meshId, gltfModel::getMeshModel); nodeModel.addMeshModel(meshModel); } String skinId = node.getSkin(); - if (skinId != null) - { - SkinModel skinModel = - get("skins", skinId, gltfModel::getSkinModel); + if (skinId != null) { + SkinModel skinModel = + get("skins", skinId, gltfModel::getSkinModel); nodeModel.setSkinModel(skinModel); } String cameraId = node.getCamera(); - if (cameraId != null) - { - CameraModel cameraModel = - get("cameras", cameraId, gltfModel::getCameraModel); + if (cameraId != null) { + CameraModel cameraModel = + get("cameras", cameraId, gltfModel::getCameraModel); nodeModel.setCameraModel(cameraModel); } - + float matrix[] = node.getMatrix(); float translation[] = node.getTranslation(); float rotation[] = node.getRotation(); @@ -1029,503 +1016,266 @@ private void initNodeModels() nodeModel.setScale(Optionals.clone(scale)); } } - + /** * Initialize the {@link SceneModel} instances */ - private void initSceneModels() - { + private void initSceneModels() { Map scenes = Optionals.of(gltf.getScenes()); - for (Entry entry : scenes.entrySet()) - { + for (Entry entry : scenes.entrySet()) { String sceneId = entry.getKey(); Scene scene = entry.getValue(); DefaultSceneModel sceneModel = - get("scenes", sceneId, gltfModel::getSceneModel); + get("scenes", sceneId, gltfModel::getSceneModel); transferGltfChildOfRootPropertyElements(scene, sceneModel); - + List nodes = Optionals.of(scene.getNodes()); - for (String nodeId : nodes) - { - NodeModel nodeModel = - get("nodes", nodeId, gltfModel::getNodeModel); + for (String nodeId : nodes) { + NodeModel nodeModel = + get("nodes", nodeId, gltfModel::getNodeModel); sceneModel.addNode(nodeModel); } } } - - /** - * Compute the mapping from joint names to the ID of the {@link Node} with - * the respective {@link Node#getJointName() joint name} - * - * @param gltf The {@link GlTF} - * @return The mapping - */ - private static Map computeJointNameToNodeIdMap(GlTF gltf) - { - Map map = new LinkedHashMap(); - Map nodes = Optionals.of(gltf.getNodes()); - for (Entry entry : nodes.entrySet()) - { - String nodeId = entry.getKey(); - Node node = entry.getValue(); - if (node.getJointName() != null) - { - String oldNodeId = map.put(node.getJointName(), nodeId); - if (oldNodeId != null) - { - logger.warning("Joint name " + node.getJointName() - + " is mapped to nodes with IDs " + nodeId + " and " - + oldNodeId); - } - } - } - return map; - } /** * Initialize the {@link SkinModel} instances */ - private void initSkinModels() - { - Map jointNameToNodeIdMap = - computeJointNameToNodeIdMap(gltf); + private void initSkinModels() { + Map jointNameToNodeIdMap = + computeJointNameToNodeIdMap(gltf); Map skins = Optionals.of(gltf.getSkins()); - for (Entry entry : skins.entrySet()) - { + for (Entry entry : skins.entrySet()) { String skinId = entry.getKey(); Skin skin = entry.getValue(); - DefaultSkinModel skinModel = - get("skins", skinId, gltfModel::getSkinModel); + DefaultSkinModel skinModel = + get("skins", skinId, gltfModel::getSkinModel); transferGltfChildOfRootPropertyElements(skin, skinModel); - + List jointNames = skin.getJointNames(); - for (String jointName : jointNames) - { + for (String jointName : jointNames) { String nodeId = jointNameToNodeIdMap.get(jointName); - NodeModel nodeModel = - get("nodes", nodeId, gltfModel::getNodeModel); + NodeModel nodeModel = + get("nodes", nodeId, gltfModel::getNodeModel); skinModel.addJoint(nodeModel); } - + String inverseBindMatricesId = skin.getInverseBindMatrices(); AccessorModel inverseBindMatrices = - get("accessors", inverseBindMatricesId, - gltfModel::getAccessorModel); + get("accessors", inverseBindMatricesId, + gltfModel::getAccessorModel); skinModel.setInverseBindMatrices(inverseBindMatrices); } } - + /** * Initialize the {@link TextureModel} instances */ - private void initTextureModels() - { + private void initTextureModels() { Map textures = Optionals.of(gltf.getTextures()); - for (Entry entry : textures.entrySet()) - { + for (Entry entry : textures.entrySet()) { String textureId = entry.getKey(); Texture texture = entry.getValue(); - DefaultTextureModel textureModel = - get("textures", textureId, gltfModel::getTextureModel); + DefaultTextureModel textureModel = + get("textures", textureId, gltfModel::getTextureModel); transferGltfChildOfRootPropertyElements(texture, textureModel); - + String imageId = texture.getSource(); - DefaultImageModel imageModel = - get("images", imageId, gltfModel::getImageModel); + DefaultImageModel imageModel = + get("images", imageId, gltfModel::getImageModel); textureModel.setImageModel(imageModel); } } - + /** * Initialize the {@link ShaderModel} instances */ - private void initShaderModels() - { + private void initShaderModels() { Map shaders = Optionals.of(gltf.getShaders()); - for (Entry entry : shaders.entrySet()) - { + for (Entry entry : shaders.entrySet()) { String shaderId = entry.getKey(); Shader shader = entry.getValue(); - DefaultShaderModel shaderModel = - get("shaders", shaderId, gltfModel::getShaderModel); + DefaultShaderModel shaderModel = + get("shaders", shaderId, gltfModel::getShaderModel); transferGltfChildOfRootPropertyElements(shader, shaderModel); - - if (BinaryGltfV1.hasBinaryGltfExtension(shader)) - { - String bufferViewId = - BinaryGltfV1.getBinaryGltfBufferViewId(shader); + + if (BinaryGltfV1.hasBinaryGltfExtension(shader)) { + String bufferViewId = + BinaryGltfV1.getBinaryGltfBufferViewId(shader); BufferViewModel bufferViewModel = - get("bufferViews", bufferViewId, - gltfModel::getBufferViewModel); - + get("bufferViews", bufferViewId, + gltfModel::getBufferViewModel); + shaderModel.setShaderData(bufferViewModel.getBufferViewData()); - } - else - { + } else { String uri = shader.getUri(); - if (IO.isDataUriString(uri)) - { + if (IO.isDataUriString(uri)) { byte data[] = IO.readDataUri(uri); ByteBuffer shaderData = Buffers.create(data); shaderModel.setShaderData(shaderData); - } - else - { + } else { ByteBuffer shaderData = gltfAsset.getReferenceData(uri); shaderModel.setShaderData(shaderData); } } } } - + /** * Initialize the {@link ProgramModel} instances */ - void initProgramModels() - { + void initProgramModels() { Map programs = Optionals.of(gltf.getPrograms()); - for (Entry entry : programs.entrySet()) - { + for (Entry entry : programs.entrySet()) { String programId = entry.getKey(); Program program = entry.getValue(); - DefaultProgramModel programModel = - get("programs", programId, gltfModel::getProgramModel); + DefaultProgramModel programModel = + get("programs", programId, gltfModel::getProgramModel); transferGltfChildOfRootPropertyElements(program, programModel); - + String vertexShaderId = program.getVertexShader(); DefaultShaderModel vertexShaderModel = - get("shaders", vertexShaderId, gltfModel::getShaderModel); + get("shaders", vertexShaderId, gltfModel::getShaderModel); programModel.setVertexShaderModel(vertexShaderModel); - + String fragmentShaderId = program.getFragmentShader(); DefaultShaderModel fragmentShaderModel = - get("shaders", fragmentShaderId, gltfModel::getShaderModel); + get("shaders", fragmentShaderId, gltfModel::getShaderModel); programModel.setFragmentShaderModel(fragmentShaderModel); - + List attributes = Optionals.of(program.getAttributes()); - for (String attribute : attributes) - { + for (String attribute : attributes) { programModel.addAttribute(attribute); } } } - - /** - * Add all {@link TechniqueParametersModel} instances for the - * attributes of the given {@link Technique} to the given - * {@link TechniqueModel} - * - * @param technique The {@link Technique} - * @param techniqueModel The {@link TechniqueModel} - * @param nodeLookup The function for looking up the {@link NodeModel} - * for a given node ID. This may be null, but if its is - * null and there is a non-null node ID - * in the technique parameters, then an error message will be - * printed. - */ - private static void addParameters(Technique technique, - DefaultTechniqueModel techniqueModel, - Function nodeLookup) - { - Map parameters = - Optionals.of(technique.getParameters()); - for (Entry entry : parameters.entrySet()) - { - String parameterName = entry.getKey(); - TechniqueParameters parameter = entry.getValue(); - - int type = parameter.getType(); - int count = Optionals.of(parameter.getCount(), 1); - String semantic = parameter.getSemantic(); - Object value = parameter.getValue(); - String nodeId = parameter.getNode(); - NodeModel nodeModel = null; - if (nodeId != null) - { - if (nodeLookup == null) - { - logger.severe("No lookup function found for the nodes"); - } - else - { - nodeModel = nodeLookup.apply(nodeId); - } - } - - TechniqueParametersModel techniqueParametersModel = - new DefaultTechniqueParametersModel( - type, count, semantic, value, nodeModel); - techniqueModel.addParameter( - parameterName, techniqueParametersModel); - } - } - - /** - * Add all attribute entries of the given {@link Technique} to the given - * {@link TechniqueModel} - * - * @param technique The {@link Technique} - * @param techniqueModel The {@link TechniqueModel} - */ - private static void addAttributes(Technique technique, - DefaultTechniqueModel techniqueModel) - { - Map attributes = - Optionals.of(technique.getAttributes()); - for (Entry entry : attributes.entrySet()) - { - String attributeName = entry.getKey(); - String parameterName = entry.getValue(); - techniqueModel.addAttribute(attributeName, parameterName); - } - } - - /** - * Add all uniform entries of the given {@link Technique} to the given - * {@link TechniqueModel} - * - * @param technique The {@link Technique} - * @param techniqueModel The {@link TechniqueModel} - */ - private static void addUniforms(Technique technique, - DefaultTechniqueModel techniqueModel) - { - Map uniforms = - Optionals.of(technique.getUniforms()); - for (Entry entry : uniforms.entrySet()) - { - String uniformName = entry.getKey(); - String parameterName = entry.getValue(); - techniqueModel.addUniform(uniformName, parameterName); - } - } - - /** * Initialize the {@link TechniqueModel} instances */ - private void initTechniqueModels() - { + private void initTechniqueModels() { Map techniques = Optionals.of(gltf.getTechniques()); - for (Entry entry : techniques.entrySet()) - { + for (Entry entry : techniques.entrySet()) { String techniqueId = entry.getKey(); Technique technique = entry.getValue(); - - DefaultTechniqueModel techniqueModel = - get("techniques", techniqueId, gltfModel::getTechniqueModel); - + + DefaultTechniqueModel techniqueModel = + get("techniques", techniqueId, gltfModel::getTechniqueModel); + String programId = technique.getProgram(); - DefaultProgramModel programModel = - get("programs", programId, gltfModel::getProgramModel); + DefaultProgramModel programModel = + get("programs", programId, gltfModel::getProgramModel); techniqueModel.setProgramModel(programModel); - Function nodeLookup = nodeId -> - get("nodes", nodeId, gltfModel::getNodeModel); - + Function nodeLookup = nodeId -> + get("nodes", nodeId, gltfModel::getNodeModel); + initTechniqueModel(techniqueModel, technique, nodeLookup); - - } - } - /** - * Initialize the given {@link TechniqueModel} with the values that are - * obtained from the given {@link Technique} - * - * @param techniqueModel The {@link TechniqueModel} - * @param technique The {@link Technique} - * @param nodeLookup The function for looking up the {@link NodeModel} - * for a given node ID. This may be null, but if its is - * null and there is a non-null node ID - * in the technique parameters, then an error message will be - * printed. - */ - public static void initTechniqueModel( - DefaultTechniqueModel techniqueModel, Technique technique, - Function nodeLookup) - { - transferGltfChildOfRootPropertyElements(technique, techniqueModel); - - addParameters(technique, techniqueModel, nodeLookup); - addAttributes(technique, techniqueModel); - addUniforms(technique, techniqueModel); - - List enableModel = null; - DefaultTechniqueStatesFunctionsModel techniqueStatesFunctionsModel = - null; - TechniqueStates states = technique.getStates(); - if (states != null) - { - List enable = states.getEnable(); - if (enable != null) - { - enableModel = new ArrayList(enable); - } - TechniqueStatesFunctions functions = states.getFunctions(); - if (functions != null) - { - techniqueStatesFunctionsModel = - TechniqueStatesFunctionsModels.create(functions); - } - - TechniqueStatesModel techniqueStatesModel = - new DefaultTechniqueStatesModel( - enableModel, techniqueStatesFunctionsModel); - techniqueModel.setTechniqueStatesModel(techniqueStatesModel); } } - - + /** * Initialize the {@link MaterialModel} instances */ - private void initMaterialModels() - { + private void initMaterialModels() { Map materials = Optionals.of(gltf.getMaterials()); - for (Entry entry : materials.entrySet()) - { + for (Entry entry : materials.entrySet()) { String materialId = entry.getKey(); Material material = entry.getValue(); - MaterialModelV1 materialModel = - (MaterialModelV1) get("materials", - materialId, gltfModel::getMaterialModel); - + MaterialModelV1 materialModel = + (MaterialModelV1) get("materials", + materialId, gltfModel::getMaterialModel); + transferGltfChildOfRootPropertyElements(material, materialModel); - + String techniqueId = material.getTechnique(); TechniqueModel techniqueModel; if (techniqueId == null || - GltfDefaults.isDefaultTechniqueId(techniqueId)) - { + GltfDefaults.isDefaultTechniqueId(techniqueId)) { techniqueModel = DefaultModels.getDefaultTechniqueModel(); - } - else - { + } else { techniqueModel = - get("techniques", techniqueId, - gltfModel::getTechniqueModel); + get("techniques", techniqueId, + gltfModel::getTechniqueModel); } materialModel.setTechniqueModel(techniqueModel); - - - Map modelValues = - new LinkedHashMap(); + + + Map modelValues = + new LinkedHashMap(); Map values = Optionals.of(material.getValues()); - for (Entry valueEntry : values.entrySet()) - { + for (Entry valueEntry : values.entrySet()) { String parameterName = valueEntry.getKey(); - TechniqueParametersModel techniqueParametersModel = - techniqueModel.getParameters().get(parameterName); + TechniqueParametersModel techniqueParametersModel = + techniqueModel.getParameters().get(parameterName); if (techniqueParametersModel != null && - techniqueParametersModel.getType() == - GltfConstants.GL_SAMPLER_2D) - { + techniqueParametersModel.getType() == + GltfConstants.GL_SAMPLER_2D) { TextureModel textureModel = null; Object value = valueEntry.getValue(); - if (value != null) - { + if (value != null) { String textureId = String.valueOf(value); - textureModel = get("textures", textureId, - gltfModel::getTextureModel); + textureModel = get("textures", textureId, + gltfModel::getTextureModel); } modelValues.put(parameterName, textureModel); - } - else - { + } else { modelValues.put(parameterName, valueEntry.getValue()); } } materialModel.setValues(modelValues); } } - + /** * Initialize the {@link ExtensionsModel} with the extensions that * are used in the glTF. */ - private void initExtensionsModel() - { + private void initExtensionsModel() { // Note that glTF 1.0 only had 'extensionsUsed', no 'extensionsRequired' List extensionsUsed = gltf.getExtensionsUsed(); DefaultExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); extensionsModel.addExtensionsUsed(extensionsUsed); } - + /** * Initialize the {@link AssetModel} with the asset information that * was given in the glTF. */ - private void initAssetModel() - { + private void initAssetModel() { Asset asset = gltf.getAsset(); - if (asset != null) - { + if (asset != null) { DefaultAssetModel assetModel = gltfModel.getAssetModel(); transferGltfPropertyElements(asset, assetModel); assetModel.setCopyright(asset.getCopyright()); assetModel.setGenerator(asset.getGenerator()); } } - - - /** - * Transfer the extensions and extras from the given property to - * the given target - * - * @param property The property - * @param modelElement The target - */ - private static void transferGltfPropertyElements( - GlTFProperty property, AbstractModelElement modelElement) - { - modelElement.setExtensions(property.getExtensions()); - modelElement.setExtras(property.getExtras()); - } - - /** - * Transfer the name and extensions and extras from the given property to - * the given target - * - * @param property The property - * @param modelElement The target - */ - private static void transferGltfChildOfRootPropertyElements( - GlTFChildOfRootProperty property, - AbstractNamedModelElement modelElement) - { - modelElement.setName(property.getName()); - transferGltfPropertyElements(property, modelElement); - } - - + /** - * Return the element from the given getter, based on the - * {@link #indexMappingSet} for the given name and ID. - * If the ID is null, then null is + * Return the element from the given getter, based on the + * {@link #indexMappingSet} for the given name and ID. + * If the ID is null, then null is * returned. If there is no proper index stored for the given * ID, then a warning will be printed and null * will be returned. - * - * @param The element type - * - * @param name The name - * @param id The ID + * + * @param The element type + * @param name The name + * @param id The ID * @param getter The getter * @return The element */ - private T get(String name, String id, IntFunction getter) - { + private T get(String name, String id, IntFunction getter) { Integer index = indexMappingSet.getIndex(name, id); - if (index == null) - { + if (index == null) { logger.severe("No index found for " + name + " ID " + id); return null; } T element = getter.apply(index); return element; } - + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfModelV1.java b/src/main/java/de/javagl/jgltf/model/v1/GltfModelV1.java index d51fe44..e2475b7 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfModelV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfModelV1.java @@ -26,12 +26,6 @@ */ package de.javagl.jgltf.model.v1; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Program; import de.javagl.jgltf.impl.v1.Shader; @@ -46,11 +40,12 @@ import de.javagl.jgltf.model.impl.DefaultGltfModel; import de.javagl.jgltf.model.io.v1.GltfAssetV1; +import java.util.*; + /** * Implementation of a {@link GltfModel}, based on a {@link GlTF glTF 1.0}.
    */ -public final class GltfModelV1 extends DefaultGltfModel implements GltfModel -{ +public final class GltfModelV1 extends DefaultGltfModel implements GltfModel { /** * The {@link ShaderModel} instances that have been created from * the {@link Shader} instances @@ -62,7 +57,7 @@ public final class GltfModelV1 extends DefaultGltfModel implements GltfModel * the {@link Program} instances */ private final List programModels; - + /** * The {@link TechniqueModel} instances that have been created from * the {@link Technique} instances @@ -71,63 +66,57 @@ public final class GltfModelV1 extends DefaultGltfModel implements GltfModel /** * Creates a new model for the given glTF - * + * * @param gltfAsset The {@link GltfAssetV1} */ - public GltfModelV1(GltfAssetV1 gltfAsset) - { - Objects.requireNonNull(gltfAsset, - "The gltfAsset may not be null"); + public GltfModelV1(GltfAssetV1 gltfAsset) { + Objects.requireNonNull(gltfAsset, + "The gltfAsset may not be null"); this.shaderModels = new ArrayList(); this.programModels = new ArrayList(); this.techniqueModels = new ArrayList(); - - GltfModelCreatorV1 gltfModelCreatorV1 = - new GltfModelCreatorV1(gltfAsset, this); + + GltfModelCreatorV1 gltfModelCreatorV1 = + new GltfModelCreatorV1(gltfAsset, this); gltfModelCreatorV1.create(); } - + /** * Creates a new, empty model */ - public GltfModelV1() - { + public GltfModelV1() { this.shaderModels = new ArrayList(); this.programModels = new ArrayList(); this.techniqueModels = new ArrayList(); } - + /** * Add the given {@link ShaderModel} to this model - * + * * @param shaderModel The instance to add */ - public void addShaderModel(DefaultShaderModel shaderModel) - { + public void addShaderModel(DefaultShaderModel shaderModel) { shaderModels.add(shaderModel); } /** * Remove the given {@link ShaderModel} from this model - * + * * @param shaderModel The instance to remove */ - public void removeShaderModel(DefaultShaderModel shaderModel) - { + public void removeShaderModel(DefaultShaderModel shaderModel) { shaderModels.remove(shaderModel); } /** * Add the given {@link ShaderModel} instances to this model - * + * * @param shaderModels The instances to add */ public void addShaderModels( - Collection shaderModels) - { - for (DefaultShaderModel shaderModel : shaderModels) - { + Collection shaderModels) { + for (DefaultShaderModel shaderModel : shaderModels) { addShaderModel(shaderModel); } } @@ -138,60 +127,53 @@ public void addShaderModels( * @param index The index * @return The {@link ShaderModel} */ - public DefaultShaderModel getShaderModel(int index) - { + public DefaultShaderModel getShaderModel(int index) { return shaderModels.get(index); } /** * Remove all {@link ShaderModel} instances */ - public void clearShaderModels() - { + public void clearShaderModels() { shaderModels.clear(); } - + /** - * Returns an unmodifiable view on the list of {@link ShaderModel} + * Returns an unmodifiable view on the list of {@link ShaderModel} * instances that have been created for the glTF. - * + * * @return The {@link ShaderModel} instances */ - public List getShaderModels() - { + public List getShaderModels() { return Collections.unmodifiableList(shaderModels); } /** * Add the given {@link ProgramModel} to this model - * + * * @param programModel The instance to add */ - public void addProgramModel(DefaultProgramModel programModel) - { + public void addProgramModel(DefaultProgramModel programModel) { programModels.add(programModel); } /** * Remove the given {@link ProgramModel} from this model - * + * * @param programModel The instance to remove */ - public void removeProgramModel(DefaultProgramModel programModel) - { + public void removeProgramModel(DefaultProgramModel programModel) { programModels.remove(programModel); } /** * Add the given {@link ProgramModel} instances to this model - * + * * @param programModels The instances to add */ public void addProgramModels( - Collection programModels) - { - for (DefaultProgramModel programModel : programModels) - { + Collection programModels) { + for (DefaultProgramModel programModel : programModels) { addProgramModel(programModel); } } @@ -202,61 +184,54 @@ public void addProgramModels( * @param index The index * @return The {@link ProgramModel} */ - public DefaultProgramModel getProgramModel(int index) - { + public DefaultProgramModel getProgramModel(int index) { return programModels.get(index); } /** * Remove all {@link ProgramModel} instances */ - public void clearProgramModels() - { + public void clearProgramModels() { programModels.clear(); } - + /** - * Returns an unmodifiable view on the list of {@link ProgramModel} + * Returns an unmodifiable view on the list of {@link ProgramModel} * instances that have been created for the glTF. - * + * * @return The {@link ProgramModel} instances */ - public List getProgramModels() - { + public List getProgramModels() { return Collections.unmodifiableList(programModels); } - - + + /** * Add the given {@link TechniqueModel} to this model - * + * * @param techniqueModel The instance to add */ - public void addTechniqueModel(DefaultTechniqueModel techniqueModel) - { + public void addTechniqueModel(DefaultTechniqueModel techniqueModel) { techniqueModels.add(techniqueModel); } /** * Remove the given {@link TechniqueModel} from this model - * + * * @param techniqueModel The instance to remove */ - public void removeTechniqueModel(DefaultTechniqueModel techniqueModel) - { + public void removeTechniqueModel(DefaultTechniqueModel techniqueModel) { techniqueModels.remove(techniqueModel); } /** * Add the given {@link TechniqueModel} instances to this model - * + * * @param techniqueModels The instances to add */ public void addTechniqueModels( - Collection techniqueModels) - { - for (DefaultTechniqueModel techniqueModel : techniqueModels) - { + Collection techniqueModels) { + for (DefaultTechniqueModel techniqueModel : techniqueModels) { addTechniqueModel(techniqueModel); } } @@ -267,28 +242,25 @@ public void addTechniqueModels( * @param index The index * @return The {@link TechniqueModel} */ - public DefaultTechniqueModel getTechniqueModel(int index) - { + public DefaultTechniqueModel getTechniqueModel(int index) { return techniqueModels.get(index); } /** * Remove all {@link TechniqueModel} instances */ - public void clearTechniqueModels() - { + public void clearTechniqueModels() { techniqueModels.clear(); } - + /** - * Returns an unmodifiable view on the list of {@link TechniqueModel} + * Returns an unmodifiable view on the list of {@link TechniqueModel} * instances that have been created for the glTF. - * + * * @return The {@link TechniqueModel} instances */ - public List getTechniqueModels() - { + public List getTechniqueModels() { return Collections.unmodifiableList(techniqueModels); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSet.java b/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSet.java index 8ec230a..e1a43ab 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSet.java +++ b/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSet.java @@ -33,68 +33,61 @@ * Helper class storing a set of index mappings, identified via names. * Each index mapping maps string IDs to integer values. */ -final class IndexMappingSet -{ +final class IndexMappingSet { /** * The index mappings */ private final Map> indexMappings; - + /** * Default constructor */ - IndexMappingSet() - { - indexMappings = new LinkedHashMap>(); + IndexMappingSet() { + indexMappings = new LinkedHashMap>(); } - + /** * Return the index mapping for the given name, creating it if necessary - * + * * @param name The name * @return The index mapping */ - private Map get(Object name) - { - Map indexMapping = - indexMappings.computeIfAbsent(name, - n -> new LinkedHashMap()); + private Map get(Object name) { + Map indexMapping = + indexMappings.computeIfAbsent(name, + n -> new LinkedHashMap()); return indexMapping; } - + /** * Generate an index mapping for the given name. This mapping will map * the keys of the given map to consecutive integer values, starting * with 0, in iteration order. - * - * @param name The name - * @param map The map to initialize the mapping from + * + * @param name The name + * @param map The map to initialize the mapping from */ - void generate(Object name, Map map) - { - if (map != null) - { + void generate(Object name, Map map) { + if (map != null) { get(name).putAll(IndexMappings.computeIndexMapping(map)); } } - + /** - * Returns the integer that is stored in the index mapping under the + * Returns the integer that is stored in the index mapping under the * given key, in the index mapping that is identified with * the given map name - * + * * @param name The name of the index mapping - * @param key The key to look up in the index mapping + * @param key The key to look up in the index mapping * @return The index */ - Integer getIndex(String name, String key) - { - if (key == null) - { + Integer getIndex(String name, String key) { + if (key == null) { return null; } return get(name).get(key); } - - + + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSets.java b/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSets.java index 18e2fb6..e236d38 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSets.java +++ b/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSets.java @@ -31,18 +31,23 @@ /** * Utility methods to create {@link IndexMappingSet} instances */ -class IndexMappingSets -{ +class IndexMappingSets { + /** + * Private constructor to prevent instantiation + */ + private IndexMappingSets() { + // Private constructor to prevent instantiation + } + /** * Compute the {@link IndexMappingSet} for the given glTF instance. * The {@link IndexMappingSet} will contain index mappings for all - * top-level dictionaries of the given glTF. - * + * top-level dictionaries of the given glTF. + * * @param gltf The glTF * @return The {@link IndexMappingSet} */ - static IndexMappingSet create(GlTF gltf) - { + static IndexMappingSet create(GlTF gltf) { IndexMappingSet indexMappingSet = new IndexMappingSet(); indexMappingSet.generate("accessors", gltf.getAccessors()); indexMappingSet.generate("animations", gltf.getAnimations()); @@ -62,12 +67,4 @@ static IndexMappingSet create(GlTF gltf) indexMappingSet.generate("textures", gltf.getTextures()); return indexMappingSet; } - - /** - * Private constructor to prevent instantiation - */ - private IndexMappingSets() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/IndexMappings.java b/src/main/java/de/javagl/jgltf/model/v1/IndexMappings.java index 93f7751..d44f8da 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/IndexMappings.java +++ b/src/main/java/de/javagl/jgltf/model/v1/IndexMappings.java @@ -33,40 +33,35 @@ /** * Utility methods to compute index mappings */ -class IndexMappings -{ +class IndexMappings { /** - * Compute the index mapping for the given map. If the given map is + * Private constructor to prevent instantiation + */ + private IndexMappings() { + // Private constructor to prevent instantiation + } + + /** + * Compute the index mapping for the given map. If the given map is * null, then an empty map will be returned. Otherwise, - * the method will iterate through the given map, and return a - * map where the keys of the given map are associated with + * the method will iterate through the given map, and return a + * map where the keys of the given map are associated with * consecutive integers, starting with 0, in iteration order. - * + * * @param map The input map * @return The index mapping */ - static Map computeIndexMapping(Map map) - { - if (map == null) - { + static Map computeIndexMapping(Map map) { + if (map == null) { return Collections.emptyMap(); } - Map indexMapping = - new LinkedHashMap(); + Map indexMapping = + new LinkedHashMap(); int indexCounter = 0; - for (String key : map.keySet()) - { + for (String key : map.keySet()) { indexMapping.put(key, indexCounter); indexCounter++; } return indexMapping; } - - /** - * Private constructor to prevent instantiation - */ - private IndexMappings() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/MaterialModelV1.java b/src/main/java/de/javagl/jgltf/model/v1/MaterialModelV1.java index 23904d5..6fc532c 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/MaterialModelV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/MaterialModelV1.java @@ -26,31 +26,30 @@ */ package de.javagl.jgltf.model.v1; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; - import de.javagl.jgltf.impl.v1.Material; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.TextureModel; import de.javagl.jgltf.model.gl.TechniqueModel; import de.javagl.jgltf.model.impl.AbstractNamedModelElement; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + /** * Implementation of a {@link MaterialModel} for glTF 1.0.
    - *
    + *
    * Note: This class is actually no longer specific for glTF 1.0. It might * be renamed to "TechniqueBasedMaterialModel" and moved to a different * package in the future. */ public final class MaterialModelV1 extends AbstractNamedModelElement - implements MaterialModel -{ + implements MaterialModel { /** * The {@link TechniqueModel} */ private TechniqueModel techniqueModel; - + /** * The material parameter values */ @@ -59,62 +58,54 @@ public final class MaterialModelV1 extends AbstractNamedModelElement /** * Creates a new instance */ - public MaterialModelV1() - { + public MaterialModelV1() { this.values = Collections.emptyMap(); } - + /** - * Set the material parameter values to be an unmodifiable shallow - * copy of the given map (or the empty map if the given map is - * null) - * - * @param values The material parameter values + * Returns the {@link TechniqueModel} + * + * @return The {@link TechniqueModel} */ - public void setValues(Map values) - { - if (values == null) - { - this.values = Collections.emptyMap(); - } - else - { - this.values = Collections.unmodifiableMap( - new LinkedHashMap(values)); - } + public TechniqueModel getTechniqueModel() { + return techniqueModel; } - + /** - * Set the {@link TechniqueModel} - * + * Set the {@link TechniqueModel} + * * @param techniqueModel The {@link TechniqueModel} */ - public void setTechniqueModel(TechniqueModel techniqueModel) - { + public void setTechniqueModel(TechniqueModel techniqueModel) { this.techniqueModel = techniqueModel; } /** - * Returns the {@link TechniqueModel} - * - * @return The {@link TechniqueModel} + * Returns the parameter values of this material. Note that if any + * parameter value of the original {@link Material} is the texture ID + * for a parameter of type GL_SAMPLER2D, then the respective value + * will be the appropriate {@link TextureModel} instance. + * + * @return The values */ - public TechniqueModel getTechniqueModel() - { - return techniqueModel; + public Map getValues() { + return values; } /** - * Returns the parameter values of this material. Note that if any - * parameter value of the original {@link Material} is the texture ID - * for a parameter of type GL_SAMPLER2D, then the respective value - * will be the appropriate {@link TextureModel} instance. - * - * @return The values + * Set the material parameter values to be an unmodifiable shallow + * copy of the given map (or the empty map if the given map is + * null) + * + * @param values The material parameter values */ - public Map getValues() - { - return values; + public void setValues(Map values) { + if (values == null) { + this.values = Collections.emptyMap(); + } else { + this.values = Collections.unmodifiableMap( + new LinkedHashMap(values)); + } } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/DefaultModels.java b/src/main/java/de/javagl/jgltf/model/v1/gl/DefaultModels.java index e4e7832..f9ecb68 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/DefaultModels.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/DefaultModels.java @@ -26,6 +26,17 @@ */ package de.javagl.jgltf.model.v1.gl; +import de.javagl.jgltf.impl.v1.*; +import de.javagl.jgltf.model.MaterialModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.Optionals; +import de.javagl.jgltf.model.gl.*; +import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; +import de.javagl.jgltf.model.gl.impl.*; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.io.IO; +import de.javagl.jgltf.model.v1.MaterialModelV1; + import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -35,111 +46,84 @@ import java.util.Map.Entry; import java.util.logging.Logger; -import de.javagl.jgltf.impl.v1.Material; -import de.javagl.jgltf.impl.v1.Shader; -import de.javagl.jgltf.impl.v1.Technique; -import de.javagl.jgltf.impl.v1.TechniqueParameters; -import de.javagl.jgltf.impl.v1.TechniqueStates; -import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; -import de.javagl.jgltf.model.MaterialModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.Optionals; -import de.javagl.jgltf.model.gl.ProgramModel; -import de.javagl.jgltf.model.gl.ShaderModel; -import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; -import de.javagl.jgltf.model.gl.TechniqueModel; -import de.javagl.jgltf.model.gl.TechniqueParametersModel; -import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; -import de.javagl.jgltf.model.gl.TechniqueStatesModel; -import de.javagl.jgltf.model.gl.impl.DefaultProgramModel; -import de.javagl.jgltf.model.gl.impl.DefaultShaderModel; -import de.javagl.jgltf.model.gl.impl.DefaultTechniqueModel; -import de.javagl.jgltf.model.gl.impl.DefaultTechniqueParametersModel; -import de.javagl.jgltf.model.gl.impl.DefaultTechniqueStatesModel; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.io.IO; -import de.javagl.jgltf.model.v1.MaterialModelV1; - /** - * A class containing the default {@link TechniqueModel} and + * A class containing the default {@link TechniqueModel} and * {@link MaterialModel} instances that correspond to the * default {@link Technique} and {@link Material} of glTF 1.0. */ -public class DefaultModels -{ +public class DefaultModels { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(DefaultModels.class.getName()); - + private static final Logger logger = + Logger.getLogger(DefaultModels.class.getName()); + /** * The default vertex {@link ShaderModel} */ private static final DefaultShaderModel DEFAULT_VERTEX_SHADER_MODEL; - + /** * The default fragment {@link ShaderModel} */ private static final DefaultShaderModel DEFAULT_FRAGMENT_SHADER_MODEL; - + /** * The default {@link ProgramModel} */ private static final DefaultProgramModel DEFAULT_PROGRAM_MODEL; - + /** * The default {@link TechniqueModel} */ private static final DefaultTechniqueModel DEFAULT_TECHNIQUE_MODEL; - + /** * The default {@link MaterialModel} */ private static final MaterialModelV1 DEFAULT_MATERIAL_MODEL; - - static - { + + static { // Create models for the default vertex- and fragment shader Shader vertexShader = GltfDefaults.getDefaultVertexShader(); - DEFAULT_VERTEX_SHADER_MODEL = - new DefaultShaderModel(vertexShader.getUri(), - ShaderType.VERTEX_SHADER); + DEFAULT_VERTEX_SHADER_MODEL = + new DefaultShaderModel(vertexShader.getUri(), + ShaderType.VERTEX_SHADER); initShaderData(DEFAULT_VERTEX_SHADER_MODEL); - + Shader fragmentShader = GltfDefaults.getDefaultFragmentShader(); - DEFAULT_FRAGMENT_SHADER_MODEL = - new DefaultShaderModel(fragmentShader.getUri(), - ShaderType.FRAGMENT_SHADER); + DEFAULT_FRAGMENT_SHADER_MODEL = + new DefaultShaderModel(fragmentShader.getUri(), + ShaderType.FRAGMENT_SHADER); initShaderData(DEFAULT_FRAGMENT_SHADER_MODEL); - + // Create a model for the default program DEFAULT_PROGRAM_MODEL = new DefaultProgramModel(); DEFAULT_PROGRAM_MODEL.setVertexShaderModel( - DEFAULT_VERTEX_SHADER_MODEL); + DEFAULT_VERTEX_SHADER_MODEL); DEFAULT_PROGRAM_MODEL.setFragmentShaderModel( - DEFAULT_FRAGMENT_SHADER_MODEL); - + DEFAULT_FRAGMENT_SHADER_MODEL); + // Create a model for the default technique Technique technique = GltfDefaults.getDefaultTechnique(); DEFAULT_TECHNIQUE_MODEL = new DefaultTechniqueModel(); DEFAULT_TECHNIQUE_MODEL.setProgramModel(DEFAULT_PROGRAM_MODEL); - + addParametersForDefaultTechnique(technique, DEFAULT_TECHNIQUE_MODEL); addAttributes(technique, DEFAULT_TECHNIQUE_MODEL); addUniforms(technique, DEFAULT_TECHNIQUE_MODEL); - + TechniqueStates states = technique.getStates(); List enable = Optionals.of( - states.getEnable(), - states.defaultEnable()); - + states.getEnable(), + states.defaultEnable()); + TechniqueStatesFunctions functions = states.getFunctions(); TechniqueStatesFunctionsModel techniqueStatesFunctionsModel = - TechniqueStatesFunctionsModels.create(functions); - TechniqueStatesModel techniqueStatesModel = - new DefaultTechniqueStatesModel( - enable, techniqueStatesFunctionsModel); + TechniqueStatesFunctionsModels.create(functions); + TechniqueStatesModel techniqueStatesModel = + new DefaultTechniqueStatesModel( + enable, techniqueStatesFunctionsModel); DEFAULT_TECHNIQUE_MODEL.setTechniqueStatesModel(techniqueStatesModel); // Create a model for the default material @@ -148,34 +132,36 @@ public class DefaultModels DEFAULT_MATERIAL_MODEL.setValues(material.getValues()); DEFAULT_MATERIAL_MODEL.setTechniqueModel(DEFAULT_TECHNIQUE_MODEL); } - + + /** + * Private constructor to prevent instantiation + */ + private DefaultModels() { + // Private constructor to prevent instantiation + } + /** * Return the default {@link MaterialModel} - * + * * @return The default {@link MaterialModel} */ - public static MaterialModel getDefaultMaterialModel() - { + public static MaterialModel getDefaultMaterialModel() { return DEFAULT_MATERIAL_MODEL; } - + /** - * Initialize the {@link DefaultShaderModel#setShaderData(ByteBuffer) + * Initialize the {@link DefaultShaderModel#setShaderData(ByteBuffer) * shader data} for the given {@link ShaderModel} - * + * * @param shaderModel The {@link ShaderModel} */ - private static void initShaderData(DefaultShaderModel shaderModel) - { - try - { + private static void initShaderData(DefaultShaderModel shaderModel) { + try { URI uri = new URI(shaderModel.getUri()); byte[] data = IO.read(uri); ByteBuffer shaderData = Buffers.create(data); shaderModel.setShaderData(shaderData); - } - catch (URISyntaxException | IOException e) - { + } catch (URISyntaxException | IOException e) { // This should never happen: The default shaders have valid // data URI that contain the shader data. logger.severe("Failed to initialize shader data"); @@ -184,62 +170,57 @@ private static void initShaderData(DefaultShaderModel shaderModel) /** * Return the default {@link TechniqueModel} - * + * * @return The default {@link TechniqueModel} */ - public static TechniqueModel getDefaultTechniqueModel() - { + public static TechniqueModel getDefaultTechniqueModel() { return DEFAULT_TECHNIQUE_MODEL; } - + /** - * Add all {@link TechniqueParametersModel} instances for the + * Add all {@link TechniqueParametersModel} instances for the * attributes of the given {@link Technique} to the given * {@link TechniqueModel} - * - * @param technique The {@link Technique} + * + * @param technique The {@link Technique} * @param techniqueModel The {@link TechniqueModel} */ private static void addParametersForDefaultTechnique( - Technique technique, DefaultTechniqueModel techniqueModel) - { - Map parameters = - Optionals.of(technique.getParameters()); - for (Entry entry : parameters.entrySet()) - { + Technique technique, DefaultTechniqueModel techniqueModel) { + Map parameters = + Optionals.of(technique.getParameters()); + for (Entry entry : parameters.entrySet()) { String parameterName = entry.getKey(); TechniqueParameters parameter = entry.getValue(); - + int type = parameter.getType(); int count = Optionals.of(parameter.getCount(), 1); String semantic = parameter.getSemantic(); Object value = parameter.getValue(); - + // The NodeModel is always null in the default technique NodeModel nodeModel = null; - + TechniqueParametersModel techniqueParametersModel = - new DefaultTechniqueParametersModel( - type, count, semantic, value, nodeModel); + new DefaultTechniqueParametersModel( + type, count, semantic, value, nodeModel); techniqueModel.addParameter( - parameterName, techniqueParametersModel); + parameterName, techniqueParametersModel); } } - + /** * Add all attribute entries of the given {@link Technique} to the given * {@link TechniqueModel} - * - * @param technique The {@link Technique} + * + * @param technique The {@link Technique} * @param techniqueModel The {@link TechniqueModel} */ private static void addAttributes(Technique technique, - DefaultTechniqueModel techniqueModel) - { - Map attributes = - Optionals.of(technique.getAttributes()); - for (Entry entry : attributes.entrySet()) - { + DefaultTechniqueModel techniqueModel) { + Map attributes = + Optionals.of(technique.getAttributes()); + for (Entry entry : attributes.entrySet()) { String attributeName = entry.getKey(); String parameterName = entry.getValue(); techniqueModel.addAttribute(attributeName, parameterName); @@ -249,31 +230,20 @@ private static void addAttributes(Technique technique, /** * Add all uniform entries of the given {@link Technique} to the given * {@link TechniqueModel} - * - * @param technique The {@link Technique} + * + * @param technique The {@link Technique} * @param techniqueModel The {@link TechniqueModel} */ private static void addUniforms(Technique technique, - DefaultTechniqueModel techniqueModel) - { - Map uniforms = - Optionals.of(technique.getUniforms()); - for (Entry entry : uniforms.entrySet()) - { + DefaultTechniqueModel techniqueModel) { + Map uniforms = + Optionals.of(technique.getUniforms()); + for (Entry entry : uniforms.entrySet()) { String uniformName = entry.getKey(); String parameterName = entry.getValue(); techniqueModel.addUniform(uniformName, parameterName); } } - - - /** - * Private constructor to prevent instantiation - */ - private DefaultModels() - { - // Private constructor to prevent instantiation - } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/GltfDefaults.java b/src/main/java/de/javagl/jgltf/model/v1/gl/GltfDefaults.java index ccde61d..77ba553 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/GltfDefaults.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/GltfDefaults.java @@ -32,143 +32,135 @@ import de.javagl.jgltf.impl.v1.Technique; /** - * A class containing the default {@link Shader}, {@link Program}, - * {@link Technique} and {@link Material} objects according to + * A class containing the default {@link Shader}, {@link Program}, + * {@link Technique} and {@link Material} objects according to * "Appendix A" of the specification. */ -public class GltfDefaults -{ +public class GltfDefaults { /** * An ID for the default vertex {@link Shader} */ - private static final String DEFAULT_VERTEX_SHADER_ID = - GltfDefaults.class.getName() + ".DEFAULT_VERTEX_SHADER_ID"; + private static final String DEFAULT_VERTEX_SHADER_ID = + GltfDefaults.class.getName() + ".DEFAULT_VERTEX_SHADER_ID"; /** * An ID for the default fragment {@link Shader} */ - private static final String DEFAULT_FRAGMENT_SHADER_ID = - GltfDefaults.class.getName() + ".DEFAULT_FRAGMENT_SHADER_ID"; - + private static final String DEFAULT_FRAGMENT_SHADER_ID = + GltfDefaults.class.getName() + ".DEFAULT_FRAGMENT_SHADER_ID"; + /** * An ID for the default {@link Program} */ - private static final String DEFAULT_PROGRAM_ID = - GltfDefaults.class.getName() + ".DEFAULT_PROGRAM_ID"; - + private static final String DEFAULT_PROGRAM_ID = + GltfDefaults.class.getName() + ".DEFAULT_PROGRAM_ID"; + /** * An ID for the default {@link Technique} */ - private static final String DEFAULT_TECHNIQUE_ID = - GltfDefaults.class.getName() + ".DEFAULT_TECHNIQUE_ID"; - + private static final String DEFAULT_TECHNIQUE_ID = + GltfDefaults.class.getName() + ".DEFAULT_TECHNIQUE_ID"; + /** * An ID for the default {@link Material} */ - private static final String DEFAULT_MATERIAL_ID = - GltfDefaults.class.getName() + ".DEFAULT_MATERIAL_ID"; - + private static final String DEFAULT_MATERIAL_ID = + GltfDefaults.class.getName() + ".DEFAULT_MATERIAL_ID"; + /** * The default vertex {@link Shader} */ - private static final Shader DEFAULT_VERTEX_SHADER = - Shaders.createDefaultVertexShader(); - + private static final Shader DEFAULT_VERTEX_SHADER = + Shaders.createDefaultVertexShader(); + /** * The default fragment {@link Shader} */ - private static final Shader DEFAULT_FRAGMENT_SHADER = - Shaders.createDefaultFragmentShader(); - + private static final Shader DEFAULT_FRAGMENT_SHADER = + Shaders.createDefaultFragmentShader(); + /** * The default {@link Program} */ - private static final Program DEFAULT_PROGRAM = - Programs.createDefaultProgram( - DEFAULT_VERTEX_SHADER_ID, DEFAULT_FRAGMENT_SHADER_ID); - + private static final Program DEFAULT_PROGRAM = + Programs.createDefaultProgram( + DEFAULT_VERTEX_SHADER_ID, DEFAULT_FRAGMENT_SHADER_ID); + /** * The default {@link Technique} */ - private static final Technique DEFAULT_TECHNIQUE = - Techniques.createDefaultTechnique(DEFAULT_PROGRAM_ID); - + private static final Technique DEFAULT_TECHNIQUE = + Techniques.createDefaultTechnique(DEFAULT_PROGRAM_ID); + /** * The default {@link Material} */ - private static final Material DEFAULT_MATERIAL = - Materials.createDefaultMaterial(DEFAULT_TECHNIQUE_ID); - + private static final Material DEFAULT_MATERIAL = + Materials.createDefaultMaterial(DEFAULT_TECHNIQUE_ID); + + /** + * Private constructor to prevent instantiation + */ + private GltfDefaults() { + // Private constructor to prevent instantiation + } + /** * Returns whether the given ID is the default ID as defined in this class - * + * * @param id The ID * @return Whether the given ID is the default ID */ - public static boolean isDefaultTechniqueId(String id) - { + public static boolean isDefaultTechniqueId(String id) { return DEFAULT_TECHNIQUE_ID.equals(id); } - + /** * Returns whether the given ID is the default ID as defined in this class - * + * * @param id The ID * @return Whether the given ID is the default ID */ - public static boolean isDefaultMaterialId(String id) - { + public static boolean isDefaultMaterialId(String id) { return DEFAULT_MATERIAL_ID.equals(id); } - + /** * Returns the default vertex {@link Shader} - * + * * @return The {@link Shader} */ - static Shader getDefaultVertexShader() - { + static Shader getDefaultVertexShader() { return DEFAULT_VERTEX_SHADER; } - + /** * Returns the default fragment {@link Shader} - * + * * @return The {@link Shader} */ - static Shader getDefaultFragmentShader() - { + static Shader getDefaultFragmentShader() { return DEFAULT_FRAGMENT_SHADER; } - + /** * Returns the default {@link Technique} - * + * * @return The {@link Technique} */ - static Technique getDefaultTechnique() - { + static Technique getDefaultTechnique() { return DEFAULT_TECHNIQUE; } - + /** * Returns the default {@link Material} - * + * * @return The {@link Material} */ - static Material getDefaultMaterial() - { + static Material getDefaultMaterial() { return DEFAULT_MATERIAL; } - - /** - * Private constructor to prevent instantiation - */ - private GltfDefaults() - { - // Private constructor to prevent instantiation - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/Materials.java b/src/main/java/de/javagl/jgltf/model/v1/gl/Materials.java index 765d549..4fa1120 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/Materials.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/Materials.java @@ -26,41 +26,38 @@ */ package de.javagl.jgltf.model.v1.gl; -import java.util.Arrays; - import de.javagl.jgltf.impl.v1.Material; import de.javagl.jgltf.impl.v1.Technique; +import java.util.Arrays; + /** * Utility methods for {@link Material}s */ -class Materials -{ +class Materials { + /** + * Private constructor to prevent instantiation + */ + private Materials() { + // Private constructor to prevent instantiation + } + /** * Create a default {@link Material} with the given {@link Technique} ID, * that is assumed to refer to a {@link Techniques#createDefaultTechnique( - * String) default technique}.
    + *String) default technique}.
    *
    - * The returned {@link Material} is the default {@link Material}, as - * described in "Appendix A" of the glTF 1.0 specification. - * + * The returned {@link Material} is the default {@link Material}, as + * described in "Appendix A" of the glTF 1.0 specification. + * * @param techniqueId The {@link Technique} ID * @return The default {@link Material} */ - static Material createDefaultMaterial(String techniqueId) - { + static Material createDefaultMaterial(String techniqueId) { Material material = new Material(); material.addValues("emission", Arrays.asList(0.5, 0.5, 0.5, 1.0)); material.setTechnique(techniqueId); return material; } - - /** - * Private constructor to prevent instantiation - */ - private Materials() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/Programs.java b/src/main/java/de/javagl/jgltf/model/v1/gl/Programs.java index 309261b..1474a71 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/Programs.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/Programs.java @@ -33,39 +33,36 @@ /** * Utility methods for {@link Program}s */ -class Programs -{ +class Programs { /** - * Creates a default {@link Program} with the given vertex- and + * Private constructor to prevent instantiation + */ + private Programs() { + // Private constructor to prevent instantiation + } + + /** + * Creates a default {@link Program} with the given vertex- and * fragment {@link Shader} IDs, which are assumed to refer to * the {@link Shaders#createDefaultVertexShader() default vertex shader} - * and {@link Shaders#createDefaultFragmentShader() default fragment + * and {@link Shaders#createDefaultFragmentShader() default fragment * shader}.
    *
    - * The returned {@link Program} is the {@link Program} for the default - * {@link Material}, as described in "Appendix A" of the - * glTF 1.0 specification. - * - * @param vertexShaderId The vertex {@link Shader} ID + * The returned {@link Program} is the {@link Program} for the default + * {@link Material}, as described in "Appendix A" of the + * glTF 1.0 specification. + * + * @param vertexShaderId The vertex {@link Shader} ID * @param fragmentShaderId The fragment {@link Shader} ID * @return The default {@link Program} */ static Program createDefaultProgram( - String vertexShaderId, String fragmentShaderId) - { + String vertexShaderId, String fragmentShaderId) { Program program = new Program(); program.setVertexShader(vertexShaderId); program.setFragmentShader(fragmentShaderId); program.addAttributes("a_position"); return program; } - - /** - * Private constructor to prevent instantiation - */ - private Programs() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/Shaders.java b/src/main/java/de/javagl/jgltf/model/v1/gl/Shaders.java index ee697d3..66dea72 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/Shaders.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/Shaders.java @@ -26,99 +26,95 @@ */ package de.javagl.jgltf.model.v1.gl; -import java.util.Base64; - import de.javagl.jgltf.impl.v1.Material; import de.javagl.jgltf.impl.v1.Shader; import de.javagl.jgltf.model.GltfConstants; +import java.util.Base64; + /** * Utility methods for {@link Shader}s. */ -class Shaders -{ +class Shaders { /** * The source code of the default vertex shader */ - private static final String DEFAULT_VERTEX_SHADER_CODE = - "#ifdef GL_ES" + "\n" + - " precision highp float;" + "\n" + - "#endif"+ "\n" + "\n" + - "uniform mat4 u_modelViewMatrix;" + "\n" + - "uniform mat4 u_projectionMatrix;" + "\n" + - "attribute vec3 a_position;" + "\n" + - "void main(void)" + "\n" + - "{" + "\n" + - " gl_Position = u_projectionMatrix * u_modelViewMatrix *" + "\n" + - " vec4(a_position,1.0);" + "\n" + - "}" + "\n" + - "\n"; - + private static final String DEFAULT_VERTEX_SHADER_CODE = + "#ifdef GL_ES" + "\n" + + " precision highp float;" + "\n" + + "#endif" + "\n" + "\n" + + "uniform mat4 u_modelViewMatrix;" + "\n" + + "uniform mat4 u_projectionMatrix;" + "\n" + + "attribute vec3 a_position;" + "\n" + + "void main(void)" + "\n" + + "{" + "\n" + + " gl_Position = u_projectionMatrix * u_modelViewMatrix *" + "\n" + + " vec4(a_position,1.0);" + "\n" + + "}" + "\n" + + "\n"; + /** * The source code of the default fragment shader */ private static final String DEFAULT_FRAGMENT_SHADER_CODE = - "#ifdef GL_ES" + "\n" + - " precision highp float;" + "\n" + - "#endif"+ "\n" + "\n" + - "uniform vec4 u_emission;" + "\n" + - "void main(void)" + "\n" + - "{" + "\n" + - " gl_FragColor = u_emission;" + "\n" + - "}" + "\n" + - "\n"; - - + "#ifdef GL_ES" + "\n" + + " precision highp float;" + "\n" + + "#endif" + "\n" + "\n" + + "uniform vec4 u_emission;" + "\n" + + "void main(void)" + "\n" + + "{" + "\n" + + " gl_FragColor = u_emission;" + "\n" + + "}" + "\n" + + "\n"; + + + /** + * Private constructor to prevent instantiation + */ + private Shaders() { + // Private constructor to prevent instantiation + } + /** - * Creates a default vertex {@link Shader}, with an embedded + * Creates a default vertex {@link Shader}, with an embedded * representation of the source code in form of a data URI.
    *
    - * The returned {@link Shader} is the vertex {@link Shader} for the - * default {@link Material}, as described in "Appendix A" of the - * specification. - * + * The returned {@link Shader} is the vertex {@link Shader} for the + * default {@link Material}, as described in "Appendix A" of the + * specification. + * * @return The default {@link Shader} */ - static Shader createDefaultVertexShader() - { + static Shader createDefaultVertexShader() { Shader shader = new Shader(); shader.setType(GltfConstants.GL_VERTEX_SHADER); - String encodedCode = - Base64.getEncoder().encodeToString( - DEFAULT_VERTEX_SHADER_CODE.getBytes()); + String encodedCode = + Base64.getEncoder().encodeToString( + DEFAULT_VERTEX_SHADER_CODE.getBytes()); String dataUriString = "data:text/plain;base64," + encodedCode; shader.setUri(dataUriString); return shader; } /** - * Creates a default fragment {@link Shader}, with an embedded + * Creates a default fragment {@link Shader}, with an embedded * representation of the source code in form of a data URI.
    *
    - * The returned {@link Shader} is the fragment {@link Shader} for the - * default {@link Material}, as described in "Appendix A" of the - * specification. - * + * The returned {@link Shader} is the fragment {@link Shader} for the + * default {@link Material}, as described in "Appendix A" of the + * specification. + * * @return The default {@link Shader} */ - static Shader createDefaultFragmentShader() - { + static Shader createDefaultFragmentShader() { Shader shader = new Shader(); shader.setType(GltfConstants.GL_FRAGMENT_SHADER); - String encodedCode = - Base64.getEncoder().encodeToString( - DEFAULT_FRAGMENT_SHADER_CODE.getBytes()); + String encodedCode = + Base64.getEncoder().encodeToString( + DEFAULT_FRAGMENT_SHADER_CODE.getBytes()); String dataUriString = "data:text/plain;base64," + encodedCode; shader.setUri(dataUriString); return shader; } - - /** - * Private constructor to prevent instantiation - */ - private Shaders() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/TechniqueStatesFunctionsModels.java b/src/main/java/de/javagl/jgltf/model/v1/gl/TechniqueStatesFunctionsModels.java index a80ba1c..ab38782 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/TechniqueStatesFunctionsModels.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/TechniqueStatesFunctionsModels.java @@ -35,51 +35,48 @@ * Methods to create {@link TechniqueStatesFunctionsModel} instances from * glTF 1.0 {@link TechniqueStatesFunctions} objects */ -public class TechniqueStatesFunctionsModels -{ +public class TechniqueStatesFunctionsModels { + /** + * Private constructor to prevent instantiation + */ + private TechniqueStatesFunctionsModels() { + // Private constructor to prevent instantiation + } + /** * Creates a new {@link TechniqueStatesFunctionsModel} object from the * given {@link TechniqueStatesFunctions} - * + * * @param techniqueStatesFunctions The {@link TechniqueStatesFunctions} * @return The {@link TechniqueStatesFunctionsModel} */ public static DefaultTechniqueStatesFunctionsModel create( - TechniqueStatesFunctions techniqueStatesFunctions) - { - DefaultTechniqueStatesFunctionsModel techniqueStatesFunctionsModel = - new DefaultTechniqueStatesFunctionsModel(); + TechniqueStatesFunctions techniqueStatesFunctions) { + DefaultTechniqueStatesFunctionsModel techniqueStatesFunctionsModel = + new DefaultTechniqueStatesFunctionsModel(); techniqueStatesFunctionsModel.setBlendColor(Optionals.clone( - techniqueStatesFunctions.getBlendColor())); + techniqueStatesFunctions.getBlendColor())); techniqueStatesFunctionsModel.setBlendEquationSeparate(Optionals.clone( - techniqueStatesFunctions.getBlendEquationSeparate())); + techniqueStatesFunctions.getBlendEquationSeparate())); techniqueStatesFunctionsModel.setBlendFuncSeparate(Optionals.clone( - techniqueStatesFunctions.getBlendFuncSeparate())); + techniqueStatesFunctions.getBlendFuncSeparate())); techniqueStatesFunctionsModel.setColorMask(Optionals.clone( - techniqueStatesFunctions.getColorMask())); + techniqueStatesFunctions.getColorMask())); techniqueStatesFunctionsModel.setCullFace(Optionals.clone( - techniqueStatesFunctions.getCullFace())); + techniqueStatesFunctions.getCullFace())); techniqueStatesFunctionsModel.setDepthFunc(Optionals.clone( - techniqueStatesFunctions.getDepthFunc())); + techniqueStatesFunctions.getDepthFunc())); techniqueStatesFunctionsModel.setDepthMask(Optionals.clone( - techniqueStatesFunctions.getDepthMask())); + techniqueStatesFunctions.getDepthMask())); techniqueStatesFunctionsModel.setDepthRange(Optionals.clone( - techniqueStatesFunctions.getDepthRange())); + techniqueStatesFunctions.getDepthRange())); techniqueStatesFunctionsModel.setFrontFace(Optionals.clone( - techniqueStatesFunctions.getFrontFace())); + techniqueStatesFunctions.getFrontFace())); techniqueStatesFunctionsModel.setLineWidth(Optionals.clone( - techniqueStatesFunctions.getLineWidth())); + techniqueStatesFunctions.getLineWidth())); techniqueStatesFunctionsModel.setPolygonOffset(Optionals.clone( - techniqueStatesFunctions.getPolygonOffset())); - + techniqueStatesFunctions.getPolygonOffset())); + return techniqueStatesFunctionsModel; } - - /** - * Private constructor to prevent instantiation - */ - private TechniqueStatesFunctionsModels() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/Techniques.java b/src/main/java/de/javagl/jgltf/model/v1/gl/Techniques.java index 0ba3c20..e379c6b 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/Techniques.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/Techniques.java @@ -26,145 +26,140 @@ */ package de.javagl.jgltf.model.v1.gl; +import de.javagl.jgltf.impl.v1.*; +import de.javagl.jgltf.model.GltfConstants; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import de.javagl.jgltf.impl.v1.Material; -import de.javagl.jgltf.impl.v1.Program; -import de.javagl.jgltf.impl.v1.Technique; -import de.javagl.jgltf.impl.v1.TechniqueParameters; -import de.javagl.jgltf.impl.v1.TechniqueStates; -import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; -import de.javagl.jgltf.model.GltfConstants; - /** * Utility methods related to {@link Technique}s */ -public class Techniques -{ +public class Techniques { + /** + * Private constructor to prevent instantiation + */ + private Techniques() { + // Private constructor to prevent instantiation + } + /** * Create a default {@link Technique} with the given {@link Program} ID, * which is assumed to refer to a {@link Programs#createDefaultProgram( - * String, String) default program}.
    + *String, String) default program}.
    *
    - * The returned {@link Technique} is the {@link Technique} for the - * default {@link Material}, as described in "Appendix A" of the - * glTF 1.0 specification. - * + * The returned {@link Technique} is the {@link Technique} for the + * default {@link Material}, as described in "Appendix A" of the + * glTF 1.0 specification. + * * @param programId The {@link Program} ID * @return The default {@link Technique} */ - static Technique createDefaultTechnique(String programId) - { + static Technique createDefaultTechnique(String programId) { Technique technique = new Technique(); technique.addAttributes("a_position", "position"); - technique.addParameters("modelViewMatrix", - createDefaultTechniqueParameters( - "MODELVIEW", GltfConstants.GL_FLOAT_MAT4, null)); - technique.addParameters("projectionMatrix", - createDefaultTechniqueParameters( - "PROJECTION", GltfConstants.GL_FLOAT_MAT4, null)); - technique.addParameters("emission", - createDefaultTechniqueParameters( - null, GltfConstants.GL_FLOAT_VEC4, - Arrays.asList(0.5f, 0.5f, 0.5f, 1.0f))); - technique.addParameters("position", - createDefaultTechniqueParameters( - "POSITION", GltfConstants.GL_FLOAT_VEC3, null)); + technique.addParameters("modelViewMatrix", + createDefaultTechniqueParameters( + "MODELVIEW", GltfConstants.GL_FLOAT_MAT4, null)); + technique.addParameters("projectionMatrix", + createDefaultTechniqueParameters( + "PROJECTION", GltfConstants.GL_FLOAT_MAT4, null)); + technique.addParameters("emission", + createDefaultTechniqueParameters( + null, GltfConstants.GL_FLOAT_VEC4, + Arrays.asList(0.5f, 0.5f, 0.5f, 1.0f))); + technique.addParameters("position", + createDefaultTechniqueParameters( + "POSITION", GltfConstants.GL_FLOAT_VEC3, null)); technique.setStates(createDefaultTechniqueStates()); technique.setProgram(programId); - + technique.addUniforms("u_modelViewMatrix", "modelViewMatrix"); technique.addUniforms("u_projectionMatrix", "projectionMatrix"); technique.addUniforms("u_emission", "emission"); - + return technique; } - + /** * Create the default {@link TechniqueStates} - * + * * @return The default {@link TechniqueStates} */ - private static TechniqueStates createDefaultTechniqueStates() - { + private static TechniqueStates createDefaultTechniqueStates() { TechniqueStates techniqueStates = new TechniqueStates(); techniqueStates.setEnable( - new ArrayList(techniqueStates.defaultEnable())); + new ArrayList(techniqueStates.defaultEnable())); techniqueStates.setFunctions(createDefaultTechniqueStatesFunctions()); return techniqueStates; } - + /** * Create the default {@link TechniqueStatesFunctions} - * + * * @return The default {@link TechniqueStatesFunctions} */ - public static TechniqueStatesFunctions - createDefaultTechniqueStatesFunctions() - { - TechniqueStatesFunctions techniqueStatesFunctions = - new TechniqueStatesFunctions(); + public static TechniqueStatesFunctions + createDefaultTechniqueStatesFunctions() { + TechniqueStatesFunctions techniqueStatesFunctions = + new TechniqueStatesFunctions(); techniqueStatesFunctions.setBlendColor( - techniqueStatesFunctions.defaultBlendColor()); + techniqueStatesFunctions.defaultBlendColor()); techniqueStatesFunctions.setBlendEquationSeparate( - techniqueStatesFunctions.defaultBlendEquationSeparate()); + techniqueStatesFunctions.defaultBlendEquationSeparate()); techniqueStatesFunctions.setBlendFuncSeparate( - techniqueStatesFunctions.defaultBlendFuncSeparate()); + techniqueStatesFunctions.defaultBlendFuncSeparate()); techniqueStatesFunctions.setColorMask( - techniqueStatesFunctions.defaultColorMask()); + techniqueStatesFunctions.defaultColorMask()); techniqueStatesFunctions.setCullFace( - techniqueStatesFunctions.defaultCullFace()); + techniqueStatesFunctions.defaultCullFace()); techniqueStatesFunctions.setDepthFunc( - techniqueStatesFunctions.defaultDepthFunc()); + techniqueStatesFunctions.defaultDepthFunc()); techniqueStatesFunctions.setDepthMask( - techniqueStatesFunctions.defaultDepthMask()); + techniqueStatesFunctions.defaultDepthMask()); techniqueStatesFunctions.setDepthRange( - techniqueStatesFunctions.defaultDepthRange()); + techniqueStatesFunctions.defaultDepthRange()); techniqueStatesFunctions.setFrontFace( - techniqueStatesFunctions.defaultFrontFace()); + techniqueStatesFunctions.defaultFrontFace()); techniqueStatesFunctions.setLineWidth( - techniqueStatesFunctions.defaultLineWidth()); + techniqueStatesFunctions.defaultLineWidth()); techniqueStatesFunctions.setPolygonOffset( - techniqueStatesFunctions.defaultPolygonOffset()); + techniqueStatesFunctions.defaultPolygonOffset()); techniqueStatesFunctions.setScissor( - techniqueStatesFunctions.defaultScissor()); + techniqueStatesFunctions.defaultScissor()); return techniqueStatesFunctions; } /** * Create default {@link TechniqueParameters} with the given semantic, * type and value - * + * * @param semantic The semantic - * @param type The type - * @param value The value + * @param type The type + * @param value The value * @return The default {@link TechniqueParameters} */ private static TechniqueParameters createDefaultTechniqueParameters( - String semantic, Integer type, Object value) - { + String semantic, Integer type, Object value) { TechniqueParameters techniqueParameters = new TechniqueParameters(); techniqueParameters.setSemantic(semantic); techniqueParameters.setType(type); techniqueParameters.setValue(value); return techniqueParameters; } - + /** - * Returns the set of states that should be enabled for the given + * Returns the set of states that should be enabled for the given * {@link Technique} - * + * * @param technique The {@link Technique} * @return The enabled states */ - public static List obtainEnabledStates(Technique technique) - { + public static List obtainEnabledStates(Technique technique) { TechniqueStates states = obtainTechniqueStates(technique); List enable = states.getEnable(); - if (enable == null) - { + if (enable == null) { return states.defaultEnable(); } return enable; @@ -172,55 +167,43 @@ public static List obtainEnabledStates(Technique technique) /** * Return the {@link TechniqueStates} from the given {@link Technique}, - * or the {@link TechniqueStates} from the + * or the {@link TechniqueStates} from the * {@link GltfDefaults#getDefaultTechnique() default technique} if - * the given {@link Technique} is null or does not + * the given {@link Technique} is null or does not * contain any {@link TechniqueStates} - * + * * @param technique The {@link Technique} * @return The {@link TechniqueStates} */ - private static TechniqueStates obtainTechniqueStates(Technique technique) - { + private static TechniqueStates obtainTechniqueStates(Technique technique) { TechniqueStates states = technique.getStates(); - if (states == null) - { + if (states == null) { return GltfDefaults.getDefaultTechnique().getStates(); } return states; } /** - * Return the {@link TechniqueStatesFunctions} from the - * {@link TechniqueStates} of the given {@link Technique}, or the - * {@link TechniqueStatesFunctions} from the + * Return the {@link TechniqueStatesFunctions} from the + * {@link TechniqueStates} of the given {@link Technique}, or the + * {@link TechniqueStatesFunctions} from the * {@link GltfDefaults#getDefaultTechnique() default technique} if - * the given {@link Technique} is null or does not + * the given {@link Technique} is null or does not * contain any {@link TechniqueStates} or {@link TechniqueStatesFunctions} - * + * * @param technique The {@link Technique} * @return The {@link TechniqueStatesFunctions} */ public static TechniqueStatesFunctions obtainTechniqueStatesFunctions( - Technique technique) - { + Technique technique) { TechniqueStates states = obtainTechniqueStates(technique); TechniqueStatesFunctions functions = states.getFunctions(); - if (functions == null) - { - TechniqueStates defaultStates = - GltfDefaults.getDefaultTechnique().getStates(); + if (functions == null) { + TechniqueStates defaultStates = + GltfDefaults.getDefaultTechnique().getStates(); return defaultStates.getFunctions(); } return functions; } - - /** - * Private constructor to prevent instantiation - */ - private Techniques() - { - // Private constructor to prevent instantiation - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/v2/AccessorSparseUtils.java b/src/main/java/de/javagl/jgltf/model/v2/AccessorSparseUtils.java index b387ae3..bc3ca27 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/AccessorSparseUtils.java +++ b/src/main/java/de/javagl/jgltf/model/v2/AccessorSparseUtils.java @@ -26,13 +26,9 @@ */ package de.javagl.jgltf.model.v2; -import java.util.logging.Logger; +import de.javagl.jgltf.model.*; -import de.javagl.jgltf.model.AccessorByteData; -import de.javagl.jgltf.model.AccessorData; -import de.javagl.jgltf.model.AccessorFloatData; -import de.javagl.jgltf.model.AccessorIntData; -import de.javagl.jgltf.model.AccessorShortData; +import java.util.logging.Logger; /** * Utility methods related to sparse accessors.
    @@ -43,208 +39,190 @@ *
    * Yes, Java does not play out so well with different primitive types... */ -class AccessorSparseUtils -{ +class AccessorSparseUtils { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(AccessorSparseUtils.class.getName()); - + private static final Logger logger = + Logger.getLogger(AccessorSparseUtils.class.getName()); + + /** + * Private constructor to prevent instantiation + */ + private AccessorSparseUtils() { + // Private constructor to prevent instantiation + } + /** - * Extract indices from the given {@link AccessorData}. The given + * Extract indices from the given {@link AccessorData}. The given * {@link AccessorData} must contain an integral type. That is, * its {@link AccessorData#getComponentType() component type} must * be byte.class, short.class or * int.class. - * + * * @param accessorData The {@link AccessorData} * @return The indices * @throws IllegalArgumentException If the given data does not contain - * an integral type + * an integral type */ - private static int[] extractIndices(AccessorData accessorData) - { - if (accessorData.getComponentType() == byte.class) - { - AccessorByteData accessorByteData = - (AccessorByteData)accessorData; + private static int[] extractIndices(AccessorData accessorData) { + if (accessorData.getComponentType() == byte.class) { + AccessorByteData accessorByteData = + (AccessorByteData) accessorData; int numElements = accessorByteData.getNumElements(); int indices[] = new int[numElements]; - for (int i=0; i *
    - * The baseAccessorData is the data that the dense data - * will be initialized with, before applying the substitution + * The baseAccessorData is the data that the dense data + * will be initialized with, before applying the substitution * that is defined by the given sparse indices and values.
    *
    * The sparseIndicesAccessorData is an {@link AccessorData} - * that was created from the accessor.sparse.indices + * that was created from the accessor.sparse.indices * structure.
    - *
    + *
    * The sparseValuesAccessorData is an {@link AccessorData} - * that was created from the accessor.sparse.values + * that was created from the accessor.sparse.values * structure.
    - *
    + *
    * This method does very few sanity checks. The caller is responsible - * for calling it only with arguments that are valid (in terms of + * for calling it only with arguments that are valid (in terms of * indices and data types). - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ static void substituteAccessorData( - AccessorData denseAccessorData, - AccessorData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorData sparseValuesAccessorData) - { + AccessorData denseAccessorData, + AccessorData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorData sparseValuesAccessorData) { Class componentType = denseAccessorData.getComponentType(); - if (componentType == byte.class) - { - AccessorByteData sparseValuesAccessorByteData = - (AccessorByteData)sparseValuesAccessorData; + if (componentType == byte.class) { + AccessorByteData sparseValuesAccessorByteData = + (AccessorByteData) sparseValuesAccessorData; AccessorByteData baseAccessorByteData = - (AccessorByteData)baseAccessorData; + (AccessorByteData) baseAccessorData; AccessorByteData denseAccessorByteData = - (AccessorByteData)denseAccessorData; + (AccessorByteData) denseAccessorData; substituteByteAccessorData( - denseAccessorByteData, - baseAccessorByteData, - sparseIndicesAccessorData, - sparseValuesAccessorByteData); - } - else if (componentType == short.class) - { - AccessorShortData sparseValuesAccessorShortData = - (AccessorShortData)sparseValuesAccessorData; + denseAccessorByteData, + baseAccessorByteData, + sparseIndicesAccessorData, + sparseValuesAccessorByteData); + } else if (componentType == short.class) { + AccessorShortData sparseValuesAccessorShortData = + (AccessorShortData) sparseValuesAccessorData; AccessorShortData baseAccessorShortData = - (AccessorShortData)baseAccessorData; + (AccessorShortData) baseAccessorData; AccessorShortData denseAccessorShortData = - (AccessorShortData)denseAccessorData; + (AccessorShortData) denseAccessorData; substituteShortAccessorData( - denseAccessorShortData, - baseAccessorShortData, - sparseIndicesAccessorData, - sparseValuesAccessorShortData); - } - else if (componentType == int.class) - { - AccessorIntData sparseValuesAccessorIntData = - (AccessorIntData)sparseValuesAccessorData; + denseAccessorShortData, + baseAccessorShortData, + sparseIndicesAccessorData, + sparseValuesAccessorShortData); + } else if (componentType == int.class) { + AccessorIntData sparseValuesAccessorIntData = + (AccessorIntData) sparseValuesAccessorData; AccessorIntData baseAccessorIntData = - (AccessorIntData)baseAccessorData; + (AccessorIntData) baseAccessorData; AccessorIntData denseAccessorIntData = - (AccessorIntData)denseAccessorData; + (AccessorIntData) denseAccessorData; substituteIntAccessorData( - denseAccessorIntData, - baseAccessorIntData, - sparseIndicesAccessorData, - sparseValuesAccessorIntData); - } - else if (componentType == float.class) - { - AccessorFloatData sparseValuesAccessorFloatData = - (AccessorFloatData)sparseValuesAccessorData; + denseAccessorIntData, + baseAccessorIntData, + sparseIndicesAccessorData, + sparseValuesAccessorIntData); + } else if (componentType == float.class) { + AccessorFloatData sparseValuesAccessorFloatData = + (AccessorFloatData) sparseValuesAccessorData; AccessorFloatData baseAccessorFloatData = - (AccessorFloatData)baseAccessorData; + (AccessorFloatData) baseAccessorData; AccessorFloatData denseAccessorFloatData = - (AccessorFloatData)denseAccessorData; - + (AccessorFloatData) denseAccessorData; + substituteFloatAccessorData( - denseAccessorFloatData, - baseAccessorFloatData, - sparseIndicesAccessorData, - sparseValuesAccessorFloatData); - } - else - { + denseAccessorFloatData, + baseAccessorFloatData, + sparseIndicesAccessorData, + sparseValuesAccessorFloatData); + } else { logger.warning("Invalid component type for accessor: " - + componentType); + + componentType); } } - - + /** * See {@link #substituteAccessorData} - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ private static void substituteByteAccessorData( - AccessorByteData denseAccessorData, - AccessorByteData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorByteData sparseValuesAccessorData) - { + AccessorByteData denseAccessorData, + AccessorByteData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorByteData sparseValuesAccessorData) { int numElements = denseAccessorData.getNumElements(); - int numComponentsPerElement = - denseAccessorData.getNumComponentsPerElement(); - - if (baseAccessorData != null) - { + int numComponentsPerElement = + denseAccessorData.getNumComponentsPerElement(); + + if (baseAccessorData != null) { // Fill the dense AccessorData with the base data - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponentsPerElement; c++) - { + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponentsPerElement; c++) { byte value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } - + // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); - for (int i = 0; i < indices.length; i++) - { + for (int i = 0; i < indices.length; i++) { int targetElementIndex = indices[i]; - for (int c = 0; c < numComponentsPerElement; c++) - { + for (int c = 0; c < numComponentsPerElement; c++) { byte substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } @@ -253,44 +231,38 @@ private static void substituteByteAccessorData( /** * See {@link #substituteAccessorData} - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ private static void substituteShortAccessorData( - AccessorShortData denseAccessorData, - AccessorShortData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorShortData sparseValuesAccessorData) - { + AccessorShortData denseAccessorData, + AccessorShortData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorShortData sparseValuesAccessorData) { int numElements = denseAccessorData.getNumElements(); - int numComponentsPerElement = - denseAccessorData.getNumComponentsPerElement(); - - if (baseAccessorData != null) - { + int numComponentsPerElement = + denseAccessorData.getNumComponentsPerElement(); + + if (baseAccessorData != null) { // Fill the dense AccessorData with the base data - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponentsPerElement; c++) - { + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponentsPerElement; c++) { short value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } - + // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); - for (int i = 0; i < indices.length; i++) - { + for (int i = 0; i < indices.length; i++) { int targetElementIndex = indices[i]; - for (int c = 0; c < numComponentsPerElement; c++) - { + for (int c = 0; c < numComponentsPerElement; c++) { short substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } @@ -299,102 +271,81 @@ private static void substituteShortAccessorData( /** * See {@link #substituteAccessorData} - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ private static void substituteIntAccessorData( - AccessorIntData denseAccessorData, - AccessorIntData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorIntData sparseValuesAccessorData) - { + AccessorIntData denseAccessorData, + AccessorIntData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorIntData sparseValuesAccessorData) { int numElements = denseAccessorData.getNumElements(); - int numComponentsPerElement = - denseAccessorData.getNumComponentsPerElement(); - - if (baseAccessorData != null) - { + int numComponentsPerElement = + denseAccessorData.getNumComponentsPerElement(); + + if (baseAccessorData != null) { // Fill the dense AccessorData with the base data - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponentsPerElement; c++) - { + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponentsPerElement; c++) { int value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } - + // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); - for (int i = 0; i < indices.length; i++) - { + for (int i = 0; i < indices.length; i++) { int targetElementIndex = indices[i]; - for (int c = 0; c < numComponentsPerElement; c++) - { + for (int c = 0; c < numComponentsPerElement; c++) { int substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } } } - + /** * See {@link #substituteAccessorData} - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ private static void substituteFloatAccessorData( - AccessorFloatData denseAccessorData, - AccessorFloatData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorFloatData sparseValuesAccessorData) - { + AccessorFloatData denseAccessorData, + AccessorFloatData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorFloatData sparseValuesAccessorData) { int numElements = denseAccessorData.getNumElements(); - int numComponentsPerElement = - denseAccessorData.getNumComponentsPerElement(); - - if (baseAccessorData != null) - { + int numComponentsPerElement = + denseAccessorData.getNumComponentsPerElement(); + + if (baseAccessorData != null) { // Fill the dense AccessorData with the base data - for (int e = 0; e < numElements; e++) - { - for (int c = 0; c < numComponentsPerElement; c++) - { + for (int e = 0; e < numElements; e++) { + for (int c = 0; c < numComponentsPerElement; c++) { float value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } - + // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); - for (int i = 0; i < indices.length; i++) - { + for (int i = 0; i < indices.length; i++) { int targetElementIndex = indices[i]; - for (int c = 0; c < numComponentsPerElement; c++) - { + for (int c = 0; c < numComponentsPerElement; c++) { float substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } } } - - - /** - * Private constructor to prevent instantiation - */ - private AccessorSparseUtils() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/de/javagl/jgltf/model/v2/GltfCreatorV2.java b/src/main/java/de/javagl/jgltf/model/v2/GltfCreatorV2.java index 0e3d106..70bc60a 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/GltfCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/v2/GltfCreatorV2.java @@ -26,235 +26,94 @@ */ package de.javagl.jgltf.model.v2; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.function.Function; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import de.javagl.jgltf.impl.v2.Accessor; -import de.javagl.jgltf.impl.v2.Animation; -import de.javagl.jgltf.impl.v2.AnimationChannel; -import de.javagl.jgltf.impl.v2.AnimationChannelTarget; -import de.javagl.jgltf.impl.v2.AnimationSampler; -import de.javagl.jgltf.impl.v2.Asset; -import de.javagl.jgltf.impl.v2.Buffer; -import de.javagl.jgltf.impl.v2.BufferView; -import de.javagl.jgltf.impl.v2.Camera; -import de.javagl.jgltf.impl.v2.CameraOrthographic; -import de.javagl.jgltf.impl.v2.CameraPerspective; -import de.javagl.jgltf.impl.v2.GlTF; -import de.javagl.jgltf.impl.v2.GlTFChildOfRootProperty; -import de.javagl.jgltf.impl.v2.GlTFProperty; -import de.javagl.jgltf.impl.v2.Image; -import de.javagl.jgltf.impl.v2.Material; -import de.javagl.jgltf.impl.v2.MaterialNormalTextureInfo; -import de.javagl.jgltf.impl.v2.MaterialOcclusionTextureInfo; -import de.javagl.jgltf.impl.v2.MaterialPbrMetallicRoughness; -import de.javagl.jgltf.impl.v2.Mesh; -import de.javagl.jgltf.impl.v2.MeshPrimitive; -import de.javagl.jgltf.impl.v2.Node; -import de.javagl.jgltf.impl.v2.Scene; -import de.javagl.jgltf.impl.v2.Skin; -import de.javagl.jgltf.impl.v2.Texture; -import de.javagl.jgltf.impl.v2.TextureInfo; -import de.javagl.jgltf.model.AccessorData; -import de.javagl.jgltf.model.AccessorDatas; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.AnimationModel; -import de.javagl.jgltf.model.AssetModel; +import de.javagl.jgltf.impl.v2.*; +import de.javagl.jgltf.model.*; import de.javagl.jgltf.model.AnimationModel.Channel; import de.javagl.jgltf.model.AnimationModel.Sampler; -import de.javagl.jgltf.model.BufferModel; -import de.javagl.jgltf.model.BufferViewModel; -import de.javagl.jgltf.model.CameraModel; -import de.javagl.jgltf.model.CameraOrthographicModel; -import de.javagl.jgltf.model.CameraPerspectiveModel; -import de.javagl.jgltf.model.ExtensionsModel; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.ImageModel; -import de.javagl.jgltf.model.MaterialModel; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; -import de.javagl.jgltf.model.ModelElement; -import de.javagl.jgltf.model.NamedModelElement; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.Optionals; -import de.javagl.jgltf.model.SceneModel; -import de.javagl.jgltf.model.SkinModel; -import de.javagl.jgltf.model.TextureModel; import de.javagl.jgltf.model.impl.DefaultNodeModel; import de.javagl.jgltf.model.v2.MaterialModelV2.AlphaMode; +import java.util.*; +import java.util.Map.Entry; +import java.util.function.Function; +import java.util.logging.Logger; +import java.util.stream.Collectors; + /** - * A class for creating the {@link GlTF version 2.0 glTF} from a - * {@link GltfModel} + * A class for creating the {@link GlTF version 2.0 glTF} from a + * {@link GltfModel} */ -public class GltfCreatorV2 -{ +public class GltfCreatorV2 { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfCreatorV2.class.getName()); - - /** - * Creates a {@link GlTF} from the given {@link GltfModel} - * - * @param gltfModel The {@link GltfModel} - * @return The {@link GlTF} - */ - public static GlTF create(GltfModel gltfModel) - { - GltfCreatorV2 creator = new GltfCreatorV2(gltfModel); - return creator.create(); - } - - /** - * Inner class containing the information that is necessary to define - * a glTF {@link de.javagl.jgltf.impl.v2.Sampler} - */ - @SuppressWarnings("javadoc") - private static class SamplerInfo - { - final Integer magFilter; - final Integer minFilter; - final Integer wrapS; - final Integer wrapT; - - SamplerInfo(TextureModel textureModel) - { - this.magFilter = textureModel.getMagFilter(); - this.minFilter = textureModel.getMinFilter(); - this.wrapS = textureModel.getWrapS(); - this.wrapT = textureModel.getWrapT(); - } - - @Override - public int hashCode() - { - return Objects.hash(magFilter, minFilter, wrapS, wrapT); - } - - @Override - public boolean equals(Object object) - { - if (this == object) - { - return true; - } - if (object == null) - { - return false; - } - if (getClass() != object.getClass()) - { - return false; - } - SamplerInfo other = (SamplerInfo) object; - if (!Objects.equals(magFilter, other.magFilter)) - { - return false; - } - if (!Objects.equals(minFilter, other.minFilter)) - { - return false; - } - if (!Objects.equals(wrapS, other.wrapS)) - { - return false; - } - if (!Objects.equals(wrapT, other.wrapT)) - { - return false; - } - return true; - } - } - + private static final Logger logger = + Logger.getLogger(GltfCreatorV2.class.getName()); /** * The {@link GltfModel} that this instance operates on */ private final GltfModel gltfModel; - /** * A list of {@link NodeModel} instances that are the same as the * ones in the {@link GltfModel}, but extended so that each node - * refers to at most one {@link MeshModel}. + * refers to at most one {@link MeshModel}. * See {@link #createNodesWithSingleMeshes(List)} */ private final List nodesWithSingleMeshes; - /** * A map from {@link AccessorModel} objects to their indices */ private final Map accessorIndices; - /** * A map from {@link BufferModel} objects to their indices */ private final Map bufferIndices; - /** * A map from {@link BufferViewModel} objects to their indices */ private final Map bufferViewIndices; - /** * A map from {@link CameraModel} objects to their indices */ private final Map cameraIndices; - /** * A map from {@link ImageModel} objects to their indices */ private final Map imageIndices; - /** * A map from {@link MaterialModel} objects to their indices */ private final Map materialIndices; - /** * A map from {@link MeshModel} objects to their indices */ private final Map meshIndices; - /** * A map from {@link NodeModel} objects to their indices */ private final Map nodeIndices; - /** * A map from {@link SkinModel} objects to their indices */ private final Map skinIndices; - /** * A map from {@link TextureModel} objects to their indices */ private final Map textureIndices; - /** * A map from {@link SamplerInfo} objects to their indices */ private final Map samplerIndices; - + /** * Creates a new instance with the given {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} */ - private GltfCreatorV2(GltfModel gltfModel) - { + private GltfCreatorV2(GltfModel gltfModel) { this.gltfModel = Objects.requireNonNull( - gltfModel, "The gltfModel may not be null"); - + gltfModel, "The gltfModel may not be null"); + accessorIndices = computeIndexMap(gltfModel.getAccessorModels()); bufferIndices = computeIndexMap(gltfModel.getBufferModels()); bufferViewIndices = computeIndexMap(gltfModel.getBufferViewModels()); @@ -262,104 +121,49 @@ private GltfCreatorV2(GltfModel gltfModel) imageIndices = computeIndexMap(gltfModel.getImageModels()); materialIndices = computeIndexMap(gltfModel.getMaterialModels()); meshIndices = computeIndexMap(gltfModel.getMeshModels()); - - this.nodesWithSingleMeshes = - createNodesWithSingleMeshes(gltfModel.getNodeModels()); + + this.nodesWithSingleMeshes = + createNodesWithSingleMeshes(gltfModel.getNodeModels()); nodeIndices = computeIndexMap(nodesWithSingleMeshes); skinIndices = computeIndexMap(gltfModel.getSkinModels()); textureIndices = computeIndexMap(gltfModel.getTextureModels()); - + samplerIndices = createSamplerIndices(gltfModel.getTextureModels()); } - + /** - * Create the {@link GlTF} instance from the {@link GltfModel} - * - * @return The {@link GlTF} instance + * Creates a {@link GlTF} from the given {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} + * @return The {@link GlTF} */ - public GlTF create() - { - GlTF gltf = new GlTF(); - transferGltfPropertyElements(gltfModel, gltf); - - gltf.setAccessors(map( - gltfModel.getAccessorModels(), this::createAccessor)); - gltf.setAnimations(map( - gltfModel.getAnimationModels(), this::createAnimation)); - gltf.setBuffers(map( - gltfModel.getBufferModels(), GltfCreatorV2::createBuffer)); - gltf.setBufferViews(map( - gltfModel.getBufferViewModels(), this::createBufferView)); - gltf.setCameras(map( - gltfModel.getCameraModels(), this::createCamera)); - gltf.setImages(map( - gltfModel.getImageModels(), this::createImage)); - gltf.setMaterials(map( - gltfModel.getMaterialModels(), this::createMaterial)); - gltf.setMeshes(map( - gltfModel.getMeshModels(), this::createMesh)); - gltf.setNodes(map( - nodesWithSingleMeshes, this::createNode)); - gltf.setScenes(map( - gltfModel.getSceneModels(), this::createScene)); - gltf.setSkins(map( - gltfModel.getSkinModels(), this::createSkin)); - - gltf.setSamplers(createSamplers()); - - gltf.setTextures(map( - gltfModel.getTextureModels(), this::createTexture)); - - if (gltf.getScenes() != null && !gltf.getScenes().isEmpty()) - { - gltf.setScene(0); - } - - ExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); - List extensionsUsed = extensionsModel.getExtensionsUsed(); - if (!extensionsUsed.isEmpty()) - { - gltf.setExtensionsUsed(extensionsUsed); - } - List extensionsRequired = - extensionsModel.getExtensionsRequired(); - if (!extensionsRequired.isEmpty()) - { - gltf.setExtensionsRequired(extensionsRequired); - } - - Asset asset = createAsset(gltfModel.getAssetModel()); - gltf.setAsset(asset); - - return gltf; + public static GlTF create(GltfModel gltfModel) { + GltfCreatorV2 creator = new GltfCreatorV2(gltfModel); + return creator.create(); } - + /** * Creates a list of nodes that contains the same elements as the given - * list, but replaces each node that has multiple {@link MeshModel} + * list, but replaces each node that has multiple {@link MeshModel} * references with a new node that has the appropriate number of child * nodes that each refers to one {@link MeshModel} - * + * * @param nodeModels The input {@link NodeModel} objects * @return The resulting {@link NodeModel} objects */ private static List createNodesWithSingleMeshes( - List nodeModels) - { + List nodeModels) { List newNodes = new ArrayList(); - List nodeModelsWithSingleMeshes = - new ArrayList(nodeModels); - for (int i=0; i nodeModelsWithSingleMeshes = + new ArrayList(nodeModels); + for (int i = 0; i < nodeModelsWithSingleMeshes.size(); i++) { NodeModel nodeModel = nodeModelsWithSingleMeshes.get(i); List meshModels = nodeModel.getMeshModels(); - if (meshModels.size() > 1) - { - DefaultNodeModel newParentNodeModel = - new DefaultNodeModel(nodeModel); - - for (int j=0; j 1) { + DefaultNodeModel newParentNodeModel = + new DefaultNodeModel(nodeModel); + + for (int j = 0; j < meshModels.size(); j++) { MeshModel meshModel = meshModels.get(j); DefaultNodeModel child = new DefaultNodeModel(); child.addMeshModel(meshModel); @@ -372,737 +176,781 @@ private static List createNodesWithSingleMeshes( nodeModelsWithSingleMeshes.addAll(newNodes); return nodeModelsWithSingleMeshes; } - - /** - * Create the {@link Accessor} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @return The {@link Accessor} - */ - private Accessor createAccessor(AccessorModel accessorModel) - { - Integer bufferViewIndex = - bufferViewIndices.get(accessorModel.getBufferViewModel()); - return createAccessor(accessorModel, bufferViewIndex); - } - + /** * Create the {@link Accessor} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} * @param bufferViewIndex The index of the {@link BufferViewModel} - * that the {@link AccessorModel} refers to + * that the {@link AccessorModel} refers to * @return The {@link Accessor} */ public static Accessor createAccessor( - AccessorModel accessorModel, Integer bufferViewIndex) - { + AccessorModel accessorModel, Integer bufferViewIndex) { Accessor accessor = new Accessor(); transferGltfChildOfRootPropertyElements(accessorModel, accessor); - + accessor.setBufferView(bufferViewIndex); - + accessor.setByteOffset(accessorModel.getByteOffset()); accessor.setComponentType(accessorModel.getComponentType()); accessor.setCount(accessorModel.getCount()); accessor.setType(accessorModel.getElementType().toString()); accessor.setNormalized( - accessorModel.isNormalized() ? true : null); - + accessorModel.isNormalized() ? true : null); + AccessorData accessorData = accessorModel.getAccessorData(); accessor.setMax(AccessorDatas.computeMax(accessorData)); accessor.setMin(AccessorDatas.computeMin(accessorData)); - + return accessor; } - + + /** + * Create the {@link Buffer} for the given {@link BufferModel} + * + * @param bufferModel The {@link BufferModel} + * @return The {@link Buffer} + */ + public static Buffer createBuffer(BufferModel bufferModel) { + Buffer buffer = new Buffer(); + transferGltfChildOfRootPropertyElements(bufferModel, buffer); + + buffer.setUri(bufferModel.getUri()); + buffer.setByteLength(bufferModel.getByteLength()); + return buffer; + } + + /** + * Create the {@link BufferView} for the given {@link BufferViewModel} + * + * @param bufferViewModel The {@link BufferViewModel} + * @param bufferIndex The index of the {@link BufferModel} that the + * {@link BufferViewModel} refers to + * @return The {@link BufferView} + */ + public static BufferView createBufferView( + BufferViewModel bufferViewModel, Integer bufferIndex) { + BufferView bufferView = new BufferView(); + transferGltfChildOfRootPropertyElements(bufferViewModel, bufferView); + + bufferView.setBuffer(bufferIndex); + bufferView.setByteOffset(bufferViewModel.getByteOffset()); + bufferView.setByteLength(bufferViewModel.getByteLength()); + bufferView.setByteStride(bufferViewModel.getByteStride()); + bufferView.setTarget(bufferViewModel.getTarget()); + + return bufferView; + } + + /** + * Create a {@link de.javagl.jgltf.impl.v2.Sampler} from the given + * {@link SamplerInfo} + * + * @param samplerInfo The {@link SamplerInfo} + * @return The {@link de.javagl.jgltf.impl.v2.Sampler} + */ + private static de.javagl.jgltf.impl.v2.Sampler createSampler( + SamplerInfo samplerInfo) { + de.javagl.jgltf.impl.v2.Sampler sampler = + new de.javagl.jgltf.impl.v2.Sampler(); + sampler.setMagFilter(samplerInfo.magFilter); + sampler.setMinFilter(samplerInfo.minFilter); + sampler.setWrapS(samplerInfo.wrapS); + sampler.setWrapT(samplerInfo.wrapT); + return sampler; + } + + /** + * Transfer the extensions and extras from the given model element to + * the given property + * + * @param modelElement The model element + * @param property The property + */ + private static void transferGltfPropertyElements( + ModelElement modelElement, GlTFProperty property) { + property.setExtensions(modelElement.getExtensions()); + property.setExtras(modelElement.getExtras()); + } + + /** + * Transfer the name and extensions and extras from the given model + * element to the given property + * + * @param modelElement The model element + * @param property The property + */ + private static void transferGltfChildOfRootPropertyElements( + NamedModelElement modelElement, + GlTFChildOfRootProperty property) { + property.setName(modelElement.getName()); + transferGltfPropertyElements(modelElement, property); + } + + /** + * Returns a list containing the result of mapping the given elements with + * the given function, or null if the given collection is + * empty + * + * @param collection The collection + * @param mapper The mapper + * @return The list + */ + private static List map( + Collection collection, + Function mapper) { + if (collection.isEmpty()) { + return null; + } + return collection.stream().map(mapper).collect(Collectors.toList()); + } + + /** + * Creates a map that has the same keys as the given map, mapped to + * the indices that are looked up for the respective values, using + * the given function + * + * @param map The map + * @param indexLookup The index lookup + * @return The index map + */ + private static Map resolveIndices( + Map map, + Function indexLookup) { + Map result = new LinkedHashMap(); + for (Entry entry : map.entrySet()) { + K key = entry.getKey(); + T value = entry.getValue(); + Integer index = indexLookup.apply(value); + result.put(key, index); + } + return result; + } + + /** + * Create an ordered map that contains a mapping of the given elements + * to consecutive integers + * + * @param elements The elements + * @return The index map + */ + private static Map computeIndexMap( + Collection elements) { + Map indices = new LinkedHashMap(); + int index = 0; + for (T element : elements) { + indices.put(element, index); + index++; + } + return indices; + } + + /** + * Returns a new list containing the elements of the given array, + * or null if the given array is null + * + * @param array The array + * @return The list + */ + private static List toList(float array[]) { + if (array == null) { + return null; + } + List list = new ArrayList(); + for (float f : array) { + list.add(f); + } + return list; + } + + /** + * Create the {@link GlTF} instance from the {@link GltfModel} + * + * @return The {@link GlTF} instance + */ + public GlTF create() { + GlTF gltf = new GlTF(); + transferGltfPropertyElements(gltfModel, gltf); + + gltf.setAccessors(map( + gltfModel.getAccessorModels(), this::createAccessor)); + gltf.setAnimations(map( + gltfModel.getAnimationModels(), this::createAnimation)); + gltf.setBuffers(map( + gltfModel.getBufferModels(), GltfCreatorV2::createBuffer)); + gltf.setBufferViews(map( + gltfModel.getBufferViewModels(), this::createBufferView)); + gltf.setCameras(map( + gltfModel.getCameraModels(), this::createCamera)); + gltf.setImages(map( + gltfModel.getImageModels(), this::createImage)); + gltf.setMaterials(map( + gltfModel.getMaterialModels(), this::createMaterial)); + gltf.setMeshes(map( + gltfModel.getMeshModels(), this::createMesh)); + gltf.setNodes(map( + nodesWithSingleMeshes, this::createNode)); + gltf.setScenes(map( + gltfModel.getSceneModels(), this::createScene)); + gltf.setSkins(map( + gltfModel.getSkinModels(), this::createSkin)); + + gltf.setSamplers(createSamplers()); + + gltf.setTextures(map( + gltfModel.getTextureModels(), this::createTexture)); + + if (gltf.getScenes() != null && !gltf.getScenes().isEmpty()) { + gltf.setScene(0); + } + + ExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); + List extensionsUsed = extensionsModel.getExtensionsUsed(); + if (!extensionsUsed.isEmpty()) { + gltf.setExtensionsUsed(extensionsUsed); + } + List extensionsRequired = + extensionsModel.getExtensionsRequired(); + if (!extensionsRequired.isEmpty()) { + gltf.setExtensionsRequired(extensionsRequired); + } + + Asset asset = createAsset(gltfModel.getAssetModel()); + gltf.setAsset(asset); + + return gltf; + } + + /** + * Create the {@link Accessor} for the given {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @return The {@link Accessor} + */ + private Accessor createAccessor(AccessorModel accessorModel) { + Integer bufferViewIndex = + bufferViewIndices.get(accessorModel.getBufferViewModel()); + return createAccessor(accessorModel, bufferViewIndex); + } + /** * Create the {@link Animation} for the given {@link AnimationModel} - * + * * @param animationModel The {@link AnimationModel} * @return The {@link Animation} */ - private Animation createAnimation(AnimationModel animationModel) - { + private Animation createAnimation(AnimationModel animationModel) { Animation animation = new Animation(); transferGltfChildOfRootPropertyElements(animationModel, animation); - + List samplers = new ArrayList(); List channels = animationModel.getChannels(); - for (Channel channel : channels) - { + for (Channel channel : channels) { samplers.add(channel.getSampler()); } - - List animationChannels = - new ArrayList(); - for (Channel channel : channels) - { + + List animationChannels = + new ArrayList(); + for (Channel channel : channels) { AnimationChannel animationChannel = new AnimationChannel(); - + AnimationChannelTarget target = new AnimationChannelTarget(); NodeModel nodeModel = channel.getNodeModel(); target.setNode(nodeIndices.get(nodeModel)); target.setPath(channel.getPath()); animationChannel.setTarget(target); - + Sampler sampler = channel.getSampler(); animationChannel.setSampler(samplers.indexOf(sampler)); - + animationChannels.add(animationChannel); } animation.setChannels(animationChannels); - - List animationSamplers = - new ArrayList(); - for (Sampler sampler : samplers) - { + + List animationSamplers = + new ArrayList(); + for (Sampler sampler : samplers) { AnimationSampler animationSampler = new AnimationSampler(); animationSampler.setInput( - accessorIndices.get(sampler.getInput())); + accessorIndices.get(sampler.getInput())); animationSampler.setInterpolation( - sampler.getInterpolation().name()); + sampler.getInterpolation().name()); animationSampler.setOutput( - accessorIndices.get(sampler.getOutput())); + accessorIndices.get(sampler.getOutput())); animationSamplers.add(animationSampler); } animation.setSamplers(animationSamplers); - + return animation; } - - - /** - * Create the {@link Buffer} for the given {@link BufferModel} - * - * @param bufferModel The {@link BufferModel} - * @return The {@link Buffer} - */ - public static Buffer createBuffer(BufferModel bufferModel) - { - Buffer buffer = new Buffer(); - transferGltfChildOfRootPropertyElements(bufferModel, buffer); - buffer.setUri(bufferModel.getUri()); - buffer.setByteLength(bufferModel.getByteLength()); - return buffer; - } - /** * Create the {@link BufferView} for the given {@link BufferViewModel} - * + * * @param bufferViewModel The {@link BufferViewModel} * @return The {@link BufferView} */ - private BufferView createBufferView(BufferViewModel bufferViewModel) - { - Integer bufferIndex = - bufferIndices.get(bufferViewModel.getBufferModel()); + private BufferView createBufferView(BufferViewModel bufferViewModel) { + Integer bufferIndex = + bufferIndices.get(bufferViewModel.getBufferModel()); return createBufferView(bufferViewModel, bufferIndex); } - - /** - * Create the {@link BufferView} for the given {@link BufferViewModel} - * - * @param bufferViewModel The {@link BufferViewModel} - * @param bufferIndex The index of the {@link BufferModel} that the - * {@link BufferViewModel} refers to - * @return The {@link BufferView} - */ - public static BufferView createBufferView( - BufferViewModel bufferViewModel, Integer bufferIndex) - { - BufferView bufferView = new BufferView(); - transferGltfChildOfRootPropertyElements(bufferViewModel, bufferView); - - bufferView.setBuffer(bufferIndex); - bufferView.setByteOffset(bufferViewModel.getByteOffset()); - bufferView.setByteLength(bufferViewModel.getByteLength()); - bufferView.setByteStride(bufferViewModel.getByteStride()); - bufferView.setTarget(bufferViewModel.getTarget()); - - return bufferView; - } - /** * Create the {@link Camera} for the given {@link CameraModel} - * + * * @param cameraModel The {@link CameraModel} * @return The {@link Camera} */ - private Camera createCamera(CameraModel cameraModel) - { + private Camera createCamera(CameraModel cameraModel) { Camera camera = new Camera(); transferGltfChildOfRootPropertyElements(cameraModel, camera); - - CameraPerspectiveModel cameraPerspectiveModel = - cameraModel.getCameraPerspectiveModel(); - CameraOrthographicModel cameraOrthographicModel = - cameraModel.getCameraOrthographicModel(); - if (cameraPerspectiveModel != null) - { + + CameraPerspectiveModel cameraPerspectiveModel = + cameraModel.getCameraPerspectiveModel(); + CameraOrthographicModel cameraOrthographicModel = + cameraModel.getCameraOrthographicModel(); + if (cameraPerspectiveModel != null) { CameraPerspective cameraPerspective = new CameraPerspective(); cameraPerspective.setAspectRatio( - cameraPerspectiveModel.getAspectRatio()); + cameraPerspectiveModel.getAspectRatio()); cameraPerspective.setYfov( - cameraPerspectiveModel.getYfov()); + cameraPerspectiveModel.getYfov()); cameraPerspective.setZfar( - cameraPerspectiveModel.getZfar()); + cameraPerspectiveModel.getZfar()); cameraPerspective.setZnear( - cameraPerspectiveModel.getZnear()); + cameraPerspectiveModel.getZnear()); camera.setPerspective(cameraPerspective); camera.setType("perspective"); - } - else if (cameraOrthographicModel != null) - { + } else if (cameraOrthographicModel != null) { CameraOrthographic cameraOrthographic = new CameraOrthographic(); cameraOrthographic.setXmag( - cameraOrthographicModel.getXmag()); + cameraOrthographicModel.getXmag()); cameraOrthographic.setYmag( - cameraOrthographicModel.getYmag()); + cameraOrthographicModel.getYmag()); cameraOrthographic.setZfar( - cameraOrthographicModel.getZfar()); + cameraOrthographicModel.getZfar()); cameraOrthographic.setZnear( - cameraOrthographicModel.getZnear()); + cameraOrthographicModel.getZnear()); camera.setOrthographic(cameraOrthographic); camera.setType("orthographic"); - } - else - { + } else { logger.severe("Camera is neither perspective nor orthographic"); } return camera; } - + /** * Create the {@link Image} for the given {@link ImageModel} - * + * * @param imageModel The {@link ImageModel} * @return The {@link Image} */ - private Image createImage(ImageModel imageModel) - { + private Image createImage(ImageModel imageModel) { Image image = new Image(); transferGltfChildOfRootPropertyElements(imageModel, image); - - Integer bufferView = - bufferViewIndices.get(imageModel.getBufferViewModel()); + + Integer bufferView = + bufferViewIndices.get(imageModel.getBufferViewModel()); image.setBufferView(bufferView); - + image.setMimeType(imageModel.getMimeType()); image.setUri(imageModel.getUri()); - + return image; } - + /** * Create the {@link Material} for the given {@link MaterialModel}. * If the given {@link MaterialModel} is not a {@link MaterialModelV2}, * then a warning is printed and null is returned. - * + * * @param materialModel The {@link MaterialModel} * @return The {@link Material} */ - private Material createMaterial(MaterialModel materialModel) - { - if (materialModel instanceof MaterialModelV2) - { - MaterialModelV2 materialModelV2 = (MaterialModelV2)materialModel; + private Material createMaterial(MaterialModel materialModel) { + if (materialModel instanceof MaterialModelV2) { + MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; return createMaterialV2(materialModelV2); } // TODO It should be possible to use a glTF 1.0 material model here logger.severe("Cannot store glTF 1.0 material in glTF 2.0"); return null; } - + /** * Create the {@link Material} for the given {@link MaterialModelV2} - * + * * @param materialModel The {@link MaterialModelV2} * @return The {@link Material} */ - private Material createMaterialV2(MaterialModelV2 materialModel) - { + private Material createMaterialV2(MaterialModelV2 materialModel) { Material material = new Material(); transferGltfChildOfRootPropertyElements(materialModel, material); - + AlphaMode alphaMode = materialModel.getAlphaMode(); - if (alphaMode == null) - { + if (alphaMode == null) { material.setAlphaMode(AlphaMode.OPAQUE.name()); - } - else - { + } else { material.setAlphaMode(alphaMode.name()); } - if (AlphaMode.MASK.equals(alphaMode)) - { + if (AlphaMode.MASK.equals(alphaMode)) { material.setAlphaCutoff(materialModel.getAlphaCutoff()); } material.setDoubleSided(materialModel.isDoubleSided()); - - MaterialPbrMetallicRoughness pbrMetallicRoughness = - new MaterialPbrMetallicRoughness(); + + MaterialPbrMetallicRoughness pbrMetallicRoughness = + new MaterialPbrMetallicRoughness(); material.setPbrMetallicRoughness(pbrMetallicRoughness); pbrMetallicRoughness.setBaseColorFactor( - materialModel.getBaseColorFactor()); - TextureModel baseColorTexture = - materialModel.getBaseColorTexture(); - if (baseColorTexture != null) - { + materialModel.getBaseColorFactor()); + TextureModel baseColorTexture = + materialModel.getBaseColorTexture(); + if (baseColorTexture != null) { TextureInfo baseColorTextureInfo = new TextureInfo(); baseColorTextureInfo.setIndex( - textureIndices.get(baseColorTexture)); + textureIndices.get(baseColorTexture)); baseColorTextureInfo.setTexCoord( - materialModel.getBaseColorTexcoord()); + materialModel.getBaseColorTexcoord()); pbrMetallicRoughness.setBaseColorTexture(baseColorTextureInfo); } pbrMetallicRoughness.setMetallicFactor( - materialModel.getMetallicFactor()); + materialModel.getMetallicFactor()); pbrMetallicRoughness.setRoughnessFactor( - materialModel.getRoughnessFactor()); - TextureModel metallicRoughnessTexture = - materialModel.getMetallicRoughnessTexture(); - if (metallicRoughnessTexture != null) - { + materialModel.getRoughnessFactor()); + TextureModel metallicRoughnessTexture = + materialModel.getMetallicRoughnessTexture(); + if (metallicRoughnessTexture != null) { TextureInfo metallicRoughnessTextureInfo = new TextureInfo(); metallicRoughnessTextureInfo.setIndex( - textureIndices.get(metallicRoughnessTexture)); + textureIndices.get(metallicRoughnessTexture)); metallicRoughnessTextureInfo.setTexCoord( - materialModel.getMetallicRoughnessTexcoord()); + materialModel.getMetallicRoughnessTexcoord()); pbrMetallicRoughness.setMetallicRoughnessTexture( - metallicRoughnessTextureInfo); + metallicRoughnessTextureInfo); } - + TextureModel normalTexture = materialModel.getNormalTexture(); - if (normalTexture != null) - { - MaterialNormalTextureInfo normalTextureInfo = - new MaterialNormalTextureInfo(); + if (normalTexture != null) { + MaterialNormalTextureInfo normalTextureInfo = + new MaterialNormalTextureInfo(); normalTextureInfo.setIndex( - textureIndices.get(normalTexture)); + textureIndices.get(normalTexture)); normalTextureInfo.setTexCoord( - materialModel.getNormalTexcoord()); + materialModel.getNormalTexcoord()); normalTextureInfo.setScale( - materialModel.getNormalScale()); + materialModel.getNormalScale()); material.setNormalTexture(normalTextureInfo); } TextureModel occlusionTexture = materialModel.getOcclusionTexture(); - if (occlusionTexture != null) - { - MaterialOcclusionTextureInfo occlusionTextureInfo = - new MaterialOcclusionTextureInfo(); + if (occlusionTexture != null) { + MaterialOcclusionTextureInfo occlusionTextureInfo = + new MaterialOcclusionTextureInfo(); occlusionTextureInfo.setIndex( - textureIndices.get(occlusionTexture)); + textureIndices.get(occlusionTexture)); occlusionTextureInfo.setTexCoord( - materialModel.getOcclusionTexcoord()); + materialModel.getOcclusionTexcoord()); occlusionTextureInfo.setStrength( - materialModel.getOcclusionStrength()); + materialModel.getOcclusionStrength()); material.setOcclusionTexture(occlusionTextureInfo); } - - TextureModel emissiveTexture = - materialModel.getEmissiveTexture(); - if (emissiveTexture != null) - { + + TextureModel emissiveTexture = + materialModel.getEmissiveTexture(); + if (emissiveTexture != null) { TextureInfo emissiveTextureInfo = new TextureInfo(); emissiveTextureInfo.setIndex( - textureIndices.get(emissiveTexture)); + textureIndices.get(emissiveTexture)); emissiveTextureInfo.setTexCoord( - materialModel.getEmissiveTexcoord()); + materialModel.getEmissiveTexcoord()); material.setEmissiveFactor( - materialModel.getEmissiveFactor()); + materialModel.getEmissiveFactor()); material.setEmissiveTexture(emissiveTextureInfo); } - + return material; } - + /** * Create the {@link Mesh} for the given {@link MeshModel} - * + * * @param meshModel The {@link MeshModel} * @return The {@link Mesh} */ - private Mesh createMesh(MeshModel meshModel) - { + private Mesh createMesh(MeshModel meshModel) { Mesh mesh = new Mesh(); transferGltfChildOfRootPropertyElements(meshModel, mesh); - + List meshPrimitives = new ArrayList(); - List meshPrimitiveModels = - meshModel.getMeshPrimitiveModels(); - for (MeshPrimitiveModel meshPrimitiveModel : meshPrimitiveModels) - { - MeshPrimitive meshPrimitive = - createMeshPrimitive(meshPrimitiveModel); + List meshPrimitiveModels = + meshModel.getMeshPrimitiveModels(); + for (MeshPrimitiveModel meshPrimitiveModel : meshPrimitiveModels) { + MeshPrimitive meshPrimitive = + createMeshPrimitive(meshPrimitiveModel); meshPrimitives.add(meshPrimitive); } mesh.setPrimitives(meshPrimitives); mesh.setWeights(toList(meshModel.getWeights())); return mesh; } - + /** * Create the {@link MeshPrimitive} for the given {@link MeshPrimitiveModel} - * + * * @param meshPrimitiveModel The {@link MeshPrimitiveModel} * @return The {@link MeshPrimitive} */ private MeshPrimitive createMeshPrimitive( - MeshPrimitiveModel meshPrimitiveModel) - { + MeshPrimitiveModel meshPrimitiveModel) { MeshPrimitive meshPrimitive = new MeshPrimitive(); transferGltfPropertyElements(meshPrimitiveModel, meshPrimitive); meshPrimitive.setMode(meshPrimitiveModel.getMode()); - + Map attributes = resolveIndices( - meshPrimitiveModel.getAttributes(), - accessorIndices::get); + meshPrimitiveModel.getAttributes(), + accessorIndices::get); meshPrimitive.setAttributes(attributes); AccessorModel indices = meshPrimitiveModel.getIndices(); meshPrimitive.setIndices(accessorIndices.get(indices)); - - List> modelTargetsList = - meshPrimitiveModel.getTargets(); - if (!modelTargetsList.isEmpty()) - { - List> targetsList = - new ArrayList>(); - for (Map modelTargets : modelTargetsList) - { + + List> modelTargetsList = + meshPrimitiveModel.getTargets(); + if (!modelTargetsList.isEmpty()) { + List> targetsList = + new ArrayList>(); + for (Map modelTargets : modelTargetsList) { Map targets = resolveIndices( - modelTargets, accessorIndices::get); + modelTargets, accessorIndices::get); targetsList.add(targets); } meshPrimitive.setTargets(targetsList); } - + Integer material = materialIndices.get( - meshPrimitiveModel.getMaterialModel()); + meshPrimitiveModel.getMaterialModel()); meshPrimitive.setMaterial(material); - + return meshPrimitive; } /** * Create the {@link Node} for the given {@link NodeModel} - * + * * @param nodeModel The {@link NodeModel} * @return The {@link Node} */ - private Node createNode(NodeModel nodeModel) - { + private Node createNode(NodeModel nodeModel) { Node node = new Node(); transferGltfChildOfRootPropertyElements(nodeModel, node); - - if (!nodeModel.getChildren().isEmpty()) - { + + if (!nodeModel.getChildren().isEmpty()) { node.setChildren(map( - nodeModel.getChildren(), nodeIndices::get)); + nodeModel.getChildren(), nodeIndices::get)); } node.setTranslation(Optionals.clone(nodeModel.getTranslation())); node.setRotation(Optionals.clone(nodeModel.getRotation())); node.setScale(Optionals.clone(nodeModel.getScale())); node.setMatrix(Optionals.clone(nodeModel.getMatrix())); - + Integer camera = cameraIndices.get(nodeModel.getCameraModel()); node.setCamera(camera); - + Integer skin = skinIndices.get(nodeModel.getSkinModel()); node.setSkin(skin); - + node.setWeights(toList(nodeModel.getWeights())); - + List nodeMeshModels = nodeModel.getMeshModels(); - if (nodeMeshModels.size() > 1) - { + if (nodeMeshModels.size() > 1) { // This should never me the case here, because this method // is called with the nodes that have been preprocessed // using #createNodesWithSingleMeshes logger.severe("Warning: glTF 2.0 only supports one mesh per node"); } - if (!nodeMeshModels.isEmpty()) - { + if (!nodeMeshModels.isEmpty()) { MeshModel nodeMeshModel = nodeMeshModels.get(0); Integer mesh = meshIndices.get(nodeMeshModel); node.setMesh(mesh); } return node; } - + /** * Create the {@link Scene} for the given {@link SceneModel} - * + * * @param sceneModel The {@link SceneModel} * @return The {@link Scene} */ - private Scene createScene(SceneModel sceneModel) - { + private Scene createScene(SceneModel sceneModel) { Scene scene = new Scene(); transferGltfChildOfRootPropertyElements(sceneModel, scene); - + scene.setNodes(map( - sceneModel.getNodeModels(), nodeIndices::get)); + sceneModel.getNodeModels(), nodeIndices::get)); return scene; } - + /** * Create the {@link Skin} for the given {@link SkinModel} - * + * * @param skinModel The {@link SkinModel} * @return The {@link Skin} */ - private Skin createSkin(SkinModel skinModel) - { + private Skin createSkin(SkinModel skinModel) { Skin skin = new Skin(); transferGltfChildOfRootPropertyElements(skinModel, skin); - - Integer inverseBindMatrices = - accessorIndices.get(skinModel.getInverseBindMatrices()); + + Integer inverseBindMatrices = + accessorIndices.get(skinModel.getInverseBindMatrices()); skin.setInverseBindMatrices(inverseBindMatrices); - + skin.setJoints(map( - skinModel.getJoints(), nodeIndices::get)); - + skinModel.getJoints(), nodeIndices::get)); + Integer skeleton = nodeIndices.get(skinModel.getSkeleton()); skin.setSkeleton(skeleton); - + return skin; } - + /** * Create a mapping from {@link SamplerInfo} objects to consecutive - * indices, based on the {@link SamplerInfo} objects that are + * indices, based on the {@link SamplerInfo} objects that are * created from the given {@link TextureModel} objects - * + * * @param textureModels The {@link TextureModel} objects * @return The indices */ private Map createSamplerIndices( - List textureModels) - { - Map samplerIndices = - new LinkedHashMap(); - for (TextureModel textureModel : textureModels) - { + List textureModels) { + Map samplerIndices = + new LinkedHashMap(); + for (TextureModel textureModel : textureModels) { SamplerInfo samplerInfo = new SamplerInfo(textureModel); - if (!samplerIndices.containsKey(samplerInfo)) - { + if (!samplerIndices.containsKey(samplerInfo)) { samplerIndices.put(samplerInfo, samplerIndices.size()); } } return samplerIndices; } - + /** * Create the {@link de.javagl.jgltf.impl.v2.Sampler} objects for * the current glTF model, returning null if there * are no samplers. - * + * * @return The samplers */ - private List createSamplers() - { - if (samplerIndices.isEmpty()) - { + private List createSamplers() { + if (samplerIndices.isEmpty()) { return null; } - List samplers = - new ArrayList(); - for (SamplerInfo samplerInfo : samplerIndices.keySet()) - { - de.javagl.jgltf.impl.v2.Sampler sampler = - createSampler(samplerInfo); + List samplers = + new ArrayList(); + for (SamplerInfo samplerInfo : samplerIndices.keySet()) { + de.javagl.jgltf.impl.v2.Sampler sampler = + createSampler(samplerInfo); samplers.add(sampler); } return samplers; } - - /** - * Create a {@link de.javagl.jgltf.impl.v2.Sampler} from the given - * {@link SamplerInfo} - * - * @param samplerInfo The {@link SamplerInfo} - * @return The {@link de.javagl.jgltf.impl.v2.Sampler} - */ - private static de.javagl.jgltf.impl.v2.Sampler createSampler( - SamplerInfo samplerInfo) - { - de.javagl.jgltf.impl.v2.Sampler sampler = - new de.javagl.jgltf.impl.v2.Sampler(); - sampler.setMagFilter(samplerInfo.magFilter); - sampler.setMinFilter(samplerInfo.minFilter); - sampler.setWrapS(samplerInfo.wrapS); - sampler.setWrapT(samplerInfo.wrapT); - return sampler; - } - /** * Creates a texture for the given {@link TextureModel} - * + * * @param textureModel The {@link TextureModel} * @return The {@link Texture} */ - private Texture createTexture(TextureModel textureModel) - { + private Texture createTexture(TextureModel textureModel) { Texture texture = new Texture(); transferGltfChildOfRootPropertyElements(textureModel, texture); - + SamplerInfo samplerInfo = new SamplerInfo(textureModel); Integer index = samplerIndices.get(samplerInfo); texture.setSampler(index); - + texture.setSource(imageIndices.get(textureModel.getImageModel())); - + return texture; } - + /** * Creates an asset for the given {@link AssetModel} - * + * * @param assetModel The {@link AssetModel} * @return The {@link Asset} */ - private Asset createAsset(AssetModel assetModel) - { + private Asset createAsset(AssetModel assetModel) { Asset asset = new Asset(); asset.setVersion("2.0"); asset.setGenerator("JglTF from https://github.com/javagl/JglTF"); - + transferGltfPropertyElements(assetModel, asset); - - if (assetModel.getCopyright() != null) - { + + if (assetModel.getCopyright() != null) { asset.setCopyright(assetModel.getCopyright()); } - if (assetModel.getGenerator() != null) - { + if (assetModel.getGenerator() != null) { asset.setGenerator(assetModel.getGenerator()); } return asset; } - - /** - * Transfer the extensions and extras from the given model element to - * the given property - * - * @param modelElement The model element - * @param property The property - */ - private static void transferGltfPropertyElements( - ModelElement modelElement, GlTFProperty property) - { - property.setExtensions(modelElement.getExtensions()); - property.setExtras(modelElement.getExtras()); - } - - /** - * Transfer the name and extensions and extras from the given model - * element to the given property - * - * @param modelElement The model element - * @param property The property - */ - private static void transferGltfChildOfRootPropertyElements( - NamedModelElement modelElement, - GlTFChildOfRootProperty property) - { - property.setName(modelElement.getName()); - transferGltfPropertyElements(modelElement, property); - } - - /** - * Returns a list containing the result of mapping the given elements with - * the given function, or null if the given collection is - * empty - * - * @param collection The collection - * @param mapper The mapper - * @return The list - */ - private static List map( - Collection collection, - Function mapper) - { - if (collection.isEmpty()) - { - return null; - } - return collection.stream().map(mapper).collect(Collectors.toList()); - } /** - * Creates a map that has the same keys as the given map, mapped to - * the indices that are looked up for the respective values, using - * the given function - * - * @param map The map - * @param indexLookup The index lookup - * @return The index map - */ - private static Map resolveIndices( - Map map, - Function indexLookup) - { - Map result = new LinkedHashMap(); - for (Entry entry : map.entrySet()) - { - K key = entry.getKey(); - T value = entry.getValue(); - Integer index = indexLookup.apply(value); - result.put(key, index); - } - return result; - } - - /** - * Create an ordered map that contains a mapping of the given elements - * to consecutive integers - * - * @param elements The elements - * @return The index map + * Inner class containing the information that is necessary to define + * a glTF {@link de.javagl.jgltf.impl.v2.Sampler} */ - private static Map computeIndexMap( - Collection elements) - { - Map indices = new LinkedHashMap(); - int index = 0; - for (T element : elements) - { - indices.put(element, index); - index++; + @SuppressWarnings("javadoc") + private static class SamplerInfo { + final Integer magFilter; + final Integer minFilter; + final Integer wrapS; + final Integer wrapT; + + SamplerInfo(TextureModel textureModel) { + this.magFilter = textureModel.getMagFilter(); + this.minFilter = textureModel.getMinFilter(); + this.wrapS = textureModel.getWrapS(); + this.wrapT = textureModel.getWrapT(); } - return indices; - } - - - /** - * Returns a new list containing the elements of the given array, - * or null if the given array is null - * - * @param array The array - * @return The list - */ - private static List toList(float array[]) - { - if (array == null) - { - return null; + + @Override + public int hashCode() { + return Objects.hash(magFilter, minFilter, wrapS, wrapT); } - List list = new ArrayList(); - for (float f : array) - { - list.add(f); + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null) { + return false; + } + if (getClass() != object.getClass()) { + return false; + } + SamplerInfo other = (SamplerInfo) object; + if (!Objects.equals(magFilter, other.magFilter)) { + return false; + } + if (!Objects.equals(minFilter, other.minFilter)) { + return false; + } + if (!Objects.equals(wrapS, other.wrapS)) { + return false; + } + if (!Objects.equals(wrapT, other.wrapT)) { + return false; + } + return true; } - return list; } } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/v2/GltfModelCreatorV2.java b/src/main/java/de/javagl/jgltf/model/v2/GltfModelCreatorV2.java index 682d852..a11ec45 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/GltfModelCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/v2/GltfModelCreatorV2.java @@ -26,94 +26,16 @@ */ package de.javagl.jgltf.model.v2; -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.logging.Logger; - import com.google.gson.Gson; import com.google.gson.JsonElement; import com.modularmods.mcgltf.MCglTF; - -import de.javagl.jgltf.impl.v2.GlTFChildOfRootProperty; -import de.javagl.jgltf.impl.v2.GlTFProperty; -import de.javagl.jgltf.impl.v2.Asset; -import de.javagl.jgltf.impl.v2.Accessor; -import de.javagl.jgltf.impl.v2.AccessorSparse; -import de.javagl.jgltf.impl.v2.AccessorSparseIndices; -import de.javagl.jgltf.impl.v2.AccessorSparseValues; -import de.javagl.jgltf.impl.v2.Animation; -import de.javagl.jgltf.impl.v2.AnimationChannel; -import de.javagl.jgltf.impl.v2.AnimationChannelTarget; -import de.javagl.jgltf.impl.v2.AnimationSampler; -import de.javagl.jgltf.impl.v2.Buffer; -import de.javagl.jgltf.impl.v2.BufferView; -import de.javagl.jgltf.impl.v2.Camera; -import de.javagl.jgltf.impl.v2.CameraOrthographic; -import de.javagl.jgltf.impl.v2.CameraPerspective; -import de.javagl.jgltf.impl.v2.GlTF; -import de.javagl.jgltf.impl.v2.Image; -import de.javagl.jgltf.impl.v2.Material; -import de.javagl.jgltf.impl.v2.MaterialNormalTextureInfo; -import de.javagl.jgltf.impl.v2.MaterialOcclusionTextureInfo; -import de.javagl.jgltf.impl.v2.MaterialPbrMetallicRoughness; -import de.javagl.jgltf.impl.v2.Mesh; -import de.javagl.jgltf.impl.v2.MeshPrimitive; -import de.javagl.jgltf.impl.v2.Node; -import de.javagl.jgltf.impl.v2.Sampler; -import de.javagl.jgltf.impl.v2.Scene; -import de.javagl.jgltf.impl.v2.Skin; -import de.javagl.jgltf.impl.v2.Texture; -import de.javagl.jgltf.impl.v2.TextureInfo; -import de.javagl.jgltf.model.AccessorData; -import de.javagl.jgltf.model.AccessorDatas; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.AnimationModel; -import de.javagl.jgltf.model.AssetModel; +import de.javagl.jgltf.impl.v2.*; +import de.javagl.jgltf.model.*; import de.javagl.jgltf.model.AnimationModel.Channel; import de.javagl.jgltf.model.AnimationModel.Interpolation; -import de.javagl.jgltf.model.BufferModel; -import de.javagl.jgltf.model.BufferViewModel; -import de.javagl.jgltf.model.CameraModel; -import de.javagl.jgltf.model.ElementType; -import de.javagl.jgltf.model.ExtensionsModel; -import de.javagl.jgltf.model.GltfConstants; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.ImageModel; -import de.javagl.jgltf.model.MaterialModel; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.Optionals; -import de.javagl.jgltf.model.SceneModel; -import de.javagl.jgltf.model.SkinModel; -import de.javagl.jgltf.model.TextureModel; -import de.javagl.jgltf.model.impl.AbstractModelElement; -import de.javagl.jgltf.model.impl.AbstractNamedModelElement; -import de.javagl.jgltf.model.impl.DefaultAccessorModel; -import de.javagl.jgltf.model.impl.DefaultAnimationModel; -import de.javagl.jgltf.model.impl.DefaultAssetModel; +import de.javagl.jgltf.model.impl.*; import de.javagl.jgltf.model.impl.DefaultAnimationModel.DefaultChannel; import de.javagl.jgltf.model.impl.DefaultAnimationModel.DefaultSampler; -import de.javagl.jgltf.model.impl.DefaultBufferModel; -import de.javagl.jgltf.model.impl.DefaultBufferViewModel; -import de.javagl.jgltf.model.impl.DefaultCameraModel; -import de.javagl.jgltf.model.impl.DefaultCameraOrthographicModel; -import de.javagl.jgltf.model.impl.DefaultCameraPerspectiveModel; -import de.javagl.jgltf.model.impl.DefaultExtensionsModel; -import de.javagl.jgltf.model.impl.DefaultGltfModel; -import de.javagl.jgltf.model.impl.DefaultImageModel; -import de.javagl.jgltf.model.impl.DefaultMeshModel; -import de.javagl.jgltf.model.impl.DefaultMeshPrimitiveModel; -import de.javagl.jgltf.model.impl.DefaultNodeModel; -import de.javagl.jgltf.model.impl.DefaultSceneModel; -import de.javagl.jgltf.model.impl.DefaultSkinModel; -import de.javagl.jgltf.model.impl.DefaultTextureModel; import de.javagl.jgltf.model.io.Buffers; import de.javagl.jgltf.model.io.GltfAsset; import de.javagl.jgltf.model.io.IO; @@ -122,70 +44,142 @@ import de.javagl.jgltf.model.v2.gl.Materials; import net.minecraft.resources.ResourceLocation; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.Map.Entry; +import java.util.function.Consumer; +import java.util.logging.Logger; + /** * A class that is responsible for filling a {@link DefaultGltfModel} with * the model instances that are created from a {@link GltfAssetV2} */ -public class GltfModelCreatorV2 -{ +public class GltfModelCreatorV2 { /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfModelCreatorV2.class.getName()); - - /** - * Create the {@link GltfModel} for the given {@link GltfAssetV2} - * - * @param gltfAsset The {@link GltfAssetV2} - * @return The {@link GltfModel} - */ - public static DefaultGltfModel create(GltfAssetV2 gltfAsset) - { - DefaultGltfModel gltfModel = new DefaultGltfModel(); - GltfModelCreatorV2 creator = - new GltfModelCreatorV2(gltfAsset, gltfModel); - creator.create(); - return gltfModel; - } - + private static final Logger logger = + Logger.getLogger(GltfModelCreatorV2.class.getName()); /** * The {@link GltfAsset} of the model */ private final GltfAsset gltfAsset; - /** * The {@link GlTF} of this model */ private final GlTF gltf; - /** * The {@link GltfModel} that is built */ private final DefaultGltfModel gltfModel; - + /** * Creates a new model for the given glTF - * + * * @param gltfAsset The {@link GltfAssetV2} * @param gltfModel The {@link GltfModel} */ - GltfModelCreatorV2(GltfAssetV2 gltfAsset, DefaultGltfModel gltfModel) - { - this.gltfAsset = Objects.requireNonNull(gltfAsset, - "The gltfAsset may not be null"); + GltfModelCreatorV2(GltfAssetV2 gltfAsset, DefaultGltfModel gltfModel) { + this.gltfAsset = Objects.requireNonNull(gltfAsset, + "The gltfAsset may not be null"); this.gltf = gltfAsset.getGltf(); - this.gltfModel = Objects.requireNonNull(gltfModel, - "The gltfModel may not be null"); + this.gltfModel = Objects.requireNonNull(gltfModel, + "The gltfModel may not be null"); + } + + /** + * Create the {@link GltfModel} for the given {@link GltfAssetV2} + * + * @param gltfAsset The {@link GltfAssetV2} + * @return The {@link GltfModel} + */ + public static DefaultGltfModel create(GltfAssetV2 gltfAsset) { + DefaultGltfModel gltfModel = new DefaultGltfModel(); + GltfModelCreatorV2 creator = + new GltfModelCreatorV2(gltfAsset, gltfModel); + creator.create(); + return gltfModel; } - + + /** + * Create a {@link DefaultBufferViewModel} for the given {@link BufferView} + * + * @param bufferView The {@link BufferView} + * @return The {@link BufferViewModel} + */ + private static DefaultBufferViewModel createBufferViewModel( + BufferView bufferView) { + int byteOffset = Optionals.of(bufferView.getByteOffset(), 0); + int byteLength = bufferView.getByteLength(); + Integer byteStride = bufferView.getByteStride(); + Integer target = bufferView.getTarget(); + DefaultBufferViewModel bufferViewModel = + new DefaultBufferViewModel(target); + bufferViewModel.setByteOffset(byteOffset); + bufferViewModel.setByteLength(byteLength); + bufferViewModel.setByteStride(byteStride); + return bufferViewModel; + } + + /** + * Create a new {@link BufferViewModel} with an associated + * {@link BufferModel} that serves as the basis for a sparse accessor, or + * an accessor that does not refer to a {@link BufferView}) + * + * @param uriString The URI string that will be assigned to the + * {@link BufferModel} that is created internally. This string + * is not strictly required, but helpful for debugging, at least + * @param bufferData The buffer data + * @return The new {@link BufferViewModel} + */ + private static DefaultBufferViewModel createBufferViewModel( + String uriString, ByteBuffer bufferData) { + DefaultBufferModel bufferModel = new DefaultBufferModel(); + bufferModel.setUri(uriString); + bufferModel.setBufferData(bufferData); + + DefaultBufferViewModel bufferViewModel = + new DefaultBufferViewModel(null); + bufferViewModel.setByteOffset(0); + bufferViewModel.setByteLength(bufferData.capacity()); + bufferViewModel.setBufferModel(bufferModel); + + return bufferViewModel; + } + + /** + * Transfer the extensions and extras from the given property to + * the given target + * + * @param property The property + * @param modelElement The target + */ + private static void transferGltfPropertyElements( + GlTFProperty property, AbstractModelElement modelElement) { + modelElement.setExtensions(property.getExtensions()); + modelElement.setExtras(property.getExtras()); + } + + /** + * Transfer the name and extensions and extras from the given property to + * the given target + * + * @param property The property + * @param modelElement The target + */ + private static void transferGltfChildOfRootPropertyElements( + GlTFChildOfRootProperty property, + AbstractNamedModelElement modelElement) { + modelElement.setName(property.getName()); + transferGltfPropertyElements(property, modelElement); + } + /** * Create and initialize all models */ - void create() - { + void create() { transferGltfPropertyElements(gltf, gltfModel); - + createAccessorModels(); createAnimationModels(); createBufferModels(); @@ -201,7 +195,7 @@ void create() initBufferModels(); initBufferViewModels(); - + initAccessorModels(); initAnimationModels(); initImageModels(); @@ -211,25 +205,23 @@ void create() initSkinModels(); initTextureModels(); initMaterialModels(); - + initExtensionsModel(); initAssetModel(); } - + /** * Create the {@link AccessorModel} instances */ - private void createAccessorModels() - { + private void createAccessorModels() { List accessors = Optionals.of(gltf.getAccessors()); - for (int i = 0; i < accessors.size(); i++) - { + for (int i = 0; i < accessors.size(); i++) { Accessor accessor = accessors.get(i); Integer componentType = accessor.getComponentType(); Integer count = accessor.getCount(); ElementType elementType = ElementType.forString(accessor.getType()); - DefaultAccessorModel accessorModel = new DefaultAccessorModel( - componentType, count, elementType); + DefaultAccessorModel accessorModel = new DefaultAccessorModel( + componentType, count, elementType); gltfModel.addAccessorModel(accessorModel); } } @@ -237,160 +229,120 @@ private void createAccessorModels() /** * Create the {@link AnimationModel} instances */ - private void createAnimationModels() - { + private void createAnimationModels() { List animations = Optionals.of(gltf.getAnimations()); - for (int i = 0; i < animations.size(); i++) - { + for (int i = 0; i < animations.size(); i++) { gltfModel.addAnimationModel(new DefaultAnimationModel()); } } - + /** * Create the {@link BufferModel} instances */ - private void createBufferModels() - { + private void createBufferModels() { List buffers = Optionals.of(gltf.getBuffers()); - for (int i = 0; i < buffers.size(); i++) - { + for (int i = 0; i < buffers.size(); i++) { Buffer buffer = buffers.get(i); DefaultBufferModel bufferModel = new DefaultBufferModel(); bufferModel.setUri(buffer.getUri()); gltfModel.addBufferModel(bufferModel); } } - + /** * Create the {@link CameraModel} instances */ - private void createCameraModels() - { + private void createCameraModels() { List cameras = Optionals.of(gltf.getCameras()); - for (int i = 0; i < cameras.size(); i++) - { + for (int i = 0; i < cameras.size(); i++) { Camera camera = cameras.get(i); String type = camera.getType(); - if ("perspective".equals(type)) - { + if ("perspective".equals(type)) { CameraPerspective cameraPerspective = camera.getPerspective(); - DefaultCameraPerspectiveModel cameraPerspectiveModel = - new DefaultCameraPerspectiveModel(); + DefaultCameraPerspectiveModel cameraPerspectiveModel = + new DefaultCameraPerspectiveModel(); cameraPerspectiveModel.setAspectRatio( - cameraPerspective.getAspectRatio()); + cameraPerspective.getAspectRatio()); cameraPerspectiveModel.setYfov( - cameraPerspective.getYfov()); + cameraPerspective.getYfov()); cameraPerspectiveModel.setZfar( - cameraPerspective.getZfar()); + cameraPerspective.getZfar()); cameraPerspectiveModel.setZnear( - cameraPerspective.getZnear()); - DefaultCameraModel cameraModel = - new DefaultCameraModel(); + cameraPerspective.getZnear()); + DefaultCameraModel cameraModel = + new DefaultCameraModel(); cameraModel.setCameraPerspectiveModel(cameraPerspectiveModel); gltfModel.addCameraModel(cameraModel); - } - else if ("orthographic".equals(type)) - { - CameraOrthographic cameraOrthographic = - camera.getOrthographic(); - DefaultCameraOrthographicModel cameraOrthographicModel = - new DefaultCameraOrthographicModel(); + } else if ("orthographic".equals(type)) { + CameraOrthographic cameraOrthographic = + camera.getOrthographic(); + DefaultCameraOrthographicModel cameraOrthographicModel = + new DefaultCameraOrthographicModel(); cameraOrthographicModel.setXmag( - cameraOrthographic.getXmag()); + cameraOrthographic.getXmag()); cameraOrthographicModel.setYmag( - cameraOrthographic.getYmag()); + cameraOrthographic.getYmag()); cameraOrthographicModel.setZfar( - cameraOrthographic.getZfar()); + cameraOrthographic.getZfar()); cameraOrthographicModel.setZnear( - cameraOrthographic.getZnear()); - DefaultCameraModel cameraModel = - new DefaultCameraModel(); + cameraOrthographic.getZnear()); + DefaultCameraModel cameraModel = + new DefaultCameraModel(); cameraModel.setCameraOrthographicModel(cameraOrthographicModel); gltfModel.addCameraModel(cameraModel); - } - else - { + } else { logger.severe("Invalid camera type: " + type); } } } - + /** * Create the {@link BufferViewModel} instances */ - private void createBufferViewModels() - { + private void createBufferViewModels() { List bufferViews = Optionals.of(gltf.getBufferViews()); - for (int i = 0; i < bufferViews.size(); i++) - { + for (int i = 0; i < bufferViews.size(); i++) { BufferView bufferView = bufferViews.get(i); - DefaultBufferViewModel bufferViewModel = - createBufferViewModel(bufferView); + DefaultBufferViewModel bufferViewModel = + createBufferViewModel(bufferView); gltfModel.addBufferViewModel(bufferViewModel); } } - /** - * Create a {@link DefaultBufferViewModel} for the given {@link BufferView} - * - * @param bufferView The {@link BufferView} - * @return The {@link BufferViewModel} - */ - private static DefaultBufferViewModel createBufferViewModel( - BufferView bufferView) - { - int byteOffset = Optionals.of(bufferView.getByteOffset(), 0); - int byteLength = bufferView.getByteLength(); - Integer byteStride = bufferView.getByteStride(); - Integer target = bufferView.getTarget(); - DefaultBufferViewModel bufferViewModel = - new DefaultBufferViewModel(target); - bufferViewModel.setByteOffset(byteOffset); - bufferViewModel.setByteLength(byteLength); - bufferViewModel.setByteStride(byteStride); - return bufferViewModel; - } - /** * Create the {@link ImageModel} instances */ - private void createImageModels() - { + private void createImageModels() { List images = Optionals.of(gltf.getImages()); - for (int i = 0; i < images.size(); i++) - { + for (int i = 0; i < images.size(); i++) { Image image = images.get(i); String mimeType = image.getMimeType(); - DefaultImageModel imageModel = - new DefaultImageModel(); + DefaultImageModel imageModel = + new DefaultImageModel(); imageModel.setMimeType(mimeType); String uri = image.getUri(); imageModel.setUri(uri); gltfModel.addImageModel(imageModel); } } - + /** * Create the {@link MaterialModel} instances */ - private void createMaterialModels() - { + private void createMaterialModels() { List materials = Optionals.of(gltf.getMaterials()); - for (int i = 0; i < materials.size(); i++) - { + for (int i = 0; i < materials.size(); i++) { MaterialModelV2 materialModel = new MaterialModelV2(); gltfModel.addMaterialModel(materialModel); } } - + /** * Create the {@link MeshModel} instances */ - private void createMeshModels() - { + private void createMeshModels() { List meshes = Optionals.of(gltf.getMeshes()); - for (int i = 0; i < meshes.size(); i++) - { + for (int i = 0; i < meshes.size(); i++) { gltfModel.addMeshModel(new DefaultMeshModel()); } } @@ -398,11 +350,9 @@ private void createMeshModels() /** * Create the {@link NodeModel} instances */ - private void createNodeModels() - { + private void createNodeModels() { List nodes = Optionals.of(gltf.getNodes()); - for (int i = 0; i < nodes.size(); i++) - { + for (int i = 0; i < nodes.size(); i++) { gltfModel.addNodeModel(new DefaultNodeModel()); } } @@ -410,55 +360,48 @@ private void createNodeModels() /** * Create the {@link SceneModel} instances */ - private void createSceneModels() - { + private void createSceneModels() { List scenes = Optionals.of(gltf.getScenes()); - for (int i = 0; i < scenes.size(); i++) - { + for (int i = 0; i < scenes.size(); i++) { gltfModel.addSceneModel(new DefaultSceneModel()); } } - + /** * Create the {@link SkinModel} instances */ - private void createSkinModels() - { + private void createSkinModels() { List skins = Optionals.of(gltf.getSkins()); - for (int i = 0; i < skins.size(); i++) - { + for (int i = 0; i < skins.size(); i++) { gltfModel.addSkinModel(new DefaultSkinModel()); } } - + /** * Create the {@link TextureModel} instances */ - private void createTextureModels() - { + private void createTextureModels() { List textures = Optionals.of(gltf.getTextures()); List samplers = Optionals.of(gltf.getSamplers()); - for (int i = 0; i < textures.size(); i++) - { + for (int i = 0; i < textures.size(); i++) { Texture texture = textures.get(i); Integer samplerIndex = texture.getSampler(); - + Integer magFilter = GltfConstants.GL_LINEAR; Integer minFilter = GltfConstants.GL_LINEAR; Integer wrapS = GltfConstants.GL_REPEAT; Integer wrapT = GltfConstants.GL_REPEAT; - - if (samplerIndex != null) - { + + if (samplerIndex != null) { Sampler sampler = samplers.get(samplerIndex); magFilter = sampler.getMagFilter(); minFilter = sampler.getMinFilter(); wrapS = Optionals.of( - sampler.getWrapS(), sampler.defaultWrapS()); + sampler.getWrapS(), sampler.defaultWrapS()); wrapT = Optionals.of( - sampler.getWrapT(), sampler.defaultWrapT()); + sampler.getWrapT(), sampler.defaultWrapT()); } - + DefaultTextureModel textureModel = new DefaultTextureModel(); textureModel.setMagFilter(magFilter); textureModel.setMinFilter(minFilter); @@ -467,69 +410,58 @@ private void createTextureModels() gltfModel.addTextureModel(textureModel); } } - + /** * Initialize the {@link AccessorModel} instances */ - private void initAccessorModels() - { + private void initAccessorModels() { List accessors = Optionals.of(gltf.getAccessors()); - for (int i = 0; i < accessors.size(); i++) - { + for (int i = 0; i < accessors.size(); i++) { Accessor accessor = accessors.get(i); - DefaultAccessorModel accessorModel = - gltfModel.getAccessorModel(i); + DefaultAccessorModel accessorModel = + gltfModel.getAccessorModel(i); transferGltfChildOfRootPropertyElements(accessor, accessorModel); - + int byteOffset = Optionals.of(accessor.getByteOffset(), 0); accessorModel.setByteOffset(byteOffset); - + Boolean normalized = accessor.isNormalized(); accessorModel.setNormalized(Boolean.TRUE.equals(normalized)); AccessorSparse accessorSparse = accessor.getSparse(); - if (accessorSparse == null) - { + if (accessorSparse == null) { initDenseAccessorModel(i, accessor, accessorModel); - } - else - { + } else { initSparseAccessorModel(i, accessor, accessorModel); } } } - /** - * Initialize the {@link AccessorModel} by setting its + * Initialize the {@link AccessorModel} by setting its * {@link AccessorModel#getBufferViewModel() buffer view model} * for the case that the accessor is dense (i.e. not sparse) - * + * * @param accessorIndex The accessor index. Only used for constructing - * the URI string of buffers that may have to be created internally - * @param accessor The {@link Accessor} + * the URI string of buffers that may have to be created internally + * @param accessor The {@link Accessor} * @param accessorModel The {@link AccessorModel} */ private void initDenseAccessorModel(int accessorIndex, - Accessor accessor, DefaultAccessorModel accessorModel) - { + Accessor accessor, DefaultAccessorModel accessorModel) { Integer bufferViewIndex = accessor.getBufferView(); - if (bufferViewIndex != null) - { - // When there is a BufferView referenced from the accessor, then + if (bufferViewIndex != null) { + // When there is a BufferView referenced from the accessor, then // the corresponding BufferViewModel may be assigned directly - BufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); + BufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); accessorModel.setBufferViewModel(bufferViewModel); Integer byteStride = bufferViewModel.getByteStride(); - if (byteStride != null) - { + if (byteStride != null) { accessorModel.setByteStride(byteStride); } accessorModel.setAccessorData(AccessorDatas.create(accessorModel)); - } - else - { + } else { // When there is no BufferView referenced from the accessor, // then a NEW BufferViewModel (and Buffer) have to be created int count = accessorModel.getCount(); @@ -537,334 +469,279 @@ private void initDenseAccessorModel(int accessorIndex, int byteLength = elementSizeInBytes * count; ByteBuffer bufferData = Buffers.create(byteLength); String uriString = "buffer_for_accessor" + accessorIndex + ".bin"; - BufferViewModel bufferViewModel = - createBufferViewModel(uriString, bufferData); + BufferViewModel bufferViewModel = + createBufferViewModel(uriString, bufferData); accessorModel.setBufferViewModel(bufferViewModel); accessorModel.setAccessorData(AccessorDatas.create(accessorModel)); } } - + /** - * Initialize the given {@link AccessorModel} by setting its + * Initialize the given {@link AccessorModel} by setting its * {@link AccessorModel#getBufferViewModel() buffer view model} - * for the case that the accessor is sparse. - * + * for the case that the accessor is sparse. + * * @param accessorIndex The accessor index. Only used for constructing - * the URI string of buffers that may have to be created internally - * @param accessor The {@link Accessor} + * the URI string of buffers that may have to be created internally + * @param accessor The {@link Accessor} * @param accessorModel The {@link AccessorModel} */ private void initSparseAccessorModel(int accessorIndex, - Accessor accessor, DefaultAccessorModel accessorModel) - { + Accessor accessor, DefaultAccessorModel accessorModel) { // When the (sparse!) Accessor already refers to a BufferView, // then this BufferView has to be replaced with a new one, - // to which the data substitution will be applied + // to which the data substitution will be applied int count = accessorModel.getCount(); int elementSizeInBytes = accessorModel.getElementSizeInBytes(); int byteLength = elementSizeInBytes * count; ByteBuffer bufferData = Buffers.create(byteLength); String uriString = "buffer_for_accessor" + accessorIndex + ".bin"; - DefaultBufferViewModel denseBufferViewModel = - createBufferViewModel(uriString, bufferData); + DefaultBufferViewModel denseBufferViewModel = + createBufferViewModel(uriString, bufferData); accessorModel.setBufferViewModel(denseBufferViewModel); accessorModel.setByteOffset(0); - + Integer bufferViewIndex = accessor.getBufferView(); - if (bufferViewIndex != null) - { + if (bufferViewIndex != null) { // If the accessor refers to a BufferView, then the corresponding - // data serves as the basis for the initialization of the values, + // data serves as the basis for the initialization of the values, // before the sparse substitution is applied - Consumer sparseSubstitutionCallback = denseByteBuffer -> + Consumer sparseSubstitutionCallback = denseByteBuffer -> { logger.fine("Substituting sparse accessor data," - + " based on existing buffer view"); - - DefaultBufferViewModel baseBufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); - ByteBuffer baseBufferViewData = - baseBufferViewModel.getBufferViewData(); + + " based on existing buffer view"); + + DefaultBufferViewModel baseBufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); + ByteBuffer baseBufferViewData = + baseBufferViewModel.getBufferViewData(); AccessorData baseAccessorData = AccessorDatas.create( - accessorModel, baseBufferViewData); - AccessorData denseAccessorData = - AccessorDatas.create(accessorModel, bufferData); - substituteSparseAccessorData(accessor, accessorModel, - denseAccessorData, baseAccessorData); + accessorModel, baseBufferViewData); + AccessorData denseAccessorData = + AccessorDatas.create(accessorModel, bufferData); + substituteSparseAccessorData(accessor, accessorModel, + denseAccessorData, baseAccessorData); }; denseBufferViewModel.setSparseSubstitutionCallback( - sparseSubstitutionCallback); - } - else - { + sparseSubstitutionCallback); + } else { // When the sparse accessor does not yet refer to a BufferView, - // then a new one is created, - Consumer sparseSubstitutionCallback = denseByteBuffer -> + // then a new one is created, + Consumer sparseSubstitutionCallback = denseByteBuffer -> { logger.fine("Substituting sparse accessor data, " - + "without an existing buffer view"); - - AccessorData denseAccessorData = - AccessorDatas.create(accessorModel, bufferData); - substituteSparseAccessorData(accessor, accessorModel, - denseAccessorData, null); + + "without an existing buffer view"); + + AccessorData denseAccessorData = + AccessorDatas.create(accessorModel, bufferData); + substituteSparseAccessorData(accessor, accessorModel, + denseAccessorData, null); }; denseBufferViewModel.setSparseSubstitutionCallback( - sparseSubstitutionCallback); + sparseSubstitutionCallback); } } - - /** - * Create a new {@link BufferViewModel} with an associated - * {@link BufferModel} that serves as the basis for a sparse accessor, or - * an accessor that does not refer to a {@link BufferView}) - * - * @param uriString The URI string that will be assigned to the - * {@link BufferModel} that is created internally. This string - * is not strictly required, but helpful for debugging, at least - * @param bufferData The buffer data - * @return The new {@link BufferViewModel} - */ - private static DefaultBufferViewModel createBufferViewModel( - String uriString, ByteBuffer bufferData) - { - DefaultBufferModel bufferModel = new DefaultBufferModel(); - bufferModel.setUri(uriString); - bufferModel.setBufferData(bufferData); - DefaultBufferViewModel bufferViewModel = - new DefaultBufferViewModel(null); - bufferViewModel.setByteOffset(0); - bufferViewModel.setByteLength(bufferData.capacity()); - bufferViewModel.setBufferModel(bufferModel); - - return bufferViewModel; - } - /** - * Substitute the sparse accessor data in the given dense + * Substitute the sparse accessor data in the given dense * {@link AccessorData} for the given {@link AccessorModel} - * based on the sparse accessor data that is defined in the given + * based on the sparse accessor data that is defined in the given * {@link Accessor}. - * - * @param accessor The {@link Accessor} - * @param accessorModel The {@link AccessorModel} + * + * @param accessor The {@link Accessor} + * @param accessorModel The {@link AccessorModel} * @param denseAccessorData The dense {@link AccessorData} - * @param baseAccessorData The optional {@link AccessorData} that contains - * the base data. If this is not null, then it will be used - * to initialize the {@link AccessorData}, before the sparse data - * substitution takes place + * @param baseAccessorData The optional {@link AccessorData} that contains + * the base data. If this is not null, then it will be used + * to initialize the {@link AccessorData}, before the sparse data + * substitution takes place */ private void substituteSparseAccessorData( - Accessor accessor, AccessorModel accessorModel, - AccessorData denseAccessorData, AccessorData baseAccessorData) - { + Accessor accessor, AccessorModel accessorModel, + AccessorData denseAccessorData, AccessorData baseAccessorData) { AccessorSparse accessorSparse = accessor.getSparse(); int count = accessorSparse.getCount(); - - AccessorSparseIndices accessorSparseIndices = - accessorSparse.getIndices(); - AccessorData sparseIndicesAccessorData = - createSparseIndicesAccessorData(accessorSparseIndices, count); - + + AccessorSparseIndices accessorSparseIndices = + accessorSparse.getIndices(); + AccessorData sparseIndicesAccessorData = + createSparseIndicesAccessorData(accessorSparseIndices, count); + AccessorSparseValues accessorSparseValues = accessorSparse.getValues(); ElementType elementType = accessorModel.getElementType(); AccessorData sparseValuesAccessorData = - createSparseValuesAccessorData(accessorSparseValues, - accessorModel.getComponentType(), - elementType, count); - + createSparseValuesAccessorData(accessorSparseValues, + accessorModel.getComponentType(), + elementType, count); + AccessorSparseUtils.substituteAccessorData( - denseAccessorData, - baseAccessorData, - sparseIndicesAccessorData, - sparseValuesAccessorData); + denseAccessorData, + baseAccessorData, + sparseIndicesAccessorData, + sparseValuesAccessorData); } - - + /** - * Create the {@link AccessorData} for the given + * Create the {@link AccessorData} for the given * {@link AccessorSparseIndices} - * + * * @param accessorSparseIndices The {@link AccessorSparseIndices} - * @param count The count from the {@link AccessorSparse} + * @param count The count from the {@link AccessorSparse} * @return The {@link AccessorData} */ private AccessorData createSparseIndicesAccessorData( - AccessorSparseIndices accessorSparseIndices, int count) - { + AccessorSparseIndices accessorSparseIndices, int count) { Integer componentType = accessorSparseIndices.getComponentType(); Integer bufferViewIndex = accessorSparseIndices.getBufferView(); - BufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); + BufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); ByteBuffer bufferViewData = bufferViewModel.getBufferViewData(); int byteOffset = Optionals.of(accessorSparseIndices.getByteOffset(), 0); return AccessorDatas.create( - componentType, bufferViewData, byteOffset, - count, ElementType.SCALAR, null); + componentType, bufferViewData, byteOffset, + count, ElementType.SCALAR, null); } - + /** - * Create the {@link AccessorData} for the given + * Create the {@link AccessorData} for the given * {@link AccessorSparseValues} - * + * * @param accessorSparseValues The {@link AccessorSparseValues} - * @param componentType The component type of the {@link Accessor} - * @param elementType The {@link ElementType} - * of the {@link AccessorModel#getElementType() accessor element type} - * @param count The count from the {@link AccessorSparse} + * @param componentType The component type of the {@link Accessor} + * @param elementType The {@link ElementType} + * of the {@link AccessorModel#getElementType() accessor element type} + * @param count The count from the {@link AccessorSparse} * @return The {@link AccessorData} */ private AccessorData createSparseValuesAccessorData( - AccessorSparseValues accessorSparseValues, - int componentType, ElementType elementType, int count) - { + AccessorSparseValues accessorSparseValues, + int componentType, ElementType elementType, int count) { Integer bufferViewIndex = accessorSparseValues.getBufferView(); - BufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); + BufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); ByteBuffer bufferViewData = bufferViewModel.getBufferViewData(); int byteOffset = Optionals.of(accessorSparseValues.getByteOffset(), 0); return AccessorDatas.create( - componentType, bufferViewData, byteOffset, count, - elementType, null); + componentType, bufferViewData, byteOffset, count, + elementType, null); } - + /** * Initialize the {@link AnimationModel} instances */ - private void initAnimationModels() - { + private void initAnimationModels() { List animations = Optionals.of(gltf.getAnimations()); - for (int i = 0; i < animations.size(); i++) - { + for (int i = 0; i < animations.size(); i++) { Animation animation = animations.get(i); - DefaultAnimationModel animationModel = - gltfModel.getAnimationModel(i); + DefaultAnimationModel animationModel = + gltfModel.getAnimationModel(i); transferGltfChildOfRootPropertyElements(animation, animationModel); - - List channels = - Optionals.of(animation.getChannels()); - for (AnimationChannel animationChannel : channels) - { + + List channels = + Optionals.of(animation.getChannels()); + for (AnimationChannel animationChannel : channels) { Channel channel = createChannel(animation, animationChannel); animationModel.addChannel(channel); } } } - + /** * Create the {@link Channel} object for the given animation and animation * channel - * - * @param animation The {@link Animation} + * + * @param animation The {@link Animation} * @param animationChannel The {@link AnimationChannel} * @return The {@link Channel} */ private Channel createChannel( - Animation animation, AnimationChannel animationChannel) - { - List samplers = - Optionals.of(animation.getSamplers()); + Animation animation, AnimationChannel animationChannel) { + List samplers = + Optionals.of(animation.getSamplers()); int samplerIndex = animationChannel.getSampler(); AnimationSampler animationSampler = samplers.get(samplerIndex); - + int inputAccessorIndex = animationSampler.getInput(); - AccessorModel inputAccessorModel = - gltfModel.getAccessorModel(inputAccessorIndex); - + AccessorModel inputAccessorModel = + gltfModel.getAccessorModel(inputAccessorIndex); + int outputAccessorIndex = animationSampler.getOutput(); - AccessorModel outputAccessorModel = - gltfModel.getAccessorModel(outputAccessorIndex); - - String interpolationString = - animationSampler.getInterpolation(); - Interpolation interpolation = - interpolationString == null ? Interpolation.LINEAR : - Interpolation.valueOf(interpolationString); - + AccessorModel outputAccessorModel = + gltfModel.getAccessorModel(outputAccessorIndex); + + String interpolationString = + animationSampler.getInterpolation(); + Interpolation interpolation = + interpolationString == null ? Interpolation.LINEAR : + Interpolation.valueOf(interpolationString); + AnimationModel.Sampler sampler = new DefaultSampler( - inputAccessorModel, interpolation, outputAccessorModel); - - AnimationChannelTarget animationChannelTarget = - animationChannel.getTarget(); - + inputAccessorModel, interpolation, outputAccessorModel); + + AnimationChannelTarget animationChannelTarget = + animationChannel.getTarget(); + Integer nodeIndex = animationChannelTarget.getNode(); NodeModel nodeModel = null; - if (nodeIndex == null) - { + if (nodeIndex == null) { // Should not happen yet. Targets always refer to nodes logger.warning("No node index given for animation channel target"); - } - else - { + } else { nodeModel = gltfModel.getNodeModel(nodeIndex); } String path = animationChannelTarget.getPath(); - - AnimationModel.Channel channel = - new DefaultChannel(sampler, nodeModel, path); + + Channel channel = + new DefaultChannel(sampler, nodeModel, path); return channel; } /** * Initialize the {@link BufferModel} instances */ - private void initBufferModels() - { + private void initBufferModels() { List buffers = Optionals.of(gltf.getBuffers()); ByteBuffer binaryData = null; ByteBuffer b = gltfAsset.getBinaryData(); - if (b != null && b.capacity() > 0) - { + if (b != null && b.capacity() > 0) { binaryData = b; } - - if (buffers.isEmpty() && binaryData != null) - { + + if (buffers.isEmpty() && binaryData != null) { logger.warning("Binary data was given, but no buffers"); return; } - for (int i = 0; i < buffers.size(); i++) - { + for (int i = 0; i < buffers.size(); i++) { Buffer buffer = buffers.get(i); DefaultBufferModel bufferModel = gltfModel.getBufferModel(i); transferGltfChildOfRootPropertyElements(buffer, bufferModel); - + Object extras = buffer.getExtras(); - if(extras != null) { - JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); - if(extra != null) { - bufferModel.setBufferData(MCglTF.getInstance().getBufferResource(new ResourceLocation(extra.getAsString()))); - continue; - } - } - - if (i == 0 && binaryData != null) - { - bufferModel.setBufferData(binaryData); + if (extras != null) { + JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); + if (extra != null) { + bufferModel.setBufferData(MCglTF.getInstance().getBufferResource(new ResourceLocation(extra.getAsString()))); + continue; + } } - else - { + + if (i == 0 && binaryData != null) { + bufferModel.setBufferData(binaryData); + } else { String uri = buffer.getUri(); - if (IO.isDataUriString(uri)) - { + if (IO.isDataUriString(uri)) { byte data[] = IO.readDataUri(uri); ByteBuffer bufferData = Buffers.create(data); bufferModel.setBufferData(bufferData); - } - else - { - if (uri == null) - { + } else { + if (uri == null) { logger.warning("Buffer " + i + " does not have " - + "a uri. Binary chunks that are not the main GLB " - + "buffer are not supported."); - } - else - { + + "a uri. Binary chunks that are not the main GLB " + + "buffer are not supported."); + } else { ByteBuffer bufferData = gltfAsset.getReferenceData(uri); bufferModel.setBufferData(bufferData); } @@ -872,157 +749,138 @@ private void initBufferModels() } } } - - + /** * Initialize the {@link BufferViewModel} instances */ - private void initBufferViewModels() - { + private void initBufferViewModels() { List bufferViews = Optionals.of(gltf.getBufferViews()); - for (int i = 0; i < bufferViews.size(); i++) - { + for (int i = 0; i < bufferViews.size(); i++) { BufferView bufferView = bufferViews.get(i); - - DefaultBufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(i); + + DefaultBufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(i); transferGltfChildOfRootPropertyElements( - bufferView, bufferViewModel); - + bufferView, bufferViewModel); + int bufferIndex = bufferView.getBuffer(); BufferModel bufferModel = gltfModel.getBufferModel(bufferIndex); bufferViewModel.setBufferModel(bufferModel); } } - /** * Initialize the {@link MeshModel} instances */ - private void initMeshModels() - { + private void initMeshModels() { List meshes = Optionals.of(gltf.getMeshes()); - for (int i = 0; i < meshes.size(); i++) - { + for (int i = 0; i < meshes.size(); i++) { Mesh mesh = meshes.get(i); DefaultMeshModel meshModel = gltfModel.getMeshModel(i); transferGltfChildOfRootPropertyElements(mesh, meshModel); - - List primitives = - Optionals.of(mesh.getPrimitives()); - for (MeshPrimitive meshPrimitive : primitives) - { - MeshPrimitiveModel meshPrimitiveModel = - createMeshPrimitiveModel(meshPrimitive); + + List primitives = + Optionals.of(mesh.getPrimitives()); + for (MeshPrimitive meshPrimitive : primitives) { + MeshPrimitiveModel meshPrimitiveModel = + createMeshPrimitiveModel(meshPrimitive); meshModel.addMeshPrimitiveModel(meshPrimitiveModel); } } } - + /** - * Create a {@link MeshPrimitiveModel} for the given + * Create a {@link MeshPrimitiveModel} for the given * {@link MeshPrimitive}.
    - * + * * @param meshPrimitive The {@link MeshPrimitive} * @return The {@link MeshPrimitiveModel} */ private DefaultMeshPrimitiveModel createMeshPrimitiveModel( - MeshPrimitive meshPrimitive) - { + MeshPrimitive meshPrimitive) { Integer mode = Optionals.of( - meshPrimitive.getMode(), - meshPrimitive.defaultMode()); - DefaultMeshPrimitiveModel meshPrimitiveModel = - new DefaultMeshPrimitiveModel(mode); + meshPrimitive.getMode(), + meshPrimitive.defaultMode()); + DefaultMeshPrimitiveModel meshPrimitiveModel = + new DefaultMeshPrimitiveModel(mode); transferGltfPropertyElements(meshPrimitive, meshPrimitiveModel); - + Integer indicesIndex = meshPrimitive.getIndices(); - if (indicesIndex != null) - { + if (indicesIndex != null) { AccessorModel indices = gltfModel.getAccessorModel(indicesIndex); meshPrimitiveModel.setIndices(indices); } - Map attributes = - Optionals.of(meshPrimitive.getAttributes()); - for (Entry entry : attributes.entrySet()) - { + Map attributes = + Optionals.of(meshPrimitive.getAttributes()); + for (Entry entry : attributes.entrySet()) { String attributeName = entry.getKey(); int attributeIndex = entry.getValue(); - AccessorModel attribute = - gltfModel.getAccessorModel(attributeIndex); + AccessorModel attribute = + gltfModel.getAccessorModel(attributeIndex); meshPrimitiveModel.putAttribute(attributeName, attribute); } - + List> morphTargets = - Optionals.of(meshPrimitive.getTargets()); - for (Map morphTarget : morphTargets) - { - Map morphTargetModel = - new LinkedHashMap(); - for (Entry entry : morphTarget.entrySet()) - { + Optionals.of(meshPrimitive.getTargets()); + for (Map morphTarget : morphTargets) { + Map morphTargetModel = + new LinkedHashMap(); + for (Entry entry : morphTarget.entrySet()) { String attribute = entry.getKey(); Integer accessorIndex = entry.getValue(); - AccessorModel accessorModel = - gltfModel.getAccessorModel(accessorIndex); + AccessorModel accessorModel = + gltfModel.getAccessorModel(accessorIndex); morphTargetModel.put(attribute, accessorModel); } meshPrimitiveModel.addTarget( - Collections.unmodifiableMap(morphTargetModel)); + Collections.unmodifiableMap(morphTargetModel)); } - + Integer materialIndex = meshPrimitive.getMaterial(); - if (materialIndex != null) - { - MaterialModelV2 materialModel = - (MaterialModelV2) gltfModel.getMaterialModel(materialIndex); + if (materialIndex != null) { + MaterialModelV2 materialModel = + (MaterialModelV2) gltfModel.getMaterialModel(materialIndex); meshPrimitiveModel.setMaterialModel(materialModel); } - + return meshPrimitiveModel; } /** * Initialize the {@link NodeModel} instances */ - private void initNodeModels() - { + private void initNodeModels() { List nodes = Optionals.of(gltf.getNodes()); - for (int i = 0; i < nodes.size(); i++) - { + for (int i = 0; i < nodes.size(); i++) { Node node = nodes.get(i); - + DefaultNodeModel nodeModel = gltfModel.getNodeModel(i); - transferGltfChildOfRootPropertyElements(node, nodeModel); - + transferGltfChildOfRootPropertyElements(node, nodeModel); + List childIndices = Optionals.of(node.getChildren()); - for (Integer childIndex : childIndices) - { + for (Integer childIndex : childIndices) { DefaultNodeModel child = gltfModel.getNodeModel(childIndex); nodeModel.addChild(child); } - + Integer meshIndex = node.getMesh(); - if (meshIndex != null) - { + if (meshIndex != null) { MeshModel meshModel = gltfModel.getMeshModel(meshIndex); nodeModel.addMeshModel(meshModel); } - + Integer skinIndex = node.getSkin(); - if (skinIndex != null) - { + if (skinIndex != null) { SkinModel skinModel = gltfModel.getSkinModel(skinIndex); nodeModel.setSkinModel(skinModel); } - + Integer cameraIndex = node.getCamera(); - if (cameraIndex != null) - { + if (cameraIndex != null) { CameraModel cameraModel = gltfModel.getCameraModel(cameraIndex); nodeModel.setCameraModel(cameraModel); } - + float matrix[] = node.getMatrix(); float translation[] = node.getTranslation(); float rotation[] = node.getRotation(); @@ -1031,275 +889,244 @@ private void initNodeModels() nodeModel.setTranslation(Optionals.clone(translation)); nodeModel.setRotation(Optionals.clone(rotation)); nodeModel.setScale(Optionals.clone(scale)); - + List weights = node.getWeights(); - if (weights != null) - { + if (weights != null) { float weightsArray[] = new float[weights.size()]; - for (int j = 0; j < weights.size(); j++) - { + for (int j = 0; j < weights.size(); j++) { weightsArray[j] = weights.get(j); } nodeModel.setWeights(weightsArray); } } } - /** * Initialize the {@link SceneModel} instances */ - private void initSceneModels() - { + private void initSceneModels() { List scenes = Optionals.of(gltf.getScenes()); - for (int i = 0; i < scenes.size(); i++) - { + for (int i = 0; i < scenes.size(); i++) { Scene scene = scenes.get(i); DefaultSceneModel sceneModel = gltfModel.getSceneModel(i); - transferGltfChildOfRootPropertyElements(scene, sceneModel); - + transferGltfChildOfRootPropertyElements(scene, sceneModel); + List nodeIndices = Optionals.of(scene.getNodes()); - for (Integer nodeIndex : nodeIndices) - { + for (Integer nodeIndex : nodeIndices) { NodeModel nodeModel = gltfModel.getNodeModel(nodeIndex); sceneModel.addNode(nodeModel); } } } - + /** * Initialize the {@link SkinModel} instances */ - private void initSkinModels() - { + private void initSkinModels() { List skins = Optionals.of(gltf.getSkins()); - for (int i = 0; i < skins.size(); i++) - { + for (int i = 0; i < skins.size(); i++) { Skin skin = skins.get(i); DefaultSkinModel skinModel = gltfModel.getSkinModel(i); transferGltfChildOfRootPropertyElements(skin, skinModel); - + List jointIndices = skin.getJoints(); - for (Integer jointIndex : jointIndices) - { + for (Integer jointIndex : jointIndices) { NodeModel jointNodeModel = gltfModel.getNodeModel(jointIndex); skinModel.addJoint(jointNodeModel); } - + Integer inverseBindMatricesIndex = skin.getInverseBindMatrices(); - AccessorModel inverseBindMatrices = - gltfModel.getAccessorModel(inverseBindMatricesIndex); + AccessorModel inverseBindMatrices = + gltfModel.getAccessorModel(inverseBindMatricesIndex); skinModel.setInverseBindMatrices(inverseBindMatrices); } } - + /** * Initialize the {@link TextureModel} instances */ - private void initTextureModels() - { + private void initTextureModels() { List textures = Optionals.of(gltf.getTextures()); - for (int i = 0; i < textures.size(); i++) - { + for (int i = 0; i < textures.size(); i++) { Texture texture = textures.get(i); DefaultTextureModel textureModel = gltfModel.getTextureModel(i); transferGltfChildOfRootPropertyElements(texture, textureModel); - + // The source may be null when the image data is provided // by an extension. Integer imageIndex = texture.getSource(); - if (imageIndex != null) - { - DefaultImageModel imageModel = - gltfModel.getImageModel(imageIndex); + if (imageIndex != null) { + DefaultImageModel imageModel = + gltfModel.getImageModel(imageIndex); textureModel.setImageModel(imageModel); } } } - + /** * Initialize the {@link ImageModel} instances */ - private void initImageModels() - { + private void initImageModels() { List images = Optionals.of(gltf.getImages()); - for (int i = 0; i < images.size(); i++) - { + for (int i = 0; i < images.size(); i++) { Image image = images.get(i); DefaultImageModel imageModel = gltfModel.getImageModel(i); transferGltfChildOfRootPropertyElements(image, imageModel); - + Object extras = image.getExtras(); - if(extras != null) { - JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); - if(extra != null) { - imageModel.setImageData(MCglTF.getInstance().getImageResource(new ResourceLocation(extra.getAsString()))); - continue; - } - } - + if (extras != null) { + JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); + if (extra != null) { + imageModel.setImageData(MCglTF.getInstance().getImageResource(new ResourceLocation(extra.getAsString()))); + continue; + } + } + Integer bufferViewIndex = image.getBufferView(); - if (bufferViewIndex != null) - { - BufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); + if (bufferViewIndex != null) { + BufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); imageModel.setBufferViewModel(bufferViewModel); - } - else - { + } else { String uri = image.getUri(); - if (IO.isDataUriString(uri)) - { + if (IO.isDataUriString(uri)) { byte data[] = IO.readDataUri(uri); ByteBuffer imageData = Buffers.create(data); imageModel.setImageData(imageData); - } - else - { + } else { ByteBuffer imageData = gltfAsset.getReferenceData(uri); imageModel.setImageData(imageData); } } } } - + /** * Initialize the {@link MaterialModel} instances */ - private void initMaterialModels() - { + private void initMaterialModels() { List materials = Optionals.of(gltf.getMaterials()); - for (int i = 0; i < materials.size(); i++) - { + for (int i = 0; i < materials.size(); i++) { Material material = materials.get(i); - MaterialModelV2 materialModel = - (MaterialModelV2) gltfModel.getMaterialModel(i); - - transferGltfChildOfRootPropertyElements(material, materialModel); + MaterialModelV2 materialModel = + (MaterialModelV2) gltfModel.getMaterialModel(i); + + transferGltfChildOfRootPropertyElements(material, materialModel); initMaterialModel(materialModel, material); } } - + /** * Initialize the given {@link MaterialModelV2} based on the given * {@link Material} - * + * * @param materialModel The {@link MaterialModelV2} - * @param material The {@link Material} + * @param material The {@link Material} */ private void initMaterialModel( - MaterialModelV2 materialModel, Material material) - { - MaterialPbrMetallicRoughness pbrMetallicRoughness = - material.getPbrMetallicRoughness(); - if (pbrMetallicRoughness == null) - { - pbrMetallicRoughness = - Materials.createDefaultMaterialPbrMetallicRoughness(); + MaterialModelV2 materialModel, Material material) { + MaterialPbrMetallicRoughness pbrMetallicRoughness = + material.getPbrMetallicRoughness(); + if (pbrMetallicRoughness == null) { + pbrMetallicRoughness = + Materials.createDefaultMaterialPbrMetallicRoughness(); } - + String alphaModeString = material.getAlphaMode(); - if (alphaModeString != null) - { + if (alphaModeString != null) { materialModel.setAlphaMode(AlphaMode.valueOf(alphaModeString)); } materialModel.setAlphaCutoff( - Optionals.of(material.getAlphaCutoff(), 0.5f)); - + Optionals.of(material.getAlphaCutoff(), 0.5f)); + materialModel.setDoubleSided( - Boolean.TRUE.equals(material.isDoubleSided())); - - TextureInfo baseColorTextureInfo = - pbrMetallicRoughness.getBaseColorTexture(); - if (baseColorTextureInfo != null) - { + Boolean.TRUE.equals(material.isDoubleSided())); + + TextureInfo baseColorTextureInfo = + pbrMetallicRoughness.getBaseColorTexture(); + if (baseColorTextureInfo != null) { int index = baseColorTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setBaseColorTexture(textureModel); materialModel.setBaseColorTexcoord( - baseColorTextureInfo.getTexCoord()); + baseColorTextureInfo.getTexCoord()); } float[] baseColorFactor = Optionals.of( - pbrMetallicRoughness.getBaseColorFactor(), - pbrMetallicRoughness.defaultBaseColorFactor()); + pbrMetallicRoughness.getBaseColorFactor(), + pbrMetallicRoughness.defaultBaseColorFactor()); materialModel.setBaseColorFactor(baseColorFactor); - - TextureInfo metallicRoughnessTextureInfo = - pbrMetallicRoughness.getMetallicRoughnessTexture(); - if (metallicRoughnessTextureInfo != null) - { + + TextureInfo metallicRoughnessTextureInfo = + pbrMetallicRoughness.getMetallicRoughnessTexture(); + if (metallicRoughnessTextureInfo != null) { int index = metallicRoughnessTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setMetallicRoughnessTexture(textureModel); materialModel.setMetallicRoughnessTexcoord( - metallicRoughnessTextureInfo.getTexCoord()); + metallicRoughnessTextureInfo.getTexCoord()); } float metallicFactor = Optionals.of( - pbrMetallicRoughness.getMetallicFactor(), - pbrMetallicRoughness.defaultMetallicFactor()); + pbrMetallicRoughness.getMetallicFactor(), + pbrMetallicRoughness.defaultMetallicFactor()); materialModel.setMetallicFactor(metallicFactor); - + float roughnessFactor = Optionals.of( - pbrMetallicRoughness.getRoughnessFactor(), - pbrMetallicRoughness.defaultRoughnessFactor()); + pbrMetallicRoughness.getRoughnessFactor(), + pbrMetallicRoughness.defaultRoughnessFactor()); materialModel.setRoughnessFactor(roughnessFactor); - - MaterialNormalTextureInfo normalTextureInfo = - material.getNormalTexture(); - if (normalTextureInfo != null) - { + + MaterialNormalTextureInfo normalTextureInfo = + material.getNormalTexture(); + if (normalTextureInfo != null) { int index = normalTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setNormalTexture(textureModel); materialModel.setNormalTexcoord( - normalTextureInfo.getTexCoord()); - + normalTextureInfo.getTexCoord()); + float normalScale = Optionals.of( - normalTextureInfo.getScale(), - normalTextureInfo.defaultScale()); + normalTextureInfo.getScale(), + normalTextureInfo.defaultScale()); materialModel.setNormalScale(normalScale); } - MaterialOcclusionTextureInfo occlusionTextureInfo = - material.getOcclusionTexture(); - if (occlusionTextureInfo != null) - { + MaterialOcclusionTextureInfo occlusionTextureInfo = + material.getOcclusionTexture(); + if (occlusionTextureInfo != null) { int index = occlusionTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setOcclusionTexture(textureModel); materialModel.setOcclusionTexcoord( - occlusionTextureInfo.getTexCoord()); - + occlusionTextureInfo.getTexCoord()); + float occlusionStrength = Optionals.of( - occlusionTextureInfo.getStrength(), - occlusionTextureInfo.defaultStrength()); + occlusionTextureInfo.getStrength(), + occlusionTextureInfo.defaultStrength()); materialModel.setOcclusionStrength(occlusionStrength); } - TextureInfo emissiveTextureInfo = - material.getEmissiveTexture(); - if (emissiveTextureInfo != null) - { + TextureInfo emissiveTextureInfo = + material.getEmissiveTexture(); + if (emissiveTextureInfo != null) { int index = emissiveTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setEmissiveTexture(textureModel); materialModel.setEmissiveTexcoord( - emissiveTextureInfo.getTexCoord()); + emissiveTextureInfo.getTexCoord()); } - + float[] emissiveFactor = Optionals.of( - material.getEmissiveFactor(), - material.defaultEmissiveFactor()); + material.getEmissiveFactor(), + material.defaultEmissiveFactor()); materialModel.setEmissiveFactor(emissiveFactor); } - + /** * Initialize the {@link ExtensionsModel} with the extensions that * are used or required in the glTF. */ - private void initExtensionsModel() - { + private void initExtensionsModel() { List extensionsUsed = gltf.getExtensionsUsed(); List extensionsRequired = gltf.getExtensionsRequired(); DefaultExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); @@ -1311,45 +1138,14 @@ private void initExtensionsModel() * Initialize the {@link AssetModel} with the asset information that * was given in the glTF. */ - private void initAssetModel() - { + private void initAssetModel() { Asset asset = gltf.getAsset(); - if (asset != null) - { + if (asset != null) { DefaultAssetModel assetModel = gltfModel.getAssetModel(); transferGltfPropertyElements(asset, assetModel); assetModel.setCopyright(asset.getCopyright()); assetModel.setGenerator(asset.getGenerator()); } } - - /** - * Transfer the extensions and extras from the given property to - * the given target - * - * @param property The property - * @param modelElement The target - */ - private static void transferGltfPropertyElements( - GlTFProperty property, AbstractModelElement modelElement) - { - modelElement.setExtensions(property.getExtensions()); - modelElement.setExtras(property.getExtras()); - } - - /** - * Transfer the name and extensions and extras from the given property to - * the given target - * - * @param property The property - * @param modelElement The target - */ - private static void transferGltfChildOfRootPropertyElements( - GlTFChildOfRootProperty property, - AbstractNamedModelElement modelElement) - { - modelElement.setName(property.getName()); - transferGltfPropertyElements(property, modelElement); - } - + } diff --git a/src/main/java/de/javagl/jgltf/model/v2/MaterialModelV2.java b/src/main/java/de/javagl/jgltf/model/v2/MaterialModelV2.java index d263846..449b368 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/MaterialModelV2.java +++ b/src/main/java/de/javagl/jgltf/model/v2/MaterialModelV2.java @@ -33,539 +33,479 @@ /** * Implementation of a {@link MaterialModel} for glTF 2.0.
    *
    - * Note: This class might be renamed to "PbrBasedMaterialModel" and moved to + * Note: This class might be renamed to "PbrBasedMaterialModel" and moved to * a different package in the future. */ public final class MaterialModelV2 extends AbstractNamedModelElement - implements MaterialModel -{ - /** - * Alpha modes - */ - public static enum AlphaMode - { - /** - * Opaque mode - */ - OPAQUE, - - /** - * Masking mode - */ - MASK, - - /** - * Blend mode - */ - BLEND - } - + implements MaterialModel { /** * The base color factor */ private float[] baseColorFactor; - /** * The base color texture */ private TextureModel baseColorTexture; - /** * The texture coordinate set for the base color texture */ private Integer baseColorTexcoord; - /** * The metallic factor */ private float metallicFactor; - /** * The roughness factor */ private float roughnessFactor; - /** * The metallic-roughness texture */ private TextureModel metallicRoughnessTexture; - /** * The texture coordinate set for the metallic-roughness texture */ private Integer metallicRoughnessTexcoord; - /** * The normal texture */ private TextureModel normalTexture; - /** * The texture coordinate set for the normal texture */ private Integer normalTexcoord; - /** * The normal scale */ private float normalScale; - /** * The occlusion texture */ private TextureModel occlusionTexture; - /** * The texture coordinate set for the occlusion texture */ private Integer occlusionTexcoord; - /** * The occlusion strength */ private float occlusionStrength; - /** * The emissive texture */ private TextureModel emissiveTexture; - /** * The texture coordinate set for the emissive texture */ private Integer emissiveTexcoord; - /** * The emissive factor */ private float[] emissiveFactor; - /** * The alpha mode */ private AlphaMode alphaMode; - /** * The alpha cutoff */ private float alphaCutoff; - /** * Whether the material is double sided */ private boolean doubleSided; - - + /** * Creates a new instance with default values */ - public MaterialModelV2() - { - baseColorFactor = new float[]{ 1.0f, 1.0f, 1.0f, 1.0f }; + public MaterialModelV2() { + baseColorFactor = new float[]{1.0f, 1.0f, 1.0f, 1.0f}; baseColorTexture = null; baseColorTexcoord = null; - + metallicFactor = 1.0f; roughnessFactor = 1.0f; metallicRoughnessTexture = null; metallicRoughnessTexcoord = null; - + normalScale = 1.0f; normalTexture = null; normalTexcoord = null; - + occlusionTexture = null; occlusionTexcoord = null; occlusionStrength = 1.0f; - + emissiveTexture = null; emissiveTexcoord = null; - emissiveFactor = new float[]{0.0f, 0.0f, 0.0f }; + emissiveFactor = new float[]{0.0f, 0.0f, 0.0f}; alphaMode = AlphaMode.OPAQUE; alphaCutoff = 0.5f; - + doubleSided = false; } - + /** * Returns the base color factor - * + * * @return The base color factor */ - public float[] getBaseColorFactor() - { + public float[] getBaseColorFactor() { return baseColorFactor; } /** * Set the base color factor - * + * * @param baseColorFactor The base color factor */ - public void setBaseColorFactor(float[] baseColorFactor) - { + public void setBaseColorFactor(float[] baseColorFactor) { this.baseColorFactor = baseColorFactor; } /** * Returns the base color texture - * + * * @return The base color texture */ - public TextureModel getBaseColorTexture() - { + public TextureModel getBaseColorTexture() { return baseColorTexture; } /** * Set the base color texture - * + * * @param baseColorTexture The base color texture */ - public void setBaseColorTexture(TextureModel baseColorTexture) - { + public void setBaseColorTexture(TextureModel baseColorTexture) { this.baseColorTexture = baseColorTexture; } - + /** * Return the base color texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getBaseColorTexcoord() - { + public Integer getBaseColorTexcoord() { return baseColorTexcoord; } - + /** * Set the base color texture coordinate set - * + * * @param baseColorTexcoord The texture coordinate set */ - public void setBaseColorTexcoord(Integer baseColorTexcoord) - { + public void setBaseColorTexcoord(Integer baseColorTexcoord) { this.baseColorTexcoord = baseColorTexcoord; } /** * Returns the metallic factor - * + * * @return The metallic factor */ - public float getMetallicFactor() - { + public float getMetallicFactor() { return metallicFactor; } /** * Set the metallic factor - * + * * @param metallicFactor The metallic factor */ - public void setMetallicFactor(float metallicFactor) - { + public void setMetallicFactor(float metallicFactor) { this.metallicFactor = metallicFactor; } /** * Returns the roughness factor - * + * * @return The roughness factor */ - public float getRoughnessFactor() - { + public float getRoughnessFactor() { return roughnessFactor; } /** * Set the roughness factor - * + * * @param roughnessFactor The roughness factor */ - public void setRoughnessFactor(float roughnessFactor) - { + public void setRoughnessFactor(float roughnessFactor) { this.roughnessFactor = roughnessFactor; } /** * Returns the metallic-roughness-texture - * + * * @return The metallic-roughness texture */ - public TextureModel getMetallicRoughnessTexture() - { + public TextureModel getMetallicRoughnessTexture() { return metallicRoughnessTexture; } /** * Set the metallic-roughness-texture - * + * * @param metallicRoughnessTexture The metallic-roughness-texture */ public void setMetallicRoughnessTexture( - TextureModel metallicRoughnessTexture) - { + TextureModel metallicRoughnessTexture) { this.metallicRoughnessTexture = metallicRoughnessTexture; } - + /** * Returns the metallic-roughness texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getMetallicRoughnessTexcoord() - { + public Integer getMetallicRoughnessTexcoord() { return metallicRoughnessTexcoord; } - + /** * Set the metallic-roughness texture coordinate set - * + * * @param metallicRoughnessTexcoord The texture coordinate set */ - public void setMetallicRoughnessTexcoord(Integer metallicRoughnessTexcoord) - { + public void setMetallicRoughnessTexcoord(Integer metallicRoughnessTexcoord) { this.metallicRoughnessTexcoord = metallicRoughnessTexcoord; } /** * Returns the normal texture - * + * * @return The normal texture */ - public TextureModel getNormalTexture() - { + public TextureModel getNormalTexture() { return normalTexture; } /** * Set the normal texture - * + * * @param normalTexture The normal texture */ - public void setNormalTexture(TextureModel normalTexture) - { + public void setNormalTexture(TextureModel normalTexture) { this.normalTexture = normalTexture; } - + /** * Returns the normal texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getNormalTexcoord() - { + public Integer getNormalTexcoord() { return normalTexcoord; } - + /** * Set the normal texture coordinate set - * + * * @param normalTexcoord The texture coordinate set */ - public void setNormalTexcoord(Integer normalTexcoord) - { + public void setNormalTexcoord(Integer normalTexcoord) { this.normalTexcoord = normalTexcoord; } /** * Returns the normal scale - * + * * @return The normal scale */ - public float getNormalScale() - { + public float getNormalScale() { return normalScale; } /** * Set the normal scale - * + * * @param normalScale The normal scale */ - public void setNormalScale(float normalScale) - { + public void setNormalScale(float normalScale) { this.normalScale = normalScale; } - + /** * Returns the occlusion texture - * + * * @return The occlusion texture */ - public TextureModel getOcclusionTexture() - { + public TextureModel getOcclusionTexture() { return occlusionTexture; } /** * Set the occlusion texture - * + * * @param occlusionTexture The occlusion texture */ - public void setOcclusionTexture(TextureModel occlusionTexture) - { + public void setOcclusionTexture(TextureModel occlusionTexture) { this.occlusionTexture = occlusionTexture; } - + /** * Returns the occlusion texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getOcclusionTexcoord() - { + public Integer getOcclusionTexcoord() { return occlusionTexcoord; } - + /** * Set the occlusion texture coordinate set - * + * * @param occlusionTexcoord The texture coordinate set */ - public void setOcclusionTexcoord(Integer occlusionTexcoord) - { + public void setOcclusionTexcoord(Integer occlusionTexcoord) { this.occlusionTexcoord = occlusionTexcoord; } /** * Returns the occlusion strength - * + * * @return The occlusion strength */ - public float getOcclusionStrength() - { + public float getOcclusionStrength() { return occlusionStrength; } /** * Set the occlusion strength - * + * * @param occlusionStrength The occlusion strength */ - public void setOcclusionStrength(float occlusionStrength) - { + public void setOcclusionStrength(float occlusionStrength) { this.occlusionStrength = occlusionStrength; } /** * Returns the emissive texture - * + * * @return The emissive texture */ - public TextureModel getEmissiveTexture() - { + public TextureModel getEmissiveTexture() { return emissiveTexture; } /** * Set the emissive texture - * + * * @param emissiveTexture The emissive texture */ - public void setEmissiveTexture(TextureModel emissiveTexture) - { + public void setEmissiveTexture(TextureModel emissiveTexture) { this.emissiveTexture = emissiveTexture; } - + /** * Set the emissive texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getEmissiveTexcoord() - { + public Integer getEmissiveTexcoord() { return emissiveTexcoord; } - + /** * Set the emissive texture coordinate set - * + * * @param emissiveTexcoord The texture coordinate set */ - public void setEmissiveTexcoord(Integer emissiveTexcoord) - { + public void setEmissiveTexcoord(Integer emissiveTexcoord) { this.emissiveTexcoord = emissiveTexcoord; } - + /** * Returns the emissive factor - * + * * @return The emissive factor */ - public float[] getEmissiveFactor() - { + public float[] getEmissiveFactor() { return emissiveFactor; } /** * Set the emissive factor - * + * * @param emissiveFactor The emissive factor */ - public void setEmissiveFactor(float[] emissiveFactor) - { + public void setEmissiveFactor(float[] emissiveFactor) { this.emissiveFactor = emissiveFactor; } /** * Returns the alpha mode - * + * * @return The alpha mode */ - public AlphaMode getAlphaMode() - { + public AlphaMode getAlphaMode() { return alphaMode; } /** * Set the alpha mode - * + * * @param alphaMode The alpha mode */ - public void setAlphaMode(AlphaMode alphaMode) - { + public void setAlphaMode(AlphaMode alphaMode) { this.alphaMode = alphaMode; } /** * Returns the alpha cutoff - * + * * @return The alpha cutoff */ - public float getAlphaCutoff() - { + public float getAlphaCutoff() { return alphaCutoff; } /** * Set the alpha cutoff - * + * * @param alphaCutoff The alpha cutoff */ - public void setAlphaCutoff(float alphaCutoff) - { + public void setAlphaCutoff(float alphaCutoff) { this.alphaCutoff = alphaCutoff; } /** * Returns whether the material is double sided - * + * * @return Whether the material is double sided */ - public boolean isDoubleSided() - { + public boolean isDoubleSided() { return doubleSided; } /** * Set whether the material is double sided - * + * * @param doubleSided Whether the material is double sided */ - public void setDoubleSided(boolean doubleSided) - { + public void setDoubleSided(boolean doubleSided) { this.doubleSided = doubleSided; } + + /** + * Alpha modes + */ + public static enum AlphaMode { + /** + * Opaque mode + */ + OPAQUE, + + /** + * Masking mode + */ + MASK, + + /** + * Blend mode + */ + BLEND + } } diff --git a/src/main/java/de/javagl/jgltf/model/v2/gl/Materials.java b/src/main/java/de/javagl/jgltf/model/v2/gl/Materials.java index 9fa46e6..fadba0a 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/gl/Materials.java +++ b/src/main/java/de/javagl/jgltf/model/v2/gl/Materials.java @@ -32,18 +32,23 @@ /** * Methods to create instances of classes related to a {@link Material} */ -public class Materials -{ +public class Materials { + /** + * Private constructor to prevent instantiation + */ + private Materials() { + // Private constructor to prevent instantiation + } + /** * Create a {@link Material} with all default values - * + * * @return The {@link Material} */ - public static Material createDefaultMaterial() - { + public static Material createDefaultMaterial() { Material material = new Material(); material.setPbrMetallicRoughness( - createDefaultMaterialPbrMetallicRoughness()); + createDefaultMaterialPbrMetallicRoughness()); material.setNormalTexture(null); material.setOcclusionTexture(null); material.setEmissiveTexture(null); @@ -53,28 +58,19 @@ public static Material createDefaultMaterial() material.setDoubleSided(material.defaultDoubleSided()); return material; } - + /** * Create a {@link MaterialPbrMetallicRoughness} with all default values - * + * * @return The {@link MaterialPbrMetallicRoughness} */ - public static MaterialPbrMetallicRoughness - createDefaultMaterialPbrMetallicRoughness() - { - MaterialPbrMetallicRoughness result = - new MaterialPbrMetallicRoughness(); + public static MaterialPbrMetallicRoughness + createDefaultMaterialPbrMetallicRoughness() { + MaterialPbrMetallicRoughness result = + new MaterialPbrMetallicRoughness(); result.setBaseColorFactor(result.defaultBaseColorFactor()); result.setMetallicFactor(result.defaultMetallicFactor()); result.setRoughnessFactor(result.defaultRoughnessFactor()); return result; } - - /** - * Private constructor to prevent instantiation - */ - private Materials() - { - // Private constructor to prevent instantiation - } } diff --git a/src/main/java/simplelibs/SimpleConfig.java b/src/main/java/simplelibs/SimpleConfig.java index 9f34da7..c2ef34b 100644 --- a/src/main/java/simplelibs/SimpleConfig.java +++ b/src/main/java/simplelibs/SimpleConfig.java @@ -41,51 +41,30 @@ public class SimpleConfig { private final ConfigRequest request; private boolean broken = false; - public interface DefaultConfig { - String get( String namespace ); - - static String empty( String namespace ) { - return ""; - } - } - - public static class ConfigRequest { - - private final File file; - private final String filename; - private DefaultConfig provider; - - private ConfigRequest(File file, String filename ) { - this.file = file; - this.filename = filename; - this.provider = DefaultConfig::empty; - } + private SimpleConfig(ConfigRequest request) { + this.request = request; + String identifier = "Config '" + request.filename + "'"; - /** - * Sets the default config provider, used to generate the - * config if it's missing. - * - * @param provider default config provider - * @return current config request object - * @see DefaultConfig - */ - public ConfigRequest provider( DefaultConfig provider ) { - this.provider = provider; - return this; - } + if (!request.file.exists()) { + LOGGER.info(identifier + " is missing, generating default one..."); - /** - * Loads the config from the filesystem. - * - * @return config object - * @see SimpleConfig - */ - public SimpleConfig request() { - return new SimpleConfig( this ); + try { + createConfig(); + } catch (IOException e) { + LOGGER.error(identifier + " failed to generate!"); + LOGGER.trace(e); + broken = true; + } } - private String getConfig() { - return provider.get( filename ) + "\n"; + if (!broken) { + try { + loadConfig(); + } catch (Exception e) { + LOGGER.error(identifier + " failed to load!"); + LOGGER.trace(e); + broken = true; + } } } @@ -97,90 +76,62 @@ private String getConfig() { * @param filename - name of the config file * @return new config request object */ - public static ConfigRequest of( String filename ) { + public static ConfigRequest of(String filename) { Path path = FabricLoader.getInstance().getConfigDir(); - return new ConfigRequest( path.resolve( filename + ".properties" ).toFile(), filename ); + return new ConfigRequest(path.resolve(filename + ".properties").toFile(), filename); } private void createConfig() throws IOException { // try creating missing files request.file.getParentFile().mkdirs(); - Files.createFile( request.file.toPath() ); + Files.createFile(request.file.toPath()); // write default config data PrintWriter writer = new PrintWriter(request.file, "UTF-8"); - writer.write( request.getConfig() ); + writer.write(request.getConfig()); writer.close(); } private void loadConfig() throws IOException { - try (Scanner reader = new Scanner( request.file )) { - for( int line = 1; reader.hasNextLine(); line ++ ) { - parseConfigEntry( reader.nextLine(), line ); - } - } - } - - private void parseConfigEntry( String entry, int line ) { - if( !entry.isEmpty() && !entry.startsWith( "#" ) ) { - String[] parts = entry.split("=", 2); - if( parts.length == 2 ) { - config.put( parts[0], parts[1] ); - }else{ - throw new RuntimeException("Syntax error in config file on line " + line + "!"); + try (Scanner reader = new Scanner(request.file)) { + for (int line = 1; reader.hasNextLine(); line++) { + parseConfigEntry(reader.nextLine(), line); } } } - private SimpleConfig( ConfigRequest request ) { - this.request = request; - String identifier = "Config '" + request.filename + "'"; - - if( !request.file.exists() ) { - LOGGER.info( identifier + " is missing, generating default one..." ); - - try { - createConfig(); - } catch (IOException e) { - LOGGER.error( identifier + " failed to generate!" ); - LOGGER.trace( e ); - broken = true; - } - } - - if( !broken ) { - try { - loadConfig(); - } catch (Exception e) { - LOGGER.error( identifier + " failed to load!" ); - LOGGER.trace( e ); - broken = true; + private void parseConfigEntry(String entry, int line) { + if (!entry.isEmpty() && !entry.startsWith("#")) { + String[] parts = entry.split("=", 2); + if (parts.length == 2) { + config.put(parts[0], parts[1]); + } else { + throw new RuntimeException("Syntax error in config file on line " + line + "!"); } } - } /** * Queries a value from config, returns `null` if the * key does not exist. * - * @return value corresponding to the given key - * @see SimpleConfig#getOrDefault + * @return value corresponding to the given key + * @see SimpleConfig#getOrDefault */ @Deprecated - public String get( String key ) { - return config.get( key ); + public String get(String key) { + return config.get(key); } /** * Returns string value from config corresponding to the given * key, or the default string if the key is missing. * - * @return value corresponding to the given key, or the default value + * @return value corresponding to the given key, or the default value */ - public String getOrDefault( String key, String def ) { + public String getOrDefault(String key, String def) { String val = get(key); return val == null ? def : val; } @@ -189,11 +140,11 @@ public String getOrDefault( String key, String def ) { * Returns integer value from config corresponding to the given * key, or the default integer if the key is missing or invalid. * - * @return value corresponding to the given key, or the default value + * @return value corresponding to the given key, or the default value */ - public int getOrDefault( String key, int def ) { + public int getOrDefault(String key, int def) { try { - return Integer.parseInt( get(key) ); + return Integer.parseInt(get(key)); } catch (Exception e) { return def; } @@ -203,11 +154,11 @@ public int getOrDefault( String key, int def ) { * Returns boolean value from config corresponding to the given * key, or the default boolean if the key is missing. * - * @return value corresponding to the given key, or the default value + * @return value corresponding to the given key, or the default value */ - public boolean getOrDefault( String key, boolean def ) { + public boolean getOrDefault(String key, boolean def) { String val = get(key); - if( val != null ) { + if (val != null) { return val.equalsIgnoreCase("true"); } @@ -218,11 +169,11 @@ public boolean getOrDefault( String key, boolean def ) { * Returns double value from config corresponding to the given * key, or the default string if the key is missing or invalid. * - * @return value corresponding to the given key, or the default value + * @return value corresponding to the given key, or the default value */ - public double getOrDefault( String key, double def ) { + public double getOrDefault(String key, double def) { try { - return Double.parseDouble( get(key) ); + return Double.parseDouble(get(key)); } catch (Exception e) { return def; } @@ -245,8 +196,57 @@ public boolean isBroken() { * @return true if the operation was successful */ public boolean delete() { - LOGGER.warn( "Config '" + request.filename + "' was removed from existence! Restart the game to regenerate it." ); + LOGGER.warn("Config '" + request.filename + "' was removed from existence! Restart the game to regenerate it."); return request.file.delete(); } + public interface DefaultConfig { + static String empty(String namespace) { + return ""; + } + + String get(String namespace); + } + + public static class ConfigRequest { + + private final File file; + private final String filename; + private DefaultConfig provider; + + private ConfigRequest(File file, String filename) { + this.file = file; + this.filename = filename; + this.provider = DefaultConfig::empty; + } + + /** + * Sets the default config provider, used to generate the + * config if it's missing. + * + * @param provider default config provider + * @return current config request object + * @see DefaultConfig + */ + public ConfigRequest provider(DefaultConfig provider) { + this.provider = provider; + return this; + } + + /** + * Loads the config from the filesystem. + * + * @return config object + * @see SimpleConfig + */ + public SimpleConfig request() { + return new SimpleConfig(this); + } + + private String getConfig() { + return provider.get(filename) + "\n"; + } + + } + } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 1af12e9..f18e878 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -2,21 +2,19 @@ "schemaVersion": 1, "id": "mcgltf", "version": "${version}", - "name": "MCglTF", "description": "A glTF model loader library based on JglTF for Minecraft.", "authors": [ - "TimLee9024", "Protoxy" + "TimLee9024", + "Protoxy" ], "contact": { "homepage": "https://www.curseforge.com/minecraft/mc-mods/mcgltf", "sources": "https://github.com/singlerr/MCglTF-1.20.4", "issues": "https://github.com/singlerr/MCglTF-1.20.4/issues" }, - "license": "MIT", "icon": "assets/mcgltf/icon.png", - "environment": "client", "entrypoints": { "main": [ @@ -26,7 +24,6 @@ "mixins": [ "mcgltf.iris.mixins.json" ], - "depends": { "fabricloader": ">=0.15.0", "fabric": "*", diff --git a/src/main/resources/mcgltf.iris.mixins.json b/src/main/resources/mcgltf.iris.mixins.json index 38f8b00..debd44a 100644 --- a/src/main/resources/mcgltf.iris.mixins.json +++ b/src/main/resources/mcgltf.iris.mixins.json @@ -5,9 +5,9 @@ "package": "com.modularmods.mcgltf.iris.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ + "MixinBufferUploader", "MixinRenderStateShard", - "MixinBufferUploader", - "MixinVertexBuffer" + "MixinVertexBuffer" ], "injectors": { "defaultRequire": 1 From e3b7e82223a9855300d830ff76abb23a4edf8b5b Mon Sep 17 00:00:00 2001 From: Ryu Seowoong Date: Wed, 8 Oct 2025 20:25:43 +0900 Subject: [PATCH 2/5] feat: add workflow --- .github/workflows/build.yml | 70 +++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..3c22f9b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,70 @@ +name: Build Mod and Upload Artifacts + +on: + push: + branches: [ "**" ] + tags: [ "v*", "*.*.*" ] + pull_request: + branches: [ "**" ] + +permissions: + contents: write # needed for creating a GitHub Release on tag pushes + +jobs: + build: + name: Build on ${{ matrix.os }} with JDK ${{ matrix.java }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest ] + java: [ 17 ] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ matrix.java }} + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + with: + gradle-home-cache-cleanup: true + + - name: Make gradlew executable (Linux/macOS) + if: runner.os != 'Windows' + run: chmod +x ./gradlew + + - name: Build + run: ./gradlew --no-daemon clean build + + - name: Upload build artifacts (all jars) + uses: actions/upload-artifact@v4 + with: + name: build-jars-${{ github.sha }} + path: | + build/libs/*.jar + if-no-files-found: error + + - name: Upload debug logs (optional) + if: always() + uses: actions/upload-artifact@v4 + with: + name: gradle-logs-${{ github.sha }} + path: | + **/build/reports/** + **/build/test-results/** + if-no-files-found: ignore + + - name: Create GitHub Release and upload jars (on tag) + if: startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@v2 + with: + files: | + build/libs/*.jar + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From d410aaf15f870e807f23bea322844de88c250c24 Mon Sep 17 00:00:00 2001 From: Ryu Seowoong Date: Sun, 19 Oct 2025 20:23:57 +0900 Subject: [PATCH 3/5] remove workflow --- .github/workflows/build.yml | 70 ------------------------------------- 1 file changed, 70 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 3c22f9b..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Build Mod and Upload Artifacts - -on: - push: - branches: [ "**" ] - tags: [ "v*", "*.*.*" ] - pull_request: - branches: [ "**" ] - -permissions: - contents: write # needed for creating a GitHub Release on tag pushes - -jobs: - build: - name: Build on ${{ matrix.os }} with JDK ${{ matrix.java }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ ubuntu-latest ] - java: [ 17 ] - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up JDK - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: ${{ matrix.java }} - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4 - with: - gradle-home-cache-cleanup: true - - - name: Make gradlew executable (Linux/macOS) - if: runner.os != 'Windows' - run: chmod +x ./gradlew - - - name: Build - run: ./gradlew --no-daemon clean build - - - name: Upload build artifacts (all jars) - uses: actions/upload-artifact@v4 - with: - name: build-jars-${{ github.sha }} - path: | - build/libs/*.jar - if-no-files-found: error - - - name: Upload debug logs (optional) - if: always() - uses: actions/upload-artifact@v4 - with: - name: gradle-logs-${{ github.sha }} - path: | - **/build/reports/** - **/build/test-results/** - if-no-files-found: ignore - - - name: Create GitHub Release and upload jars (on tag) - if: startsWith(github.ref, 'refs/tags/') - uses: softprops/action-gh-release@v2 - with: - files: | - build/libs/*.jar - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From cbdf2e0842012e51fb801e208e038a471b4333f1 Mon Sep 17 00:00:00 2001 From: Ryu Seowoong Date: Sun, 16 Nov 2025 21:40:29 +0900 Subject: [PATCH 4/5] rollback --- build.gradle | 8 +- gradle.properties | 2 +- settings.gradle | 2 + .../util/mikktspace/MikkTSpaceContext.java | 34 +- .../MikktspaceTangentGenerator.java | 110 +- .../com/jme3/util/mikktspace/Vector3f.java | 180 +- .../modularmods/mcgltf/AccessorDataUtils.java | 187 +- .../mcgltf/AccessorModelCreation.java | 93 +- .../mcgltf/IGltfModelReceiver.java | 19 +- .../java/com/modularmods/mcgltf/MCglTF.java | 890 +- .../modularmods/mcgltf/RenderedGltfModel.java | 10135 ++++++++-------- .../mcgltf/RenderedGltfModelGL30.java | 209 +- .../mcgltf/RenderedGltfModelGL33.java | 2268 ++-- .../mcgltf/RenderedGltfModelGL40.java | 367 +- .../modularmods/mcgltf/RenderedGltfScene.java | 214 +- .../mcgltf/RenderedGltfSceneGL30.java | 156 +- .../mcgltf/RenderedGltfSceneGL33.java | 197 +- .../mcgltf/RenderedGltfSceneGL40.java | 202 +- .../CubicSplineInterpolatedChannel.java | 104 +- .../animation/GltfAnimationCreator.java | 740 +- .../mcgltf/animation/InterpolatedChannel.java | 70 +- .../animation/LinearInterpolatedChannel.java | 74 +- .../SphericalLinearInterpolatedChannel.java | 142 +- .../animation/StepInterpolatedChannel.java | 32 +- .../mcgltf/iris/IrisRenderingHook.java | 322 +- .../iris/RenderedGltfModelGL30Iris.java | 142 +- .../iris/RenderedGltfModelGL33Iris.java | 150 +- .../iris/RenderedGltfModelGL40Iris.java | 150 +- .../mcgltf/iris/RenderedGltfModelIris.java | 475 +- .../iris/RenderedGltfSceneGL30Iris.java | 35 +- .../iris/RenderedGltfSceneGL33Iris.java | 73 +- .../iris/RenderedGltfSceneGL40Iris.java | 78 +- .../mcgltf/iris/RenderedGltfSceneIris.java | 74 +- .../iris/mixin/IrisCompatMixinPlugin.java | 51 +- .../iris/mixin/MixinBufferUploader.java | 15 +- .../iris/mixin/MixinRenderStateShard.java | 14 +- .../mcgltf/iris/mixin/MixinVertexBuffer.java | 13 +- .../de/javagl/jgltf/impl/v1/Accessor.java | 388 +- .../de/javagl/jgltf/impl/v1/Animation.java | 281 +- .../jgltf/impl/v1/AnimationChannel.java | 76 +- .../jgltf/impl/v1/AnimationChannelTarget.java | 84 +- .../jgltf/impl/v1/AnimationSampler.java | 140 +- .../java/de/javagl/jgltf/impl/v1/Asset.java | 190 +- .../de/javagl/jgltf/impl/v1/AssetProfile.java | 104 +- .../java/de/javagl/jgltf/impl/v1/Buffer.java | 150 +- .../de/javagl/jgltf/impl/v1/BufferView.java | 172 +- .../java/de/javagl/jgltf/impl/v1/Camera.java | 128 +- .../jgltf/impl/v1/CameraOrthographic.java | 144 +- .../jgltf/impl/v1/CameraPerspective.java | 166 +- .../java/de/javagl/jgltf/impl/v1/GlTF.java | 1383 +-- .../impl/v1/GlTFChildOfRootProperty.java | 42 +- .../de/javagl/jgltf/impl/v1/GlTFProperty.java | 100 +- .../java/de/javagl/jgltf/impl/v1/Image.java | 46 +- .../de/javagl/jgltf/impl/v1/Material.java | 113 +- .../java/de/javagl/jgltf/impl/v1/Mesh.java | 113 +- .../javagl/jgltf/impl/v1/MeshPrimitive.java | 209 +- .../java/de/javagl/jgltf/impl/v1/Node.java | 627 +- .../java/de/javagl/jgltf/impl/v1/Program.java | 157 +- .../java/de/javagl/jgltf/impl/v1/Sampler.java | 242 +- .../java/de/javagl/jgltf/impl/v1/Scene.java | 99 +- .../java/de/javagl/jgltf/impl/v1/Shader.java | 84 +- .../java/de/javagl/jgltf/impl/v1/Skin.java | 195 +- .../de/javagl/jgltf/impl/v1/Technique.java | 323 +- .../jgltf/impl/v1/TechniqueParameters.java | 198 +- .../javagl/jgltf/impl/v1/TechniqueStates.java | 151 +- .../impl/v1/TechniqueStatesFunctions.java | 918 +- .../java/de/javagl/jgltf/impl/v1/Texture.java | 290 +- .../de/javagl/jgltf/impl/v2/Accessor.java | 404 +- .../javagl/jgltf/impl/v2/AccessorSparse.java | 132 +- .../jgltf/impl/v2/AccessorSparseIndices.java | 166 +- .../jgltf/impl/v2/AccessorSparseValues.java | 122 +- .../de/javagl/jgltf/impl/v2/Animation.java | 215 +- .../jgltf/impl/v2/AnimationChannel.java | 78 +- .../jgltf/impl/v2/AnimationChannelTarget.java | 126 +- .../jgltf/impl/v2/AnimationSampler.java | 134 +- .../java/de/javagl/jgltf/impl/v2/Asset.java | 142 +- .../java/de/javagl/jgltf/impl/v2/Buffer.java | 82 +- .../de/javagl/jgltf/impl/v2/BufferView.java | 218 +- .../java/de/javagl/jgltf/impl/v2/Camera.java | 140 +- .../jgltf/impl/v2/CameraOrthographic.java | 180 +- .../jgltf/impl/v2/CameraPerspective.java | 170 +- .../java/de/javagl/jgltf/impl/v2/GlTF.java | 1393 +-- .../impl/v2/GlTFChildOfRootProperty.java | 42 +- .../de/javagl/jgltf/impl/v2/GlTFProperty.java | 100 +- .../java/de/javagl/jgltf/impl/v2/Image.java | 114 +- .../de/javagl/jgltf/impl/v2/Material.java | 356 +- .../impl/v2/MaterialNormalTextureInfo.java | 64 +- .../impl/v2/MaterialOcclusionTextureInfo.java | 80 +- .../impl/v2/MaterialPbrMetallicRoughness.java | 276 +- .../java/de/javagl/jgltf/impl/v2/Mesh.java | 201 +- .../javagl/jgltf/impl/v2/MeshPrimitive.java | 299 +- .../java/de/javagl/jgltf/impl/v2/Node.java | 593 +- .../java/de/javagl/jgltf/impl/v2/Sampler.java | 202 +- .../java/de/javagl/jgltf/impl/v2/Scene.java | 105 +- .../java/de/javagl/jgltf/impl/v2/Skin.java | 157 +- .../java/de/javagl/jgltf/impl/v2/Texture.java | 94 +- .../de/javagl/jgltf/impl/v2/TextureInfo.java | 102 +- .../jgltf/model/AbstractAccessorData.java | 142 +- .../javagl/jgltf/model/AccessorByteData.java | 265 +- .../de/javagl/jgltf/model/AccessorData.java | 29 +- .../de/javagl/jgltf/model/AccessorDatas.java | 639 +- .../javagl/jgltf/model/AccessorFloatData.java | 202 +- .../javagl/jgltf/model/AccessorIntData.java | 267 +- .../de/javagl/jgltf/model/AccessorModel.java | 97 +- .../javagl/jgltf/model/AccessorShortData.java | 269 +- .../java/de/javagl/jgltf/model/Accessors.java | 149 +- .../de/javagl/jgltf/model/AnimationModel.java | 58 +- .../de/javagl/jgltf/model/AssetModel.java | 13 +- .../de/javagl/jgltf/model/BoundingBox.java | 77 +- .../jgltf/model/BoundingBoxComputer.java | 189 +- .../de/javagl/jgltf/model/BoundingBoxes.java | 43 +- .../de/javagl/jgltf/model/BufferModel.java | 21 +- .../javagl/jgltf/model/BufferViewModel.java | 31 +- .../de/javagl/jgltf/model/CameraModel.java | 41 +- .../jgltf/model/CameraOrthographicModel.java | 17 +- .../jgltf/model/CameraPerspectiveModel.java | 19 +- .../de/javagl/jgltf/model/ElementType.java | 131 +- .../javagl/jgltf/model/ExtensionsModel.java | 11 +- .../de/javagl/jgltf/model/GltfAnimations.java | 303 +- .../de/javagl/jgltf/model/GltfConstants.java | 440 +- .../de/javagl/jgltf/model/GltfException.java | 19 +- .../java/de/javagl/jgltf/model/GltfModel.java | 69 +- .../de/javagl/jgltf/model/GltfModels.java | 39 +- .../java/de/javagl/jgltf/model/GltfUtils.java | 33 +- .../de/javagl/jgltf/model/ImageModel.java | 23 +- .../de/javagl/jgltf/model/MaterialModel.java | 3 +- .../java/de/javagl/jgltf/model/MathUtils.java | 741 +- .../java/de/javagl/jgltf/model/MeshModel.java | 13 +- .../jgltf/model/MeshPrimitiveModel.java | 23 +- .../de/javagl/jgltf/model/ModelElement.java | 11 +- .../javagl/jgltf/model/NamedModelElement.java | 5 +- .../java/de/javagl/jgltf/model/NodeModel.java | 149 +- .../de/javagl/jgltf/model/NumberArrays.java | 47 +- .../java/de/javagl/jgltf/model/Optionals.java | 119 +- .../de/javagl/jgltf/model/SceneModel.java | 7 +- .../java/de/javagl/jgltf/model/SkinModel.java | 39 +- .../java/de/javagl/jgltf/model/Suppliers.java | 38 +- .../de/javagl/jgltf/model/TextureModel.java | 15 +- .../java/de/javagl/jgltf/model/Utils.java | 28 +- .../jgltf/model/animation/Animation.java | 114 +- .../model/animation/AnimationListener.java | 9 +- .../model/animation/AnimationManager.java | 210 +- .../animation/AnimationManagerListener.java | 5 +- .../model/animation/AnimationRunner.java | 65 +- .../jgltf/model/animation/Interpolator.java | 21 +- .../model/animation/InterpolatorKeys.java | 57 +- .../model/animation/InterpolatorType.java | 11 +- .../jgltf/model/animation/Interpolators.java | 35 +- .../model/animation/LinearInterpolator.java | 11 +- .../SlerpQuaternionInterpolator.java | 24 +- .../model/animation/StepInterpolator.java | 6 +- .../model/extensions/GltfExtensions.java | 106 +- .../jgltf/model/extensions/package-info.java | 2 +- .../javagl/jgltf/model/gl/ProgramModel.java | 19 +- .../de/javagl/jgltf/model/gl/Semantic.java | 61 +- .../de/javagl/jgltf/model/gl/ShaderModel.java | 58 +- .../javagl/jgltf/model/gl/TechniqueModel.java | 43 +- .../model/gl/TechniqueParametersModel.java | 25 +- .../gl/TechniqueStatesFunctionsModel.java | 49 +- .../jgltf/model/gl/TechniqueStatesModel.java | 53 +- .../model/gl/impl/DefaultProgramModel.java | 70 +- .../model/gl/impl/DefaultShaderModel.java | 65 +- .../model/gl/impl/DefaultTechniqueModel.java | 126 +- .../impl/DefaultTechniqueParametersModel.java | 47 +- .../DefaultTechniqueStatesFunctionsModel.java | 74 +- .../gl/impl/DefaultTechniqueStatesModel.java | 33 +- .../model/gl/impl/TechniqueStatesModels.java | 66 +- .../jgltf/model/gl/impl/package-info.java | 2 +- .../javagl/jgltf/model/gl/package-info.java | 2 +- .../jgltf/model/image/DefaultPixelData.java | 29 +- .../jgltf/model/image/ImageReaders.java | 53 +- .../javagl/jgltf/model/image/ImageUtils.java | 228 +- .../javagl/jgltf/model/image/PixelData.java | 11 +- .../javagl/jgltf/model/image/PixelDatas.java | 52 +- .../model/impl/AbstractModelElement.java | 83 +- .../model/impl/AbstractNamedModelElement.java | 19 +- .../de/javagl/jgltf/model/impl/Cameras.java | 96 +- .../model/impl/DefaultAccessorModel.java | 207 +- .../model/impl/DefaultAnimationModel.java | 158 +- .../jgltf/model/impl/DefaultAssetModel.java | 29 +- .../jgltf/model/impl/DefaultBufferModel.java | 59 +- .../model/impl/DefaultBufferViewModel.java | 146 +- .../jgltf/model/impl/DefaultCameraModel.java | 69 +- .../impl/DefaultCameraOrthographicModel.java | 67 +- .../impl/DefaultCameraPerspectiveModel.java | 67 +- .../model/impl/DefaultExtensionsModel.java | 79 +- .../jgltf/model/impl/DefaultGltfModel.java | 384 +- .../jgltf/model/impl/DefaultImageModel.java | 99 +- .../jgltf/model/impl/DefaultMeshModel.java | 54 +- .../model/impl/DefaultMeshPrimitiveModel.java | 121 +- .../jgltf/model/impl/DefaultNodeModel.java | 430 +- .../jgltf/model/impl/DefaultSceneModel.java | 30 +- .../jgltf/model/impl/DefaultSkinModel.java | 121 +- .../jgltf/model/impl/DefaultTextureModel.java | 78 +- .../javagl/jgltf/model/impl/UriStrings.java | 127 +- .../javagl/jgltf/model/impl/package-info.java | 2 +- .../de/javagl/jgltf/model/io/Buffers.java | 245 +- .../jgltf/model/io/ByteBufferInputStream.java | 28 +- .../de/javagl/jgltf/model/io/GltfAsset.java | 35 +- .../jgltf/model/io/GltfAssetReader.java | 102 +- .../jgltf/model/io/GltfAssetWriter.java | 174 +- .../de/javagl/jgltf/model/io/GltfAssets.java | 108 +- .../jgltf/model/io/GltfModelReader.java | 98 +- .../jgltf/model/io/GltfModelWriter.java | 149 +- .../de/javagl/jgltf/model/io/GltfReader.java | 144 +- .../javagl/jgltf/model/io/GltfReference.java | 47 +- .../jgltf/model/io/GltfReferenceResolver.java | 82 +- .../de/javagl/jgltf/model/io/GltfWriter.java | 58 +- .../java/de/javagl/jgltf/model/io/IO.java | 326 +- .../de/javagl/jgltf/model/io/MimeTypes.java | 177 +- .../jgltf/model/io/ProgressInputStream.java | 94 +- .../de/javagl/jgltf/model/io/RawGltfData.java | 47 +- .../jgltf/model/io/RawGltfDataReader.java | 53 +- .../javagl/jgltf/model/io/UriResolvers.java | 162 +- .../javagl/jgltf/model/io/VersionUtils.java | 54 +- .../javagl/jgltf/model/io/package-info.java | 2 +- .../model/io/v1/BinaryAssetCreatorV1.java | 305 +- .../model/io/v1/DefaultAssetCreatorV1.java | 237 +- .../model/io/v1/EmbeddedAssetCreatorV1.java | 198 +- .../javagl/jgltf/model/io/v1/GltfAssetV1.java | 145 +- .../jgltf/model/io/v1/GltfAssetWriterV1.java | 59 +- .../jgltf/model/io/v1/GltfAssetsV1.java | 45 +- .../jgltf/model/io/v1/GltfModelWriterV1.java | 77 +- .../jgltf/model/io/v1/GltfReaderV1.java | 30 +- .../javagl/jgltf/model/io/v1/GltfUtilsV1.java | 82 +- .../io/v1/RawBinaryGltfDataReaderV1.java | 65 +- .../model/io/v2/BinaryAssetCreatorV2.java | 233 +- .../model/io/v2/DefaultAssetCreatorV2.java | 147 +- .../model/io/v2/EmbeddedAssetCreatorV2.java | 142 +- .../javagl/jgltf/model/io/v2/GltfAssetV2.java | 117 +- .../jgltf/model/io/v2/GltfAssetWriterV2.java | 112 +- .../jgltf/model/io/v2/GltfAssetsV2.java | 45 +- .../jgltf/model/io/v2/GltfModelWriterV2.java | 61 +- .../jgltf/model/io/v2/GltfReaderV2.java | 30 +- .../javagl/jgltf/model/io/v2/GltfUtilsV2.java | 43 +- .../io/v2/RawBinaryGltfDataReaderV2.java | 131 +- .../de/javagl/jgltf/model/package-info.java | 2 +- .../javagl/jgltf/model/v1/BinaryGltfV1.java | 137 +- .../javagl/jgltf/model/v1/GltfCreatorV1.java | 1329 +- .../jgltf/model/v1/GltfExtensionsV1.java | 171 +- .../de/javagl/jgltf/model/v1/GltfIds.java | 48 +- .../jgltf/model/v1/GltfModelCreatorV1.java | 1560 ++- .../de/javagl/jgltf/model/v1/GltfModelV1.java | 140 +- .../jgltf/model/v1/IndexMappingSet.java | 55 +- .../jgltf/model/v1/IndexMappingSets.java | 25 +- .../javagl/jgltf/model/v1/IndexMappings.java | 39 +- .../jgltf/model/v1/MaterialModelV1.java | 87 +- .../jgltf/model/v1/gl/DefaultModels.java | 208 +- .../jgltf/model/v1/gl/GltfDefaults.java | 124 +- .../javagl/jgltf/model/v1/gl/Materials.java | 33 +- .../de/javagl/jgltf/model/v1/gl/Programs.java | 35 +- .../de/javagl/jgltf/model/v1/gl/Shaders.java | 110 +- .../v1/gl/TechniqueStatesFunctionsModels.java | 51 +- .../javagl/jgltf/model/v1/gl/Techniques.java | 173 +- .../jgltf/model/v2/AccessorSparseUtils.java | 369 +- .../javagl/jgltf/model/v2/GltfCreatorV2.java | 1164 +- .../jgltf/model/v2/GltfModelCreatorV2.java | 1212 +- .../jgltf/model/v2/MaterialModelV2.java | 300 +- .../javagl/jgltf/model/v2/gl/Materials.java | 38 +- src/main/java/simplelibs/SimpleConfig.java | 198 +- 260 files changed, 28150 insertions(+), 25015 deletions(-) diff --git a/build.gradle b/build.gradle index 8e36018..9484d59 100644 --- a/build.gradle +++ b/build.gradle @@ -82,9 +82,9 @@ publishing { // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. + maven { + name = "local" + url = uri(localMvnRepo) + } } } diff --git a/gradle.properties b/gradle.properties index d8f48dc..b255d7a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.parallel=true minecraft_version=1.20.4 loader_version=0.16.3 # Mod Properties -mod_version=1.20.4-Fabric-2.1.0.0 +mod_version=1.20.4-Fabric-3.2.0.0 maven_group=com.modularmods.mcgltf archives_base_name=MCglTF # Dependencies diff --git a/settings.gradle b/settings.gradle index b02216b..c556364 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,3 +8,5 @@ pluginManagement { gradlePluginPortal() } } + +rootProject.name = "MCglTF" \ No newline at end of file diff --git a/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java b/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java index 3a3d93b..d050d4a 100644 --- a/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java +++ b/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java @@ -60,8 +60,8 @@ public interface MikkTSpaceContext { * for quads. * * @param posOut storage for the results (modified) - * @param face which face (≥0, <numFaces) - * @param vert which vertex in the face (≥0, <numVertices) + * @param face which face (≥0, <numFaces) + * @param vert which vertex in the face (≥0, <numVertices) */ public void getPosition(float posOut[], int face, int vert); @@ -75,18 +75,18 @@ public interface MikkTSpaceContext { * tangent is a unit length vector. For normal maps it is sufficient to use * the following simplified version of the bitangent which is generated at * pixel/vertex level. - *

    + * * bitangent = fSign * cross(vN, tangent); - *

    + * * Note that the results are returned unindexed. It is possible to generate * a new index list But averaging/overwriting tangent spaces by using an * already existing index list WILL produce INCORRECT results. DO NOT! use * an already existing index list. * * @param tangent the desired tangent vector (unaffected) - * @param sign the desired sign - * @param face which face (≥0, <numFaces) - * @param vert which vertex in the face (≥0, <numVertices) + * @param sign the desired sign + * @param face which face (≥0, <numFaces) + * @param vert which vertex in the face (≥0, <numVertices) */ public void setTSpaceBasic(float tangent[], float sign, int face, int vert); @@ -94,7 +94,7 @@ public interface MikkTSpaceContext { * This function is used to return tangent space results to the application. * tangent and biTangent are unit length vectors and fMagS and fMagT are * their true magnitudes which can be used for relief mapping effects. - *

    + * * biTangent is the "real" bitangent and thus may not be perpendicular to * tangent. However, both are perpendicular to the vertex normal. For normal * maps it is sufficient to use the following simplified version of the @@ -104,21 +104,21 @@ public interface MikkTSpaceContext { * fSign = bIsOrientationPreserving ? 1.0f : (-1.0f); * bitangent = fSign * cross(vN, tangent); * - *

    + * * Note that the results are returned unindexed. It is possible to generate * a new index list. But averaging/overwriting tangent spaces by using an * already existing index list WILL produce INCORRECT results. DO NOT! use * an already existing index list. * - * @param tangent the desired tangent vector (unaffected) - * @param biTangent the desired bitangent vector (unaffected) - * @param magS true magnitude of S - * @param magT true magnitude of T + * @param tangent the desired tangent vector (unaffected) + * @param biTangent the desired bitangent vector (unaffected) + * @param magS true magnitude of S + * @param magT true magnitude of T * @param isOrientationPreserving true→preserves, false→doesn't - * preserve - * @param face which face (≥0, <numFaces) - * @param vert which vertex in the face (≥0, <numVertices) + * preserve + * @param face which face (≥0, <numFaces) + * @param vert which vertex in the face (≥0, <numVertices) */ void setTSpace(float tangent[], float biTangent[], float magS, float magT, - boolean isOrientationPreserving, int face, int vert); + boolean isOrientationPreserving, int face, int vert); } diff --git a/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java b/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java index 572c779..df29252 100644 --- a/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java +++ b/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java @@ -31,35 +31,37 @@ */ package com.jme3.util.mikktspace; -import net.minecraft.util.Mth; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import net.minecraft.util.Mth; + /** * This tangent generator is highly experimental. * This is the Java translation of the mikktspace generator made by Morten S. Mikkelsen * C Source code can be found here * https://developer.blender.org/diffusion/B/browse/master/intern/mikktspace/mikktspace.c * https://developer.blender.org/diffusion/B/browse/master/intern/mikktspace/mikktspace.h - *

    + * * Mikktspace looks like the new standard of tangent generation in 3-D software. * Xnormal, Blender, Substance painter, and many more use it. - *

    + * * Usage is : * MikktspaceTangentGenerator.generate(spatial); - * + * + * + * * @author Nehon */ public class MikktspaceTangentGenerator { - static final int CELLS = 2048; private final static int MARK_DEGENERATE = 1; private final static int QUAD_ONE_DEGEN_TRI = 2; private final static int GROUP_WITH_ANY = 4; private final static int ORIENT_PRESERVING = 8; private final static long INTERNAL_RND_SORT_SEED = 39871946 & 0xffffffffL; + static final int CELLS = 2048; /** * A private constructor to inhibit instantiation of this class. @@ -114,7 +116,7 @@ public static boolean genTangSpace(MikkTSpaceContext mikkTSpace, final float ang int iNrActiveGroups, index; final int iNrFaces = mikkTSpace.getNumFaces(); //boolean bRes = false; - final float fThresCos = Mth.cos((angularThreshold * (float) Math.PI) / 180.0f); + final float fThresCos = Mth.cos((angularThreshold * (float)Math.PI) / 180.0f); // count triangles on supported faces for (int f = 0; f < iNrFaces; f++) { @@ -236,7 +238,7 @@ public static boolean genTangSpace(MikkTSpaceContext mikkTSpace, final float ang return true; } - /// //////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // it is IMPORTANT that this function is called to evaluate the hash since // inlining could potentially reorder instructions and generate different // results for the same effective input value fVal. @@ -870,15 +872,15 @@ static int build4RuleGroups(TriInfo pTriInfos[], Group pGroups[], int piGroupTri for (int i = 0; i < 3; i++) { // if not assigned to a group if ((pTriInfos[f].flag & GROUP_WITH_ANY) == 0 && pTriInfos[f].assignedGroup[i] == null) { - boolean bOrPre; + boolean bOrPre; final int vert_index = piTriListIn[f * 3 + i]; assert (iNrActiveGroups < iNrMaxGroups); - pTriInfos[f].assignedGroup[i] = new Group(); + pTriInfos[f].assignedGroup[i] = new Group(); pGroups[iNrActiveGroups] = pTriInfos[f].assignedGroup[i]; pTriInfos[f].assignedGroup[i].vertexRepresentative = vert_index; pTriInfos[f].assignedGroup[i].orientationPreserving = (pTriInfos[f].flag & ORIENT_PRESERVING) != 0; pTriInfos[f].assignedGroup[i].nrFaces = 0; - + ++iNrActiveGroups; addTriToGroup(pTriInfos[f].assignedGroup[i], f); @@ -889,7 +891,7 @@ static int build4RuleGroups(TriInfo pTriInfos[], Group pGroups[], int piGroupTri // neighbor final boolean bAnswer = assignRecur(piTriListIn, pTriInfos, neigh_indexL, - pTriInfos[f].assignedGroup[i]); + pTriInfos[f].assignedGroup[i]); final boolean bOrPre2 = (pTriInfos[neigh_indexL].flag & ORIENT_PRESERVING) != 0; final boolean bDiff = bOrPre != bOrPre2; @@ -900,7 +902,7 @@ static int build4RuleGroups(TriInfo pTriInfos[], Group pGroups[], int piGroupTri // neighbor final boolean bAnswer = assignRecur(piTriListIn, pTriInfos, neigh_indexR, - pTriInfos[f].assignedGroup[i]); + pTriInfos[f].assignedGroup[i]); final boolean bOrPre2 = (pTriInfos[neigh_indexR].flag & ORIENT_PRESERVING) != 0; final boolean bDiff = bOrPre != bOrPre2; @@ -913,9 +915,9 @@ static int build4RuleGroups(TriInfo pTriInfos[], Group pGroups[], int piGroupTri for (int j = 0; j < faceIndices.length; j++) { faceIndices[j] = pTriInfos[f].assignedGroup[i].faceIndices.get(j); } - + //Nehon: copy back the faceIndices data into the groupTriangleBuffer. - System.arraycopy(faceIndices, 0, piGroupTrianglesBuffer, iOffset, pTriInfos[f].assignedGroup[i].nrFaces); + System.arraycopy( faceIndices, 0, piGroupTrianglesBuffer, iOffset, pTriInfos[f].assignedGroup[i].nrFaces); // update offset iOffset += pTriInfos[f].assignedGroup[i].nrFaces; // since the groups are disjoint a triangle can never @@ -993,8 +995,8 @@ static boolean assignRecur(final int piTriListIn[], TriInfo psTriInfos[], final } static boolean generateTSpaces(TSpace psTspace[], final TriInfo pTriInfos[], final Group pGroups[], - final int iNrActiveGroups, final int piTriListIn[], final float fThresCos, - final MikkTSpaceContext mikkTSpace) { + final int iNrActiveGroups, final int piTriListIn[], final float fThresCos, + final MikkTSpaceContext mikkTSpace) { TSpace[] pSubGroupTspace; SubGroup[] pUniSubGroups; int[] pTmpMembers; @@ -1139,16 +1141,16 @@ static boolean generateTSpaces(TSpace psTspace[], final TriInfo pTriInfos[], fin } static TSpace evalTspace(int face_indices[], final int iFaces, final int piTriListIn[], final TriInfo pTriInfos[], - final MikkTSpaceContext mikkTSpace, final int iVertexRepresentative) { + final MikkTSpaceContext mikkTSpace, final int iVertexRepresentative) { TSpace res = new TSpace(); - float fAngleSum = 0; + float fAngleSum = 0; for (int face = 0; face < iFaces; face++) { final int f = face_indices[face]; // only valid triangles get to add their contribution if ((pTriInfos[f].flag & GROUP_WITH_ANY) == 0) { - + int i = -1; if (piTriListIn[3 * f + 0] == iVertexRepresentative) { i = 0; @@ -1173,7 +1175,7 @@ static TSpace evalTspace(int face_indices[], final int iFaces, final int piTriLi Vector3f p0 = getPosition(mikkTSpace, i0); Vector3f p1 = getPosition(mikkTSpace, i1); - Vector3f p2 = getPosition(mikkTSpace, i2); + Vector3f p2 = getPosition(mikkTSpace, i2); Vector3f v1 = p0.subtract(p1); Vector3f v2 = p2.subtract(p1); @@ -1210,11 +1212,11 @@ static TSpace evalTspace(int face_indices[], final int iFaces, final int piTriLi } static boolean compareSubGroups(final SubGroup pg1, final SubGroup pg2) { - if (pg2 == null || (pg1.nrFaces != pg2.nrFaces)) { + if(pg2 == null || (pg1.nrFaces != pg2.nrFaces)){ return false; } boolean stillSame = true; - int i = 0; + int i = 0; while (i < pg1.nrFaces && stillSame) { stillSame = pg1.triMembers[i] == pg2.triMembers[i]; if (stillSame) { @@ -1270,7 +1272,7 @@ static void quickSort(int[] pSortBuffer, int iLeft, int iRight, long uSeed) { static void buildNeighborsFast(TriInfo pTriInfos[], Edge[] pEdges, final int piTriListIn[], final int iNrTrianglesIn) { // build array of edges long uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed? - + for (int f = 0; f < iNrTrianglesIn; f++) { for (int i = 0; i < 3; i++) { final int i0 = piTriListIn[f * 3 + i]; @@ -1363,7 +1365,7 @@ static void buildNeighborsFast(TriInfo pTriInfos[], Edge[] pEdges, final int piT } static void buildNeighborsSlow(TriInfo pTriInfos[], final int piTriListIn[], final int iNrTrianglesIn) { - + for (int f = 0; f < iNrTrianglesIn; f++) { for (int i = 0; i < 3; i++) { // if unassigned @@ -1426,7 +1428,7 @@ static void quickSortEdges(Edge[] pSortBuffer, int iLeft, int iRight, final int t = (uSeed << t) | (uSeed >> (32 - t)); uSeed = uSeed + t + 3; // Random end - + uSeed = uSeed & 0xffffffffL; int iL = iLeft; @@ -1462,7 +1464,7 @@ static void quickSortEdges(Edge[] pSortBuffer, int iLeft, int iRight, final int } } - // resolve ordering and edge number +// resolve ordering and edge number static void getEdge(int[] i0_out, int[] i1_out, int[] edgenum_out, final int[] indices, final int i0_in, final int i1_in) { edgenum_out[0] = -1; @@ -1487,7 +1489,7 @@ static void getEdge(int[] i0_out, int[] i1_out, int[] edgenum_out, final int[] i } static void degenPrologue(TriInfo pTriInfos[], int piTriList_out[], final int iNrTrianglesIn, final int iTotTris) { - + // locate quads with only one good triangle int t = 0; while (t < (iTotTris - 1)) { @@ -1519,7 +1521,7 @@ static void degenPrologue(TriInfo pTriInfos[], int piTriList_out[], final int iN if (iNextGoodTriangleSearchIndex < (t + 2)) { iNextGoodTriangleSearchIndex = t + 2; } - } else { + } else { // search for the first good triangle. boolean bJustADegenerate = true; while (bJustADegenerate && iNextGoodTriangleSearchIndex < iTotTris) { @@ -1537,7 +1539,7 @@ static void degenPrologue(TriInfo pTriInfos[], int piTriList_out[], final int iN assert (iNextGoodTriangleSearchIndex > (t + 1)); // swap triangle t0 and t1 - if (!bJustADegenerate) { + if (!bJustADegenerate) { for (int i = 0; i < 3; i++) { final int index = piTriList_out[t0 * 3 + i]; piTriList_out[t0 * 3 + i] = piTriList_out[t1 * 3 + i]; @@ -1563,7 +1565,7 @@ static void degenPrologue(TriInfo pTriInfos[], int piTriList_out[], final int iN } static void DegenEpilogue(TSpace psTspace[], TriInfo pTriInfos[], int piTriListIn[], final MikkTSpaceContext mikkTSpace, final int iNrTrianglesIn, final int iTotTris) { - + // deal with degenerate triangles // punishment for degenerate triangles is O(N^2) for (int t = iNrTrianglesIn; t < iTotTris; t++) { @@ -1606,7 +1608,7 @@ static void DegenEpilogue(TSpace psTspace[], TriInfo pTriInfos[], int piTriListI // this triangle belongs to a quad where the // other triangle is degenerate if ((pTriInfos[t].flag & QUAD_ONE_DEGEN_TRI) != 0) { - + byte[] pV = pTriInfos[t].vertNum; int iFlag = (1 << pV[0]) | (1 << pV[1]) | (1 << pV[2]); int iMissingIndex = 0; @@ -1637,7 +1639,7 @@ static void DegenEpilogue(TSpace psTspace[], TriInfo pTriInfos[], int piTriListI } } - } + } /** * SubGroup inner class @@ -1678,8 +1680,8 @@ private static class TSpace { float magT; int counter; // this is to average back into quads. boolean orient; - - void set(TSpace ts) { + + void set(TSpace ts){ os.set(ts.os); magS = ts.magS; ot.set(ts.ot); @@ -1697,31 +1699,31 @@ private static class TmpVert { private static class Edge { - int[] array = new int[3]; - - int getI0() { - return array[0]; - } - - void setI0(int i) { + void setI0(int i){ array[0] = i; } - - int getI1() { - return array[1]; - } - - void setI1(int i) { + + void setI1(int i){ array[1] = i; } - - int getF() { - return array[2]; - } - - void setF(int i) { + + void setF(int i){ array[2] = i; } + + int getI0(){ + return array[0]; + } + + int getI1(){ + return array[1]; + } + + int getF(){ + return array[2]; + } + + int[] array = new int[3]; } } diff --git a/src/main/java/com/jme3/util/mikktspace/Vector3f.java b/src/main/java/com/jme3/util/mikktspace/Vector3f.java index d4567bd..34b27fe 100644 --- a/src/main/java/com/jme3/util/mikktspace/Vector3f.java +++ b/src/main/java/com/jme3/util/mikktspace/Vector3f.java @@ -45,6 +45,8 @@ */ public final class Vector3f implements Cloneable, java.io.Serializable { + static final long serialVersionUID = 1; + private static final Logger logger = Logger.getLogger(Vector3f.class.getName()); /** * Shared instance of the all-zero vector (0,0,0). Do not modify! */ @@ -85,8 +87,6 @@ public final class Vector3f implements Cloneable, java.io.Serializable { Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); - static final long serialVersionUID = 1; - private static final Logger logger = Logger.getLogger(Vector3f.class.getName()); /** * The first (X) component. */ @@ -129,60 +129,6 @@ public Vector3f(Vector3f copy) { this.set(copy); } - /** - * Tests whether the argument is a valid vector, returning false if it's - * null or if any component is NaN or infinite. - * - * @param vector the vector to test (unaffected) - * @return true if non-null and finite, otherwise false - */ - public static boolean isValidVector(Vector3f vector) { - if (vector == null) { - return false; - } - if (Float.isNaN(vector.x) - || Float.isNaN(vector.y) - || Float.isNaN(vector.z)) { - return false; - } - if (Float.isInfinite(vector.x) - || Float.isInfinite(vector.y) - || Float.isInfinite(vector.z)) { - return false; - } - return true; - } - - public static void generateOrthonormalBasis(Vector3f u, Vector3f v, Vector3f w) { - w.normalizeLocal(); - generateComplementBasis(u, v, w); - } - - public static void generateComplementBasis(Vector3f u, Vector3f v, - Vector3f w) { - float fInvLength; - - if ((float) Math.abs(w.x) >= (float) Math.abs(w.y)) { - // w.x or w.z is the largest magnitude component, swap them - fInvLength = (float) (1.0f / Math.sqrt(w.x * w.x + w.z * w.z)); - u.x = -w.z * fInvLength; - u.y = 0.0f; - u.z = +w.x * fInvLength; - v.x = w.y * u.z; - v.y = w.z * u.x - w.x * u.z; - v.z = -w.y * u.x; - } else { - // w.y or w.z is the largest magnitude component, swap them - fInvLength = (float) (1.0f / Math.sqrt(w.y * w.y + w.z * w.z)); - u.x = 0.0f; - u.y = +w.z * fInvLength; - u.z = -w.y * fInvLength; - v.x = w.y * u.z - w.z * u.y; - v.y = -w.x * u.z; - v.z = w.x * u.y; - } - } - /** * Sets all 3 components to specified values. * @@ -231,8 +177,8 @@ public Vector3f add(Vector3f vec) { * Adds a specified vector and returns the sum in a 3rd vector. The current * instance is unaffected unless it's result. * - * @param vec the vector to add (not null, unaffected unless it's - * result) + * @param vec the vector to add (not null, unaffected unless it's + * result) * @param result storage for the sum (not null) * @return result (for chaining) */ @@ -248,7 +194,7 @@ public Vector3f add(Vector3f vec, Vector3f result) { * argument is null, null is returned. * * @param vec the vector to add (unaffected unless it's this) - * or null for none + * or null for none * @return the (modified) current instance or null */ public Vector3f addLocal(Vector3f vec) { @@ -298,8 +244,8 @@ public Vector3f addLocal(float addX, float addY, float addZ) { *

    this = scalar * this + add * * @param scalar the scaling factor - * @param add the vector to add (not null, unaffected unless it's - * this) + * @param add the vector to add (not null, unaffected unless it's + * this) * @return the (modified) current instance (for chaining) */ public Vector3f scaleAdd(float scalar, Vector3f add) { @@ -317,10 +263,10 @@ public Vector3f scaleAdd(float scalar, Vector3f add) { *

    this = scalar * mult + add * * @param scalar the scaling factor - * @param mult the vector to scale (not null, unaffected unless it's - * this) - * @param add the vector to add (not null, unaffected unless it's - * this) + * @param mult the vector to scale (not null, unaffected unless it's + * this) + * @param add the vector to add (not null, unaffected unless it's + * this) * @return the (modified) current instance (for chaining) */ public Vector3f scaleAdd(float scalar, Vector3f mult, Vector3f add) { @@ -361,11 +307,11 @@ public Vector3f cross(Vector3f v) { * product in a 3rd vector. The current instance is unaffected unless it's * result. * - * @param v the right factor (not null, unaffected unless it's - * result) + * @param v the right factor (not null, unaffected unless it's + * result) * @param result storage for the product, or null for a new Vector3f * @return this cross v (either - * result or a new Vector3f) + * result or a new Vector3f) */ public Vector3f cross(Vector3f v, Vector3f result) { return cross(v.x, v.y, v.z, result); @@ -381,7 +327,7 @@ public Vector3f cross(Vector3f v, Vector3f result) { * @param otherZ the Z component of the right factor * @param result storage for the product, or null for a new Vector3f * @return this cross v (either - * result or a new Vector3f) + * result or a new Vector3f) */ public Vector3f cross(float otherX, float otherY, float otherZ, Vector3f result) { if (result == null) { @@ -399,7 +345,7 @@ public Vector3f cross(float otherX, float otherY, float otherZ, Vector3f result) * (modified) current instance. * * @param v the right factor (not null, unaffected unless it's - * this) + * this) * @return the (modified) current instance (for chaining) */ public Vector3f crossLocal(Vector3f v) { @@ -441,7 +387,7 @@ public Vector3f project(Vector3f other) { * Projects onto the argument and returns the (modified) current instance. * * @param other the vector to project onto (not null, unaffected unless it's - * this) + * this) * @return the (modified) current instance (for chaining) */ public Vector3f projectLocal(Vector3f other) { @@ -455,7 +401,7 @@ public Vector3f projectLocal(Vector3f other) { * unaffected. * * @return true if the current vector's length is between 0.99 and 1.01 - * inclusive, otherwise false + * inclusive, otherwise false */ public boolean isUnitVector() { float len = length(); @@ -543,7 +489,7 @@ public Vector3f mult(float scalar) { * specified vector. The current instance is unaffected, unless it's * product. * - * @param scalar the scaling factor + * @param scalar the scaling factor * @param product storage for the product, or null for a new Vector3f * @return either product or a new Vector3f */ @@ -576,7 +522,7 @@ public Vector3f multLocal(float scalar) { * current instance. If the argument is null, null is returned. * * @param vec the scale vector (unaffected unless it's this) or - * null for none + * null for none * @return the (modified) current instance (for chaining) or null */ public Vector3f multLocal(Vector3f vec) { @@ -641,8 +587,8 @@ public Vector3f mult(float x, float y, float z) { * Either way, the current instance is unaffected, unless it's * store. * - * @param vec the scale vector (unaffected unless it's store) - * or null for none + * @param vec the scale vector (unaffected unless it's store) + * or null for none * @param store storage for the product, or null for a new Vector3f * @return either store or a new Vector3f or null */ @@ -774,7 +720,7 @@ public Vector3f subtract(Vector3f vec) { * the argument is null, null is returned. * * @param vec the vector to subtract (unaffected unless it's - * this) or null for none + * this) or null for none * @return the (modified) current instance or null */ public Vector3f subtractLocal(Vector3f vec) { @@ -793,8 +739,8 @@ public Vector3f subtractLocal(Vector3f vec) { * vector. The current instance is unaffected unless it's * result. * - * @param vec the vector to subtract (not null, unaffected unless it's - * result) + * @param vec the vector to subtract (not null, unaffected unless it's + * result) * @param result storage for the difference, or null for a new Vector3f * @return either result or a new Vector3f */ @@ -945,8 +891,8 @@ public float angleBetween(Vector3f otherVector) { * *

    this = (1 - changeAmount) * this + changeAmount * finalVec * - * @param finalVec the desired value when changeAmount=1 (not null, unaffected - * unless it's this) + * @param finalVec the desired value when changeAmount=1 (not null, unaffected + * unless it's this) * @param changeAmount the fractional change amount * @return the (modified) current instance (for chaining) */ @@ -963,10 +909,10 @@ public Vector3f interpolateLocal(Vector3f finalVec, float changeAmount) { * *

    this = (1 - changeAmount) * beginVec + changeAmount * finalVec * - * @param beginVec the desired value when changeAmount=0 (not null, unaffected - * unless it's this) - * @param finalVec the desired value when changeAmount=1 (not null, unaffected - * unless it's this) + * @param beginVec the desired value when changeAmount=0 (not null, unaffected + * unless it's this) + * @param finalVec the desired value when changeAmount=1 (not null, unaffected + * unless it's this) * @param changeAmount the fractional change amount * @return the (modified) current instance (for chaining) */ @@ -977,6 +923,60 @@ public Vector3f interpolateLocal(Vector3f beginVec, Vector3f finalVec, float cha return this; } + /** + * Tests whether the argument is a valid vector, returning false if it's + * null or if any component is NaN or infinite. + * + * @param vector the vector to test (unaffected) + * @return true if non-null and finite, otherwise false + */ + public static boolean isValidVector(Vector3f vector) { + if (vector == null) { + return false; + } + if (Float.isNaN(vector.x) + || Float.isNaN(vector.y) + || Float.isNaN(vector.z)) { + return false; + } + if (Float.isInfinite(vector.x) + || Float.isInfinite(vector.y) + || Float.isInfinite(vector.z)) { + return false; + } + return true; + } + + public static void generateOrthonormalBasis(Vector3f u, Vector3f v, Vector3f w) { + w.normalizeLocal(); + generateComplementBasis(u, v, w); + } + + public static void generateComplementBasis(Vector3f u, Vector3f v, + Vector3f w) { + float fInvLength; + + if ((float) Math.abs(w.x) >= (float) Math.abs(w.y)) { + // w.x or w.z is the largest magnitude component, swap them + fInvLength = (float) (1.0f / Math.sqrt(w.x * w.x + w.z * w.z)); + u.x = -w.z * fInvLength; + u.y = 0.0f; + u.z = +w.x * fInvLength; + v.x = w.y * u.z; + v.y = w.z * u.x - w.x * u.z; + v.z = -w.y * u.x; + } else { + // w.y or w.z is the largest magnitude component, swap them + fInvLength = (float) (1.0f / Math.sqrt(w.y * w.y + w.z * w.z)); + u.x = 0.0f; + u.y = +w.z * fInvLength; + u.z = -w.y * fInvLength; + v.x = w.y * u.z - w.z * u.y; + v.y = -w.x * u.z; + v.z = w.x * u.y; + } + } + /** * Creates a copy. The current instance is unaffected. * @@ -995,9 +995,9 @@ public Vector3f clone() { * Copies the vector into the argument. The current instance is unaffected. * * @param floats storage for the components (must have length≥3) or null - * for a new float[3] + * for a new float[3] * @return an array containing the X, Y, and Z components in that order - * (either floats or a new float[3]) + * (either floats or a new float[3]) */ public float[] toArray(float[] floats) { if (floats == null) { @@ -1045,7 +1045,7 @@ public boolean equals(Object o) { * specified tolerance. If {@code other} is null, false is returned. Either * way, the current instance is unaffected. * - * @param other the vector to compare (unaffected) or null for none + * @param other the vector to compare (unaffected) or null for none * @param epsilon the tolerance for each component * @return true if all 3 components are within tolerance, otherwise false */ @@ -1158,7 +1158,7 @@ public Vector3f setZ(float z) { * * @param index 0, 1, or 2 * @return the X component if index=0, the Y component if index=1, or the Z - * component if index=2 + * component if index=2 * @throws IllegalArgumentException if index is not 0, 1, or 2 */ public float get(int index) { @@ -1177,7 +1177,7 @@ public float get(int index) { * Sets the indexed component. * * @param index which component to set: 0 → the X component, 1 → - * the Y component, 2 → the Z component + * the Y component, 2 → the Z component * @param value the desired component value * @throws IllegalArgumentException if index is not 0, 1, or 2 */ diff --git a/src/main/java/com/modularmods/mcgltf/AccessorDataUtils.java b/src/main/java/com/modularmods/mcgltf/AccessorDataUtils.java index faf5e6c..ff88fa9 100644 --- a/src/main/java/com/modularmods/mcgltf/AccessorDataUtils.java +++ b/src/main/java/com/modularmods/mcgltf/AccessorDataUtils.java @@ -26,72 +26,77 @@ */ package com.modularmods.mcgltf; -import de.javagl.jgltf.model.*; +import de.javagl.jgltf.model.AccessorByteData; +import de.javagl.jgltf.model.AccessorData; +import de.javagl.jgltf.model.AccessorFloatData; +import de.javagl.jgltf.model.AccessorIntData; +import de.javagl.jgltf.model.AccessorShortData; /** * Utility methods for extracting raw data from {@link AccessorData} */ -public class AccessorDataUtils { - /** - * Private constructor to prevent instantiation - */ - private AccessorDataUtils() { - // Private constructor to prevent instantiation - } - +public class AccessorDataUtils +{ /** * Returns the values that are stored in the given {@link AccessorData}. - *

    + * * This assumes the given data to be either a {@link AccessorByteData}, * {@link AccessorShortData} or {@link AccessorIntData}. - *

    + * * This method writes all components from the given data into an array. - * + * * @param accessorData The {@link AccessorData} * @return The int values * @throws IllegalArgumentException If the given data does not have one - * of the valid types. + * of the valid types. */ - public static int[] readInts(AccessorData accessorData) { + public static int[] readInts(AccessorData accessorData) + { int numElements = accessorData.getNumElements(); - int numComponents = accessorData.getNumComponentsPerElement(); - if (accessorData instanceof AccessorByteData) { - AccessorByteData accessorByteData = - (AccessorByteData) accessorData; + int numComponents = accessorData.getNumComponentsPerElement(); + if (accessorData instanceof AccessorByteData) + { + AccessorByteData accessorByteData = + (AccessorByteData) accessorData; return readIntsFromBytes( - accessorByteData, numElements, numComponents); + accessorByteData, numElements, numComponents); } - if (accessorData instanceof AccessorShortData) { - AccessorShortData accessorShortData = - (AccessorShortData) accessorData; + if (accessorData instanceof AccessorShortData) + { + AccessorShortData accessorShortData = + (AccessorShortData) accessorData; return readIntsFromShorts( - accessorShortData, numElements, numComponents); + accessorShortData, numElements, numComponents); } - if (accessorData instanceof AccessorIntData) { - AccessorIntData accessorIntData = - (AccessorIntData) accessorData; + if (accessorData instanceof AccessorIntData) + { + AccessorIntData accessorIntData = + (AccessorIntData) accessorData; return readIntsFromInts( - accessorIntData, numElements, numComponents); + accessorIntData, numElements, numComponents); } throw new IllegalArgumentException( - "Not a valid index type: " + accessorData); + "Not a valid index type: " + accessorData); } - + /** * Implementation of {@link #readInts(AccessorData)} for bytes - * + * * @param accessorByteData The input data - * @param numElements The number of elements - * @param numComponents The number of components per element + * @param numElements The number of elements + * @param numComponents The number of components per element * @return The indices */ private static int[] readIntsFromBytes( - AccessorByteData accessorByteData, int numElements, int numComponents) { + AccessorByteData accessorByteData, int numElements, int numComponents) + { int n = numElements * numComponents; int result[] = new int[n]; int index = 0; - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponents; c++) { + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponents; c++) + { result[index] = accessorByteData.getInt(e, c); index++; } @@ -101,19 +106,22 @@ private static int[] readIntsFromBytes( /** * Implementation of {@link #readInts(AccessorData)} for shorts - * + * * @param accessorShortData The input data - * @param numElements The number of elements - * @param numComponents The number of components per element + * @param numElements The number of elements + * @param numComponents The number of components per element * @return The indices */ private static int[] readIntsFromShorts( - AccessorShortData accessorShortData, int numElements, int numComponents) { + AccessorShortData accessorShortData, int numElements, int numComponents) + { int n = numElements * numComponents; int result[] = new int[n]; int index = 0; - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponents; c++) { + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponents; c++) + { result[index] = accessorShortData.getInt(e, c); index++; } @@ -123,103 +131,124 @@ private static int[] readIntsFromShorts( /** * Implementation of {@link #readInts(AccessorData)} for ints - * + * * @param accessorIntData The input data - * @param numElements The number of elements - * @param numComponents The number of components per element + * @param numElements The number of elements + * @param numComponents The number of components per element * @return The indices */ private static int[] readIntsFromInts( - AccessorIntData accessorIntData, int numElements, int numComponents) { + AccessorIntData accessorIntData, int numElements, int numComponents) + { int n = numElements * numComponents; int result[] = new int[n]; int index = 0; - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponents; c++) { + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponents; c++) + { result[index] = accessorIntData.get(e, c); index++; } } return result; - } + } /** * Reads the raw data from the given {@link AccessorFloatData}. - *

    + * * This reads the specified number of components for each element * from the input, and writes them into a result array, without * any padding. This means that the given number of components * may be smaller than the number of components that the accessor - * data actually has. - * - * @param accessorData The input data - * @param numElements The number of elements + * data actually has. + * + * @param accessorData The input data + * @param numElements The number of elements * @param numComponents The number of components per element * @return The indices */ public static float[] readFloats( - AccessorFloatData accessorData, int numElements, int numComponents) { + AccessorFloatData accessorData, int numElements, int numComponents) + { int n = numElements * numComponents; float result[] = new float[n]; int index = 0; - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponents; c++) { + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponents; c++) + { result[index] = accessorData.get(e, c); index++; } } return result; } - + /** * Writes the given raw data into the given {@link AccessorFloatData}. - *

    + * * This reads the specified number of components for each element - * from the data, and writes them into a the given accessor data. - * This means that the given number of components may be smaller - * than the number of components that the accessor data actually has. - * - * @param accessorData The input data - * @param numElements The number of elements + * from the data, and writes them into a the given accessor data. + * This means that the given number of components may be smaller + * than the number of components that the accessor data actually has. + * + * @param accessorData The input data + * @param numElements The number of elements * @param numComponents The number of components per element - * @param data The raw data + * @param data The raw data */ public static void writeFloats( - AccessorFloatData accessorData, int numElements, int numComponents, - float data[]) { + AccessorFloatData accessorData, int numElements, int numComponents, + float data[]) + { int index = 0; - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponents; c++) { + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponents; c++) + { accessorData.set(e, c, data[index]); index++; } } } - + + /** * Set the values of the given target {@link AccessorData} to the same * values as in the given source {@link AccessorData}. If either of * them has fewer elements (or fewer components per element) than the * other, then the minimum of both will be used, respectively. - * + * * @param target The target {@link AccessorData} * @param source The source {@link AccessorData} */ public static void copyFloats( - AccessorFloatData target, - AccessorFloatData source) { + AccessorFloatData target, + AccessorFloatData source) + { int numElements = - Math.min(target.getNumElements(), source.getNumElements()); + Math.min(target.getNumElements(), source.getNumElements()); int numComponents = Math.min( - target.getNumComponentsPerElement(), - source.getNumComponentsPerElement()); - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponents; c++) { + target.getNumComponentsPerElement(), + source.getNumComponentsPerElement()); + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponents; c++) + { float value = source.get(e, c); target.set(e, c, value); } } } + + /** + * Private constructor to prevent instantiation + */ + private AccessorDataUtils() + { + // Private constructor to prevent instantiation + } - + } diff --git a/src/main/java/com/modularmods/mcgltf/AccessorModelCreation.java b/src/main/java/com/modularmods/mcgltf/AccessorModelCreation.java index f6c3b82..8acb285 100644 --- a/src/main/java/com/modularmods/mcgltf/AccessorModelCreation.java +++ b/src/main/java/com/modularmods/mcgltf/AccessorModelCreation.java @@ -26,56 +26,57 @@ */ package com.modularmods.mcgltf; +import java.nio.ByteBuffer; + import de.javagl.jgltf.impl.v2.BufferView; -import de.javagl.jgltf.model.*; +import de.javagl.jgltf.model.AccessorData; +import de.javagl.jgltf.model.AccessorDatas; +import de.javagl.jgltf.model.AccessorFloatData; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.BufferModel; +import de.javagl.jgltf.model.BufferViewModel; +import de.javagl.jgltf.model.ElementType; import de.javagl.jgltf.model.impl.DefaultAccessorModel; import de.javagl.jgltf.model.impl.DefaultBufferModel; import de.javagl.jgltf.model.impl.DefaultBufferViewModel; import de.javagl.jgltf.model.io.Buffers; -import java.nio.ByteBuffer; - /** * Methods to create {@link AccessorModel} instances programmatically */ -public class AccessorModelCreation { - /** - * Private constructor to prevent instantiation - */ - private AccessorModelCreation() { - // Private constructor to prevent instantiation - } - +public class AccessorModelCreation +{ /** * Create a new {@link AccessorModel} that describes the same data as * the given {@link AccessorModel}, but in a compact form. The returned - * {@link AccessorModel} will refer to a newly created + * {@link AccessorModel} will refer to a newly created * {@link BufferViewModel} and a newly created {@link BufferModel} that * contain exactly the data for the accessor.
    *
    * The given {@link AccessorModel} is assumed to have a float * component type. - * - * @param accessorModel The {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} * @param bufferUriString The URI string for the {@link BufferModel} * @return The new {@link AccessorModel} instance. */ - public static AccessorModel instantiate( - AccessorModel accessorModel, String bufferUriString) { + public static AccessorModel instantiate( + AccessorModel accessorModel, String bufferUriString) + { AccessorModel instantiatedAccessorModel = createAccessorModel( - accessorModel.getComponentType(), accessorModel.getCount(), - accessorModel.getElementType(), bufferUriString); + accessorModel.getComponentType(), accessorModel.getCount(), + accessorModel.getElementType(), bufferUriString); AccessorData accessorData = accessorModel.getAccessorData(); - AccessorFloatData accessorFloatData = (AccessorFloatData) accessorData; - + AccessorFloatData accessorFloatData = (AccessorFloatData)accessorData; + AccessorData instantiatedAccessorData = - instantiatedAccessorModel.getAccessorData(); + instantiatedAccessorModel.getAccessorData(); AccessorFloatData instantiatedAccessorFloatData = - (AccessorFloatData) instantiatedAccessorData; + (AccessorFloatData)instantiatedAccessorData; AccessorDataUtils.copyFloats( - instantiatedAccessorFloatData, accessorFloatData); + instantiatedAccessorFloatData, accessorFloatData); return instantiatedAccessorModel; } @@ -85,52 +86,62 @@ public static AccessorModel instantiate( * refer to a newly created {@link BufferViewModel}, which in turn refers to * a newly created {@link BufferModel}, each containing exactly the data * required for the accessor. - * - * @param componentType The component type - * @param count The count - * @param elementType The element type + * + * @param componentType The component type + * @param count The count + * @param elementType The element type * @param bufferUriString The URI string for the {@link BufferModel} * @return The {@link AccessorModel} */ - public static AccessorModel createAccessorModel(int componentType, - int count, ElementType elementType, String bufferUriString) { + public static AccessorModel createAccessorModel(int componentType, + int count, ElementType elementType, String bufferUriString) + { DefaultAccessorModel accessorModel = - new DefaultAccessorModel(componentType, count, elementType); + new DefaultAccessorModel(componentType, count, elementType); int elementSize = accessorModel.getElementSizeInBytes(); accessorModel.setByteOffset(0); - + ByteBuffer bufferData = Buffers.create(count * elementSize); accessorModel.setBufferViewModel( - createBufferViewModel(bufferUriString, bufferData)); + createBufferViewModel(bufferUriString, bufferData)); accessorModel.setAccessorData(AccessorDatas.create(accessorModel)); return accessorModel; } /** * Create a new {@link BufferViewModel} with an associated - * {@link BufferModel} that serves as the basis for a sparse accessor, or + * {@link BufferModel} that serves as the basis for a sparse accessor, or * an accessor that does not refer to a {@link BufferView}) - * - * @param uriString The URI string that will be assigned to the - * {@link BufferModel} that is created internally. This string is not - * strictly required, but helpful for debugging, at least + * + * @param uriString The URI string that will be assigned to the + * {@link BufferModel} that is created internally. This string is not + * strictly required, but helpful for debugging, at least * @param bufferData The buffer data * @return The new {@link BufferViewModel} */ private static DefaultBufferViewModel createBufferViewModel( - String uriString, ByteBuffer bufferData) { + String uriString, ByteBuffer bufferData) + { DefaultBufferModel bufferModel = new DefaultBufferModel(); bufferModel.setUri(uriString); bufferModel.setBufferData(bufferData); DefaultBufferViewModel bufferViewModel = - new DefaultBufferViewModel(null); + new DefaultBufferViewModel(null); bufferViewModel.setByteOffset(0); bufferViewModel.setByteLength(bufferData.capacity()); bufferViewModel.setBufferModel(bufferModel); return bufferViewModel; } - - + + /** + * Private constructor to prevent instantiation + */ + private AccessorModelCreation() + { + // Private constructor to prevent instantiation + } + + } diff --git a/src/main/java/com/modularmods/mcgltf/IGltfModelReceiver.java b/src/main/java/com/modularmods/mcgltf/IGltfModelReceiver.java index 3424f67..8e8e1dc 100644 --- a/src/main/java/com/modularmods/mcgltf/IGltfModelReceiver.java +++ b/src/main/java/com/modularmods/mcgltf/IGltfModelReceiver.java @@ -1,18 +1,17 @@ package com.modularmods.mcgltf; +import java.util.List; + import de.javagl.jgltf.model.GltfModel; import net.minecraft.resources.ResourceLocation; -import java.util.List; - public interface IGltfModelReceiver { - ResourceLocation getModelLocation(); - - default void onReceiveSharedModel(RenderedGltfModel renderedModel) { - } - - default boolean isReceiveSharedModel(GltfModel gltfModel, List gltfRenderDatas) { - return true; - } + ResourceLocation getModelLocation(); + + default void onReceiveSharedModel(RenderedGltfModel renderedModel) {} + + default boolean isReceiveSharedModel(GltfModel gltfModel, List gltfRenderDatas) { + return true; + } } diff --git a/src/main/java/com/modularmods/mcgltf/MCglTF.java b/src/main/java/com/modularmods/mcgltf/MCglTF.java index 512a578..886257c 100644 --- a/src/main/java/com/modularmods/mcgltf/MCglTF.java +++ b/src/main/java/com/modularmods/mcgltf/MCglTF.java @@ -1,9 +1,38 @@ package com.modularmods.mcgltf; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.lwjgl.opengl.GL; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL31; +import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.GL43; +import org.lwjgl.opengl.GLCapabilities; + import com.modularmods.mcgltf.iris.RenderedGltfModelGL30Iris; import com.modularmods.mcgltf.iris.RenderedGltfModelGL33Iris; import com.modularmods.mcgltf.iris.RenderedGltfModelGL40Iris; import com.modularmods.mcgltf.iris.RenderedGltfModelIris; + import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.io.Buffers; import de.javagl.jgltf.model.io.GltfModelReader; @@ -16,444 +45,435 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.resources.ResourceManager; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.tuple.MutablePair; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.lwjgl.opengl.*; import simplelibs.SimpleConfig; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.function.BiFunction; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.function.Supplier; - public class MCglTF implements ModInitializer { - public static final String MODID = "mcgltf"; - public static final String RESOURCE_LOCATION = "resourceLocation"; - - public static final Logger logger = LogManager.getLogger(MODID); - - private static MCglTF INSTANCE; - - private final EnumRenderedModelGLProfile renderedModelGLProfile; - private final Map> loadedBufferResources = new HashMap>(); - private final Map> loadedImageResources = new HashMap>(); - private final List gltfModelReceivers = new ArrayList(); - private final List gltfRenderData = new ArrayList(); - private int glProgramSkinnig = -1; - private int defaultColorMap; - private int defaultNormalMap; - private AbstractTexture lightTexture; - private BooleanSupplier shaderModActive; - - public MCglTF() { - INSTANCE = this; - renderedModelGLProfile = EnumRenderedModelGLProfile.valueOf(SimpleConfig.of(MODID).provider(this::provider).request().getOrDefault("RenderedModelGLProfile", "AUTO")); - } - - public static MCglTF getInstance() { - return INSTANCE; - } - - @Override - public void onInitialize() { - Consumer>>> processRenderedGltfModelSelector; - if (FabricLoader.getInstance().isModLoaded("iris")) { - shaderModActive = net.irisshaders.iris.api.v0.IrisApi.getInstance()::isShaderPackInUse; - - processRenderedGltfModelSelector = (lookup) -> { - switch (renderedModelGLProfile) { - case GL43: - processRenderedGltfModelsGL43Iris(lookup); - break; - case GL40: - processRenderedGltfModelsGL40Iris(lookup); - break; - case GL33: - processRenderedGltfModelsGL33Iris(lookup); - break; - case GL30: - processRenderedGltfModelsGL30Iris(lookup); - break; - default: - GLCapabilities glCapabilities = GL.getCapabilities(); - if (glCapabilities.glTexBufferRange != 0) processRenderedGltfModelsGL43Iris(lookup); - else if (glCapabilities.glGenTransformFeedbacks != 0) processRenderedGltfModelsGL40Iris(lookup); - else processRenderedGltfModelsGL33Iris(lookup); - break; - } - }; - } else { - shaderModActive = () -> false; - - processRenderedGltfModelSelector = (lookup) -> { - switch (renderedModelGLProfile) { - case GL43: - processRenderedGltfModelsGL43(lookup); - break; - case GL40: - processRenderedGltfModelsGL40(lookup); - break; - case GL33: - processRenderedGltfModelsGL33(lookup); - break; - case GL30: - processRenderedGltfModelsGL30(lookup); - break; - default: - GLCapabilities glCapabilities = GL.getCapabilities(); - if (glCapabilities.glTexBufferRange != 0) processRenderedGltfModelsGL43(lookup); - else if (glCapabilities.glGenTransformFeedbacks != 0) processRenderedGltfModelsGL40(lookup); - else processRenderedGltfModelsGL33(lookup); - break; - } - }; - } - - Minecraft.getInstance().execute(() -> { - lightTexture = Minecraft.getInstance().getTextureManager().getTexture(new ResourceLocation("dynamic/light_map_1")); - - switch (renderedModelGLProfile) { - case GL43: - createSkinningProgramGL43(); - break; - case GL40: - case GL33: - createSkinningProgramGL33(); - break; - case GL30: - break; - default: - //Since max OpenGL version on Windows from GLCapabilities will always return 3.2 as of Minecraft 1.17, this is a workaround to check if OpenGL 4.3 is available. - if (GL.getCapabilities().glTexBufferRange != 0) createSkinningProgramGL43(); - else createSkinningProgramGL33(); - break; - } - - GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4); - - int currentTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - defaultColorMap = GL11.glGenTextures(); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, defaultColorMap); - GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 2, 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, Buffers.create(new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1})); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); - - defaultNormalMap = GL11.glGenTextures(); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, defaultNormalMap); - GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 2, 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, Buffers.create(new byte[]{-128, -128, -1, -1, -128, -128, -1, -1, -128, -128, -1, -1, -128, -128, -1, -1})); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); - - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture); - }); - - ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { - - @Override - public ResourceLocation getFabricId() { - return new ResourceLocation(MODID, "gltf_reload_listener"); - } - - @Override - public void onResourceManagerReload(ResourceManager resourceManager) { - gltfRenderData.forEach(Runnable::run); - gltfRenderData.clear(); - - GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); - GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4); - - int currentTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - Map>> lookup = new HashMap>>(); - gltfModelReceivers.forEach((receiver) -> { - ResourceLocation modelLocation = receiver.getModelLocation(); - MutablePair> receivers = lookup.get(modelLocation); - if (receivers == null) { - receivers = MutablePair.of(null, new ArrayList()); - lookup.put(modelLocation, receivers); - } - receivers.getRight().add(receiver); - }); - lookup.entrySet().parallelStream().forEach((entry) -> { - try { - entry.getValue().setLeft(new GltfModelReader().readWithoutReferences(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(entry.getKey()).orElseThrow().open()))); - } catch (IOException e) { - e.printStackTrace(); - } - }); - processRenderedGltfModelSelector.accept(lookup); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); - GL30.glBindVertexArray(0); - - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture); - - loadedBufferResources.clear(); - loadedImageResources.clear(); - } - - }); - } - - public int getGlProgramSkinnig() { - return glProgramSkinnig; - } - - public int getDefaultColorMap() { - return defaultColorMap; - } - - public int getDefaultNormalMap() { - return defaultNormalMap; - } - - public int getDefaultSpecularMap() { - return 0; - } - - public AbstractTexture getLightTexture() { - return lightTexture; - } - - public ByteBuffer getBufferResource(ResourceLocation location) { - Supplier supplier; - synchronized (loadedBufferResources) { - supplier = loadedBufferResources.get(location); - if (supplier == null) { - supplier = new Supplier() { - ByteBuffer bufferData; - - @Override - public synchronized ByteBuffer get() { - if (bufferData == null) { - try { - bufferData = Buffers.create(IOUtils.toByteArray(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(location).orElseThrow().open()))); - } catch (IOException e) { - e.printStackTrace(); - } - } - return bufferData; - } - - }; - loadedBufferResources.put(location, supplier); - } - } - return supplier.get(); - } - - public ByteBuffer getImageResource(ResourceLocation location) { - Supplier supplier; - synchronized (loadedImageResources) { - supplier = loadedImageResources.get(location); - if (supplier == null) { - supplier = new Supplier() { - ByteBuffer bufferData; - - @Override - public synchronized ByteBuffer get() { - if (bufferData == null) { - try { - bufferData = Buffers.create(IOUtils.toByteArray(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(location).orElseThrow().open()))); - } catch (IOException e) { - e.printStackTrace(); - } - } - return bufferData; - } - - }; - loadedImageResources.put(location, supplier); - } - } - return supplier.get(); - } - - public synchronized void addGltfModelReceiver(IGltfModelReceiver receiver) { - gltfModelReceivers.add(receiver); - } - - public synchronized boolean removeGltfModelReceiver(IGltfModelReceiver receiver) { - return gltfModelReceivers.remove(receiver); - } - - public boolean isShaderModActive() { - return shaderModActive.getAsBoolean(); - } - - private void createSkinningProgramGL43() { - int glShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); - GL20.glShaderSource(glShader, - "#version 430\r\n" - + "layout(location = 0) in vec4 joint;" - + "layout(location = 1) in vec4 weight;" - + "layout(location = 2) in vec3 position;" - + "layout(location = 3) in vec3 normal;" - + "layout(location = 4) in vec4 tangent;" - + "layout(std430, binding = 0) readonly buffer jointMatrixBuffer {mat4 jointMatrices[];};" - + "out vec3 outPosition;" - + "out vec3 outNormal;" - + "out vec4 outTangent;" - + "void main() {" - + "mat4 skinMatrix =" - + " weight.x * jointMatrices[int(joint.x)] +" - + " weight.y * jointMatrices[int(joint.y)] +" - + " weight.z * jointMatrices[int(joint.z)] +" - + " weight.w * jointMatrices[int(joint.w)];" - + "outPosition = (skinMatrix * vec4(position, 1.0)).xyz;" - + "mat3 upperLeft = mat3(skinMatrix);" - + "outNormal = upperLeft * normal;" - + "outTangent.xyz = upperLeft * tangent.xyz;" - + "outTangent.w = tangent.w;" - + "}"); - GL20.glCompileShader(glShader); - - glProgramSkinnig = GL20.glCreateProgram(); - GL20.glAttachShader(glProgramSkinnig, glShader); - GL20.glDeleteShader(glShader); - GL30.glTransformFeedbackVaryings(glProgramSkinnig, new CharSequence[]{"outPosition", "outNormal", "outTangent"}, GL30.GL_SEPARATE_ATTRIBS); - GL20.glLinkProgram(glProgramSkinnig); - } - - private void createSkinningProgramGL33() { - int glShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); - GL20.glShaderSource(glShader, - "#version 330\r\n" - + "layout(location = 0) in vec4 joint;" - + "layout(location = 1) in vec4 weight;" - + "layout(location = 2) in vec3 position;" - + "layout(location = 3) in vec3 normal;" - + "layout(location = 4) in vec4 tangent;" - + "uniform samplerBuffer jointMatrices;" - + "out vec3 outPosition;" - + "out vec3 outNormal;" - + "out vec4 outTangent;" - + "void main() {" - + "int jx = int(joint.x) * 4;" - + "int jy = int(joint.y) * 4;" - + "int jz = int(joint.z) * 4;" - + "int jw = int(joint.w) * 4;" - + "mat4 skinMatrix =" - + " weight.x * mat4(texelFetch(jointMatrices, jx), texelFetch(jointMatrices, jx + 1), texelFetch(jointMatrices, jx + 2), texelFetch(jointMatrices, jx + 3)) +" - + " weight.y * mat4(texelFetch(jointMatrices, jy), texelFetch(jointMatrices, jy + 1), texelFetch(jointMatrices, jy + 2), texelFetch(jointMatrices, jy + 3)) +" - + " weight.z * mat4(texelFetch(jointMatrices, jz), texelFetch(jointMatrices, jz + 1), texelFetch(jointMatrices, jz + 2), texelFetch(jointMatrices, jz + 3)) +" - + " weight.w * mat4(texelFetch(jointMatrices, jw), texelFetch(jointMatrices, jw + 1), texelFetch(jointMatrices, jw + 2), texelFetch(jointMatrices, jw + 3));" - + "outPosition = (skinMatrix * vec4(position, 1.0)).xyz;" - + "mat3 upperLeft = mat3(skinMatrix);" - + "outNormal = upperLeft * normal;" - + "outTangent.xyz = upperLeft * tangent.xyz;" - + "outTangent.w = tangent.w;" - + "}"); - GL20.glCompileShader(glShader); - - glProgramSkinnig = GL20.glCreateProgram(); - GL20.glAttachShader(glProgramSkinnig, glShader); - GL20.glDeleteShader(glShader); - GL30.glTransformFeedbackVaryings(glProgramSkinnig, new CharSequence[]{"outPosition", "outNormal", "outTangent"}, GL30.GL_SEPARATE_ATTRIBS); - GL20.glLinkProgram(glProgramSkinnig); - } - - private void processRenderedGltfModels(Map>> lookup, BiFunction, GltfModel, RenderedGltfModel> renderedGltfModelBuilder) { - lookup.forEach((modelLocation, receivers) -> { - Iterator iterator = receivers.getRight().iterator(); - do { - IGltfModelReceiver receiver = iterator.next(); - if (receiver.isReceiveSharedModel(receivers.getLeft(), gltfRenderData)) { - RenderedGltfModel renderedModel = renderedGltfModelBuilder.apply(gltfRenderData, receivers.getLeft()); - receiver.onReceiveSharedModel(renderedModel); - while (iterator.hasNext()) { - receiver = iterator.next(); - if (receiver.isReceiveSharedModel(receivers.getLeft(), gltfRenderData)) { - receiver.onReceiveSharedModel(renderedModel); - } - } - return; - } - } - while (iterator.hasNext()); - }); - } - - private void processRenderedGltfModelsGL43(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModel::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - } - - private void processRenderedGltfModelsGL40(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL40::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - } - - private void processRenderedGltfModelsGL33(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL33::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - } - - private void processRenderedGltfModelsGL30(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL30::new); - } - - private void processRenderedGltfModelsGL43Iris(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelIris::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - } - - private void processRenderedGltfModelsGL40Iris(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL40Iris::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - } - - private void processRenderedGltfModelsGL33Iris(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL33Iris::new); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - } - - private void processRenderedGltfModelsGL30Iris(Map>> lookup) { - processRenderedGltfModels(lookup, RenderedGltfModelGL30Iris::new); - } - - public EnumRenderedModelGLProfile getRenderedModelGLProfile() { - return renderedModelGLProfile; - } - - private String provider(String filename) { - return "#Set maximum version of OpenGL to enable some optimizations for rendering glTF model.\n" - + "#The AUTO means it will select maximum OpenGL version available based on your hardware. The GL43 is highest it may select.\n" - + "#The lower OpenGL version you set, the more negative impact on performance you will probably get.\n" - + "#The GL30 is a special profile which essentially the GL33 and above but replace hardware(GPU) skinning with software(CPU) skinning. This will trade a lots of CPU performance for a few GPU performance increase.\n" - + "#Allowed Values: AUTO, GL43, GL40, GL33, GL30\n" - + "RenderedModelGLProfile=AUTO"; - } - - public enum EnumRenderedModelGLProfile { - AUTO, - GL43, - GL40, - GL33, - GL30 - } + public static final String MODID = "mcgltf"; + public static final String RESOURCE_LOCATION = "resourceLocation"; + + public static final Logger logger = LogManager.getLogger(MODID); + + private static MCglTF INSTANCE; + + private final EnumRenderedModelGLProfile renderedModelGLProfile; + + private int glProgramSkinnig = -1; + private int defaultColorMap; + private int defaultNormalMap; + + private AbstractTexture lightTexture; + + private final Map> loadedBufferResources = new HashMap>(); + private final Map> loadedImageResources = new HashMap>(); + private final List gltfModelReceivers = new ArrayList(); + private final List gltfRenderData = new ArrayList(); + + private BooleanSupplier shaderModActive; + + public MCglTF() { + INSTANCE = this; + renderedModelGLProfile = EnumRenderedModelGLProfile.valueOf(SimpleConfig.of(MODID).provider(this::provider).request().getOrDefault("RenderedModelGLProfile", "AUTO")); + } + + @Override + public void onInitialize() { + Consumer>>> processRenderedGltfModelSelector; + if(FabricLoader.getInstance().isModLoaded("iris")) { + shaderModActive = net.irisshaders.iris.api.v0.IrisApi.getInstance()::isShaderPackInUse; + + processRenderedGltfModelSelector = (lookup) -> { + switch(renderedModelGLProfile) { + case GL43: + processRenderedGltfModelsGL43Iris(lookup); + break; + case GL40: + processRenderedGltfModelsGL40Iris(lookup); + break; + case GL33: + processRenderedGltfModelsGL33Iris(lookup); + break; + case GL30: + processRenderedGltfModelsGL30Iris(lookup); + break; + default: + GLCapabilities glCapabilities = GL.getCapabilities(); + if(glCapabilities.glTexBufferRange != 0) processRenderedGltfModelsGL43Iris(lookup); + else if(glCapabilities.glGenTransformFeedbacks != 0) processRenderedGltfModelsGL40Iris(lookup); + else processRenderedGltfModelsGL33Iris(lookup); + break; + } + }; + } + else { + shaderModActive = () -> false; + + processRenderedGltfModelSelector = (lookup) -> { + switch(renderedModelGLProfile) { + case GL43: + processRenderedGltfModelsGL43(lookup); + break; + case GL40: + processRenderedGltfModelsGL40(lookup); + break; + case GL33: + processRenderedGltfModelsGL33(lookup); + break; + case GL30: + processRenderedGltfModelsGL30(lookup); + break; + default: + GLCapabilities glCapabilities = GL.getCapabilities(); + if(glCapabilities.glTexBufferRange != 0) processRenderedGltfModelsGL43(lookup); + else if(glCapabilities.glGenTransformFeedbacks != 0) processRenderedGltfModelsGL40(lookup); + else processRenderedGltfModelsGL33(lookup); + break; + } + }; + } + + Minecraft.getInstance().execute(() -> { + lightTexture = Minecraft.getInstance().getTextureManager().getTexture(new ResourceLocation("dynamic/light_map_1")); + + switch(renderedModelGLProfile) { + case GL43: + createSkinningProgramGL43(); + break; + case GL40: + case GL33: + createSkinningProgramGL33(); + break; + case GL30: + break; + default: + //Since max OpenGL version on Windows from GLCapabilities will always return 3.2 as of Minecraft 1.17, this is a workaround to check if OpenGL 4.3 is available. + if(GL.getCapabilities().glTexBufferRange != 0) createSkinningProgramGL43(); + else createSkinningProgramGL33(); + break; + } + + GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4); + + int currentTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + defaultColorMap = GL11.glGenTextures(); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, defaultColorMap); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 2, 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, Buffers.create(new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1})); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); + + defaultNormalMap = GL11.glGenTextures(); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, defaultNormalMap); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 2, 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, Buffers.create(new byte[]{-128, -128, -1, -1, -128, -128, -1, -1, -128, -128, -1, -1, -128, -128, -1, -1})); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); + + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture); + }); + + ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { + + @Override + public ResourceLocation getFabricId() { + return new ResourceLocation(MODID, "gltf_reload_listener"); + } + + @Override + public void onResourceManagerReload(ResourceManager resourceManager) { + gltfRenderData.forEach(Runnable::run); + gltfRenderData.clear(); + + GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); + GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4); + + int currentTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + Map>> lookup = new HashMap>>(); + gltfModelReceivers.forEach((receiver) -> { + ResourceLocation modelLocation = receiver.getModelLocation(); + MutablePair> receivers = lookup.get(modelLocation); + if(receivers == null) { + receivers = MutablePair.of(null, new ArrayList()); + lookup.put(modelLocation, receivers); + } + receivers.getRight().add(receiver); + }); + lookup.entrySet().parallelStream().forEach((entry) -> { + try { + entry.getValue().setLeft(new GltfModelReader().readWithoutReferences(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(entry.getKey()).orElseThrow().open()))); + } catch (IOException e) { + e.printStackTrace(); + } + }); + processRenderedGltfModelSelector.accept(lookup); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); + GL30.glBindVertexArray(0); + + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture); + + loadedBufferResources.clear(); + loadedImageResources.clear(); + } + + }); + } + + public int getGlProgramSkinnig() { + return glProgramSkinnig; + } + + public int getDefaultColorMap() { + return defaultColorMap; + } + + public int getDefaultNormalMap() { + return defaultNormalMap; + } + + public int getDefaultSpecularMap() { + return 0; + } + + public AbstractTexture getLightTexture() { + return lightTexture; + } + + public ByteBuffer getBufferResource(ResourceLocation location) { + Supplier supplier; + synchronized(loadedBufferResources) { + supplier = loadedBufferResources.get(location); + if(supplier == null) { + supplier = new Supplier() { + ByteBuffer bufferData; + + @Override + public synchronized ByteBuffer get() { + if(bufferData == null) { + try { + bufferData = Buffers.create(IOUtils.toByteArray(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(location).orElseThrow().open()))); + } catch (IOException e) { + e.printStackTrace(); + } + } + return bufferData; + } + + }; + loadedBufferResources.put(location, supplier); + } + } + return supplier.get(); + } + + public ByteBuffer getImageResource(ResourceLocation location) { + Supplier supplier; + synchronized(loadedImageResources) { + supplier = loadedImageResources.get(location); + if(supplier == null) { + supplier = new Supplier() { + ByteBuffer bufferData; + + @Override + public synchronized ByteBuffer get() { + if(bufferData == null) { + try { + bufferData = Buffers.create(IOUtils.toByteArray(new BufferedInputStream(Minecraft.getInstance().getResourceManager().getResource(location).orElseThrow().open()))); + } catch (IOException e) { + e.printStackTrace(); + } + } + return bufferData; + } + + }; + loadedImageResources.put(location, supplier); + } + } + return supplier.get(); + } + + public synchronized void addGltfModelReceiver(IGltfModelReceiver receiver) { + gltfModelReceivers.add(receiver); + } + + public synchronized boolean removeGltfModelReceiver(IGltfModelReceiver receiver) { + return gltfModelReceivers.remove(receiver); + } + + public boolean isShaderModActive() { + return shaderModActive.getAsBoolean(); + } + + public static MCglTF getInstance() { + return INSTANCE; + } + + private void createSkinningProgramGL43() { + int glShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); + GL20.glShaderSource(glShader, + "#version 430\r\n" + + "layout(location = 0) in vec4 joint;" + + "layout(location = 1) in vec4 weight;" + + "layout(location = 2) in vec3 position;" + + "layout(location = 3) in vec3 normal;" + + "layout(location = 4) in vec4 tangent;" + + "layout(std430, binding = 0) readonly buffer jointMatrixBuffer {mat4 jointMatrices[];};" + + "out vec3 outPosition;" + + "out vec3 outNormal;" + + "out vec4 outTangent;" + + "void main() {" + + "mat4 skinMatrix =" + + " weight.x * jointMatrices[int(joint.x)] +" + + " weight.y * jointMatrices[int(joint.y)] +" + + " weight.z * jointMatrices[int(joint.z)] +" + + " weight.w * jointMatrices[int(joint.w)];" + + "outPosition = (skinMatrix * vec4(position, 1.0)).xyz;" + + "mat3 upperLeft = mat3(skinMatrix);" + + "outNormal = upperLeft * normal;" + + "outTangent.xyz = upperLeft * tangent.xyz;" + + "outTangent.w = tangent.w;" + + "}"); + GL20.glCompileShader(glShader); + + glProgramSkinnig = GL20.glCreateProgram(); + GL20.glAttachShader(glProgramSkinnig, glShader); + GL20.glDeleteShader(glShader); + GL30.glTransformFeedbackVaryings(glProgramSkinnig, new CharSequence[]{"outPosition", "outNormal", "outTangent"}, GL30.GL_SEPARATE_ATTRIBS); + GL20.glLinkProgram(glProgramSkinnig); + } + + private void createSkinningProgramGL33() { + int glShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); + GL20.glShaderSource(glShader, + "#version 330\r\n" + + "layout(location = 0) in vec4 joint;" + + "layout(location = 1) in vec4 weight;" + + "layout(location = 2) in vec3 position;" + + "layout(location = 3) in vec3 normal;" + + "layout(location = 4) in vec4 tangent;" + + "uniform samplerBuffer jointMatrices;" + + "out vec3 outPosition;" + + "out vec3 outNormal;" + + "out vec4 outTangent;" + + "void main() {" + + "int jx = int(joint.x) * 4;" + + "int jy = int(joint.y) * 4;" + + "int jz = int(joint.z) * 4;" + + "int jw = int(joint.w) * 4;" + + "mat4 skinMatrix =" + + " weight.x * mat4(texelFetch(jointMatrices, jx), texelFetch(jointMatrices, jx + 1), texelFetch(jointMatrices, jx + 2), texelFetch(jointMatrices, jx + 3)) +" + + " weight.y * mat4(texelFetch(jointMatrices, jy), texelFetch(jointMatrices, jy + 1), texelFetch(jointMatrices, jy + 2), texelFetch(jointMatrices, jy + 3)) +" + + " weight.z * mat4(texelFetch(jointMatrices, jz), texelFetch(jointMatrices, jz + 1), texelFetch(jointMatrices, jz + 2), texelFetch(jointMatrices, jz + 3)) +" + + " weight.w * mat4(texelFetch(jointMatrices, jw), texelFetch(jointMatrices, jw + 1), texelFetch(jointMatrices, jw + 2), texelFetch(jointMatrices, jw + 3));" + + "outPosition = (skinMatrix * vec4(position, 1.0)).xyz;" + + "mat3 upperLeft = mat3(skinMatrix);" + + "outNormal = upperLeft * normal;" + + "outTangent.xyz = upperLeft * tangent.xyz;" + + "outTangent.w = tangent.w;" + + "}"); + GL20.glCompileShader(glShader); + + glProgramSkinnig = GL20.glCreateProgram(); + GL20.glAttachShader(glProgramSkinnig, glShader); + GL20.glDeleteShader(glShader); + GL30.glTransformFeedbackVaryings(glProgramSkinnig, new CharSequence[]{"outPosition", "outNormal", "outTangent"}, GL30.GL_SEPARATE_ATTRIBS); + GL20.glLinkProgram(glProgramSkinnig); + } + + private void processRenderedGltfModels(Map>> lookup, BiFunction, GltfModel, RenderedGltfModel> renderedGltfModelBuilder) { + lookup.forEach((modelLocation, receivers) -> { + Iterator iterator = receivers.getRight().iterator(); + do { + IGltfModelReceiver receiver = iterator.next(); + if(receiver.isReceiveSharedModel(receivers.getLeft(), gltfRenderData)) { + RenderedGltfModel renderedModel = renderedGltfModelBuilder.apply(gltfRenderData, receivers.getLeft()); + receiver.onReceiveSharedModel(renderedModel); + while(iterator.hasNext()) { + receiver = iterator.next(); + if(receiver.isReceiveSharedModel(receivers.getLeft(), gltfRenderData)) { + receiver.onReceiveSharedModel(renderedModel); + } + } + return; + } + } + while(iterator.hasNext()); + }); + } + + private void processRenderedGltfModelsGL43(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModel::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + } + + private void processRenderedGltfModelsGL40(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL40::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + } + + private void processRenderedGltfModelsGL33(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL33::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + } + + private void processRenderedGltfModelsGL30(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL30::new); + } + + private void processRenderedGltfModelsGL43Iris(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelIris::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + } + + private void processRenderedGltfModelsGL40Iris(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL40Iris::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + } + + private void processRenderedGltfModelsGL33Iris(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL33Iris::new); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, 0); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + } + + private void processRenderedGltfModelsGL30Iris(Map>> lookup) { + processRenderedGltfModels(lookup, RenderedGltfModelGL30Iris::new); + } + + public enum EnumRenderedModelGLProfile { + AUTO, + GL43, + GL40, + GL33, + GL30 + } + + public EnumRenderedModelGLProfile getRenderedModelGLProfile() { + return renderedModelGLProfile; + } + + private String provider(String filename) { + return "#Set maximum version of OpenGL to enable some optimizations for rendering glTF model.\n" + + "#The AUTO means it will select maximum OpenGL version available based on your hardware. The GL43 is highest it may select.\n" + + "#The lower OpenGL version you set, the more negative impact on performance you will probably get.\n" + + "#The GL30 is a special profile which essentially the GL33 and above but replace hardware(GPU) skinning with software(CPU) skinning. This will trade a lots of CPU performance for a few GPU performance increase.\n" + + "#Allowed Values: AUTO, GL43, GL40, GL33, GL30\n" + + "RenderedModelGLProfile=AUTO"; + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfModel.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfModel.java index 6bed9d6..76785d9 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfModel.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfModel.java @@ -1,4999 +1,5168 @@ package com.modularmods.mcgltf; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.tuple.Triple; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.GL43; + import com.google.gson.Gson; import com.jme3.util.mikktspace.MikkTSpaceContext; import com.jme3.util.mikktspace.MikktspaceTangentGenerator; -import de.javagl.jgltf.model.*; + +import de.javagl.jgltf.model.AccessorByteData; +import de.javagl.jgltf.model.AccessorData; +import de.javagl.jgltf.model.AccessorDatas; +import de.javagl.jgltf.model.AccessorFloatData; +import de.javagl.jgltf.model.AccessorIntData; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.AccessorShortData; +import de.javagl.jgltf.model.BufferViewModel; +import de.javagl.jgltf.model.ElementType; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.MaterialModel; +import de.javagl.jgltf.model.MathUtils; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.Optionals; +import de.javagl.jgltf.model.SceneModel; +import de.javagl.jgltf.model.SkinModel; +import de.javagl.jgltf.model.TextureModel; import de.javagl.jgltf.model.image.PixelData; import de.javagl.jgltf.model.image.PixelDatas; import de.javagl.jgltf.model.impl.DefaultNodeModel; import de.javagl.jgltf.model.v2.MaterialModelV2; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.renderer.ShaderInstance; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.commons.lang3.tuple.Triple; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.lwjgl.BufferUtils; -import org.lwjgl.opengl.*; - -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.util.*; public class RenderedGltfModel { - /** - * ShaderMod attribute location for middle UV coordinates, used for parallax occlusion mapping.
    - * This may change in different Minecraft version.
    - * optifine/shaders.txt - */ - public static final int mc_midTexCoord; - - /** - * ShaderMod attribute location for Tangent.
    - * This may change in different Minecraft version.
    - * optifine/shaders.txt - */ - public static final int at_tangent; - - /** - * ShaderMod Texture index, this may change in different Minecraft version.
    - * optifine/shaders.txt - */ - public static final int COLOR_MAP_INDEX = GL13.GL_TEXTURE0; - public static final int vaPosition = 0; - public static final int vaColor = 1; - public static final int vaUV0 = 2; - public static final int vaUV1 = 3; - public static final int vaUV2 = 4; - public static final int vaNormal = 10; - public static final Map NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE = new IdentityHashMap(); - protected static final Runnable vanillaDefaultMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); - GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - protected static final Runnable shaderModDefaultMaterialCommand; - protected static final int skinning_joint = 0; - protected static final int skinning_weight = 1; - protected static final int skinning_position = 2; - protected static final int skinning_normal = 3; - protected static final int skinning_tangent = 4; - protected static final int skinning_out_position = 0; - protected static final int skinning_out_normal = 1; - protected static final int skinning_out_tangent = 2; - protected static final FloatBuffer BUF_FLOAT_9 = BufferUtils.createFloatBuffer(9); - protected static final FloatBuffer BUF_FLOAT_16 = BufferUtils.createFloatBuffer(16); - public static int NORMAL_MAP_INDEX = GL13.GL_TEXTURE2; - public static int SPECULAR_MAP_INDEX = GL13.GL_TEXTURE1; - public static int MODEL_VIEW_MATRIX; - public static int MODEL_VIEW_MATRIX_INVERSE; - public static int NORMAL_MATRIX; - public static ShaderInstance CURRENT_SHADER_INSTANCE; - public static Vector3f LIGHT0_DIRECTION; - public static Vector3f LIGHT1_DIRECTION; - protected static Matrix4f CURRENT_POSE; - protected static Matrix3f CURRENT_NORMAL; - protected static FloatBuffer uniformFloatBuffer = null; - - static { - if (FabricLoader.getInstance().isModLoaded("iris")) { - mc_midTexCoord = 12; - at_tangent = 13; - - shaderModDefaultMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); - - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - int normalMapLocation = GL20.glGetUniformLocation(currentProgram, "normals"); - if (normalMapLocation != -1) { - GL13.glActiveTexture(GL13.GL_TEXTURE0 + 2); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultNormalMap()); - GL20.glUniform1i(normalMapLocation, 2); - } - int specularMapLocation = GL20.glGetUniformLocation(currentProgram, "specular"); - if (specularMapLocation != -1) { - GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultSpecularMap()); - GL20.glUniform1i(specularMapLocation, 1); - } - - // Enhanced color attribute with proper alpha handling - GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); - - // Add entityColor uniform support for shader packs like SEUS PTGI - int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); - if (entityColorLocation != -1) { - GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); - } - - // Ensure proper blending state for Iris rendering - GL11.glDisable(GL11.GL_BLEND); - - GL11.glEnable(GL11.GL_CULL_FACE); - }; - } else { - mc_midTexCoord = 12; - at_tangent = 13; - - shaderModDefaultMaterialCommand = () -> { - GL13.glActiveTexture(COLOR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); - GL13.glActiveTexture(NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultNormalMap()); - GL13.glActiveTexture(SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultSpecularMap()); - - // Enhanced color attribute with proper alpha handling - GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); - - // Add entityColor uniform support for shader packs like SEUS PTGI - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); - if (entityColorLocation != -1) { - GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); - } - - // Ensure proper blending state for non-Iris rendering - GL11.glDisable(GL11.GL_BLEND); - - GL11.glEnable(GL11.GL_CULL_FACE); - }; - } - } - - public final GltfModel gltfModel; - public final List renderedGltfScenes; - protected final Map, List, List>> rootNodeModelToCommands = new IdentityHashMap, List, List>>(); - protected final Map positionsAccessorModelToNormalsAccessorModel = new IdentityHashMap(); - protected final Map normalsAccessorModelToTangentsAccessorModel = new IdentityHashMap(); - protected final Map colorsAccessorModelVec3ToVec4 = new IdentityHashMap(); - protected final Map jointsAccessorModelUnsignedLookup = new IdentityHashMap(); - protected final Map weightsAccessorModelDequantizedLookup = new IdentityHashMap(); - protected final Map colorsMorphTargetAccessorModelToAccessorData = new IdentityHashMap(); - protected final Map texcoordsMorphTargetAccessorModelToAccessorData = new IdentityHashMap(); - protected final Map meshPrimitiveModelToTangentsAccessorModel = new IdentityHashMap(); - protected final Map, List>>> meshPrimitiveModelToUnindexed = new IdentityHashMap, List>>>(); - protected final Map bufferViewModelToGlBufferView = new IdentityHashMap(); - protected final Map textureModelToGlTexture = new IdentityHashMap(); - protected final Map materialModelToRenderedMaterial = new IdentityHashMap(); - - protected RenderedGltfModel(GltfModel gltfModel, List renderedGltfScenes) { - this.gltfModel = gltfModel; - this.renderedGltfScenes = renderedGltfScenes; - } - - public RenderedGltfModel(List gltfRenderData, GltfModel gltfModel) { - this.gltfModel = gltfModel; - List sceneModels = gltfModel.getSceneModels(); - renderedGltfScenes = new ArrayList(sceneModels.size()); - processSceneModels(gltfRenderData, sceneModels); - } - - protected static float[] findGlobalTransform(NodeModel nodeModel) { - float[] found = NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.get(nodeModel); - if (found != null) { - return found; - } else { - List pathToNode = new ArrayList(); - pathToNode.add(nodeModel); - nodeModel = nodeModel.getParent(); - while (nodeModel != null) { - found = NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.get(nodeModel); - if (found != null) { - int i = pathToNode.size() - 1; - do { - nodeModel = pathToNode.get(i); - float[] transform = DefaultNodeModel.computeLocalTransform(nodeModel, null); - MathUtils.mul4x4(found, transform, transform); - NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.put(nodeModel, transform); - found = transform; - } - while (--i >= 0); - return found; - } else { - pathToNode.add(nodeModel); - nodeModel = nodeModel.getParent(); - } - } - int i = pathToNode.size() - 1; - nodeModel = pathToNode.get(i); - found = DefaultNodeModel.computeLocalTransform(nodeModel, null); - while (--i >= 0) { - nodeModel = pathToNode.get(i); - float[] transform = DefaultNodeModel.computeLocalTransform(nodeModel, null); - MathUtils.mul4x4(found, transform, transform); - NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.put(nodeModel, transform); - found = transform; - } - return found; - } - } - - /** - * Put the given values into a direct FloatBuffer and return it. - * The returned buffer may always be a slice of the same instance. - * This method is supposed to be called only from the OpenGL thread. - * - * @param value The value - * @return The FloatBuffer - */ - protected static FloatBuffer putFloatBuffer(float value[]) { - int total = value.length; - if (uniformFloatBuffer == null || uniformFloatBuffer.capacity() < total) { - uniformFloatBuffer = BufferUtils.createFloatBuffer(total); - } - uniformFloatBuffer.position(0); - uniformFloatBuffer.limit(uniformFloatBuffer.capacity()); - uniformFloatBuffer.put(value); - uniformFloatBuffer.flip(); - return uniformFloatBuffer; - } - - public static void setCurrentPose(Matrix4f currentPose) { - CURRENT_POSE = currentPose; - } - - public static void setCurrentNormal(Matrix3f currentNormal) { - CURRENT_NORMAL = currentNormal; - } - - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for (SceneModel sceneModel : sceneModels) { - RenderedGltfScene renderedGltfScene = new RenderedGltfScene(); - renderedGltfScenes.add(renderedGltfScene); - - for (NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if (commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List skinningCommands, List vanillaRenderCommands, List shaderModRenderCommands) { - ArrayList nodeSkinningCommands = new ArrayList(); - ArrayList vanillaNodeRenderCommands = new ArrayList(); - ArrayList shaderModNodeRenderCommands = new ArrayList(); - SkinModel skinModel = nodeModel.getSkinModel(); - if (skinModel != null) { - boolean canHaveHardwareSkinning; - checkHardwareSkinning: - { - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - if (!meshPrimitiveModel.getAttributes().containsKey("JOINTS_1")) { - canHaveHardwareSkinning = true; - break checkHardwareSkinning; - } - } - } - canHaveHardwareSkinning = false; - } - - int jointCount = skinModel.getJoints().size(); - - float[][] transforms = new float[jointCount][]; - float[] invertNodeTransform = new float[16]; - float[] bindShapeMatrix = new float[16]; - - if (canHaveHardwareSkinning) { - int jointMatrixSize = jointCount * 16; - float[] jointMatrices = new float[jointMatrixSize]; - - int jointMatrixBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(jointMatrixBuffer)); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixBuffer); - GL15.glBufferData(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixSize * Float.BYTES, GL15.GL_STATIC_DRAW); - - List jointMatricesTransformCommands = new ArrayList(jointCount); - for (int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - System.arraycopy(transform, 0, jointMatrices, i * 16, 16); - }); - } - - nodeSkinningCommands.add(() -> { - for (int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixBuffer); - GL15.glBufferSubData(GL43.GL_SHADER_STORAGE_BUFFER, 0, putFloatBuffer(jointMatrices)); - - GL30.glBindBufferBase(GL43.GL_SHADER_STORAGE_BUFFER, 0, jointMatrixBuffer); - }); - - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } else { - List jointMatricesTransformCommands = new ArrayList(jointCount); - for (int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - }); - } - - Runnable jointMatricesTransformCommand = () -> { - for (int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - }; - vanillaNodeRenderCommands.add(jointMatricesTransformCommand); - shaderModNodeRenderCommands.add(jointMatricesTransformCommand); - - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } else { - if (!nodeModel.getMeshModels().isEmpty()) { - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } - nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); - if (!nodeSkinningCommands.isEmpty()) { - // Zero-scale meshes visibility optimization - // https://github.com/KhronosGroup/glTF/pull/2059 - skinningCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - nodeSkinningCommands.forEach(Runnable::run); - } - }); - } - if (!vanillaNodeRenderCommands.isEmpty()) { - vanillaRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformVanilla(nodeModel); - - vanillaNodeRenderCommands.forEach(Runnable::run); - } - }); - shaderModRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformShaderMod(nodeModel); - - shaderModNodeRenderCommands.forEach(Runnable::run); - } - }); - } - } - - protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List vanillaRenderCommands, List shaderModRenderCommands) { - Map attributes = meshPrimitiveModel.getAttributes(); - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - if (positionsAccessorModel != null) { - List renderCommand = new ArrayList(); - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - if (normalsAccessorModel != null) { - AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); - if (tangentsAccessorModel != null) { - processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if (materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - } else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - } - } else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if (materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if (renderedMaterial.normalTexture != null) { - processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); - } else { - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel); - } - } else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel); - } - } - } else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if (materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if (renderedMaterial.normalTexture != null) { - processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); - } else { - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); - } - } else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); - } - } - vanillaRenderCommands.addAll(renderCommand); - shaderModRenderCommands.addAll(renderCommand); - } - } - - protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if (indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - try { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - } finally { - GL20.glDisableVertexAttribArray(at_tangent); - } - }); - } else { - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - try { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - } finally { - GL20.glDisableVertexAttribArray(at_tangent); - } - }); - } - } - - protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - } else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - } - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if (indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - try { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - } finally { - GL20.glDisableVertexAttribArray(at_tangent); - } - }); - } else { - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - try { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - } finally { - GL20.glDisableVertexAttribArray(at_tangent); - } - }); - } - } - - protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - try { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - } finally { - GL20.glDisableVertexAttribArray(at_tangent); - } - }); - } - - protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - } - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - try { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - } finally { - GL20.glDisableVertexAttribArray(at_tangent); - } - }); - } - - protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - int count = positionsAccessorModel.getCount(); - renderCommand.add(() -> { - try { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, count); - } finally { - GL20.glDisableVertexAttribArray(at_tangent); - } - }); - } - - protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, float[][] jointMatrices, List skinningCommand, List vanillaRenderCommands, List shaderModRenderCommands) { - Map attributes = meshPrimitiveModel.getAttributes(); - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - if (positionsAccessorModel != null) { - List renderCommand = new ArrayList(); - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - if (normalsAccessorModel != null) { - AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); - if (tangentsAccessorModel != null) { - if (attributes.containsKey("JOINTS_1")) - processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); - else - processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if (materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - } else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - } - } else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if (materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if (renderedMaterial.normalTexture != null) { - if (attributes.containsKey("JOINTS_1")) - processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - else - processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); - } else { - if (attributes.containsKey("JOINTS_1")) - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); - else - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel); - } - } else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - if (attributes.containsKey("JOINTS_1")) - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); - else - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel); - } - } - } else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if (materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if (renderedMaterial.normalTexture != null) { - if (attributes.containsKey("JOINTS_1")) - processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - else - processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); - } else { - if (attributes.containsKey("JOINTS_1")) - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - else - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); - } - } else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - if (attributes.containsKey("JOINTS_1")) - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - else - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); - } - } - vanillaRenderCommands.addAll(renderCommand); - shaderModRenderCommands.addAll(renderCommand); - } - } - - protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if (indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - try { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - } finally { - GL20.glDisableVertexAttribArray(at_tangent); - } - }); - } else { - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - } - - protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if (indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } else { - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - } - - protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - - protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - - protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glTransformFeedback = GL40.glGenTransformFeedbacks(); - gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL40.glDrawTransformFeedback(mode, glTransformFeedback); - }); - } - - protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, float[][] jointMatrices, List vanillaRenderCommands, List shaderModRenderCommands) { - Map attributes = meshPrimitiveModel.getAttributes(); - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - if (positionsAccessorModel != null) { - List renderCommand = new ArrayList(); - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - if (normalsAccessorModel != null) { - AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); - if (tangentsAccessorModel != null) { - processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if (materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - } else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - } - } else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if (materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if (renderedMaterial.normalTexture != null) { - processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - } else { - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); - } - } else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); - } - } - } else { - MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); - if (materialModel != null) { - Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); - vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); - shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); - if (renderedMaterial.normalTexture != null) { - processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - } else { - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - } - } else { - vanillaRenderCommands.add(vanillaDefaultMaterialCommand); - shaderModRenderCommands.add(shaderModDefaultMaterialCommand); - processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); - } - } - vanillaRenderCommands.addAll(renderCommand); - shaderModRenderCommands.addAll(renderCommand); - } - } - - protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel outputPositionsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - } - - AccessorModel outputNormalsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } else { - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - } - - AccessorModel outputTangentsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if (indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } else { - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - } - - protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel outputPositionsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - } - - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - AccessorModel outputNormalsAccessorModel; - AccessorModel outputTangentsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if (indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } else { - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - } - - protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel outputPositionsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - } else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - } - - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - AccessorModel outputNormalsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } else { - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel outputTangentsAccessorModel; - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); - if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - AccessorModel outputPositionsAccessorModel; - AccessorModel outputNormalsAccessorModel; - AccessorModel outputTangentsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel outputPositionsAccessorModel; - AccessorModel outputNormalsAccessorModel; - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { - outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); - outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); - } else { - outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); - outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - AccessorModel outputTangentsAccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { - outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); - } - - int pointCount = positionsAccessorModel.getCount(); - List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, - AccessorDatas.createFloat(positionsAccessorModel), - AccessorDatas.createFloat(normalsAccessorModel), - AccessorDatas.createFloat(tangentsAccessorModel), - AccessorDatas.createFloat(outputPositionsAccessorModel), - AccessorDatas.createFloat(outputNormalsAccessorModel), - AccessorDatas.createFloat(outputTangentsAccessorModel)); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaPosition, - outputPositionsAccessorModel.getElementType().getNumComponents(), - outputPositionsAccessorModel.getComponentType(), - false, - outputPositionsAccessorModel.getByteStride(), - outputPositionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaPosition); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - vaNormal, - outputNormalsAccessorModel.getElementType().getNumComponents(), - outputNormalsAccessorModel.getComponentType(), - false, - outputNormalsAccessorModel.getByteStride(), - outputNormalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaNormal); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - GL20.glVertexAttribPointer( - at_tangent, - outputTangentsAccessorModel.getElementType().getNumComponents(), - outputTangentsAccessorModel.getComponentType(), - false, - outputTangentsAccessorModel.getByteStride(), - outputTangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); - ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - skinningCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); - - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - protected void applyTransformVanilla(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - Matrix3f normal = new Matrix3f(pose); - - pose.transpose(); - pose.mulLocal(CURRENT_POSE); - - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - CURRENT_SHADER_INSTANCE.MODEL_VIEW_MATRIX.set(pose); - CURRENT_SHADER_INSTANCE.MODEL_VIEW_MATRIX.upload(); - - CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.set((new Vector3f(LIGHT0_DIRECTION)).mulTranspose(normal)); - CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.set((new Vector3f(LIGHT1_DIRECTION)).mulTranspose(normal)); - CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.upload(); - CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.upload(); - } - - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - Matrix3f normal = new Matrix3f(pose); - - pose.transpose(); - pose.mulLocal(CURRENT_POSE); - - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - - pose.invert(); - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX_INVERSE, false, BUF_FLOAT_16); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } - - public void bindArrayBufferViewModel(List gltfRenderData, BufferViewModel bufferViewModel) { - Integer glBufferView = bufferViewModelToGlBufferView.get(bufferViewModel); - if (glBufferView == null) { - Integer glBufferViewNew = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferViewNew)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferViewNew); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, bufferViewModel.getBufferViewData(), GL15.GL_STATIC_DRAW); - bufferViewModelToGlBufferView.put(bufferViewModel, glBufferViewNew); - } else GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - } - - public int obtainElementArrayBuffer(List gltfRenderData, BufferViewModel bufferViewModel) { - Integer glBufferView = bufferViewModelToGlBufferView.get(bufferViewModel); - if (glBufferView == null) { - Integer glBufferViewNew = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferViewNew)); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glBufferViewNew); - GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, bufferViewModel.getBufferViewData(), GL15.GL_STATIC_DRAW); - bufferViewModelToGlBufferView.put(bufferViewModel, glBufferViewNew); - return glBufferViewNew; - } else { - return glBufferView; - } - } - - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if (material == null) { - Object extras = materialModel.getExtras(); - if (extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), Material.class); - } else material = new Material(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } - - public int obtainGlTexture(List gltfRenderData, TextureModel textureModel) { - Integer glTexture = textureModelToGlTexture.get(textureModel); - if (glTexture == null) { - PixelData pixelData = PixelDatas.create(textureModel.getImageModel().getImageData()); - if (pixelData == null) { - MCglTF.logger.warn("Could not extract pixel data from image"); - pixelData = PixelDatas.createErrorPixelData(); - } - - Integer glTextureNew = GL11.glGenTextures(); - gltfRenderData.add(() -> GL11.glDeleteTextures(glTextureNew)); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, glTextureNew); - GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, pixelData.getWidth(), pixelData.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixelData.getPixelsRGBA()); - - int minFilter = Optionals.of( - textureModel.getMinFilter(), - GL11.GL_NEAREST_MIPMAP_LINEAR); - int magFilter = Optionals.of( - textureModel.getMagFilter(), - GL11.GL_LINEAR); - int wrapS = Optionals.of( - textureModel.getWrapS(), - GL11.GL_REPEAT); - int wrapT = Optionals.of( - textureModel.getWrapT(), - GL11.GL_REPEAT); - - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, minFilter); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, magFilter); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrapS); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrapT); - - textureModelToGlTexture.put(textureModel, glTextureNew); - - return glTextureNew; - } else { - return glTexture; - } - } - - public AccessorModel obtainNormalsAccessorModel(AccessorModel positionsAccessorModel) { - AccessorModel normalsAccessorModel = positionsAccessorModelToNormalsAccessorModel.get(positionsAccessorModel); - if (normalsAccessorModel == null) { - int count = positionsAccessorModel.getCount(); - int numTriangles = count / 3; - normalsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, ""); - positionsAccessorModelToNormalsAccessorModel.put(positionsAccessorModel, normalsAccessorModel); - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - float vertex0[] = new float[3]; - float vertex1[] = new float[3]; - float vertex2[] = new float[3]; - float edge01[] = new float[3]; - float edge02[] = new float[3]; - float cross[] = new float[3]; - float normal[] = new float[3]; - for (int i = 0; i < numTriangles; i++) { - int index0 = i * 3; - int index1 = index0 + 1; - int index2 = index0 + 2; - - vertex0[0] = positionsAccessorData.get(index0, 0); - vertex0[1] = positionsAccessorData.get(index0, 1); - vertex0[2] = positionsAccessorData.get(index0, 2); - - vertex1[0] = positionsAccessorData.get(index1, 0); - vertex1[1] = positionsAccessorData.get(index1, 1); - vertex1[2] = positionsAccessorData.get(index1, 2); - - vertex2[0] = positionsAccessorData.get(index2, 0); - vertex2[1] = positionsAccessorData.get(index2, 1); - vertex2[2] = positionsAccessorData.get(index2, 2); - - MathUtils.subtract(vertex1, vertex0, edge01); - MathUtils.subtract(vertex2, vertex0, edge02); - MathUtils.cross(edge01, edge02, cross); - MathUtils.normalize(cross, normal); - - normalsAccessorData.set(index0, 0, normal[0]); - normalsAccessorData.set(index0, 1, normal[1]); - normalsAccessorData.set(index0, 2, normal[2]); - - normalsAccessorData.set(index1, 0, normal[0]); - normalsAccessorData.set(index1, 1, normal[1]); - normalsAccessorData.set(index1, 2, normal[2]); - - normalsAccessorData.set(index2, 0, normal[0]); - normalsAccessorData.set(index2, 1, normal[1]); - normalsAccessorData.set(index2, 2, normal[2]); - } - } - return normalsAccessorModel; - } - - /** - * Found this simple normals to tangent algorithm here:
    - * How to find a randomic Vector orthogonal to a given Vector - */ - public AccessorModel obtainTangentsAccessorModel(AccessorModel normalsAccessorModel) { - AccessorModel tangentsAccessorModel = normalsAccessorModelToTangentsAccessorModel.get(normalsAccessorModel); - if (tangentsAccessorModel == null) { - int count = normalsAccessorModel.getCount(); - tangentsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); - normalsAccessorModelToTangentsAccessorModel.put(normalsAccessorModel, tangentsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - float[] normal0 = new float[3]; - float[] normal1 = new float[3]; - float[] cross = new float[3]; - float[] tangent = new float[3]; - - for (int i = 0; i < count; i++) { - normal0[0] = normalsAccessorData.get(i, 0); - normal0[1] = normalsAccessorData.get(i, 1); - normal0[2] = normalsAccessorData.get(i, 2); - - normal1[0] = -normal0[2]; - normal1[1] = normal0[0]; - normal1[2] = normal0[1]; - - MathUtils.cross(normal0, normal1, cross); - MathUtils.normalize(cross, tangent); - - tangentsAccessorData.set(i, 0, tangent[0]); - tangentsAccessorData.set(i, 1, tangent[1]); - tangentsAccessorData.set(i, 2, tangent[2]); - tangentsAccessorData.set(i, 3, 1.0F); - } - } - return tangentsAccessorModel; - } - - public AccessorModel obtainTangentsAccessorModel(MeshPrimitiveModel meshPrimitiveModel, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel) { - AccessorModel tangentsAccessorModel = meshPrimitiveModelToTangentsAccessorModel.get(meshPrimitiveModel); - if (tangentsAccessorModel == null) { - int count = positionsAccessorModel.getCount(); - int numFaces = count / 3; - tangentsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); - meshPrimitiveModelToTangentsAccessorModel.put(meshPrimitiveModel, tangentsAccessorModel); - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0]); - tangentsAccessorData.set(index, 1, tangent[1]); - tangentsAccessorData.set(index, 2, tangent[2]); - tangentsAccessorData.set(index, 3, -sign); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - return tangentsAccessorModel; - } - - public AccessorModel obtainVec4ColorsAccessorModel(AccessorModel colorsAccessorModel) { - if (colorsAccessorModel.getElementType() == ElementType.VEC3) { - AccessorModel colorsVec4AccessorModel = colorsAccessorModelVec3ToVec4.get(colorsAccessorModel); - if (colorsVec4AccessorModel == null) { - int count = colorsAccessorModel.getCount(); - colorsVec4AccessorModel = AccessorModelCreation.createAccessorModel(colorsAccessorModel.getComponentType(), count, ElementType.VEC4, ""); - colorsAccessorModelVec3ToVec4.put(colorsAccessorModel, colorsVec4AccessorModel); - AccessorData accessorData = AccessorDatas.create(colorsVec4AccessorModel); - if (accessorData instanceof AccessorByteData) { - AccessorByteData colorsVec4AccessorData = (AccessorByteData) accessorData; - AccessorByteData colorsAccessorData = AccessorDatas.createByte(colorsAccessorModel); - if (colorsAccessorData.isUnsigned()) { - for (int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, (byte) -1); - } - } else { - for (int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, Byte.MAX_VALUE); - } - } - } else if (accessorData instanceof AccessorShortData) { - AccessorShortData colorsVec4AccessorData = (AccessorShortData) accessorData; - AccessorShortData colorsAccessorData = AccessorDatas.createShort(colorsAccessorModel); - if (colorsAccessorData.isUnsigned()) { - for (int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, (short) -1); - } - } else { - for (int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, Short.MAX_VALUE); - } - } - } else if (accessorData instanceof AccessorFloatData) { - AccessorFloatData colorsVec4AccessorData = (AccessorFloatData) accessorData; - AccessorFloatData colorsAccessorData = AccessorDatas.createFloat(colorsAccessorModel); - for (int i = 0; i < count; i++) { - colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); - colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); - colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); - colorsVec4AccessorData.set(i, 3, 1.0F); - } - } - } - return colorsVec4AccessorModel; - } - return colorsAccessorModel; - } - - public AccessorModel obtainUnsignedJointsModel(AccessorModel accessorModel) { - AccessorModel unsignedAccessorModel = jointsAccessorModelUnsignedLookup.get(accessorModel); - if (unsignedAccessorModel == null) { - int count = accessorModel.getCount(); - unsignedAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_INT, count, ElementType.VEC4, ""); - AccessorIntData unsignedAccessorData = AccessorDatas.createInt(unsignedAccessorModel); - if (accessorModel.getComponentDataType() == short.class) { - AccessorShortData accessorData = AccessorDatas.createShort(accessorModel); - for (int i = 0; i < count; i++) { - unsignedAccessorData.set(i, 0, Short.toUnsignedInt(accessorData.get(i, 0))); - unsignedAccessorData.set(i, 1, Short.toUnsignedInt(accessorData.get(i, 1))); - unsignedAccessorData.set(i, 2, Short.toUnsignedInt(accessorData.get(i, 2))); - unsignedAccessorData.set(i, 3, Short.toUnsignedInt(accessorData.get(i, 3))); - } - } else { - AccessorByteData accessorData = AccessorDatas.createByte(accessorModel); - for (int i = 0; i < count; i++) { - unsignedAccessorData.set(i, 0, Byte.toUnsignedInt(accessorData.get(i, 0))); - unsignedAccessorData.set(i, 1, Byte.toUnsignedInt(accessorData.get(i, 1))); - unsignedAccessorData.set(i, 2, Byte.toUnsignedInt(accessorData.get(i, 2))); - unsignedAccessorData.set(i, 3, Byte.toUnsignedInt(accessorData.get(i, 3))); - } - } - jointsAccessorModelUnsignedLookup.put(accessorModel, unsignedAccessorModel); - } - return unsignedAccessorModel; - } - - public AccessorModel obtainDequantizedWeightsModel(AccessorModel accessorModel) { - AccessorModel dequantizedAccessorModel = weightsAccessorModelDequantizedLookup.get(accessorModel); - if (dequantizedAccessorModel == null) { - if (accessorModel.getComponentDataType() != float.class) { - AccessorData accessorData = AccessorDatas.create(accessorModel); - int count = accessorModel.getCount(); - dequantizedAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); - AccessorFloatData dequantizedAccessorData = AccessorDatas.createFloat(dequantizedAccessorModel); - for (int i = 0; i < count; i++) { - dequantizedAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - dequantizedAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - dequantizedAccessorData.set(i, 2, accessorData.getFloat(i, 2)); - dequantizedAccessorData.set(i, 3, accessorData.getFloat(i, 3)); - } - weightsAccessorModelDequantizedLookup.put(accessorModel, dequantizedAccessorModel); - } else { - return accessorModel; - } - } - return dequantizedAccessorModel; - } - - public AccessorModel obtainVec3FloatMorphedModel(NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - AccessorFloatData baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - AccessorFloatData morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - - float weights[] = new float[targetAccessorDatas.size()]; - int numComponents = 3; - int numElements = morphedAccessorData.getNumElements(); - - List morphingCommands = new ArrayList(numElements * numComponents); - for (int element = 0; element < numElements; element++) { - for (int component = 0; component < numComponents; component++) { - int e = element; - int c = component; - morphingCommands.add(() -> { - float r = baseAccessorData.get(e, c); - for (int i = 0; i < weights.length; i++) { - AccessorFloatData target = targetAccessorDatas.get(i); - if (target != null) { - r += weights[i] * target.get(e, c); - } - } - morphedAccessorData.set(e, c, r); - }); - } - } - - command.add(() -> { - if (nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); - else if (meshModel.getWeights() != null) - System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); - - morphingCommands.parallelStream().forEach(Runnable::run); - }); - return morphedAccessorModel; - } - - public Pair, List>> obtainUnindexed(MeshPrimitiveModel meshPrimitiveModel) { - Pair, List>> unindexed; - AccessorModel indicesAccessorModel = meshPrimitiveModel.getIndices(); - if (indicesAccessorModel != null) { - unindexed = meshPrimitiveModelToUnindexed.get(meshPrimitiveModel); - if (unindexed == null) { - int indices[] = AccessorDataUtils.readInts(AccessorDatas.create(indicesAccessorModel)); - Map attributes = meshPrimitiveModel.getAttributes(); - Map attributesUnindexed = new LinkedHashMap(attributes.size()); - attributes.forEach((name, attribute) -> { - ElementType elementType = attribute.getElementType(); - int size = elementType.getNumComponents(); - AccessorModel accessorModel = AccessorModelCreation.createAccessorModel(attribute.getComponentType(), indices.length, elementType, ""); - attributesUnindexed.put(name, accessorModel); - AccessorData accessorData = AccessorDatas.create(accessorModel); - if (accessorData instanceof AccessorByteData) { - AccessorByteData accessorDataUnindexed = (AccessorByteData) accessorData; - AccessorByteData accessorDataIndexed = AccessorDatas.createByte(attribute); - for (int i = 0; i < indices.length; i++) { - int index = indices[i]; - for (int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } else if (accessorData instanceof AccessorShortData) { - AccessorShortData accessorDataUnindexed = (AccessorShortData) accessorData; - AccessorShortData accessorDataIndexed = AccessorDatas.createShort(attribute); - for (int i = 0; i < indices.length; i++) { - int index = indices[i]; - for (int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } else if (accessorData instanceof AccessorIntData) { - AccessorIntData accessorDataUnindexed = (AccessorIntData) accessorData; - AccessorIntData accessorDataIndexed = AccessorDatas.createInt(attribute); - for (int i = 0; i < indices.length; i++) { - int index = indices[i]; - for (int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } else if (accessorData instanceof AccessorFloatData) { - AccessorFloatData accessorDataUnindexed = (AccessorFloatData) accessorData; - AccessorFloatData accessorDataIndexed = AccessorDatas.createFloat(attribute); - for (int i = 0; i < indices.length; i++) { - int index = indices[i]; - for (int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - }); - - List> targets = meshPrimitiveModel.getTargets(); - List> targetsUnindexed = new ArrayList>(targets.size()); - targets.forEach((target) -> { - Map targetUnindexed = new LinkedHashMap(target.size()); - targetsUnindexed.add(targetUnindexed); - target.forEach((name, attribute) -> { - ElementType elementType = attribute.getElementType(); - int size = elementType.getNumComponents(); - AccessorModel accessorModel = AccessorModelCreation.createAccessorModel(attribute.getComponentType(), indices.length, elementType, ""); - targetUnindexed.put(name, accessorModel); - AccessorData accessorData = AccessorDatas.create(accessorModel); - if (accessorData instanceof AccessorByteData) { - AccessorByteData accessorDataUnindexed = (AccessorByteData) accessorData; - AccessorByteData accessorDataIndexed = AccessorDatas.createByte(attribute); - for (int i = 0; i < indices.length; i++) { - int index = indices[i]; - for (int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } else if (accessorData instanceof AccessorShortData) { - AccessorShortData accessorDataUnindexed = (AccessorShortData) accessorData; - AccessorShortData accessorDataIndexed = AccessorDatas.createShort(attribute); - for (int i = 0; i < indices.length; i++) { - int index = indices[i]; - for (int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } else if (accessorData instanceof AccessorIntData) { - AccessorIntData accessorDataUnindexed = (AccessorIntData) accessorData; - AccessorIntData accessorDataIndexed = AccessorDatas.createInt(attribute); - for (int i = 0; i < indices.length; i++) { - int index = indices[i]; - for (int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } else if (accessorData instanceof AccessorFloatData) { - AccessorFloatData accessorDataUnindexed = (AccessorFloatData) accessorData; - AccessorFloatData accessorDataIndexed = AccessorDatas.createFloat(attribute); - for (int i = 0; i < indices.length; i++) { - int index = indices[i]; - for (int j = 0; j < size; j++) { - accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); - } - } - } - }); - }); - unindexed = Pair.of(attributesUnindexed, targetsUnindexed); - meshPrimitiveModelToUnindexed.put(meshPrimitiveModel, unindexed); - } - } else unindexed = Pair.of(meshPrimitiveModel.getAttributes(), meshPrimitiveModel.getTargets()); - return unindexed; - } - - public List createSoftwareSkinningCommands(int pointCount, float[][] jointMatrices, Map attributes, AccessorFloatData inputPositionsAccessorData, AccessorFloatData inputNormalsAccessorData, AccessorFloatData inputTangentsAccessorData, AccessorFloatData outputPositionsAccessorData, AccessorFloatData outputNormalsAccessorData, AccessorFloatData outputTangentsAccessorData) { - int skinningAttributeCount = 0; - for (String name : attributes.keySet()) { - if (name.startsWith("JOINTS_")) { - skinningAttributeCount += 1; - } - } - AccessorIntData[] jointsAccessorDatas = new AccessorIntData[skinningAttributeCount]; - AccessorFloatData[] weightsAccessorDatas = new AccessorFloatData[skinningAttributeCount]; - attributes.forEach((name, attribute) -> { - if (name.startsWith("JOINTS_")) - jointsAccessorDatas[Integer.parseInt(name.substring("JOINTS_".length()))] = AccessorDatas.createInt(obtainUnsignedJointsModel(attribute)); - else if (name.startsWith("WEIGHTS_")) - weightsAccessorDatas[Integer.parseInt(name.substring("WEIGHTS_".length()))] = AccessorDatas.createFloat(obtainDequantizedWeightsModel(attribute)); - }); - - List commands = new ArrayList(pointCount); - for (int point = 0; point < pointCount; point++) { - int p = point; - commands.add(() -> { - float sm00 = 0; - float sm01 = 0; - float sm02 = 0; - float sm03 = 0; - float sm10 = 0; - float sm11 = 0; - float sm12 = 0; - float sm13 = 0; - float sm20 = 0; - float sm21 = 0; - float sm22 = 0; - float sm23 = 0; - - for (int i = 0; i < jointsAccessorDatas.length; i++) { - AccessorIntData jointsAccessorData = jointsAccessorDatas[i]; - float[] jmx = jointMatrices[jointsAccessorData.get(p, 0)]; - float[] jmy = jointMatrices[jointsAccessorData.get(p, 1)]; - float[] jmz = jointMatrices[jointsAccessorData.get(p, 2)]; - float[] jmw = jointMatrices[jointsAccessorData.get(p, 3)]; - - AccessorFloatData weightsAccessorData = weightsAccessorDatas[i]; - float wx = weightsAccessorData.get(p, 0); - float wy = weightsAccessorData.get(p, 1); - float wz = weightsAccessorData.get(p, 2); - float ww = weightsAccessorData.get(p, 3); - - sm00 += wx * jmx[0] + wy * jmy[0] + wz * jmz[0] + ww * jmw[0]; - sm01 += wx * jmx[4] + wy * jmy[4] + wz * jmz[4] + ww * jmw[4]; - sm02 += wx * jmx[8] + wy * jmy[8] + wz * jmz[8] + ww * jmw[8]; - sm03 += wx * jmx[12] + wy * jmy[12] + wz * jmz[12] + ww * jmw[12]; - sm10 += wx * jmx[1] + wy * jmy[1] + wz * jmz[1] + ww * jmw[1]; - sm11 += wx * jmx[5] + wy * jmy[5] + wz * jmz[5] + ww * jmw[5]; - sm12 += wx * jmx[9] + wy * jmy[9] + wz * jmz[9] + ww * jmw[9]; - sm13 += wx * jmx[13] + wy * jmy[13] + wz * jmz[13] + ww * jmw[13]; - sm20 += wx * jmx[2] + wy * jmy[2] + wz * jmz[2] + ww * jmw[2]; - sm21 += wx * jmx[6] + wy * jmy[6] + wz * jmz[6] + ww * jmw[6]; - sm22 += wx * jmx[10] + wy * jmy[10] + wz * jmz[10] + ww * jmw[10]; - sm23 += wx * jmx[14] + wy * jmy[14] + wz * jmz[14] + ww * jmw[14]; - } - - float px = inputPositionsAccessorData.get(p, 0); - float py = inputPositionsAccessorData.get(p, 1); - float pz = inputPositionsAccessorData.get(p, 2); - - outputPositionsAccessorData.set(p, 0, sm00 * px + sm01 * py + sm02 * pz + sm03); - outputPositionsAccessorData.set(p, 1, sm10 * px + sm11 * py + sm12 * pz + sm13); - outputPositionsAccessorData.set(p, 2, sm20 * px + sm21 * py + sm22 * pz + sm23); - - float nx = inputNormalsAccessorData.get(p, 0); - float ny = inputNormalsAccessorData.get(p, 1); - float nz = inputNormalsAccessorData.get(p, 2); - - outputNormalsAccessorData.set(p, 0, sm00 * nx + sm01 * ny + sm02 * nz); - outputNormalsAccessorData.set(p, 1, sm10 * nx + sm11 * ny + sm12 * nz); - outputNormalsAccessorData.set(p, 2, sm20 * nx + sm21 * ny + sm22 * nz); - - float tx = inputTangentsAccessorData.get(p, 0); - float ty = inputTangentsAccessorData.get(p, 1); - float tz = inputTangentsAccessorData.get(p, 2); - - outputTangentsAccessorData.set(p, 0, sm00 * tx + sm01 * ty + sm02 * tz); - outputTangentsAccessorData.set(p, 1, sm10 * tx + sm11 * ty + sm12 * tz); - outputTangentsAccessorData.set(p, 2, sm20 * tx + sm21 * ty + sm22 * tz); - }); - } - return commands; - } - - public boolean createMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { - boolean isMorphableAttribute = false; - for (Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get(attributeName); - if (accessorModel != null) { - isMorphableAttribute = true; - targetAccessorDatas.add(AccessorDatas.createFloat(accessorModel)); - } else targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public boolean createPositionNormalMorphTarget(List> morphTargets, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, List positionTargetAccessorDatas, List normalTargetAccessorDatas) { - boolean isMorphableAttribute = false; - int count = positionsAccessorModel.getCount(); - int numTriangles = count / 3; - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - for (Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get("POSITION"); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); - positionTargetAccessorDatas.add(deltaPositionsAccessorData); - AccessorFloatData normalTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - normalTargetAccessorDatas.add(normalTargetAccessorData); - float[] vertex0 = new float[3]; - float[] vertex1 = new float[3]; - float[] vertex2 = new float[3]; - float[] edge01 = new float[3]; - float[] edge02 = new float[3]; - float[] cross = new float[3]; - float[] normal0 = new float[3]; - float[] normal1 = new float[3]; - for (int i = 0; i < numTriangles; i++) { - int index0 = i * 3; - int index1 = index0 + 1; - int index2 = index0 + 2; - - vertex0[0] = positionsAccessorData.get(index0, 0) + deltaPositionsAccessorData.get(index0, 0); - vertex0[1] = positionsAccessorData.get(index0, 1) + deltaPositionsAccessorData.get(index0, 1); - vertex0[2] = positionsAccessorData.get(index0, 2) + deltaPositionsAccessorData.get(index0, 2); - - vertex1[0] = positionsAccessorData.get(index1, 0) + deltaPositionsAccessorData.get(index1, 0); - vertex1[1] = positionsAccessorData.get(index1, 1) + deltaPositionsAccessorData.get(index1, 1); - vertex1[2] = positionsAccessorData.get(index1, 2) + deltaPositionsAccessorData.get(index1, 2); - - vertex2[0] = positionsAccessorData.get(index2, 0) + deltaPositionsAccessorData.get(index2, 0); - vertex2[1] = positionsAccessorData.get(index2, 1) + deltaPositionsAccessorData.get(index2, 1); - vertex2[2] = positionsAccessorData.get(index2, 2) + deltaPositionsAccessorData.get(index2, 2); - - normal0[0] = normalsAccessorData.get(index0, 0); - normal0[1] = normalsAccessorData.get(index0, 1); - normal0[2] = normalsAccessorData.get(index0, 2); - - MathUtils.subtract(vertex1, vertex0, edge01); - MathUtils.subtract(vertex2, vertex0, edge02); - MathUtils.cross(edge01, edge02, cross); - MathUtils.normalize(cross, normal1); - - MathUtils.subtract(normal1, normal0, normal1); - - normalTargetAccessorData.set(index0, 0, normal1[0]); - normalTargetAccessorData.set(index0, 1, normal1[1]); - normalTargetAccessorData.set(index0, 2, normal1[2]); - - normalTargetAccessorData.set(index1, 0, normal1[0]); - normalTargetAccessorData.set(index1, 1, normal1[1]); - normalTargetAccessorData.set(index1, 2, normal1[2]); - - normalTargetAccessorData.set(index2, 0, normal1[0]); - normalTargetAccessorData.set(index2, 1, normal1[1]); - normalTargetAccessorData.set(index2, 2, normal1[2]); - } - } else { - positionTargetAccessorDatas.add(null); - normalTargetAccessorDatas.add(null); - } - } - return isMorphableAttribute; - } - - public boolean createPositionNormalTangentMorphTarget(List> morphTargets, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel, List positionTargetAccessorDatas, List normalTargetAccessorDatas, List tangentTargetAccessorDatas) { - boolean isMorphableAttribute = false; - int count = positionsAccessorModel.getCount(); - int numTriangles = count / 3; - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - for (Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get("POSITION"); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); - positionTargetAccessorDatas.add(deltaPositionsAccessorData); - AccessorFloatData normalTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - normalTargetAccessorDatas.add(normalTargetAccessorData); - AccessorFloatData tangentTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - tangentTargetAccessorDatas.add(tangentTargetAccessorData); - float[] vertex0 = new float[3]; - float[] vertex1 = new float[3]; - float[] vertex2 = new float[3]; - float[] edge01 = new float[3]; - float[] edge02 = new float[3]; - float[] cross = new float[3]; - float[] normal0 = new float[3]; - float[] normal1 = new float[3]; - float[] normal2 = new float[3]; - float[] tangent0 = new float[3]; - float[] tangent1 = new float[3]; - for (int i = 0; i < numTriangles; i++) { - int index0 = i * 3; - int index1 = index0 + 1; - int index2 = index0 + 2; - - vertex0[0] = positionsAccessorData.get(index0, 0) + deltaPositionsAccessorData.get(index0, 0); - vertex0[1] = positionsAccessorData.get(index0, 1) + deltaPositionsAccessorData.get(index0, 1); - vertex0[2] = positionsAccessorData.get(index0, 2) + deltaPositionsAccessorData.get(index0, 2); - - vertex1[0] = positionsAccessorData.get(index1, 0) + deltaPositionsAccessorData.get(index1, 0); - vertex1[1] = positionsAccessorData.get(index1, 1) + deltaPositionsAccessorData.get(index1, 1); - vertex1[2] = positionsAccessorData.get(index1, 2) + deltaPositionsAccessorData.get(index1, 2); - - vertex2[0] = positionsAccessorData.get(index2, 0) + deltaPositionsAccessorData.get(index2, 0); - vertex2[1] = positionsAccessorData.get(index2, 1) + deltaPositionsAccessorData.get(index2, 1); - vertex2[2] = positionsAccessorData.get(index2, 2) + deltaPositionsAccessorData.get(index2, 2); - - normal0[0] = normalsAccessorData.get(index0, 0); - normal0[1] = normalsAccessorData.get(index0, 1); - normal0[2] = normalsAccessorData.get(index0, 2); - - tangent0[0] = tangentsAccessorData.get(index0, 0); - tangent0[1] = tangentsAccessorData.get(index0, 1); - tangent0[2] = tangentsAccessorData.get(index0, 2); - - MathUtils.subtract(vertex1, vertex0, edge01); - MathUtils.subtract(vertex2, vertex0, edge02); - MathUtils.cross(edge01, edge02, cross); - MathUtils.normalize(cross, normal1); - - normal2[0] = -normal1[2]; - normal2[1] = normal1[0]; - normal2[2] = normal1[1]; - - MathUtils.cross(normal1, normal2, cross); - MathUtils.normalize(cross, tangent1); - - MathUtils.subtract(normal1, normal0, normal1); - MathUtils.subtract(tangent1, tangent0, tangent1); - - normalTargetAccessorData.set(index0, 0, normal1[0]); - normalTargetAccessorData.set(index0, 1, normal1[1]); - normalTargetAccessorData.set(index0, 2, normal1[2]); - - tangentTargetAccessorData.set(index0, 0, tangent1[0]); - tangentTargetAccessorData.set(index0, 1, tangent1[1]); - tangentTargetAccessorData.set(index0, 2, tangent1[2]); - - normalTargetAccessorData.set(index1, 0, normal1[0]); - normalTargetAccessorData.set(index1, 1, normal1[1]); - normalTargetAccessorData.set(index1, 2, normal1[2]); - - tangentTargetAccessorData.set(index1, 0, tangent1[0]); - tangentTargetAccessorData.set(index1, 1, tangent1[1]); - tangentTargetAccessorData.set(index1, 2, tangent1[2]); - - normalTargetAccessorData.set(index2, 0, normal1[0]); - normalTargetAccessorData.set(index2, 1, normal1[1]); - normalTargetAccessorData.set(index2, 2, normal1[2]); - - tangentTargetAccessorData.set(index2, 0, tangent1[0]); - tangentTargetAccessorData.set(index2, 1, tangent1[1]); - tangentTargetAccessorData.set(index2, 2, tangent1[2]); - } - } else { - positionTargetAccessorDatas.add(null); - normalTargetAccessorDatas.add(null); - tangentTargetAccessorDatas.add(null); - } - } - return isMorphableAttribute; - } - - public boolean createNormalTangentMorphTarget(List> morphTargets, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel, List normalTargetAccessorDatas, List tangentTargetAccessorDatas) { - boolean isMorphableAttribute = false; - int count = normalsAccessorModel.getCount(); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - for (Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get("NORMAL"); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); - normalTargetAccessorDatas.add(deltaNormalsAccessorData); - AccessorFloatData tangentTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - tangentTargetAccessorDatas.add(tangentTargetAccessorData); - float[] normal0 = new float[3]; - float[] normal1 = new float[3]; - float[] cross = new float[3]; - float[] tangent = new float[3]; - - for (int i = 0; i < count; i++) { - normal0[0] = normalsAccessorData.get(i, 0) + deltaNormalsAccessorData.get(i, 0); - normal0[1] = normalsAccessorData.get(i, 1) + deltaNormalsAccessorData.get(i, 1); - normal0[2] = normalsAccessorData.get(i, 2) + deltaNormalsAccessorData.get(i, 2); - - normal1[0] = -normal0[2]; - normal1[1] = normal0[0]; - normal1[2] = normal0[1]; - - MathUtils.cross(normal0, normal1, cross); - MathUtils.normalize(cross, tangent); - - tangentTargetAccessorData.set(i, 0, tangent[0] - tangentsAccessorData.get(i, 0)); - tangentTargetAccessorData.set(i, 1, tangent[1] - tangentsAccessorData.get(i, 1)); - tangentTargetAccessorData.set(i, 2, tangent[2] - tangentsAccessorData.get(i, 2)); - } - } else { - normalTargetAccessorDatas.add(null); - tangentTargetAccessorDatas.add(null); - } - } - return isMorphableAttribute; - } - - public boolean createTangentMorphTarget(List> morphTargets, List targetAccessorDatas, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel, String texcoordsAccessorName, AccessorModel tangentsAccessorModel) { - boolean isMorphableAttribute = false; - int count = positionsAccessorModel.getCount(); - int numFaces = count / 3; - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); - for (Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get("POSITION"); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); - accessorModel = morphTarget.get("NORMAL"); - if (accessorModel != null) { - AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); - accessorModel = morphTarget.get(texcoordsAccessorName); - if (accessorModel != null) { - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } else { - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - } else { - accessorModel = morphTarget.get(texcoordsAccessorName); - if (accessorModel != null) { - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } else { - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - } - continue; - } - accessorModel = morphTarget.get("NORMAL"); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); - accessorModel = morphTarget.get(texcoordsAccessorName); - if (accessorModel != null) { - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } else { - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - continue; - } - accessorModel = morphTarget.get(texcoordsAccessorName); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - continue; - } - targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public boolean createTangentMorphTarget(List> morphTargets, List targetAccessorDatas, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel, String texcoordsAccessorName, AccessorModel tangentsAccessorModel, List normalTargetAccessorDatas) { - boolean isMorphableAttribute = false; - int count = positionsAccessorModel.getCount(); - int numFaces = count / 3; - AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); - AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); - AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); - AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); - Iterator iterator = normalTargetAccessorDatas.iterator(); - for (Map morphTarget : morphTargets) { - AccessorFloatData deltaNormalsAccessorData = iterator.next(); - AccessorModel accessorModel = morphTarget.get("POSITION"); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); - accessorModel = morphTarget.get(texcoordsAccessorName); - if (accessorModel != null) { - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } else { - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - } - continue; - } - accessorModel = morphTarget.get(texcoordsAccessorName); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); - targetAccessorDatas.add(targetAccessorData); - AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); - MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { - - @Override - public int getNumFaces() { - return numFaces; - } - - @Override - public int getNumVerticesOfFace(int face) { - return 3; - } - - @Override - public void getPosition(float[] posOut, int face, int vert) { - int index = (face * 3) + vert; - posOut[0] = positionsAccessorData.get(index, 0); - posOut[1] = positionsAccessorData.get(index, 1); - posOut[2] = positionsAccessorData.get(index, 2); - } - - @Override - public void getNormal(float[] normOut, int face, int vert) { - int index = (face * 3) + vert; - normOut[0] = normalsAccessorData.get(index, 0); - normOut[1] = normalsAccessorData.get(index, 1); - normOut[2] = normalsAccessorData.get(index, 2); - } - - @Override - public void getTexCoord(float[] texOut, int face, int vert) { - int index = (face * 3) + vert; - texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); - texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); - } - - @Override - public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { - int index = (face * 3) + vert; - tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); - tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); - tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); - } - - @Override - public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { - //Do nothing - } - - }); - continue; - } - targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public boolean createColorMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { - boolean isMorphableAttribute = false; - for (Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get(attributeName); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData morphAccessorData = colorsMorphTargetAccessorModelToAccessorData.get(accessorModel); - if (morphAccessorData == null) { - if (accessorModel.getElementType() == ElementType.VEC3) { - int count = accessorModel.getCount(); - morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, "")); - AccessorData accessorData = AccessorDatas.create(accessorModel); - for (int i = 0; i < count; i++) { - morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - morphAccessorData.set(i, 2, accessorData.getFloat(i, 2)); - morphAccessorData.set(i, 3, 0.0F); - } - } else if (accessorModel.getComponentDataType() != float.class) { - int count = accessorModel.getCount(); - morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, "")); - AccessorData accessorData = AccessorDatas.create(accessorModel); - for (int i = 0; i < count; i++) { - morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - morphAccessorData.set(i, 2, accessorData.getFloat(i, 2)); - morphAccessorData.set(i, 3, accessorData.getFloat(i, 3)); - } - } else { - morphAccessorData = AccessorDatas.createFloat(accessorModel); - } - colorsMorphTargetAccessorModelToAccessorData.put(accessorModel, morphAccessorData); - } - targetAccessorDatas.add(morphAccessorData); - } else targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public boolean createTexcoordMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { - boolean isMorphableAttribute = false; - for (Map morphTarget : morphTargets) { - AccessorModel accessorModel = morphTarget.get(attributeName); - if (accessorModel != null) { - isMorphableAttribute = true; - AccessorFloatData morphAccessorData = texcoordsMorphTargetAccessorModelToAccessorData.get(accessorModel); - if (morphAccessorData == null) { - if (accessorModel.getComponentDataType() != float.class) { - int count = accessorModel.getCount(); - morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC2, "")); - AccessorData accessorData = AccessorDatas.create(accessorModel); - for (int i = 0; i < count; i++) { - morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - } - } else { - morphAccessorData = AccessorDatas.createFloat(accessorModel); - } - texcoordsMorphTargetAccessorModelToAccessorData.put(accessorModel, morphAccessorData); - } - targetAccessorDatas.add(morphAccessorData); - } else targetAccessorDatas.add(null); - } - return isMorphableAttribute; - } - - public void bindVec3FloatMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - AccessorFloatData baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - AccessorFloatData morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - ByteBuffer morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - - int glBufferView = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); - - float weights[] = new float[targetAccessorDatas.size()]; - int numComponents = 3; - int numElements = morphedAccessorData.getNumElements(); - - List morphingCommands = new ArrayList(numElements * numComponents); - for (int element = 0; element < numElements; element++) { - for (int component = 0; component < numComponents; component++) { - int e = element; - int c = component; - morphingCommands.add(() -> { - float r = baseAccessorData.get(e, c); - for (int i = 0; i < weights.length; i++) { - AccessorFloatData target = targetAccessorDatas.get(i); - if (target != null) { - r += weights[i] * target.get(e, c); - } - } - morphedAccessorData.set(e, c, r); - }); - } - } - - command.add(() -> { - if (nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); - else if (meshModel.getWeights() != null) - System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); - - morphingCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); - }); - } - - public AccessorModel bindColorMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { - AccessorFloatData baseAccessorData; - AccessorFloatData morphedAccessorData; - ByteBuffer morphedBufferViewData; - - if (baseAccessorModel.getComponentDataType() != float.class) { - int count = baseAccessorModel.getCount(); - AccessorData accessorData = AccessorDatas.create(baseAccessorModel); - baseAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); - baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - for (int i = 0; i < count; i++) { - baseAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - baseAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - baseAccessorData.set(i, 2, accessorData.getFloat(i, 2)); - baseAccessorData.set(i, 3, accessorData.getFloat(i, 3)); - } - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - } else { - baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - } - - int glBufferView = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); - - float weights[] = new float[targetAccessorDatas.size()]; - int numComponents = 4; - int numElements = morphedAccessorData.getNumElements(); - - List morphingCommands = new ArrayList(numElements * numComponents); - for (int element = 0; element < numElements; element++) { - for (int component = 0; component < numComponents; component++) { - int e = element; - int c = component; - morphingCommands.add(() -> { - float r = baseAccessorData.get(e, c); - for (int i = 0; i < weights.length; i++) { - AccessorFloatData target = targetAccessorDatas.get(i); - if (target != null) { - r += weights[i] * target.get(e, c); - } - } - morphedAccessorData.set(e, c, r); - }); - } - } - - command.add(() -> { - if (nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); - else if (meshModel.getWeights() != null) - System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); - - morphingCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); - }); - return baseAccessorModel; - } - - public AccessorModel bindTexcoordMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { - AccessorFloatData baseAccessorData; - AccessorFloatData morphedAccessorData; - ByteBuffer morphedBufferViewData; - - if (baseAccessorModel.getComponentDataType() != float.class) { - int count = baseAccessorModel.getCount(); - AccessorData accessorData = AccessorDatas.create(baseAccessorModel); - baseAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC2, ""); - baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - for (int i = 0; i < count; i++) { - baseAccessorData.set(i, 0, accessorData.getFloat(i, 0)); - baseAccessorData.set(i, 1, accessorData.getFloat(i, 1)); - } - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - } else { - baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); - AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); - morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); - morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); - } - - int glBufferView = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); - - float weights[] = new float[targetAccessorDatas.size()]; - int numComponents = 2; - int numElements = morphedAccessorData.getNumElements(); - - List morphingCommands = new ArrayList(numElements * numComponents); - for (int element = 0; element < numElements; element++) { - for (int component = 0; component < numComponents; component++) { - int e = element; - int c = component; - morphingCommands.add(() -> { - float r = baseAccessorData.get(e, c); - for (int i = 0; i < weights.length; i++) { - AccessorFloatData target = targetAccessorDatas.get(i); - if (target != null) { - r += weights[i] * target.get(e, c); - } - } - morphedAccessorData.set(e, c, r); - }); - } - } - - command.add(() -> { - if (nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); - else if (meshModel.getWeights() != null) - System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); - - morphingCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); - GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); - }); - return baseAccessorModel; - } - - public static class Material { - - public TextureInfo baseColorTexture; - public TextureInfo normalTexture; - public TextureInfo specularTexture; - public float[] baseColorFactor; - public Boolean doubleSided; - public Runnable vanillaMaterialCommand; - public Runnable shaderModMaterialCommand; - - public void initMaterialCommand(List gltfRenderData, RenderedGltfModel renderedModel, MaterialModel materialModel) { - int colorMap; - final int normalMap; - final int specularMap; - List textureModels = renderedModel.gltfModel.getTextureModels(); - if (materialModel instanceof MaterialModelV2) { - MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; - - if (baseColorTexture == null) { - TextureModel textureModel = materialModelV2.getBaseColorTexture(); - if (textureModel != null) { - colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - baseColorTexture = new TextureInfo(); - baseColorTexture.index = textureModels.indexOf(textureModel); - } else colorMap = MCglTF.getInstance().getDefaultColorMap(); - } else - colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); - - if (normalTexture == null) { - TextureModel textureModel = materialModelV2.getNormalTexture(); - if (textureModel != null) { - normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - normalTexture = new TextureInfo(); - normalTexture.index = textureModels.indexOf(textureModel); - } else normalMap = MCglTF.getInstance().getDefaultNormalMap(); - } else - normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); - - if (specularTexture == null) { - TextureModel textureModel = materialModelV2.getMetallicRoughnessTexture(); - if (textureModel != null) { - specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - specularTexture = new TextureInfo(); - specularTexture.index = textureModels.indexOf(textureModel); - } else specularMap = MCglTF.getInstance().getDefaultSpecularMap(); - } else - specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); - - if (baseColorFactor == null) baseColorFactor = materialModelV2.getBaseColorFactor(); - - if (doubleSided == null) doubleSided = materialModelV2.isDoubleSided(); - } else { - colorMap = baseColorTexture == null ? MCglTF.getInstance().getDefaultColorMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); - normalMap = normalTexture == null ? MCglTF.getInstance().getDefaultNormalMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); - specularMap = specularTexture == null ? MCglTF.getInstance().getDefaultSpecularMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); - if (baseColorFactor == null) baseColorFactor = new float[]{1.0F, 1.0F, 1.0F, 1.0F}; - if (doubleSided == null) doubleSided = false; - } - - if (doubleSided) { - vanillaMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glDisable(GL11.GL_CULL_FACE); - }; - shaderModMaterialCommand = () -> { - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glDisable(GL11.GL_CULL_FACE); - }; - } else { - vanillaMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - shaderModMaterialCommand = () -> { - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - GL11.glEnable(GL11.GL_CULL_FACE); - }; - } - } - - public class TextureInfo { - public int index; - } - } + /** + * ShaderMod attribute location for middle UV coordinates, used for parallax occlusion mapping.
    + * This may change in different Minecraft version.
    + * optifine/shaders.txt + */ + public static final int mc_midTexCoord; + + /** + * ShaderMod attribute location for Tangent.
    + * This may change in different Minecraft version.
    + * optifine/shaders.txt + */ + public static final int at_tangent; + + /** + * ShaderMod Texture index, this may change in different Minecraft version.
    + * optifine/shaders.txt + */ + public static final int COLOR_MAP_INDEX = GL13.GL_TEXTURE0; + public static int NORMAL_MAP_INDEX = GL13.GL_TEXTURE2; + public static int SPECULAR_MAP_INDEX = GL13.GL_TEXTURE1; + + public static int MODEL_VIEW_MATRIX; + public static int MODEL_VIEW_MATRIX_INVERSE; + public static int NORMAL_MATRIX; + + public static final int vaPosition = 0; + public static final int vaColor = 1; + public static final int vaUV0 = 2; + public static final int vaUV1 = 3; + public static final int vaUV2 = 4; + public static final int vaNormal = 10; + + protected static final Runnable vanillaDefaultMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); + GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); + GL11.glEnable(GL11.GL_CULL_FACE); + }; + + protected static final Runnable shaderModDefaultMaterialCommand; + + public static ShaderInstance CURRENT_SHADER_INSTANCE; + protected static Matrix4f CURRENT_POSE; + protected static Matrix3f CURRENT_NORMAL; + public static Vector3f LIGHT0_DIRECTION; + public static Vector3f LIGHT1_DIRECTION; + + protected static final int skinning_joint = 0; + protected static final int skinning_weight = 1; + protected static final int skinning_position = 2; + protected static final int skinning_normal = 3; + protected static final int skinning_tangent = 4; + + protected static final int skinning_out_position = 0; + protected static final int skinning_out_normal = 1; + protected static final int skinning_out_tangent = 2; + + protected static FloatBuffer uniformFloatBuffer = null; + + protected static final FloatBuffer BUF_FLOAT_9 = BufferUtils.createFloatBuffer(9); + protected static final FloatBuffer BUF_FLOAT_16 = BufferUtils.createFloatBuffer(16); + + public static final Map NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE = new IdentityHashMap(); + + protected final Map, List, List>> rootNodeModelToCommands = new IdentityHashMap, List, List>>(); + protected final Map positionsAccessorModelToNormalsAccessorModel = new IdentityHashMap(); + protected final Map normalsAccessorModelToTangentsAccessorModel = new IdentityHashMap(); + protected final Map colorsAccessorModelVec3ToVec4 = new IdentityHashMap(); + protected final Map jointsAccessorModelUnsignedLookup = new IdentityHashMap(); + protected final Map weightsAccessorModelDequantizedLookup = new IdentityHashMap(); + protected final Map colorsMorphTargetAccessorModelToAccessorData = new IdentityHashMap(); + protected final Map texcoordsMorphTargetAccessorModelToAccessorData = new IdentityHashMap(); + protected final Map meshPrimitiveModelToTangentsAccessorModel = new IdentityHashMap(); + protected final Map, List>>> meshPrimitiveModelToUnindexed = new IdentityHashMap, List>>>(); + protected final Map bufferViewModelToGlBufferView = new IdentityHashMap(); + protected final Map textureModelToGlTexture = new IdentityHashMap(); + protected final Map materialModelToRenderedMaterial = new IdentityHashMap(); + + public final GltfModel gltfModel; + + public final List renderedGltfScenes; + + static { + if(FabricLoader.getInstance().isModLoaded("iris")) { + mc_midTexCoord = 12; + at_tangent = 13; + + shaderModDefaultMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); + + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + int normalMapLocation = GL20.glGetUniformLocation(currentProgram, "normals"); + if(normalMapLocation != -1) { + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 2); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultNormalMap()); + GL20.glUniform1i(normalMapLocation, 2); + } + int specularMapLocation = GL20.glGetUniformLocation(currentProgram, "specular"); + if(specularMapLocation != -1) { + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultSpecularMap()); + GL20.glUniform1i(specularMapLocation, 1); + } + + // Enhanced color attribute with proper alpha handling + GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); + + // Add entityColor uniform support for shader packs like SEUS PTGI + int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); + if (entityColorLocation != -1) { + GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); + } + + // Ensure proper blending state for Iris rendering + GL11.glDisable(GL11.GL_BLEND); + + GL11.glEnable(GL11.GL_CULL_FACE); + }; + } + else { + mc_midTexCoord = 12; + at_tangent = 13; + + shaderModDefaultMaterialCommand = () -> { + GL13.glActiveTexture(COLOR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultColorMap()); + GL13.glActiveTexture(NORMAL_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultNormalMap()); + GL13.glActiveTexture(SPECULAR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, MCglTF.getInstance().getDefaultSpecularMap()); + + // Enhanced color attribute with proper alpha handling + GL20.glVertexAttrib4f(vaColor, 1.0F, 1.0F, 1.0F, 1.0F); + + // Add entityColor uniform support for shader packs like SEUS PTGI + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); + if (entityColorLocation != -1) { + GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); + } + + // Ensure proper blending state for non-Iris rendering + GL11.glDisable(GL11.GL_BLEND); + + GL11.glEnable(GL11.GL_CULL_FACE); + }; + } + } + + protected RenderedGltfModel(GltfModel gltfModel, List renderedGltfScenes) { + this.gltfModel = gltfModel; + this.renderedGltfScenes = renderedGltfScenes; + } + + public RenderedGltfModel(List gltfRenderData, GltfModel gltfModel) { + this.gltfModel = gltfModel; + List sceneModels = gltfModel.getSceneModels(); + renderedGltfScenes = new ArrayList(sceneModels.size()); + processSceneModels(gltfRenderData, sceneModels); + } + + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for(SceneModel sceneModel : sceneModels) { + RenderedGltfScene renderedGltfScene = new RenderedGltfScene(); + renderedGltfScenes.add(renderedGltfScene); + + for(NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if(commands == null) { + rootSkinningCommands = new ArrayList<>(); + vanillaRootRenderCommands = new ArrayList<>(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } + else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List skinningCommands, List vanillaRenderCommands, List shaderModRenderCommands) { + ArrayList nodeSkinningCommands = new ArrayList(); + ArrayList vanillaNodeRenderCommands = new ArrayList(); + ArrayList shaderModNodeRenderCommands = new ArrayList(); + SkinModel skinModel = nodeModel.getSkinModel(); + if(skinModel != null) { + boolean canHaveHardwareSkinning; + checkHardwareSkinning: { + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + if(!meshPrimitiveModel.getAttributes().containsKey("JOINTS_1")) { + canHaveHardwareSkinning = true; + break checkHardwareSkinning; + } + } + } + canHaveHardwareSkinning = false; + } + + int jointCount = skinModel.getJoints().size(); + + float[][] transforms = new float[jointCount][]; + float[] invertNodeTransform = new float[16]; + float[] bindShapeMatrix = new float[16]; + + if(canHaveHardwareSkinning) { + int jointMatrixSize = jointCount * 16; + float[] jointMatrices = new float[jointMatrixSize]; + + int jointMatrixBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(jointMatrixBuffer)); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixBuffer); + GL15.glBufferData(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixSize * Float.BYTES, GL15.GL_STATIC_DRAW); + + List jointMatricesTransformCommands = new ArrayList(jointCount); + for(int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + System.arraycopy(transform, 0, jointMatrices, i * 16, 16); + }); + } + + nodeSkinningCommands.add(() -> { + for(int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, jointMatrixBuffer); + GL15.glBufferSubData(GL43.GL_SHADER_STORAGE_BUFFER, 0, putFloatBuffer(jointMatrices)); + + GL30.glBindBufferBase(GL43.GL_SHADER_STORAGE_BUFFER, 0, jointMatrixBuffer); + }); + + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + else { + List jointMatricesTransformCommands = new ArrayList(jointCount); + for(int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + }); + } + + Runnable jointMatricesTransformCommand = () -> { + for(int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + }; + vanillaNodeRenderCommands.add(jointMatricesTransformCommand); + shaderModNodeRenderCommands.add(jointMatricesTransformCommand); + + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } + else { + if(!nodeModel.getMeshModels().isEmpty()) { + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } + nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); + if(!nodeSkinningCommands.isEmpty()) { + // Zero-scale meshes visibility optimization + // https://github.com/KhronosGroup/glTF/pull/2059 + skinningCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + nodeSkinningCommands.forEach(Runnable::run); + } + }); + } + if(!vanillaNodeRenderCommands.isEmpty()) { + vanillaRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformVanilla(nodeModel); + + vanillaNodeRenderCommands.forEach(Runnable::run); + } + }); + shaderModRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformShaderMod(nodeModel); + + shaderModNodeRenderCommands.forEach(Runnable::run); + } + }); + } + } + + protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List vanillaRenderCommands, List shaderModRenderCommands) { + Map attributes = meshPrimitiveModel.getAttributes(); + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + if(positionsAccessorModel != null) { + List renderCommand = new ArrayList(); + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + if(normalsAccessorModel != null) { + AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); + if(tangentsAccessorModel != null) { + processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if(materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + } + else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + } + } + else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if(materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if(renderedMaterial.normalTexture != null) { + processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); + } + else { + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel); + } + } + else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, attributes, positionsAccessorModel, normalsAccessorModel); + } + } + } + else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if(materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if(renderedMaterial.normalTexture != null) { + processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); + } + else { + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); + } + } + else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand); + } + } + vanillaRenderCommands.addAll(renderCommand); + shaderModRenderCommands.addAll(renderCommand); + } + } + + protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if(indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + else { + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } } + + protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + } + else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + } + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if(indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + else { + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + } + + protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); } + + protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + } + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); } + + protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand) { + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + int count = positionsAccessorModel.getCount(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, count); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + + protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, float[][] jointMatrices, List skinningCommand, List vanillaRenderCommands, List shaderModRenderCommands) { + Map attributes = meshPrimitiveModel.getAttributes(); + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + if(positionsAccessorModel != null) { + List renderCommand = new ArrayList(); + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + if(normalsAccessorModel != null) { + AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); + if(tangentsAccessorModel != null) { + if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); + else processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if(materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + } + else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + } + } + else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if(materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if(renderedMaterial.normalTexture != null) { + if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + else processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); + } + else { + if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); + else processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel); + } + } + else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); + else processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand, attributes, positionsAccessorModel, normalsAccessorModel); + } + } + } + else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if(materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if(renderedMaterial.normalTexture != null) { + if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + else processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); + } + else { + if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + else processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); + } + } + else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + if(attributes.containsKey("JOINTS_1")) processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + else processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, skinningCommand); + } + } + vanillaRenderCommands.addAll(renderCommand); + shaderModRenderCommands.addAll(renderCommand); + } + } + + protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if(indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + try { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + } finally { + GL20.glDisableVertexAttribArray(at_tangent); + } + }); + } + else { + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } } + + protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if(indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } + else { + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } + } + + protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } + + protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } + + protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glTransformFeedback = GL40.glGenTransformFeedbacks(); + gltfRenderData.add(() -> GL40.glDeleteTransformFeedbacks(glTransformFeedback)); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, glTransformFeedback); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL40.glDrawTransformFeedback(mode, glTransformFeedback); + }); + } + + protected void processMeshPrimitiveModel(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, float[][] jointMatrices, List vanillaRenderCommands, List shaderModRenderCommands) { + Map attributes = meshPrimitiveModel.getAttributes(); + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + if(positionsAccessorModel != null) { + List renderCommand = new ArrayList(); + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + if(normalsAccessorModel != null) { + AccessorModel tangentsAccessorModel = attributes.get("TANGENT"); + if(tangentsAccessorModel != null) { + processMeshPrimitiveModelIncludedTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel); + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if(materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + } + else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + } + } + else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if(materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if(renderedMaterial.normalTexture != null) { + processMeshPrimitiveModelMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + } + else { + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); + } + } + else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + processMeshPrimitiveModelSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices, attributes, positionsAccessorModel, normalsAccessorModel); + } + } + } + else { + MaterialModel materialModel = meshPrimitiveModel.getMaterialModel(); + if(materialModel != null) { + Material renderedMaterial = obtainMaterial(gltfRenderData, materialModel); + vanillaRenderCommands.add(renderedMaterial.vanillaMaterialCommand); + shaderModRenderCommands.add(renderedMaterial.shaderModMaterialCommand); + if(renderedMaterial.normalTexture != null) { + processMeshPrimitiveModelFlatNormalMikkTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + } + else { + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + } + } + else { + vanillaRenderCommands.add(vanillaDefaultMaterialCommand); + shaderModRenderCommands.add(shaderModDefaultMaterialCommand); + processMeshPrimitiveModelFlatNormalSimpleTangent(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, renderCommand, jointMatrices); + } + } + vanillaRenderCommands.addAll(renderCommand); + shaderModRenderCommands.addAll(renderCommand); + } + } + + protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel outputPositionsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + } + + AccessorModel outputNormalsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } + else { + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + } + + AccessorModel outputTangentsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if(indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } + else { + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + } + + protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel outputPositionsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + } + + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + AccessorModel outputNormalsAccessorModel; + AccessorModel outputTangentsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if(indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } + else { + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + } + + protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel outputPositionsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + } + + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + AccessorModel outputNormalsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } + else { + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel outputTangentsAccessorModel; + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); + if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + AccessorModel outputPositionsAccessorModel; + AccessorModel outputNormalsAccessorModel; + AccessorModel outputTangentsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, float[][] jointMatrices) { + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel outputPositionsAccessorModel; + AccessorModel outputNormalsAccessorModel; + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { + outputPositionsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, positionsAccessorModel, targetAccessorDatas); + outputNormalsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, normalsAccessorModel, targetAccessorDatas); + } + else { + outputPositionsAccessorModel = AccessorModelCreation.instantiate(positionsAccessorModel, ""); + outputNormalsAccessorModel = AccessorModelCreation.instantiate(normalsAccessorModel, ""); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + AccessorModel outputTangentsAccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { + outputTangentsAccessorModel = obtainVec3FloatMorphedModel(nodeModel, meshModel, renderCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + outputTangentsAccessorModel = AccessorModelCreation.instantiate(tangentsAccessorModel, ""); + } + + int pointCount = positionsAccessorModel.getCount(); + List skinningCommands = createSoftwareSkinningCommands(pointCount, jointMatrices, attributes, + AccessorDatas.createFloat(positionsAccessorModel), + AccessorDatas.createFloat(normalsAccessorModel), + AccessorDatas.createFloat(tangentsAccessorModel), + AccessorDatas.createFloat(outputPositionsAccessorModel), + AccessorDatas.createFloat(outputNormalsAccessorModel), + AccessorDatas.createFloat(outputTangentsAccessorModel)); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputPositionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaPosition, + outputPositionsAccessorModel.getElementType().getNumComponents(), + outputPositionsAccessorModel.getComponentType(), + false, + outputPositionsAccessorModel.getByteStride(), + outputPositionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaPosition); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputNormalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + vaNormal, + outputNormalsAccessorModel.getElementType().getNumComponents(), + outputNormalsAccessorModel.getComponentType(), + false, + outputNormalsAccessorModel.getByteStride(), + outputNormalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaNormal); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, outputTangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + GL20.glVertexAttribPointer( + at_tangent, + outputTangentsAccessorModel.getElementType().getNumComponents(), + outputTangentsAccessorModel.getComponentType(), + false, + outputTangentsAccessorModel.getByteStride(), + outputTangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + ByteBuffer positionsBufferViewData = outputPositionsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer normalsBufferViewData = outputNormalsAccessorModel.getBufferViewModel().getBufferViewData(); + ByteBuffer tangentsBufferViewData = outputTangentsAccessorModel.getBufferViewModel().getBufferViewData(); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + skinningCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, positionsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, normalsBufferViewData); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, tangentsBufferViewData); + + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + protected void applyTransformVanilla(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + Matrix3f normal = new Matrix3f(pose); + + pose.transpose(); + pose.mulLocal(CURRENT_POSE); + + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + CURRENT_SHADER_INSTANCE.MODEL_VIEW_MATRIX.set(pose); + CURRENT_SHADER_INSTANCE.MODEL_VIEW_MATRIX.upload(); + + CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.set((new Vector3f(LIGHT0_DIRECTION)).mulTranspose(normal)); + CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.set((new Vector3f(LIGHT1_DIRECTION)).mulTranspose(normal)); + CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.upload(); + CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.upload(); + } + + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + Matrix3f normal = new Matrix3f(pose); + + pose.transpose(); + pose.mulLocal(CURRENT_POSE); + + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + + pose.invert(); + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX_INVERSE, false, BUF_FLOAT_16); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } + + public static class Material { + + public class TextureInfo { + public int index; + } + + public TextureInfo baseColorTexture; + public TextureInfo normalTexture; + public TextureInfo specularTexture; + public float[] baseColorFactor; + public Boolean doubleSided; + + public Runnable vanillaMaterialCommand; + public Runnable shaderModMaterialCommand; + + public void initMaterialCommand(List gltfRenderData, RenderedGltfModel renderedModel, MaterialModel materialModel) { + int colorMap; + final int normalMap; + final int specularMap; + List textureModels = renderedModel.gltfModel.getTextureModels(); + if(materialModel instanceof MaterialModelV2) { + MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; + + if(baseColorTexture == null) { + TextureModel textureModel = materialModelV2.getBaseColorTexture(); + if(textureModel != null) { + colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + baseColorTexture = new TextureInfo(); + baseColorTexture.index = textureModels.indexOf(textureModel); + } + else colorMap = MCglTF.getInstance().getDefaultColorMap(); + } + else colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); + + if(normalTexture == null) { + TextureModel textureModel = materialModelV2.getNormalTexture(); + if(textureModel != null) { + normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + normalTexture = new TextureInfo(); + normalTexture.index = textureModels.indexOf(textureModel); + } + else normalMap = MCglTF.getInstance().getDefaultNormalMap(); + } + else normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); + + if(specularTexture == null) { + TextureModel textureModel = materialModelV2.getMetallicRoughnessTexture(); + if(textureModel != null) { + specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + specularTexture = new TextureInfo(); + specularTexture.index = textureModels.indexOf(textureModel); + } + else specularMap = MCglTF.getInstance().getDefaultSpecularMap(); + } + else specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); + + if(baseColorFactor == null) baseColorFactor = materialModelV2.getBaseColorFactor(); + + if(doubleSided == null) doubleSided = materialModelV2.isDoubleSided(); + } + else { + colorMap = baseColorTexture == null ? MCglTF.getInstance().getDefaultColorMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); + normalMap = normalTexture == null ? MCglTF.getInstance().getDefaultNormalMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); + specularMap = specularTexture == null ? MCglTF.getInstance().getDefaultSpecularMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); + if(baseColorFactor == null) baseColorFactor = new float[]{1.0F, 1.0F, 1.0F, 1.0F}; + if(doubleSided == null) doubleSided = false; + } + + if(doubleSided) { + vanillaMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + GL11.glDisable(GL11.GL_CULL_FACE); + }; + shaderModMaterialCommand = () -> { + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + GL11.glDisable(GL11.GL_CULL_FACE); + }; } + else { + vanillaMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + GL11.glEnable(GL11.GL_CULL_FACE); + }; + shaderModMaterialCommand = () -> { + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + GL11.glEnable(GL11.GL_CULL_FACE); + }; } + } } + + public void bindArrayBufferViewModel(List gltfRenderData, BufferViewModel bufferViewModel) { + Integer glBufferView = bufferViewModelToGlBufferView.get(bufferViewModel); + if(glBufferView == null) { + Integer glBufferViewNew = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferViewNew)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferViewNew); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, bufferViewModel.getBufferViewData(), GL15.GL_STATIC_DRAW); + bufferViewModelToGlBufferView.put(bufferViewModel, glBufferViewNew); + } + else GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + } + + public int obtainElementArrayBuffer(List gltfRenderData, BufferViewModel bufferViewModel) { + Integer glBufferView = bufferViewModelToGlBufferView.get(bufferViewModel); + if(glBufferView == null) { + Integer glBufferViewNew = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferViewNew)); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glBufferViewNew); + GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, bufferViewModel.getBufferViewData(), GL15.GL_STATIC_DRAW); + bufferViewModelToGlBufferView.put(bufferViewModel, glBufferViewNew); + return glBufferViewNew; + } + else { + return glBufferView; + } + } + + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if(material == null) { + Object extras = materialModel.getExtras(); + if(extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), Material.class); + } + else material = new Material(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } + + public int obtainGlTexture(List gltfRenderData, TextureModel textureModel) { + Integer glTexture = textureModelToGlTexture.get(textureModel); + if(glTexture == null) { + PixelData pixelData = PixelDatas.create(textureModel.getImageModel().getImageData()); + if (pixelData == null) + { + MCglTF.logger.warn("Could not extract pixel data from image"); + pixelData = PixelDatas.createErrorPixelData(); + } + + Integer glTextureNew = GL11.glGenTextures(); + gltfRenderData.add(() -> GL11.glDeleteTextures(glTextureNew)); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, glTextureNew); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, pixelData.getWidth(), pixelData.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixelData.getPixelsRGBA()); + + int minFilter = Optionals.of( + textureModel.getMinFilter(), + GL11.GL_NEAREST_MIPMAP_LINEAR); + int magFilter = Optionals.of( + textureModel.getMagFilter(), + GL11.GL_LINEAR); + int wrapS = Optionals.of( + textureModel.getWrapS(), + GL11.GL_REPEAT); + int wrapT = Optionals.of( + textureModel.getWrapT(), + GL11.GL_REPEAT); + + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, minFilter); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, magFilter); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrapS); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrapT); + + textureModelToGlTexture.put(textureModel, glTextureNew); + + return glTextureNew; + } + else { + return glTexture; + } + } + + public AccessorModel obtainNormalsAccessorModel(AccessorModel positionsAccessorModel) { + AccessorModel normalsAccessorModel = positionsAccessorModelToNormalsAccessorModel.get(positionsAccessorModel); + if(normalsAccessorModel == null) { + int count = positionsAccessorModel.getCount(); + int numTriangles = count / 3; + normalsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, ""); + positionsAccessorModelToNormalsAccessorModel.put(positionsAccessorModel, normalsAccessorModel); + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + float vertex0[] = new float[3]; + float vertex1[] = new float[3]; + float vertex2[] = new float[3]; + float edge01[] = new float[3]; + float edge02[] = new float[3]; + float cross[] = new float[3]; + float normal[] = new float[3]; + for(int i = 0; i < numTriangles; i++) { + int index0 = i * 3; + int index1 = index0 + 1; + int index2 = index0 + 2; + + vertex0[0] = positionsAccessorData.get(index0, 0); + vertex0[1] = positionsAccessorData.get(index0, 1); + vertex0[2] = positionsAccessorData.get(index0, 2); + + vertex1[0] = positionsAccessorData.get(index1, 0); + vertex1[1] = positionsAccessorData.get(index1, 1); + vertex1[2] = positionsAccessorData.get(index1, 2); + + vertex2[0] = positionsAccessorData.get(index2, 0); + vertex2[1] = positionsAccessorData.get(index2, 1); + vertex2[2] = positionsAccessorData.get(index2, 2); + + MathUtils.subtract(vertex1, vertex0, edge01); + MathUtils.subtract(vertex2, vertex0, edge02); + MathUtils.cross(edge01, edge02, cross); + MathUtils.normalize(cross, normal); + + normalsAccessorData.set(index0, 0, normal[0]); + normalsAccessorData.set(index0, 1, normal[1]); + normalsAccessorData.set(index0, 2, normal[2]); + + normalsAccessorData.set(index1, 0, normal[0]); + normalsAccessorData.set(index1, 1, normal[1]); + normalsAccessorData.set(index1, 2, normal[2]); + + normalsAccessorData.set(index2, 0, normal[0]); + normalsAccessorData.set(index2, 1, normal[1]); + normalsAccessorData.set(index2, 2, normal[2]); + } + } + return normalsAccessorModel; + } + + /** + * Found this simple normals to tangent algorithm here:
    + * How to find a randomic Vector orthogonal to a given Vector + */ + public AccessorModel obtainTangentsAccessorModel(AccessorModel normalsAccessorModel) { + AccessorModel tangentsAccessorModel = normalsAccessorModelToTangentsAccessorModel.get(normalsAccessorModel); + if(tangentsAccessorModel == null) { + int count = normalsAccessorModel.getCount(); + tangentsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); + normalsAccessorModelToTangentsAccessorModel.put(normalsAccessorModel, tangentsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + float[] normal0 = new float[3]; + float[] normal1 = new float[3]; + float[] cross = new float[3]; + float[] tangent = new float[3]; + + for(int i = 0; i < count; i++) { + normal0[0] = normalsAccessorData.get(i, 0); + normal0[1] = normalsAccessorData.get(i, 1); + normal0[2] = normalsAccessorData.get(i, 2); + + normal1[0] = -normal0[2]; + normal1[1] = normal0[0]; + normal1[2] = normal0[1]; + + MathUtils.cross(normal0, normal1, cross); + MathUtils.normalize(cross, tangent); + + tangentsAccessorData.set(i, 0, tangent[0]); + tangentsAccessorData.set(i, 1, tangent[1]); + tangentsAccessorData.set(i, 2, tangent[2]); + tangentsAccessorData.set(i, 3, 1.0F); + } + } + return tangentsAccessorModel; + } + + public AccessorModel obtainTangentsAccessorModel(MeshPrimitiveModel meshPrimitiveModel, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel) { + AccessorModel tangentsAccessorModel = meshPrimitiveModelToTangentsAccessorModel.get(meshPrimitiveModel); + if(tangentsAccessorModel == null) { + int count = positionsAccessorModel.getCount(); + int numFaces = count / 3; + tangentsAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); + meshPrimitiveModelToTangentsAccessorModel.put(meshPrimitiveModel, tangentsAccessorModel); + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0]); + tangentsAccessorData.set(index, 1, tangent[1]); + tangentsAccessorData.set(index, 2, tangent[2]); + tangentsAccessorData.set(index, 3, -sign); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + return tangentsAccessorModel; + } + + public AccessorModel obtainVec4ColorsAccessorModel(AccessorModel colorsAccessorModel) { + if(colorsAccessorModel.getElementType() == ElementType.VEC3) { + AccessorModel colorsVec4AccessorModel = colorsAccessorModelVec3ToVec4.get(colorsAccessorModel); + if(colorsVec4AccessorModel == null) { + int count = colorsAccessorModel.getCount(); + colorsVec4AccessorModel = AccessorModelCreation.createAccessorModel(colorsAccessorModel.getComponentType(), count, ElementType.VEC4, ""); + colorsAccessorModelVec3ToVec4.put(colorsAccessorModel, colorsVec4AccessorModel); + AccessorData accessorData = AccessorDatas.create(colorsVec4AccessorModel); + if(accessorData instanceof AccessorByteData) { + AccessorByteData colorsVec4AccessorData = (AccessorByteData) accessorData; + AccessorByteData colorsAccessorData = AccessorDatas.createByte(colorsAccessorModel); + if(colorsAccessorData.isUnsigned()) { + for(int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, (byte) -1); + } + } + else { + for(int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, Byte.MAX_VALUE); + } + } + } + else if(accessorData instanceof AccessorShortData) { + AccessorShortData colorsVec4AccessorData = (AccessorShortData) accessorData; + AccessorShortData colorsAccessorData = AccessorDatas.createShort(colorsAccessorModel); + if(colorsAccessorData.isUnsigned()) { + for(int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, (short) -1); + } + } + else { + for(int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, Short.MAX_VALUE); + } + } + } + else if(accessorData instanceof AccessorFloatData) { + AccessorFloatData colorsVec4AccessorData = (AccessorFloatData) accessorData; + AccessorFloatData colorsAccessorData = AccessorDatas.createFloat(colorsAccessorModel); + for(int i = 0; i < count; i++) { + colorsVec4AccessorData.set(i, 0, colorsAccessorData.get(i, 0)); + colorsVec4AccessorData.set(i, 1, colorsAccessorData.get(i, 1)); + colorsVec4AccessorData.set(i, 2, colorsAccessorData.get(i, 2)); + colorsVec4AccessorData.set(i, 3, 1.0F); + } + } + } + return colorsVec4AccessorModel; + } + return colorsAccessorModel; + } + + public AccessorModel obtainUnsignedJointsModel(AccessorModel accessorModel) { + AccessorModel unsignedAccessorModel = jointsAccessorModelUnsignedLookup.get(accessorModel); + if(unsignedAccessorModel == null) { + int count = accessorModel.getCount(); + unsignedAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_INT, count, ElementType.VEC4, ""); + AccessorIntData unsignedAccessorData = AccessorDatas.createInt(unsignedAccessorModel); + if(accessorModel.getComponentDataType() == short.class) { + AccessorShortData accessorData = AccessorDatas.createShort(accessorModel); + for(int i = 0; i < count; i++) { + unsignedAccessorData.set(i, 0, Short.toUnsignedInt(accessorData.get(i, 0))); + unsignedAccessorData.set(i, 1, Short.toUnsignedInt(accessorData.get(i, 1))); + unsignedAccessorData.set(i, 2, Short.toUnsignedInt(accessorData.get(i, 2))); + unsignedAccessorData.set(i, 3, Short.toUnsignedInt(accessorData.get(i, 3))); + } + } + else { + AccessorByteData accessorData = AccessorDatas.createByte(accessorModel); + for(int i = 0; i < count; i++) { + unsignedAccessorData.set(i, 0, Byte.toUnsignedInt(accessorData.get(i, 0))); + unsignedAccessorData.set(i, 1, Byte.toUnsignedInt(accessorData.get(i, 1))); + unsignedAccessorData.set(i, 2, Byte.toUnsignedInt(accessorData.get(i, 2))); + unsignedAccessorData.set(i, 3, Byte.toUnsignedInt(accessorData.get(i, 3))); + } + } + jointsAccessorModelUnsignedLookup.put(accessorModel, unsignedAccessorModel); + } + return unsignedAccessorModel; + } + + public AccessorModel obtainDequantizedWeightsModel(AccessorModel accessorModel) { + AccessorModel dequantizedAccessorModel = weightsAccessorModelDequantizedLookup.get(accessorModel); + if(dequantizedAccessorModel == null) { + if(accessorModel.getComponentDataType() != float.class) { + AccessorData accessorData = AccessorDatas.create(accessorModel); + int count = accessorModel.getCount(); + dequantizedAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); + AccessorFloatData dequantizedAccessorData = AccessorDatas.createFloat(dequantizedAccessorModel); + for(int i = 0; i < count; i++) { + dequantizedAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + dequantizedAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + dequantizedAccessorData.set(i, 2, accessorData.getFloat(i, 2)); + dequantizedAccessorData.set(i, 3, accessorData.getFloat(i, 3)); + } + weightsAccessorModelDequantizedLookup.put(accessorModel, dequantizedAccessorModel); + } + else { + return accessorModel; + } + } + return dequantizedAccessorModel; + } + + public AccessorModel obtainVec3FloatMorphedModel(NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + AccessorFloatData baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + AccessorFloatData morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + + float weights[] = new float[targetAccessorDatas.size()]; + int numComponents = 3; + int numElements = morphedAccessorData.getNumElements(); + + List morphingCommands = new ArrayList(numElements * numComponents); + for(int element = 0; element < numElements; element++) { + for(int component = 0; component < numComponents; component++) { + int e = element; + int c = component; + morphingCommands.add(() -> { + float r = baseAccessorData.get(e, c); + for(int i = 0; i < weights.length; i++) { + AccessorFloatData target = targetAccessorDatas.get(i); + if(target != null) { + r += weights[i] * target.get(e, c); + } + } + morphedAccessorData.set(e, c, r); + }); + } + } + + command.add(() -> { + if(nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); + else if(meshModel.getWeights() != null) System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); + + morphingCommands.parallelStream().forEach(Runnable::run); + }); + return morphedAccessorModel; + } + + public Pair, List>> obtainUnindexed(MeshPrimitiveModel meshPrimitiveModel) { + Pair, List>> unindexed; + AccessorModel indicesAccessorModel = meshPrimitiveModel.getIndices(); + if(indicesAccessorModel != null) { + unindexed = meshPrimitiveModelToUnindexed.get(meshPrimitiveModel); + if(unindexed == null) { + int indices[] = AccessorDataUtils.readInts(AccessorDatas.create(indicesAccessorModel)); + Map attributes = meshPrimitiveModel.getAttributes(); + Map attributesUnindexed = new LinkedHashMap(attributes.size()); + attributes.forEach((name, attribute) -> { + ElementType elementType = attribute.getElementType(); + int size = elementType.getNumComponents(); + AccessorModel accessorModel = AccessorModelCreation.createAccessorModel(attribute.getComponentType(), indices.length, elementType, ""); + attributesUnindexed.put(name, accessorModel); + AccessorData accessorData = AccessorDatas.create(accessorModel); + if(accessorData instanceof AccessorByteData) { + AccessorByteData accessorDataUnindexed = (AccessorByteData) accessorData; + AccessorByteData accessorDataIndexed = AccessorDatas.createByte(attribute); + for(int i = 0; i < indices.length; i++) { + int index = indices[i]; + for(int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + else if(accessorData instanceof AccessorShortData) { + AccessorShortData accessorDataUnindexed = (AccessorShortData) accessorData; + AccessorShortData accessorDataIndexed = AccessorDatas.createShort(attribute); + for(int i = 0; i < indices.length; i++) { + int index = indices[i]; + for(int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + else if(accessorData instanceof AccessorIntData) { + AccessorIntData accessorDataUnindexed = (AccessorIntData) accessorData; + AccessorIntData accessorDataIndexed = AccessorDatas.createInt(attribute); + for(int i = 0; i < indices.length; i++) { + int index = indices[i]; + for(int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + else if(accessorData instanceof AccessorFloatData) { + AccessorFloatData accessorDataUnindexed = (AccessorFloatData) accessorData; + AccessorFloatData accessorDataIndexed = AccessorDatas.createFloat(attribute); + for(int i = 0; i < indices.length; i++) { + int index = indices[i]; + for(int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + }); + + List> targets = meshPrimitiveModel.getTargets(); + List> targetsUnindexed = new ArrayList>(targets.size()); + targets.forEach((target) -> { + Map targetUnindexed = new LinkedHashMap(target.size()); + targetsUnindexed.add(targetUnindexed); + target.forEach((name, attribute) -> { + ElementType elementType = attribute.getElementType(); + int size = elementType.getNumComponents(); + AccessorModel accessorModel = AccessorModelCreation.createAccessorModel(attribute.getComponentType(), indices.length, elementType, ""); + targetUnindexed.put(name, accessorModel); + AccessorData accessorData = AccessorDatas.create(accessorModel); + if(accessorData instanceof AccessorByteData) { + AccessorByteData accessorDataUnindexed = (AccessorByteData) accessorData; + AccessorByteData accessorDataIndexed = AccessorDatas.createByte(attribute); + for(int i = 0; i < indices.length; i++) { + int index = indices[i]; + for(int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + else if(accessorData instanceof AccessorShortData) { + AccessorShortData accessorDataUnindexed = (AccessorShortData) accessorData; + AccessorShortData accessorDataIndexed = AccessorDatas.createShort(attribute); + for(int i = 0; i < indices.length; i++) { + int index = indices[i]; + for(int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + else if(accessorData instanceof AccessorIntData) { + AccessorIntData accessorDataUnindexed = (AccessorIntData) accessorData; + AccessorIntData accessorDataIndexed = AccessorDatas.createInt(attribute); + for(int i = 0; i < indices.length; i++) { + int index = indices[i]; + for(int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + else if(accessorData instanceof AccessorFloatData) { + AccessorFloatData accessorDataUnindexed = (AccessorFloatData) accessorData; + AccessorFloatData accessorDataIndexed = AccessorDatas.createFloat(attribute); + for(int i = 0; i < indices.length; i++) { + int index = indices[i]; + for(int j = 0; j < size; j++) { + accessorDataUnindexed.set(i, j, accessorDataIndexed.get(index, j)); + } + } + } + }); + }); + unindexed = Pair.of(attributesUnindexed, targetsUnindexed); + meshPrimitiveModelToUnindexed.put(meshPrimitiveModel, unindexed); + } + } + else unindexed = Pair.of(meshPrimitiveModel.getAttributes(), meshPrimitiveModel.getTargets()); + return unindexed; + } + + public List createSoftwareSkinningCommands(int pointCount, float[][] jointMatrices, Map attributes, AccessorFloatData inputPositionsAccessorData, AccessorFloatData inputNormalsAccessorData, AccessorFloatData inputTangentsAccessorData, AccessorFloatData outputPositionsAccessorData, AccessorFloatData outputNormalsAccessorData, AccessorFloatData outputTangentsAccessorData) { + int skinningAttributeCount = 0; + for(String name : attributes.keySet()) { + if(name.startsWith("JOINTS_")) { + skinningAttributeCount += 1; + } + } + AccessorIntData[] jointsAccessorDatas = new AccessorIntData[skinningAttributeCount]; + AccessorFloatData[] weightsAccessorDatas = new AccessorFloatData[skinningAttributeCount]; + attributes.forEach((name, attribute) -> { + if(name.startsWith("JOINTS_")) jointsAccessorDatas[Integer.parseInt(name.substring("JOINTS_".length()))] = AccessorDatas.createInt(obtainUnsignedJointsModel(attribute)); + else if(name.startsWith("WEIGHTS_")) weightsAccessorDatas[Integer.parseInt(name.substring("WEIGHTS_".length()))] = AccessorDatas.createFloat(obtainDequantizedWeightsModel(attribute)); + }); + + List commands = new ArrayList(pointCount); + for(int point = 0; point < pointCount; point++) { + int p = point; + commands.add(() -> { + float sm00 = 0; + float sm01 = 0; + float sm02 = 0; + float sm03 = 0; + float sm10 = 0; + float sm11 = 0; + float sm12 = 0; + float sm13 = 0; + float sm20 = 0; + float sm21 = 0; + float sm22 = 0; + float sm23 = 0; + + for(int i = 0; i < jointsAccessorDatas.length; i++) { + AccessorIntData jointsAccessorData = jointsAccessorDatas[i]; + float[] jmx = jointMatrices[jointsAccessorData.get(p, 0)]; + float[] jmy = jointMatrices[jointsAccessorData.get(p, 1)]; + float[] jmz = jointMatrices[jointsAccessorData.get(p, 2)]; + float[] jmw = jointMatrices[jointsAccessorData.get(p, 3)]; + + AccessorFloatData weightsAccessorData = weightsAccessorDatas[i]; + float wx = weightsAccessorData.get(p, 0); + float wy = weightsAccessorData.get(p, 1); + float wz = weightsAccessorData.get(p, 2); + float ww = weightsAccessorData.get(p, 3); + + sm00 += wx * jmx[ 0] + wy * jmy[ 0] + wz * jmz[ 0] + ww * jmw[ 0]; + sm01 += wx * jmx[ 4] + wy * jmy[ 4] + wz * jmz[ 4] + ww * jmw[ 4]; + sm02 += wx * jmx[ 8] + wy * jmy[ 8] + wz * jmz[ 8] + ww * jmw[ 8]; + sm03 += wx * jmx[12] + wy * jmy[12] + wz * jmz[12] + ww * jmw[12]; + sm10 += wx * jmx[ 1] + wy * jmy[ 1] + wz * jmz[ 1] + ww * jmw[ 1]; + sm11 += wx * jmx[ 5] + wy * jmy[ 5] + wz * jmz[ 5] + ww * jmw[ 5]; + sm12 += wx * jmx[ 9] + wy * jmy[ 9] + wz * jmz[ 9] + ww * jmw[ 9]; + sm13 += wx * jmx[13] + wy * jmy[13] + wz * jmz[13] + ww * jmw[13]; + sm20 += wx * jmx[ 2] + wy * jmy[ 2] + wz * jmz[ 2] + ww * jmw[ 2]; + sm21 += wx * jmx[ 6] + wy * jmy[ 6] + wz * jmz[ 6] + ww * jmw[ 6]; + sm22 += wx * jmx[10] + wy * jmy[10] + wz * jmz[10] + ww * jmw[10]; + sm23 += wx * jmx[14] + wy * jmy[14] + wz * jmz[14] + ww * jmw[14]; + } + + float px = inputPositionsAccessorData.get(p, 0); + float py = inputPositionsAccessorData.get(p, 1); + float pz = inputPositionsAccessorData.get(p, 2); + + outputPositionsAccessorData.set(p, 0, sm00 * px + sm01 * py + sm02 * pz + sm03); + outputPositionsAccessorData.set(p, 1, sm10 * px + sm11 * py + sm12 * pz + sm13); + outputPositionsAccessorData.set(p, 2, sm20 * px + sm21 * py + sm22 * pz + sm23); + + float nx = inputNormalsAccessorData.get(p, 0); + float ny = inputNormalsAccessorData.get(p, 1); + float nz = inputNormalsAccessorData.get(p, 2); + + outputNormalsAccessorData.set(p, 0, sm00 * nx + sm01 * ny + sm02 * nz); + outputNormalsAccessorData.set(p, 1, sm10 * nx + sm11 * ny + sm12 * nz); + outputNormalsAccessorData.set(p, 2, sm20 * nx + sm21 * ny + sm22 * nz); + + float tx = inputTangentsAccessorData.get(p, 0); + float ty = inputTangentsAccessorData.get(p, 1); + float tz = inputTangentsAccessorData.get(p, 2); + + outputTangentsAccessorData.set(p, 0, sm00 * tx + sm01 * ty + sm02 * tz); + outputTangentsAccessorData.set(p, 1, sm10 * tx + sm11 * ty + sm12 * tz); + outputTangentsAccessorData.set(p, 2, sm20 * tx + sm21 * ty + sm22 * tz); + }); + } + return commands; + } + + public boolean createMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { + boolean isMorphableAttribute = false; + for(Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get(attributeName); + if(accessorModel != null) { + isMorphableAttribute = true; + targetAccessorDatas.add(AccessorDatas.createFloat(accessorModel)); + } + else targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public boolean createPositionNormalMorphTarget(List> morphTargets, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, List positionTargetAccessorDatas, List normalTargetAccessorDatas) { + boolean isMorphableAttribute = false; + int count = positionsAccessorModel.getCount(); + int numTriangles = count / 3; + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + for(Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get("POSITION"); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); + positionTargetAccessorDatas.add(deltaPositionsAccessorData); + AccessorFloatData normalTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + normalTargetAccessorDatas.add(normalTargetAccessorData); + float[] vertex0 = new float[3]; + float[] vertex1 = new float[3]; + float[] vertex2 = new float[3]; + float[] edge01 = new float[3]; + float[] edge02 = new float[3]; + float[] cross = new float[3]; + float[] normal0 = new float[3]; + float[] normal1 = new float[3]; + for(int i = 0; i < numTriangles; i++) { + int index0 = i * 3; + int index1 = index0 + 1; + int index2 = index0 + 2; + + vertex0[0] = positionsAccessorData.get(index0, 0) + deltaPositionsAccessorData.get(index0, 0); + vertex0[1] = positionsAccessorData.get(index0, 1) + deltaPositionsAccessorData.get(index0, 1); + vertex0[2] = positionsAccessorData.get(index0, 2) + deltaPositionsAccessorData.get(index0, 2); + + vertex1[0] = positionsAccessorData.get(index1, 0) + deltaPositionsAccessorData.get(index1, 0); + vertex1[1] = positionsAccessorData.get(index1, 1) + deltaPositionsAccessorData.get(index1, 1); + vertex1[2] = positionsAccessorData.get(index1, 2) + deltaPositionsAccessorData.get(index1, 2); + + vertex2[0] = positionsAccessorData.get(index2, 0) + deltaPositionsAccessorData.get(index2, 0); + vertex2[1] = positionsAccessorData.get(index2, 1) + deltaPositionsAccessorData.get(index2, 1); + vertex2[2] = positionsAccessorData.get(index2, 2) + deltaPositionsAccessorData.get(index2, 2); + + normal0[0] = normalsAccessorData.get(index0, 0); + normal0[1] = normalsAccessorData.get(index0, 1); + normal0[2] = normalsAccessorData.get(index0, 2); + + MathUtils.subtract(vertex1, vertex0, edge01); + MathUtils.subtract(vertex2, vertex0, edge02); + MathUtils.cross(edge01, edge02, cross); + MathUtils.normalize(cross, normal1); + + MathUtils.subtract(normal1, normal0, normal1); + + normalTargetAccessorData.set(index0, 0, normal1[0]); + normalTargetAccessorData.set(index0, 1, normal1[1]); + normalTargetAccessorData.set(index0, 2, normal1[2]); + + normalTargetAccessorData.set(index1, 0, normal1[0]); + normalTargetAccessorData.set(index1, 1, normal1[1]); + normalTargetAccessorData.set(index1, 2, normal1[2]); + + normalTargetAccessorData.set(index2, 0, normal1[0]); + normalTargetAccessorData.set(index2, 1, normal1[1]); + normalTargetAccessorData.set(index2, 2, normal1[2]); + } + } + else { + positionTargetAccessorDatas.add(null); + normalTargetAccessorDatas.add(null); + } + } + return isMorphableAttribute; + } + + public boolean createPositionNormalTangentMorphTarget(List> morphTargets, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel, List positionTargetAccessorDatas, List normalTargetAccessorDatas, List tangentTargetAccessorDatas) { + boolean isMorphableAttribute = false; + int count = positionsAccessorModel.getCount(); + int numTriangles = count / 3; + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + for(Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get("POSITION"); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); + positionTargetAccessorDatas.add(deltaPositionsAccessorData); + AccessorFloatData normalTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + normalTargetAccessorDatas.add(normalTargetAccessorData); + AccessorFloatData tangentTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + tangentTargetAccessorDatas.add(tangentTargetAccessorData); + float[] vertex0 = new float[3]; + float[] vertex1 = new float[3]; + float[] vertex2 = new float[3]; + float[] edge01 = new float[3]; + float[] edge02 = new float[3]; + float[] cross = new float[3]; + float[] normal0 = new float[3]; + float[] normal1 = new float[3]; + float[] normal2 = new float[3]; + float[] tangent0 = new float[3]; + float[] tangent1 = new float[3]; + for(int i = 0; i < numTriangles; i++) { + int index0 = i * 3; + int index1 = index0 + 1; + int index2 = index0 + 2; + + vertex0[0] = positionsAccessorData.get(index0, 0) + deltaPositionsAccessorData.get(index0, 0); + vertex0[1] = positionsAccessorData.get(index0, 1) + deltaPositionsAccessorData.get(index0, 1); + vertex0[2] = positionsAccessorData.get(index0, 2) + deltaPositionsAccessorData.get(index0, 2); + + vertex1[0] = positionsAccessorData.get(index1, 0) + deltaPositionsAccessorData.get(index1, 0); + vertex1[1] = positionsAccessorData.get(index1, 1) + deltaPositionsAccessorData.get(index1, 1); + vertex1[2] = positionsAccessorData.get(index1, 2) + deltaPositionsAccessorData.get(index1, 2); + + vertex2[0] = positionsAccessorData.get(index2, 0) + deltaPositionsAccessorData.get(index2, 0); + vertex2[1] = positionsAccessorData.get(index2, 1) + deltaPositionsAccessorData.get(index2, 1); + vertex2[2] = positionsAccessorData.get(index2, 2) + deltaPositionsAccessorData.get(index2, 2); + + normal0[0] = normalsAccessorData.get(index0, 0); + normal0[1] = normalsAccessorData.get(index0, 1); + normal0[2] = normalsAccessorData.get(index0, 2); + + tangent0[0] = tangentsAccessorData.get(index0, 0); + tangent0[1] = tangentsAccessorData.get(index0, 1); + tangent0[2] = tangentsAccessorData.get(index0, 2); + + MathUtils.subtract(vertex1, vertex0, edge01); + MathUtils.subtract(vertex2, vertex0, edge02); + MathUtils.cross(edge01, edge02, cross); + MathUtils.normalize(cross, normal1); + + normal2[0] = -normal1[2]; + normal2[1] = normal1[0]; + normal2[2] = normal1[1]; + + MathUtils.cross(normal1, normal2, cross); + MathUtils.normalize(cross, tangent1); + + MathUtils.subtract(normal1, normal0, normal1); + MathUtils.subtract(tangent1, tangent0, tangent1); + + normalTargetAccessorData.set(index0, 0, normal1[0]); + normalTargetAccessorData.set(index0, 1, normal1[1]); + normalTargetAccessorData.set(index0, 2, normal1[2]); + + tangentTargetAccessorData.set(index0, 0, tangent1[0]); + tangentTargetAccessorData.set(index0, 1, tangent1[1]); + tangentTargetAccessorData.set(index0, 2, tangent1[2]); + + normalTargetAccessorData.set(index1, 0, normal1[0]); + normalTargetAccessorData.set(index1, 1, normal1[1]); + normalTargetAccessorData.set(index1, 2, normal1[2]); + + tangentTargetAccessorData.set(index1, 0, tangent1[0]); + tangentTargetAccessorData.set(index1, 1, tangent1[1]); + tangentTargetAccessorData.set(index1, 2, tangent1[2]); + + normalTargetAccessorData.set(index2, 0, normal1[0]); + normalTargetAccessorData.set(index2, 1, normal1[1]); + normalTargetAccessorData.set(index2, 2, normal1[2]); + + tangentTargetAccessorData.set(index2, 0, tangent1[0]); + tangentTargetAccessorData.set(index2, 1, tangent1[1]); + tangentTargetAccessorData.set(index2, 2, tangent1[2]); + } + } + else { + positionTargetAccessorDatas.add(null); + normalTargetAccessorDatas.add(null); + tangentTargetAccessorDatas.add(null); + } + } + return isMorphableAttribute; + } + + public boolean createNormalTangentMorphTarget(List> morphTargets, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel, List normalTargetAccessorDatas, List tangentTargetAccessorDatas) { + boolean isMorphableAttribute = false; + int count = normalsAccessorModel.getCount(); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + for(Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get("NORMAL"); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); + normalTargetAccessorDatas.add(deltaNormalsAccessorData); + AccessorFloatData tangentTargetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + tangentTargetAccessorDatas.add(tangentTargetAccessorData); + float[] normal0 = new float[3]; + float[] normal1 = new float[3]; + float[] cross = new float[3]; + float[] tangent = new float[3]; + + for(int i = 0; i < count; i++) { + normal0[0] = normalsAccessorData.get(i, 0) + deltaNormalsAccessorData.get(i, 0); + normal0[1] = normalsAccessorData.get(i, 1) + deltaNormalsAccessorData.get(i, 1); + normal0[2] = normalsAccessorData.get(i, 2) + deltaNormalsAccessorData.get(i, 2); + + normal1[0] = -normal0[2]; + normal1[1] = normal0[0]; + normal1[2] = normal0[1]; + + MathUtils.cross(normal0, normal1, cross); + MathUtils.normalize(cross, tangent); + + tangentTargetAccessorData.set(i, 0, tangent[0] - tangentsAccessorData.get(i, 0)); + tangentTargetAccessorData.set(i, 1, tangent[1] - tangentsAccessorData.get(i, 1)); + tangentTargetAccessorData.set(i, 2, tangent[2] - tangentsAccessorData.get(i, 2)); + } + } + else { + normalTargetAccessorDatas.add(null); + tangentTargetAccessorDatas.add(null); + } + } + return isMorphableAttribute; + } + + public boolean createTangentMorphTarget(List> morphTargets, List targetAccessorDatas, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel, String texcoordsAccessorName, AccessorModel tangentsAccessorModel) { + boolean isMorphableAttribute = false; + int count = positionsAccessorModel.getCount(); + int numFaces = count / 3; + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); + for(Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get("POSITION"); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); + accessorModel = morphTarget.get("NORMAL"); + if(accessorModel != null) { + AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); + accessorModel = morphTarget.get(texcoordsAccessorName); + if(accessorModel != null) { + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + else { + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + } + else { + accessorModel = morphTarget.get(texcoordsAccessorName); + if(accessorModel != null) { + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + else { + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + } + continue; + } + accessorModel = morphTarget.get("NORMAL"); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorFloatData deltaNormalsAccessorData = AccessorDatas.createFloat(accessorModel); + accessorModel = morphTarget.get(texcoordsAccessorName); + if(accessorModel != null) { + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + else { + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + continue; + } + accessorModel = morphTarget.get(texcoordsAccessorName); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + continue; + } + targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public boolean createTangentMorphTarget(List> morphTargets, List targetAccessorDatas, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel texcoordsAccessorModel, String texcoordsAccessorName, AccessorModel tangentsAccessorModel, List normalTargetAccessorDatas) { + boolean isMorphableAttribute = false; + int count = positionsAccessorModel.getCount(); + int numFaces = count / 3; + AccessorFloatData positionsAccessorData = AccessorDatas.createFloat(positionsAccessorModel); + AccessorFloatData normalsAccessorData = AccessorDatas.createFloat(normalsAccessorModel); + AccessorFloatData tangentsAccessorData = AccessorDatas.createFloat(tangentsAccessorModel); + AccessorData texcoordsAccessorData = AccessorDatas.create(texcoordsAccessorModel); + Iterator iterator = normalTargetAccessorDatas.iterator(); + for(Map morphTarget : morphTargets) { + AccessorFloatData deltaNormalsAccessorData = iterator.next(); + AccessorModel accessorModel = morphTarget.get("POSITION"); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorFloatData deltaPositionsAccessorData = AccessorDatas.createFloat(accessorModel); + accessorModel = morphTarget.get(texcoordsAccessorName); + if(accessorModel != null) { + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + else { + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0) + deltaPositionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1) + deltaPositionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2) + deltaPositionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0) + deltaNormalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1) + deltaNormalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2) + deltaNormalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + } + continue; + } + accessorModel = morphTarget.get(texcoordsAccessorName); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData targetAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC3, "")); + targetAccessorDatas.add(targetAccessorData); + AccessorData deltaTexcoordsAccessorData = AccessorDatas.create(accessorModel); + MikktspaceTangentGenerator.genTangSpaceDefault(new MikkTSpaceContext() { + + @Override + public int getNumFaces() { + return numFaces; + } + + @Override + public int getNumVerticesOfFace(int face) { + return 3; + } + + @Override + public void getPosition(float[] posOut, int face, int vert) { + int index = (face * 3) + vert; + posOut[0] = positionsAccessorData.get(index, 0); + posOut[1] = positionsAccessorData.get(index, 1); + posOut[2] = positionsAccessorData.get(index, 2); + } + + @Override + public void getNormal(float[] normOut, int face, int vert) { + int index = (face * 3) + vert; + normOut[0] = normalsAccessorData.get(index, 0); + normOut[1] = normalsAccessorData.get(index, 1); + normOut[2] = normalsAccessorData.get(index, 2); + } + + @Override + public void getTexCoord(float[] texOut, int face, int vert) { + int index = (face * 3) + vert; + texOut[0] = texcoordsAccessorData.getFloat(index, 0) + deltaTexcoordsAccessorData.getFloat(index, 0); + texOut[1] = texcoordsAccessorData.getFloat(index, 1) + deltaTexcoordsAccessorData.getFloat(index, 1); + } + + @Override + public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) { + int index = (face * 3) + vert; + tangentsAccessorData.set(index, 0, tangent[0] - tangentsAccessorData.get(index, 0)); + tangentsAccessorData.set(index, 1, tangent[1] - tangentsAccessorData.get(index, 1)); + tangentsAccessorData.set(index, 2, tangent[2] - tangentsAccessorData.get(index, 2)); + } + + @Override + public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) { + //Do nothing + } + + }); + continue; + } + targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public boolean createColorMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { + boolean isMorphableAttribute = false; + for(Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get(attributeName); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData morphAccessorData = colorsMorphTargetAccessorModelToAccessorData.get(accessorModel); + if(morphAccessorData == null) { + if(accessorModel.getElementType() == ElementType.VEC3) { + int count = accessorModel.getCount(); + morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, "")); + AccessorData accessorData = AccessorDatas.create(accessorModel); + for(int i = 0; i < count; i++) { + morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + morphAccessorData.set(i, 2, accessorData.getFloat(i, 2)); + morphAccessorData.set(i, 3, 0.0F); + } + } + else if(accessorModel.getComponentDataType() != float.class) { + int count = accessorModel.getCount(); + morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, "")); + AccessorData accessorData = AccessorDatas.create(accessorModel); + for(int i = 0; i < count; i++) { + morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + morphAccessorData.set(i, 2, accessorData.getFloat(i, 2)); + morphAccessorData.set(i, 3, accessorData.getFloat(i, 3)); + } + } + else { + morphAccessorData = AccessorDatas.createFloat(accessorModel); + } + colorsMorphTargetAccessorModelToAccessorData.put(accessorModel, morphAccessorData); + } + targetAccessorDatas.add(morphAccessorData); + } + else targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public boolean createTexcoordMorphTarget(List> morphTargets, List targetAccessorDatas, String attributeName) { + boolean isMorphableAttribute = false; + for(Map morphTarget : morphTargets) { + AccessorModel accessorModel = morphTarget.get(attributeName); + if(accessorModel != null) { + isMorphableAttribute = true; + AccessorFloatData morphAccessorData = texcoordsMorphTargetAccessorModelToAccessorData.get(accessorModel); + if(morphAccessorData == null) { + if(accessorModel.getComponentDataType() != float.class) { + int count = accessorModel.getCount(); + morphAccessorData = AccessorDatas.createFloat(AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC2, "")); + AccessorData accessorData = AccessorDatas.create(accessorModel); + for(int i = 0; i < count; i++) { + morphAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + morphAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + } + } + else { + morphAccessorData = AccessorDatas.createFloat(accessorModel); + } + texcoordsMorphTargetAccessorModelToAccessorData.put(accessorModel, morphAccessorData); + } + targetAccessorDatas.add(morphAccessorData); + } + else targetAccessorDatas.add(null); + } + return isMorphableAttribute; + } + + public void bindVec3FloatMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + AccessorFloatData baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + AccessorFloatData morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + ByteBuffer morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + + int glBufferView = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); + + float weights[] = new float[targetAccessorDatas.size()]; + int numComponents = 3; + int numElements = morphedAccessorData.getNumElements(); + + List morphingCommands = new ArrayList(numElements * numComponents); + for(int element = 0; element < numElements; element++) { + for(int component = 0; component < numComponents; component++) { + int e = element; + int c = component; + morphingCommands.add(() -> { + float r = baseAccessorData.get(e, c); + for(int i = 0; i < weights.length; i++) { + AccessorFloatData target = targetAccessorDatas.get(i); + if(target != null) { + r += weights[i] * target.get(e, c); + } + } + morphedAccessorData.set(e, c, r); + }); + } + } + + command.add(() -> { + if(nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); + else if(meshModel.getWeights() != null) System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); + + morphingCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); + }); + } + + public AccessorModel bindColorMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { + AccessorFloatData baseAccessorData; + AccessorFloatData morphedAccessorData; + ByteBuffer morphedBufferViewData; + + if(baseAccessorModel.getComponentDataType() != float.class) { + int count = baseAccessorModel.getCount(); + AccessorData accessorData = AccessorDatas.create(baseAccessorModel); + baseAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC4, ""); + baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + for(int i = 0; i < count; i++) { + baseAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + baseAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + baseAccessorData.set(i, 2, accessorData.getFloat(i, 2)); + baseAccessorData.set(i, 3, accessorData.getFloat(i, 3)); + } + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + } + else { + baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + } + + int glBufferView = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); + + float weights[] = new float[targetAccessorDatas.size()]; + int numComponents = 4; + int numElements = morphedAccessorData.getNumElements(); + + List morphingCommands = new ArrayList(numElements * numComponents); + for(int element = 0; element < numElements; element++) { + for(int component = 0; component < numComponents; component++) { + int e = element; + int c = component; + morphingCommands.add(() -> { + float r = baseAccessorData.get(e, c); + for(int i = 0; i < weights.length; i++) { + AccessorFloatData target = targetAccessorDatas.get(i); + if(target != null) { + r += weights[i] * target.get(e, c); + } + } + morphedAccessorData.set(e, c, r); + }); + } + } + + command.add(() -> { + if(nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); + else if(meshModel.getWeights() != null) System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); + + morphingCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); + }); + return baseAccessorModel; + } + + public AccessorModel bindTexcoordMorphed(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, List command, AccessorModel baseAccessorModel, List targetAccessorDatas) { + AccessorFloatData baseAccessorData; + AccessorFloatData morphedAccessorData; + ByteBuffer morphedBufferViewData; + + if(baseAccessorModel.getComponentDataType() != float.class) { + int count = baseAccessorModel.getCount(); + AccessorData accessorData = AccessorDatas.create(baseAccessorModel); + baseAccessorModel = AccessorModelCreation.createAccessorModel(GL11.GL_FLOAT, count, ElementType.VEC2, ""); + baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + for(int i = 0; i < count; i++) { + baseAccessorData.set(i, 0, accessorData.getFloat(i, 0)); + baseAccessorData.set(i, 1, accessorData.getFloat(i, 1)); + } + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + } + else { + baseAccessorData = AccessorDatas.createFloat(baseAccessorModel); + AccessorModel morphedAccessorModel = AccessorModelCreation.instantiate(baseAccessorModel, ""); + morphedAccessorData = AccessorDatas.createFloat(morphedAccessorModel); + morphedBufferViewData = morphedAccessorModel.getBufferViewModel().getBufferViewData(); + } + + int glBufferView = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(glBufferView)); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, morphedBufferViewData, GL15.GL_STATIC_DRAW); + + float weights[] = new float[targetAccessorDatas.size()]; + int numComponents = 2; + int numElements = morphedAccessorData.getNumElements(); + + List morphingCommands = new ArrayList(numElements * numComponents); + for(int element = 0; element < numElements; element++) { + for(int component = 0; component < numComponents; component++) { + int e = element; + int c = component; + morphingCommands.add(() -> { + float r = baseAccessorData.get(e, c); + for(int i = 0; i < weights.length; i++) { + AccessorFloatData target = targetAccessorDatas.get(i); + if(target != null) { + r += weights[i] * target.get(e, c); + } + } + morphedAccessorData.set(e, c, r); + }); + } + } + + command.add(() -> { + if(nodeModel.getWeights() != null) System.arraycopy(nodeModel.getWeights(), 0, weights, 0, weights.length); + else if(meshModel.getWeights() != null) System.arraycopy(meshModel.getWeights(), 0, weights, 0, weights.length); + + morphingCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, glBufferView); + GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, morphedBufferViewData); + }); + return baseAccessorModel; + } + + protected static float[] findGlobalTransform(NodeModel nodeModel) { + float[] found = NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.get(nodeModel); + if(found != null) { + return found; + } + else { + List pathToNode = new ArrayList(); + pathToNode.add(nodeModel); + nodeModel = nodeModel.getParent(); + while(nodeModel != null) { + found = NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.get(nodeModel); + if(found != null) { + int i = pathToNode.size() - 1; + do { + nodeModel = pathToNode.get(i); + float[] transform = DefaultNodeModel.computeLocalTransform(nodeModel, null); + MathUtils.mul4x4(found, transform, transform); + NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.put(nodeModel, transform); + found = transform; + } + while(--i >= 0); + return found; + } + else { + pathToNode.add(nodeModel); + nodeModel = nodeModel.getParent(); + } + } + int i = pathToNode.size() - 1; + nodeModel = pathToNode.get(i); + found = DefaultNodeModel.computeLocalTransform(nodeModel, null); + while(--i >= 0) { + nodeModel = pathToNode.get(i); + float[] transform = DefaultNodeModel.computeLocalTransform(nodeModel, null); + MathUtils.mul4x4(found, transform, transform); + NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.put(nodeModel, transform); + found = transform; + } + return found; + } + } + + /** + * Put the given values into a direct FloatBuffer and return it. + * The returned buffer may always be a slice of the same instance. + * This method is supposed to be called only from the OpenGL thread. + * + * @param value The value + * @return The FloatBuffer + */ + protected static FloatBuffer putFloatBuffer(float value[]) + { + int total = value.length; + if (uniformFloatBuffer == null || uniformFloatBuffer.capacity() < total) + { + uniformFloatBuffer = BufferUtils.createFloatBuffer(total); + } + uniformFloatBuffer.position(0); + uniformFloatBuffer.limit(uniformFloatBuffer.capacity()); + uniformFloatBuffer.put(value); + uniformFloatBuffer.flip(); + return uniformFloatBuffer; + } + + public static void setCurrentPose(Matrix4f currentPose) { + CURRENT_POSE = currentPose; + } + + public static void setCurrentNormal(Matrix3f currentNormal) { + CURRENT_NORMAL = currentNormal; + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL30.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL30.java index 91d259b..9d701a6 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL30.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL30.java @@ -1,109 +1,118 @@ package com.modularmods.mcgltf; -import de.javagl.jgltf.model.*; -import org.apache.commons.lang3.tuple.Triple; - import java.util.ArrayList; import java.util.List; -public class RenderedGltfModelGL30 extends RenderedGltfModel { - - public RenderedGltfModelGL30(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for (SceneModel sceneModel : sceneModels) { - RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL30(); - renderedGltfScenes.add(renderedGltfScene); - - for (NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if (commands == null) { - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(null, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } else { - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List vanillaRenderCommands, List shaderModRenderCommands) { - ArrayList vanillaNodeRenderCommands = new ArrayList(); - ArrayList shaderModNodeRenderCommands = new ArrayList(); - SkinModel skinModel = nodeModel.getSkinModel(); - if (skinModel != null) { - int jointCount = skinModel.getJoints().size(); - - float[][] transforms = new float[jointCount][]; - float[] invertNodeTransform = new float[16]; - float[] bindShapeMatrix = new float[16]; - - List jointMatricesTransformCommands = new ArrayList(jointCount); - for (int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - }); - } - - Runnable jointMatricesTransformCommand = () -> { - for (int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - }; - vanillaNodeRenderCommands.add(jointMatricesTransformCommand); - shaderModNodeRenderCommands.add(jointMatricesTransformCommand); +import org.apache.commons.lang3.tuple.Triple; - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } else { - if (!nodeModel.getMeshModels().isEmpty()) { - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } - nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); - if (!vanillaNodeRenderCommands.isEmpty()) { - vanillaRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformVanilla(nodeModel); +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.MathUtils; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.SceneModel; +import de.javagl.jgltf.model.SkinModel; - vanillaNodeRenderCommands.forEach(Runnable::run); - } - }); - shaderModRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformShaderMod(nodeModel); +public class RenderedGltfModelGL30 extends RenderedGltfModel { - shaderModNodeRenderCommands.forEach(Runnable::run); - } - }); - } - } + public RenderedGltfModelGL30(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for(SceneModel sceneModel : sceneModels) { + RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL30(); + renderedGltfScenes.add(renderedGltfScene); + + for(NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if(commands == null) { + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(null, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } + else { + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List vanillaRenderCommands, List shaderModRenderCommands) { + ArrayList vanillaNodeRenderCommands = new ArrayList(); + ArrayList shaderModNodeRenderCommands = new ArrayList(); + SkinModel skinModel = nodeModel.getSkinModel(); + if(skinModel != null) { + int jointCount = skinModel.getJoints().size(); + + float[][] transforms = new float[jointCount][]; + float[] invertNodeTransform = new float[16]; + float[] bindShapeMatrix = new float[16]; + + List jointMatricesTransformCommands = new ArrayList(jointCount); + for(int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + }); + } + + Runnable jointMatricesTransformCommand = () -> { + for(int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + }; + vanillaNodeRenderCommands.add(jointMatricesTransformCommand); + shaderModNodeRenderCommands.add(jointMatricesTransformCommand); + + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + else { + if(!nodeModel.getMeshModels().isEmpty()) { + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } + nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); + if(!vanillaNodeRenderCommands.isEmpty()) { + vanillaRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformVanilla(nodeModel); + + vanillaNodeRenderCommands.forEach(Runnable::run); + } + }); + shaderModRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformShaderMod(nodeModel); + + shaderModNodeRenderCommands.forEach(Runnable::run); + } + }); + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL33.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL33.java index fd8a7b8..c75940d 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL33.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL33.java @@ -1,6 +1,9 @@ package com.modularmods.mcgltf; -import de.javagl.jgltf.model.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import org.lwjgl.opengl.GL11; @@ -8,1123 +11,1156 @@ import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import de.javagl.jgltf.model.AccessorFloatData; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.SceneModel; public class RenderedGltfModelGL33 extends RenderedGltfModelGL40 { - public RenderedGltfModelGL33(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for (SceneModel sceneModel : sceneModels) { - RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL33(); - renderedGltfScenes.add(renderedGltfScene); - - for (NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if (commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - @Override - protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if (indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } else { - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - } - - protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - List> morphTargets = meshPrimitiveModel.getTargets(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - AccessorModel indices = meshPrimitiveModel.getIndices(); - if (indices != null) { - int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); - int count = indices.getCount(); - int type = indices.getComponentType(); - int offset = indices.getByteOffset(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); - GL11.glDrawElements(mode, count, type, offset); - }); - } else { - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - } - - @Override - protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - AccessorModel normalsAccessorModel = attributes.get("NORMAL"); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - @Override - protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - } - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - if (texcoordsAccessorModel != null) { - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - } - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } - - @Override - protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { - int glVertexArraySkinning = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); - GL30.glBindVertexArray(glVertexArraySkinning); - - Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); - Map attributes = unindexed.getLeft(); - List> morphTargets = unindexed.getRight(); - - AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); - bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_joint, - jointsAccessorModel.getElementType().getNumComponents(), - jointsAccessorModel.getComponentType(), - false, - jointsAccessorModel.getByteStride(), - jointsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_joint); - - AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); - bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_weight, - weightsAccessorModel.getElementType().getNumComponents(), - weightsAccessorModel.getComponentType(), - false, - weightsAccessorModel.getByteStride(), - weightsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_weight); - - AccessorModel positionsAccessorModel = attributes.get("POSITION"); - AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); - List targetAccessorDatas = new ArrayList(morphTargets.size()); - List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); - if (createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - } else { - bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_position, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - positionsAccessorModel.getByteStride(), - positionsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_position); - - bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); - GL20.glVertexAttribPointer( - skinning_normal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - normalsAccessorModel.getByteStride(), - normalsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_normal); - } - - AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); - AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { - bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - skinning_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - tangentsAccessorModel.getByteStride(), - tangentsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(skinning_tangent); - - int positionBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int normalBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int tangentBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); - GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); - GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); - - int pointCount = positionsAccessorModel.getCount(); - skinningCommand.add(() -> { - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); - GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); - - GL30.glBeginTransformFeedback(GL11.GL_POINTS); - GL30.glBindVertexArray(glVertexArraySkinning); - GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); - GL30.glEndTransformFeedback(); - }); - - int glVertexArray = GL30.glGenVertexArrays(); - gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); - GL30.glBindVertexArray(glVertexArray); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); - GL20.glVertexAttribPointer( - vaPosition, - positionsAccessorModel.getElementType().getNumComponents(), - positionsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaPosition); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); - GL20.glVertexAttribPointer( - vaNormal, - normalsAccessorModel.getElementType().getNumComponents(), - normalsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(vaNormal); - - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); - GL20.glVertexAttribPointer( - at_tangent, - tangentsAccessorModel.getElementType().getNumComponents(), - tangentsAccessorModel.getComponentType(), - false, - 0, - 0); - GL20.glEnableVertexAttribArray(at_tangent); - - AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); - if (colorsAccessorModel != null) { - colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { - colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaColor, - colorsAccessorModel.getElementType().getNumComponents(), - colorsAccessorModel.getComponentType(), - false, - colorsAccessorModel.getByteStride(), - colorsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaColor); - } - - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - GL20.glVertexAttribPointer( - vaUV0, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(vaUV0); - - AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); - if (texcoords1AccessorModel != null) { - texcoordsAccessorModel = texcoords1AccessorModel; - targetAccessorDatas = new ArrayList(morphTargets.size()); - if (createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { - texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); - } else { - bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); - } - } - GL20.glVertexAttribPointer( - mc_midTexCoord, - texcoordsAccessorModel.getElementType().getNumComponents(), - texcoordsAccessorModel.getComponentType(), - false, - texcoordsAccessorModel.getByteStride(), - texcoordsAccessorModel.getByteOffset()); - GL20.glEnableVertexAttribArray(mc_midTexCoord); - - int mode = meshPrimitiveModel.getMode(); - renderCommand.add(() -> { - GL30.glBindVertexArray(glVertexArray); - GL11.glDrawArrays(mode, 0, pointCount); - }); - } + public RenderedGltfModelGL33(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for(SceneModel sceneModel : sceneModels) { + RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL33(); + renderedGltfScenes.add(renderedGltfScene); + + for(NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if(commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } + else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + @Override + protected void processMeshPrimitiveModelIncludedTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel, AccessorModel tangentsAccessorModel) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "TANGENT")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if(indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } + else { + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + } + + protected void processMeshPrimitiveModelSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand, Map attributes, AccessorModel positionsAccessorModel, AccessorModel normalsAccessorModel) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + List> morphTargets = meshPrimitiveModel.getTargets(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createNormalTangentMorphTarget(morphTargets, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + AccessorModel indices = meshPrimitiveModel.getIndices(); + if(indices != null) { + int glIndicesBufferView = obtainElementArrayBuffer(gltfRenderData, indices.getBufferViewModel()); + int count = indices.getCount(); + int type = indices.getComponentType(); + int offset = indices.getByteOffset(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, glIndicesBufferView); + GL11.glDrawElements(mode, count, type, offset); + }); + } + else { + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + } + + @Override + protected void processMeshPrimitiveModelMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "POSITION")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + AccessorModel normalsAccessorModel = attributes.get("NORMAL"); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createMorphTarget(morphTargets, targetAccessorDatas, "NORMAL")) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(meshPrimitiveModel, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + @Override + protected void processMeshPrimitiveModelFlatNormalSimpleTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + List tangentTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createPositionNormalTangentMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, tangentsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas, tangentTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, tangentTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + } + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + if(texcoordsAccessorModel != null) { + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + } + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } + + @Override + protected void processMeshPrimitiveModelFlatNormalMikkTangent(List gltfRenderData, NodeModel nodeModel, MeshModel meshModel, MeshPrimitiveModel meshPrimitiveModel, List renderCommand, List skinningCommand) { + int glVertexArraySkinning = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArraySkinning)); + GL30.glBindVertexArray(glVertexArraySkinning); + + Pair, List>> unindexed = obtainUnindexed(meshPrimitiveModel); + Map attributes = unindexed.getLeft(); + List> morphTargets = unindexed.getRight(); + + AccessorModel jointsAccessorModel = attributes.get("JOINTS_0"); + bindArrayBufferViewModel(gltfRenderData, jointsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_joint, + jointsAccessorModel.getElementType().getNumComponents(), + jointsAccessorModel.getComponentType(), + false, + jointsAccessorModel.getByteStride(), + jointsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_joint); + + AccessorModel weightsAccessorModel = attributes.get("WEIGHTS_0"); + bindArrayBufferViewModel(gltfRenderData, weightsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_weight, + weightsAccessorModel.getElementType().getNumComponents(), + weightsAccessorModel.getComponentType(), + false, + weightsAccessorModel.getByteStride(), + weightsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_weight); + + AccessorModel positionsAccessorModel = attributes.get("POSITION"); + AccessorModel normalsAccessorModel = obtainNormalsAccessorModel(positionsAccessorModel); + List targetAccessorDatas = new ArrayList(morphTargets.size()); + List normalTargetAccessorDatas = new ArrayList(morphTargets.size()); + if(createPositionNormalMorphTarget(morphTargets, positionsAccessorModel, normalsAccessorModel, targetAccessorDatas, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, positionsAccessorModel, targetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, normalsAccessorModel, normalTargetAccessorDatas); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + } + else { + bindArrayBufferViewModel(gltfRenderData, positionsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_position, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + positionsAccessorModel.getByteStride(), + positionsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_position); + + bindArrayBufferViewModel(gltfRenderData, normalsAccessorModel.getBufferViewModel()); + GL20.glVertexAttribPointer( + skinning_normal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + normalsAccessorModel.getByteStride(), + normalsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_normal); + } + + AccessorModel texcoordsAccessorModel = attributes.get("TEXCOORD_0"); + AccessorModel tangentsAccessorModel = obtainTangentsAccessorModel(normalsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTangentMorphTarget(morphTargets, targetAccessorDatas, positionsAccessorModel, normalsAccessorModel, texcoordsAccessorModel, "TEXCOORD_0", tangentsAccessorModel, normalTargetAccessorDatas)) { + bindVec3FloatMorphed(gltfRenderData, nodeModel, meshModel, skinningCommand, tangentsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, tangentsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + skinning_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + tangentsAccessorModel.getByteStride(), + tangentsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(skinning_tangent); + + int positionBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(positionBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, positionsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int normalBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(normalBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, normalsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int tangentBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(tangentBuffer)); + GL15.glBindBuffer(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentBuffer); + GL15.glBufferData(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, tangentsAccessorModel.getBufferViewModel().getByteLength(), GL15.GL_STATIC_DRAW); + + int pointCount = positionsAccessorModel.getCount(); + skinningCommand.add(() -> { + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_position, positionBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_normal, normalBuffer); + GL30.glBindBufferBase(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, skinning_out_tangent, tangentBuffer); + + GL30.glBeginTransformFeedback(GL11.GL_POINTS); + GL30.glBindVertexArray(glVertexArraySkinning); + GL11.glDrawArrays(GL11.GL_POINTS, 0, pointCount); + GL30.glEndTransformFeedback(); + }); + + int glVertexArray = GL30.glGenVertexArrays(); + gltfRenderData.add(() -> GL30.glDeleteVertexArrays(glVertexArray)); + GL30.glBindVertexArray(glVertexArray); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, positionBuffer); + GL20.glVertexAttribPointer( + vaPosition, + positionsAccessorModel.getElementType().getNumComponents(), + positionsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaPosition); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, normalBuffer); + GL20.glVertexAttribPointer( + vaNormal, + normalsAccessorModel.getElementType().getNumComponents(), + normalsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(vaNormal); + + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tangentBuffer); + GL20.glVertexAttribPointer( + at_tangent, + tangentsAccessorModel.getElementType().getNumComponents(), + tangentsAccessorModel.getComponentType(), + false, + 0, + 0); + GL20.glEnableVertexAttribArray(at_tangent); + + AccessorModel colorsAccessorModel = attributes.get("COLOR_0"); + if(colorsAccessorModel != null) { + colorsAccessorModel = obtainVec4ColorsAccessorModel(colorsAccessorModel); + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createColorMorphTarget(morphTargets, targetAccessorDatas, "COLOR_0")) { + colorsAccessorModel = bindColorMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, colorsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, colorsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaColor, + colorsAccessorModel.getElementType().getNumComponents(), + colorsAccessorModel.getComponentType(), + false, + colorsAccessorModel.getByteStride(), + colorsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaColor); + } + + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_0")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + GL20.glVertexAttribPointer( + vaUV0, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(vaUV0); + + AccessorModel texcoords1AccessorModel = attributes.get("TEXCOORD_1"); + if(texcoords1AccessorModel != null) { + texcoordsAccessorModel = texcoords1AccessorModel; + targetAccessorDatas = new ArrayList(morphTargets.size()); + if(createTexcoordMorphTarget(morphTargets, targetAccessorDatas, "TEXCOORD_1")) { + texcoordsAccessorModel = bindTexcoordMorphed(gltfRenderData, nodeModel, meshModel, renderCommand, texcoordsAccessorModel, targetAccessorDatas); + } + else { + bindArrayBufferViewModel(gltfRenderData, texcoordsAccessorModel.getBufferViewModel()); + } + } + GL20.glVertexAttribPointer( + mc_midTexCoord, + texcoordsAccessorModel.getElementType().getNumComponents(), + texcoordsAccessorModel.getComponentType(), + false, + texcoordsAccessorModel.getByteStride(), + texcoordsAccessorModel.getByteOffset()); + GL20.glEnableVertexAttribArray(mc_midTexCoord); + + int mode = meshPrimitiveModel.getMode(); + renderCommand.add(() -> { + GL30.glBindVertexArray(glVertexArray); + GL11.glDrawArrays(mode, 0, pointCount); + }); + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL40.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL40.java index f7f523b..0e77865 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL40.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfModelGL40.java @@ -1,192 +1,201 @@ package com.modularmods.mcgltf; -import de.javagl.jgltf.model.*; +import java.util.ArrayList; +import java.util.List; + import org.apache.commons.lang3.tuple.Triple; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL31; -import java.util.ArrayList; -import java.util.List; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.MathUtils; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.SceneModel; +import de.javagl.jgltf.model.SkinModel; public class RenderedGltfModelGL40 extends RenderedGltfModel { - public RenderedGltfModelGL40(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for (SceneModel sceneModel : sceneModels) { - RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL40(); - renderedGltfScenes.add(renderedGltfScene); - - for (NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if (commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - @Override - protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List skinningCommands, List vanillaRenderCommands, List shaderModRenderCommands) { - ArrayList nodeSkinningCommands = new ArrayList(); - ArrayList vanillaNodeRenderCommands = new ArrayList(); - ArrayList shaderModNodeRenderCommands = new ArrayList(); - SkinModel skinModel = nodeModel.getSkinModel(); - if (skinModel != null) { - boolean canHaveHardwareSkinning; - checkHardwareSkinning: - { - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - if (!meshPrimitiveModel.getAttributes().containsKey("JOINTS_1")) { - canHaveHardwareSkinning = true; - break checkHardwareSkinning; - } - } - } - canHaveHardwareSkinning = false; - } - - int jointCount = skinModel.getJoints().size(); - - float[][] transforms = new float[jointCount][]; - float[] invertNodeTransform = new float[16]; - float[] bindShapeMatrix = new float[16]; - - if (canHaveHardwareSkinning) { - int jointMatrixSize = jointCount * 16; - float[] jointMatrices = new float[jointMatrixSize]; - - int jointMatrixBuffer = GL15.glGenBuffers(); - gltfRenderData.add(() -> GL15.glDeleteBuffers(jointMatrixBuffer)); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, jointMatrixBuffer); - GL15.glBufferData(GL31.GL_TEXTURE_BUFFER, jointMatrixSize * Float.BYTES, GL15.GL_STATIC_DRAW); - int glTexture = GL11.glGenTextures(); - gltfRenderData.add(() -> GL11.glDeleteTextures(glTexture)); - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, glTexture); - GL31.glTexBuffer(GL31.GL_TEXTURE_BUFFER, GL30.GL_RGBA32F, jointMatrixBuffer); - - List jointMatricesTransformCommands = new ArrayList(jointCount); - for (int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - System.arraycopy(transform, 0, jointMatrices, i * 16, 16); - }); - } - - nodeSkinningCommands.add(() -> { - for (int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, jointMatrixBuffer); - GL15.glBufferSubData(GL31.GL_TEXTURE_BUFFER, 0, putFloatBuffer(jointMatrices)); - - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, glTexture); - }); - - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } else { - List jointMatricesTransformCommands = new ArrayList(jointCount); - for (int joint = 0; joint < jointCount; joint++) { - int i = joint; - float[] transform = transforms[i] = new float[16]; - float[] inverseBindMatrix = new float[16]; - jointMatricesTransformCommands.add(() -> { - MathUtils.mul4x4(invertNodeTransform, transform, transform); - skinModel.getInverseBindMatrix(i, inverseBindMatrix); - MathUtils.mul4x4(transform, inverseBindMatrix, transform); - MathUtils.mul4x4(transform, bindShapeMatrix, transform); - }); - } - - Runnable jointMatricesTransformCommand = () -> { - for (int i = 0; i < transforms.length; i++) { - System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); - } - MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); - skinModel.getBindShapeMatrix(bindShapeMatrix); - jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); - }; - vanillaNodeRenderCommands.add(jointMatricesTransformCommand); - shaderModNodeRenderCommands.add(jointMatricesTransformCommand); - - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } else { - if (!nodeModel.getMeshModels().isEmpty()) { - for (MeshModel meshModel : nodeModel.getMeshModels()) { - for (MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { - processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); - } - } - } - } - nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); - if (!nodeSkinningCommands.isEmpty()) { - // Zero-scale meshes visibility optimization - // https://github.com/KhronosGroup/glTF/pull/2059 - skinningCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - nodeSkinningCommands.forEach(Runnable::run); - } - }); - } - if (!vanillaNodeRenderCommands.isEmpty()) { - vanillaRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformVanilla(nodeModel); - - vanillaNodeRenderCommands.forEach(Runnable::run); - } - }); - shaderModRenderCommands.add(() -> { - float[] scale = nodeModel.getScale(); - if (scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { - applyTransformShaderMod(nodeModel); - - shaderModNodeRenderCommands.forEach(Runnable::run); - } - }); - } - } + public RenderedGltfModelGL40(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for(SceneModel sceneModel : sceneModels) { + RenderedGltfScene renderedGltfScene = new RenderedGltfSceneGL40(); + renderedGltfScenes.add(renderedGltfScene); + + for(NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if(commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } + else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + @Override + protected void processNodeModel(List gltfRenderData, NodeModel nodeModel, List skinningCommands, List vanillaRenderCommands, List shaderModRenderCommands) { + ArrayList nodeSkinningCommands = new ArrayList(); + ArrayList vanillaNodeRenderCommands = new ArrayList(); + ArrayList shaderModNodeRenderCommands = new ArrayList(); + SkinModel skinModel = nodeModel.getSkinModel(); + if(skinModel != null) { + boolean canHaveHardwareSkinning; + checkHardwareSkinning: { + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + if(!meshPrimitiveModel.getAttributes().containsKey("JOINTS_1")) { + canHaveHardwareSkinning = true; + break checkHardwareSkinning; + } + } + } + canHaveHardwareSkinning = false; + } + + int jointCount = skinModel.getJoints().size(); + + float[][] transforms = new float[jointCount][]; + float[] invertNodeTransform = new float[16]; + float[] bindShapeMatrix = new float[16]; + + if(canHaveHardwareSkinning) { + int jointMatrixSize = jointCount * 16; + float[] jointMatrices = new float[jointMatrixSize]; + + int jointMatrixBuffer = GL15.glGenBuffers(); + gltfRenderData.add(() -> GL15.glDeleteBuffers(jointMatrixBuffer)); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, jointMatrixBuffer); + GL15.glBufferData(GL31.GL_TEXTURE_BUFFER, jointMatrixSize * Float.BYTES, GL15.GL_STATIC_DRAW); + int glTexture = GL11.glGenTextures(); + gltfRenderData.add(() -> GL11.glDeleteTextures(glTexture)); + GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, glTexture); + GL31.glTexBuffer(GL31.GL_TEXTURE_BUFFER, GL30.GL_RGBA32F, jointMatrixBuffer); + + List jointMatricesTransformCommands = new ArrayList(jointCount); + for(int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + System.arraycopy(transform, 0, jointMatrices, i * 16, 16); + }); + } + + nodeSkinningCommands.add(() -> { + for(int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, jointMatrixBuffer); + GL15.glBufferSubData(GL31.GL_TEXTURE_BUFFER, 0, putFloatBuffer(jointMatrices)); + + GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, glTexture); + }); + + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + else { + List jointMatricesTransformCommands = new ArrayList(jointCount); + for(int joint = 0; joint < jointCount; joint++) { + int i = joint; + float[] transform = transforms[i] = new float[16]; + float[] inverseBindMatrix = new float[16]; + jointMatricesTransformCommands.add(() -> { + MathUtils.mul4x4(invertNodeTransform, transform, transform); + skinModel.getInverseBindMatrix(i, inverseBindMatrix); + MathUtils.mul4x4(transform, inverseBindMatrix, transform); + MathUtils.mul4x4(transform, bindShapeMatrix, transform); + }); + } + + Runnable jointMatricesTransformCommand = () -> { + for(int i = 0; i < transforms.length; i++) { + System.arraycopy(findGlobalTransform(skinModel.getJoints().get(i)), 0, transforms[i], 0, 16); + } + MathUtils.invert4x4(findGlobalTransform(nodeModel), invertNodeTransform); + skinModel.getBindShapeMatrix(bindShapeMatrix); + jointMatricesTransformCommands.parallelStream().forEach(Runnable::run); + }; + vanillaNodeRenderCommands.add(jointMatricesTransformCommand); + shaderModNodeRenderCommands.add(jointMatricesTransformCommand); + + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, transforms, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } + else { + if(!nodeModel.getMeshModels().isEmpty()) { + for(MeshModel meshModel : nodeModel.getMeshModels()) { + for(MeshPrimitiveModel meshPrimitiveModel : meshModel.getMeshPrimitiveModels()) { + processMeshPrimitiveModel(gltfRenderData, nodeModel, meshModel, meshPrimitiveModel, vanillaNodeRenderCommands, shaderModNodeRenderCommands); + } + } + } + } + nodeModel.getChildren().forEach((childNode) -> processNodeModel(gltfRenderData, childNode, nodeSkinningCommands, vanillaNodeRenderCommands, shaderModNodeRenderCommands)); + if(!nodeSkinningCommands.isEmpty()) { + // Zero-scale meshes visibility optimization + // https://github.com/KhronosGroup/glTF/pull/2059 + skinningCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + nodeSkinningCommands.forEach(Runnable::run); + } + }); + } + if(!vanillaNodeRenderCommands.isEmpty()) { + vanillaRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformVanilla(nodeModel); + + vanillaNodeRenderCommands.forEach(Runnable::run); + } + }); + shaderModRenderCommands.add(() -> { + float[] scale = nodeModel.getScale(); + if(scale == null || scale[0] != 0.0F || scale[1] != 0.0F || scale[2] != 0.0F) { + applyTransformShaderMod(nodeModel); + + shaderModNodeRenderCommands.forEach(Runnable::run); + } + }); + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfScene.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfScene.java index bd73535..470c83b 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfScene.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfScene.java @@ -1,114 +1,122 @@ package com.modularmods.mcgltf; -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.renderer.GameRenderer; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.lwjgl.opengl.*; - import java.util.ArrayList; import java.util.List; -public class RenderedGltfScene { - - public final List skinningCommands = new ArrayList(); - - public final List vanillaRenderCommands = new ArrayList(); - - public final List shaderModRenderCommands = new ArrayList(); - - public void renderForVanilla() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - } - - RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); - int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); - GL20.glUseProgram(entitySolidProgram); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); - - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); - - RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); - - vanillaRenderCommands.forEach(Runnable::run); - - GL20.glUseProgram(currentProgram); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(currentProgram); - } - - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); - RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); - - Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); - projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); - (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.GL43; - GL13.glActiveTexture(GL13.GL_TEXTURE3); - int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); +import com.mojang.blaze3d.systems.RenderSystem; - shaderModRenderCommands.forEach(Runnable::run); +import net.minecraft.client.renderer.GameRenderer; - GL13.glActiveTexture(GL13.GL_TEXTURE3); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); +public class RenderedGltfScene { - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + public final List skinningCommands = new ArrayList(); + + public final List vanillaRenderCommands = new ArrayList(); + + public final List shaderModRenderCommands = new ArrayList(); + + public void renderForVanilla() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + } + + RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); + int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); + GL20.glUseProgram(entitySolidProgram); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); + + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); + + RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); + + vanillaRenderCommands.forEach(Runnable::run); + + GL20.glUseProgram(currentProgram); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); + RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); + + Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); + projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); + (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + shaderModRenderCommands.forEach(Runnable::run); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL30.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL30.java index f005fc9..87ab27e 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL30.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL30.java @@ -1,90 +1,92 @@ package com.modularmods.mcgltf; -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.renderer.GameRenderer; import org.joml.Matrix4f; import org.joml.Vector3f; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL20; -public class RenderedGltfSceneGL30 extends RenderedGltfScene { - - @Override - public void renderForVanilla() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); - int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); - GL20.glUseProgram(entitySolidProgram); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); - - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); - - RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); - - vanillaRenderCommands.forEach(Runnable::run); - - GL20.glUseProgram(currentProgram); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); - RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); - - Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); - projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); - (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); +import com.mojang.blaze3d.systems.RenderSystem; - shaderModRenderCommands.forEach(Runnable::run); +import net.minecraft.client.renderer.GameRenderer; - GL13.glActiveTexture(GL13.GL_TEXTURE3); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); +public class RenderedGltfSceneGL30 extends RenderedGltfScene { - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); + int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); + GL20.glUseProgram(entitySolidProgram); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); + + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); + + RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); + + vanillaRenderCommands.forEach(Runnable::run); + + GL20.glUseProgram(currentProgram); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); + RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); + + Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); + projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); + (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + shaderModRenderCommands.forEach(Runnable::run); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL33.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL33.java index 0109629..71b4bf2 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL33.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL33.java @@ -1,105 +1,112 @@ package com.modularmods.mcgltf; -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.renderer.GameRenderer; import org.joml.Matrix4f; import org.joml.Vector3f; -import org.lwjgl.opengl.*; - -public class RenderedGltfSceneGL33 extends RenderedGltfScene { - - @Override - public void renderForVanilla() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - } - - RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); - int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); - GL20.glUseProgram(entitySolidProgram); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL31; - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); - - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); - - RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); - - vanillaRenderCommands.forEach(Runnable::run); - - GL20.glUseProgram(currentProgram); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(currentProgram); - } - - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); - RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); - - Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); - projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); - (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); +import com.mojang.blaze3d.systems.RenderSystem; - shaderModRenderCommands.forEach(Runnable::run); +import net.minecraft.client.renderer.GameRenderer; - GL13.glActiveTexture(GL13.GL_TEXTURE3); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); +public class RenderedGltfSceneGL33 extends RenderedGltfScene { - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + } + + RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); + int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); + GL20.glUseProgram(entitySolidProgram); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); + + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); + + RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); + + vanillaRenderCommands.forEach(Runnable::run); + + GL20.glUseProgram(currentProgram); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); + RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); + + Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); + projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); + (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + shaderModRenderCommands.forEach(Runnable::run); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL40.java b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL40.java index 8982854..d49bb86 100644 --- a/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL40.java +++ b/src/main/java/com/modularmods/mcgltf/RenderedGltfSceneGL40.java @@ -1,107 +1,115 @@ package com.modularmods.mcgltf; -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.renderer.GameRenderer; import org.joml.Matrix4f; import org.joml.Vector3f; -import org.lwjgl.opengl.*; - -public class RenderedGltfSceneGL40 extends RenderedGltfScene { - - @Override - public void renderForVanilla() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - } - - RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); - int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); - GL20.glUseProgram(entitySolidProgram); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); - - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL31; +import org.lwjgl.opengl.GL40; - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); - RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); - - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); - GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); - - RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); - - vanillaRenderCommands.forEach(Runnable::run); - - GL20.glUseProgram(currentProgram); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(currentProgram); - } - - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); - RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); - - Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); - projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); - (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); - - GL13.glActiveTexture(GL13.GL_TEXTURE3); - int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); +import com.mojang.blaze3d.systems.RenderSystem; - shaderModRenderCommands.forEach(Runnable::run); +import net.minecraft.client.renderer.GameRenderer; - GL13.glActiveTexture(GL13.GL_TEXTURE3); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); - GL13.glActiveTexture(GL13.GL_TEXTURE1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); +public class RenderedGltfSceneGL40 extends RenderedGltfScene { - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + } + + RenderedGltfModel.CURRENT_SHADER_INSTANCE = GameRenderer.getRendertypeEntitySolidShader(); + int entitySolidProgram = RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId(); + GL20.glUseProgram(entitySolidProgram); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.PROJECTION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.INVERSE_VIEW_ROTATION_MATRIX.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.set(RenderSystem.getShaderFogStart()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_START.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.set(RenderSystem.getShaderFogEnd()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_END.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_COLOR.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.FOG_SHAPE.upload(); + + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.set(1.0F, 1.0F, 1.0F, 1.0F); + RenderedGltfModel.CURRENT_SHADER_INSTANCE.COLOR_MODULATOR.upload(); + + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler0"), 0); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler1"), 1); + GL20.glUniform1i(GL20.glGetUniformLocation(entitySolidProgram, "Sampler2"), 2); + + RenderSystem.setupShaderLights(RenderedGltfModel.CURRENT_SHADER_INSTANCE); + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(RenderedGltfModel.CURRENT_SHADER_INSTANCE.LIGHT1_DIRECTION.getFloatBuffer()); + + vanillaRenderCommands.forEach(Runnable::run); + + GL20.glUseProgram(currentProgram); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "modelViewMatrix"); + RenderedGltfModel.MODEL_VIEW_MATRIX_INVERSE = GL20.glGetUniformLocation(currentProgram, "modelViewMatrixInverse"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "normalMatrix"); + + Matrix4f projectionMatrix = RenderSystem.getProjectionMatrix(); + projectionMatrix.get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrix"), false, RenderedGltfModel.BUF_FLOAT_16); + (new Matrix4f(projectionMatrix)).invert().get(RenderedGltfModel.BUF_FLOAT_16); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(currentProgram, "projectionMatrixInverse"), false, RenderedGltfModel.BUF_FLOAT_16); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + int currentTexture3 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + int currentTexture1 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + int currentTexture0 = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + shaderModRenderCommands.forEach(Runnable::run); + + GL13.glActiveTexture(GL13.GL_TEXTURE3); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture3); + GL13.glActiveTexture(GL13.GL_TEXTURE1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture1); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture0); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/CubicSplineInterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/CubicSplineInterpolatedChannel.java index 8c95898..ab1b7b9 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/CubicSplineInterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/CubicSplineInterpolatedChannel.java @@ -2,56 +2,58 @@ public abstract class CubicSplineInterpolatedChannel extends InterpolatedChannel { - /** - * The values. Each element of this array corresponds to one key - * frame time - */ - protected final float[][][] values; - - public CubicSplineInterpolatedChannel(float[] timesS, float[][][] values) { - super(timesS); - this.values = values; - } - - @Override - public void update(float timeS) { - float[] output = getListener(); - if (timeS <= timesS[0]) { - System.arraycopy(values[0][1], 0, output, 0, output.length); - } else if (timeS >= timesS[timesS.length - 1]) { - System.arraycopy(values[timesS.length - 1][1], 0, output, 0, output.length); - } else { - // Adapted from https://github.khronos.org/glTF-Tutorials/gltfTutorial/gltfTutorial_007_Animations.html#cubic-spline-interpolation - int previousIndex = computeIndex(timeS, timesS); - int nextIndex = previousIndex + 1; - - float local = timeS - timesS[previousIndex]; - float delta = timesS[nextIndex] - timesS[previousIndex]; - float alpha = local / delta; - float alpha2 = alpha * alpha; - float alpha3 = alpha2 * alpha; - - float aa = 2 * alpha3 - 3 * alpha2 + 1; - float ab = alpha3 - 2 * alpha2 + alpha; - float ac = -2 * alpha3 + 3 * alpha2; - float ad = alpha3 - alpha2; - - float[][] previous = values[previousIndex]; - float[][] next = values[nextIndex]; - - float[] previousPoint = previous[1]; - float[] nextPoint = next[1]; - float[] previousOutputTangent = previous[2]; - float[] nextInputTangent = next[0]; - - for (int i = 0; i < output.length; i++) { - float p = previousPoint[i]; - float pt = previousOutputTangent[i] * delta; - float n = nextPoint[i]; - float nt = nextInputTangent[i] * delta; - output[i] = aa * p + ab * pt + ac * n + ad * nt; - } - } - } + /** + * The values. Each element of this array corresponds to one key + * frame time + */ + protected final float[][][] values; + + public CubicSplineInterpolatedChannel(float[] timesS, float[][][] values) { + super(timesS); + this.values = values; + } + + @Override + public void update(float timeS) { + float[] output = getListener(); + if(timeS <= timesS[0]) { + System.arraycopy(values[0][1], 0, output, 0, output.length); + } + else if(timeS >= timesS[timesS.length - 1]) { + System.arraycopy(values[timesS.length - 1][1], 0, output, 0, output.length); + } + else { + // Adapted from https://github.khronos.org/glTF-Tutorials/gltfTutorial/gltfTutorial_007_Animations.html#cubic-spline-interpolation + int previousIndex = computeIndex(timeS, timesS); + int nextIndex = previousIndex + 1; + + float local = timeS - timesS[previousIndex]; + float delta = timesS[nextIndex] - timesS[previousIndex]; + float alpha = local / delta; + float alpha2 = alpha * alpha; + float alpha3 = alpha2 * alpha; + + float aa = 2 * alpha3 - 3 * alpha2 + 1; + float ab = alpha3 - 2 * alpha2 + alpha; + float ac = -2 * alpha3 + 3 * alpha2; + float ad = alpha3 - alpha2; + + float[][] previous = values[previousIndex]; + float[][] next = values[nextIndex]; + + float[] previousPoint = previous[1]; + float[] nextPoint = next[1]; + float[] previousOutputTangent = previous[2]; + float[] nextInputTangent = next[0]; + + for(int i = 0; i < output.length; i++) { + float p = previousPoint[i]; + float pt = previousOutputTangent[i] * delta; + float n = nextPoint[i]; + float nt = nextInputTangent[i] * delta; + output[i] = aa * p + ab * pt + ac * n + ad * nt; + } + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/GltfAnimationCreator.java b/src/main/java/com/modularmods/mcgltf/animation/GltfAnimationCreator.java index 883fe0d..65d0894 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/GltfAnimationCreator.java +++ b/src/main/java/com/modularmods/mcgltf/animation/GltfAnimationCreator.java @@ -1,376 +1,384 @@ package com.modularmods.mcgltf.animation; +import java.util.ArrayList; +import java.util.List; + import com.modularmods.mcgltf.MCglTF; -import de.javagl.jgltf.model.*; + +import de.javagl.jgltf.model.AccessorData; +import de.javagl.jgltf.model.AccessorFloatData; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.AnimationModel; +import de.javagl.jgltf.model.NodeModel; import de.javagl.jgltf.model.AnimationModel.Channel; import de.javagl.jgltf.model.AnimationModel.Interpolation; import de.javagl.jgltf.model.AnimationModel.Sampler; - -import java.util.ArrayList; -import java.util.List; +import net.minecraft.client.Minecraft; public final class GltfAnimationCreator { - public static List createGltfAnimation(AnimationModel animationModel) { - List channels = animationModel.getChannels(); - List interpolatedChannels = new ArrayList(channels.size()); - for (Channel channel : channels) { - Sampler sampler = channel.getSampler(); - - AccessorModel input = sampler.getInput(); - AccessorData inputData = input.getAccessorData(); - if (!(inputData instanceof AccessorFloatData)) { - MCglTF.logger.warn("Input data is not an AccessorFloatData, but " - + inputData.getClass()); - continue; - } - AccessorFloatData inputFloatData = (AccessorFloatData) inputData; - AccessorModel output = sampler.getOutput(); - AccessorData outputData = output.getAccessorData(); - if (!(outputData instanceof AccessorFloatData)) { - MCglTF.logger.warn("Output data is not an AccessorFloatData, but " - + outputData.getClass()); - continue; - } - AccessorFloatData outputFloatData = (AccessorFloatData) outputData; - - int numKeyElements = inputFloatData.getNumElements(); - float[] keys = new float[numKeyElements]; - for (int e = 0; e < numKeyElements; e++) { - keys[e] = inputFloatData.get(e); - } - - int globalIndex = 0; - int numComponentsPerElement; - float[][] values; - float[][][] valuesCubic; - - NodeModel nodeModel = channel.getNodeModel(); - - String path = channel.getPath(); - Interpolation interpolation; - switch (path) { - case "translation": - numComponentsPerElement = outputData.getNumComponentsPerElement(); - interpolation = sampler.getInterpolation(); - switch (interpolation) { - case STEP: - values = new float[numKeyElements][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] translation = nodeModel.getTranslation(); - if (translation == null) { - translation = new float[numComponentsPerElement]; - nodeModel.setTranslation(translation); - } - return translation; - } - - }); - break; - case LINEAR: - values = new float[numKeyElements][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] translation = nodeModel.getTranslation(); - if (translation == null) { - translation = new float[numComponentsPerElement]; - nodeModel.setTranslation(translation); - } - return translation; - } - - }); - break; - case CUBICSPLINE: - valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[][] elements = valuesCubic[e]; - for (int i = 0; i < 3; i++) { - float[] components = elements[i]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - } - interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { - - @Override - protected float[] getListener() { - float[] translation = nodeModel.getTranslation(); - if (translation == null) { - translation = new float[numComponentsPerElement]; - nodeModel.setTranslation(translation); - } - return translation; - } - - }); - break; - default: - MCglTF.logger.warn("Interpolation type not supported: " + interpolation); - break; - } - break; - case "rotation": - numComponentsPerElement = outputData.getNumComponentsPerElement(); - interpolation = sampler.getInterpolation(); - switch (interpolation) { - case STEP: - values = new float[numKeyElements][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] rotation = nodeModel.getRotation(); - if (rotation == null) { - rotation = new float[numComponentsPerElement]; - nodeModel.setRotation(rotation); - } - return rotation; - } - - }); - break; - case LINEAR: - values = new float[numKeyElements][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new SphericalLinearInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] rotation = nodeModel.getRotation(); - if (rotation == null) { - rotation = new float[numComponentsPerElement]; - nodeModel.setRotation(rotation); - } - return rotation; - } - - }); - break; - case CUBICSPLINE: - valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[][] elements = valuesCubic[e]; - for (int i = 0; i < 3; i++) { - float[] components = elements[i]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - } - interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { - - @Override - protected float[] getListener() { - float[] rotation = nodeModel.getRotation(); - if (rotation == null) { - rotation = new float[numComponentsPerElement]; - nodeModel.setRotation(rotation); - } - return rotation; - } - - }); - break; - default: - MCglTF.logger.warn("Interpolation type not supported: " + interpolation); - break; - } - break; - case "scale": - numComponentsPerElement = outputData.getNumComponentsPerElement(); - interpolation = sampler.getInterpolation(); - switch (interpolation) { - case STEP: - values = new float[numKeyElements][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] scale = nodeModel.getScale(); - if (scale == null) { - scale = new float[numComponentsPerElement]; - nodeModel.setScale(scale); - } - return scale; - } - - }); - break; - case LINEAR: - values = new float[numKeyElements][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] scale = nodeModel.getScale(); - if (scale == null) { - scale = new float[numComponentsPerElement]; - nodeModel.setScale(scale); - } - return scale; - } - - }); - break; - case CUBICSPLINE: - valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[][] elements = valuesCubic[e]; - for (int i = 0; i < 3; i++) { - float[] components = elements[i]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - } - interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { - - @Override - protected float[] getListener() { - float[] scale = nodeModel.getScale(); - if (scale == null) { - scale = new float[numComponentsPerElement]; - nodeModel.setScale(scale); - } - return scale; - } - - }); - break; - default: - MCglTF.logger.warn("Interpolation type not supported: " + interpolation); - break; - } - break; - case "weights": - interpolation = sampler.getInterpolation(); - switch (interpolation) { - case STEP: - numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements; - values = new float[numKeyElements][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] weights = nodeModel.getWeights(); - if (weights == null) { - weights = new float[numComponentsPerElement]; - nodeModel.setWeights(weights); - } - return weights; - } - - }); - break; - case LINEAR: - numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements; - values = new float[numKeyElements][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[] components = values[e]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { - - @Override - protected float[] getListener() { - float[] weights = nodeModel.getWeights(); - if (weights == null) { - weights = new float[numComponentsPerElement]; - nodeModel.setWeights(weights); - } - return weights; - } - - }); - break; - case CUBICSPLINE: - numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements / 3; - valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; - for (int e = 0; e < numKeyElements; e++) { - float[][] elements = valuesCubic[e]; - for (int i = 0; i < 3; i++) { - float[] components = elements[i]; - for (int c = 0; c < numComponentsPerElement; c++) { - components[c] = outputFloatData.get(globalIndex++); - } - } - } - interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { - - @Override - protected float[] getListener() { - float[] weights = nodeModel.getWeights(); - if (weights == null) { - weights = new float[numComponentsPerElement]; - nodeModel.setWeights(weights); - } - return weights; - } - - }); - break; - default: - MCglTF.logger.warn("Interpolation type not supported: " + interpolation); - break; - } - break; - default: - MCglTF.logger.warn("Animation channel target path must be " - + "\"translation\", \"rotation\", \"scale\" or \"weights\", " - + "but is " + path); - break; - } - } - return interpolatedChannels; - } + public static List createGltfAnimation(AnimationModel animationModel) { + List channels = animationModel.getChannels(); + List interpolatedChannels = new ArrayList(channels.size()); + for(Channel channel : channels) { + Sampler sampler = channel.getSampler(); + + AccessorModel input = sampler.getInput(); + AccessorData inputData = input.getAccessorData(); + if (!(inputData instanceof AccessorFloatData)) + { + MCglTF.logger.warn("Input data is not an AccessorFloatData, but " + + inputData.getClass()); + continue; + } + AccessorFloatData inputFloatData = (AccessorFloatData)inputData; + AccessorModel output = sampler.getOutput(); + AccessorData outputData = output.getAccessorData(); + if (!(outputData instanceof AccessorFloatData)) + { + MCglTF.logger.warn("Output data is not an AccessorFloatData, but " + + outputData.getClass()); + continue; + } + AccessorFloatData outputFloatData = (AccessorFloatData)outputData; + + int numKeyElements = inputFloatData.getNumElements(); + float[] keys = new float[numKeyElements]; + for(int e = 0; e < numKeyElements; e++) { + keys[e] = inputFloatData.get(e); + } + + int globalIndex = 0; + int numComponentsPerElement; + float[][] values; + float[][][] valuesCubic; + + NodeModel nodeModel = channel.getNodeModel(); + + String path = channel.getPath(); + Interpolation interpolation; + switch(path) { + case "translation": + numComponentsPerElement = outputData.getNumComponentsPerElement(); + interpolation = sampler.getInterpolation(); + switch(interpolation) { + case STEP: + values = new float[numKeyElements][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] translation = nodeModel.getTranslation(); + if(translation == null) { + translation = new float[numComponentsPerElement]; + nodeModel.setTranslation(translation); + } + return translation; + } + + }); + break; + case LINEAR: + values = new float[numKeyElements][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] translation = nodeModel.getTranslation(); + if(translation == null) { + translation = new float[numComponentsPerElement]; + nodeModel.setTranslation(translation); + } + return translation; + } + + }); + break; + case CUBICSPLINE: + valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[][] elements = valuesCubic[e]; + for(int i = 0; i < 3; i++) { + float[] components = elements[i]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + } + interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { + + @Override + protected float[] getListener() { + float[] translation = nodeModel.getTranslation(); + if(translation == null) { + translation = new float[numComponentsPerElement]; + nodeModel.setTranslation(translation); + } + return translation; + } + + }); + break; + default: + MCglTF.logger.warn("Interpolation type not supported: " + interpolation); + break; + } + break; + case "rotation": + numComponentsPerElement = outputData.getNumComponentsPerElement(); + interpolation = sampler.getInterpolation(); + switch(interpolation) { + case STEP: + values = new float[numKeyElements][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] rotation = nodeModel.getRotation(); + if(rotation == null) { + rotation = new float[numComponentsPerElement]; + nodeModel.setRotation(rotation); + } + return rotation; + } + + }); + break; + case LINEAR: + values = new float[numKeyElements][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new SphericalLinearInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] rotation = nodeModel.getRotation(); + if(rotation == null) { + rotation = new float[numComponentsPerElement]; + nodeModel.setRotation(rotation); + } + return rotation; + } + + }); + break; + case CUBICSPLINE: + valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[][] elements = valuesCubic[e]; + for(int i = 0; i < 3; i++) { + float[] components = elements[i]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + } + interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { + + @Override + protected float[] getListener() { + float[] rotation = nodeModel.getRotation(); + if(rotation == null) { + rotation = new float[numComponentsPerElement]; + nodeModel.setRotation(rotation); + } + return rotation; + } + + }); + break; + default: + MCglTF.logger.warn("Interpolation type not supported: " + interpolation); + break; + } + break; + case "scale": + numComponentsPerElement = outputData.getNumComponentsPerElement(); + interpolation = sampler.getInterpolation(); + switch(interpolation) { + case STEP: + values = new float[numKeyElements][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] scale = nodeModel.getScale(); + if(scale == null) { + scale = new float[numComponentsPerElement]; + nodeModel.setScale(scale); + } + return scale; + } + + }); + break; + case LINEAR: + values = new float[numKeyElements][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] scale = nodeModel.getScale(); + if(scale == null) { + scale = new float[numComponentsPerElement]; + nodeModel.setScale(scale); + } + return scale; + } + + }); + break; + case CUBICSPLINE: + valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[][] elements = valuesCubic[e]; + for(int i = 0; i < 3; i++) { + float[] components = elements[i]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + } + interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { + + @Override + protected float[] getListener() { + float[] scale = nodeModel.getScale(); + if(scale == null) { + scale = new float[numComponentsPerElement]; + nodeModel.setScale(scale); + } + return scale; + } + + }); + break; + default: + MCglTF.logger.warn("Interpolation type not supported: " + interpolation); + break; + } + break; + case "weights": + interpolation = sampler.getInterpolation(); + switch(interpolation) { + case STEP: + numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements; + values = new float[numKeyElements][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new StepInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] weights = nodeModel.getWeights(); + if(weights == null) { + weights = new float[numComponentsPerElement]; + nodeModel.setWeights(weights); + } + return weights; + } + + }); + break; + case LINEAR: + numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements; + values = new float[numKeyElements][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[] components = values[e]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + interpolatedChannels.add(new LinearInterpolatedChannel(keys, values) { + + @Override + protected float[] getListener() { + float[] weights = nodeModel.getWeights(); + if(weights == null) { + weights = new float[numComponentsPerElement]; + nodeModel.setWeights(weights); + } + return weights; + } + + }); + break; + case CUBICSPLINE: + numComponentsPerElement = outputData.getTotalNumComponents() / numKeyElements / 3; + valuesCubic = new float[numKeyElements][3][numComponentsPerElement]; + for(int e = 0; e < numKeyElements; e++) { + float[][] elements = valuesCubic[e]; + for(int i = 0; i < 3; i++) { + float[] components = elements[i]; + for(int c = 0; c < numComponentsPerElement; c++) { + components[c] = outputFloatData.get(globalIndex++); + } + } + } + interpolatedChannels.add(new CubicSplineInterpolatedChannel(keys, valuesCubic) { + + @Override + protected float[] getListener() { + float[] weights = nodeModel.getWeights(); + if(weights == null) { + weights = new float[numComponentsPerElement]; + nodeModel.setWeights(weights); + } + return weights; + } + + }); + break; + default: + MCglTF.logger.warn("Interpolation type not supported: " + interpolation); + break; + } + break; + default: + MCglTF.logger.warn("Animation channel target path must be " + + "\"translation\", \"rotation\", \"scale\" or \"weights\", " + + "but is " + path); + break; + } + } + return interpolatedChannels; + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/InterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/InterpolatedChannel.java index c255888..30ab3b4 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/InterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/InterpolatedChannel.java @@ -4,39 +4,41 @@ public abstract class InterpolatedChannel { - /** - * The key frame times, in seconds - */ - protected final float[] timesS; - - public InterpolatedChannel(float[] timesS) { - this.timesS = timesS; - } - - /** - * Compute the index of the segment that the given key belongs to. - * If the given key is smaller than the smallest or larger than - * the largest key, then 0 or keys.length-1 will be returned, - * respectively. - * - * @param key The key - * @param keys The sorted keys - * @return The index for the key - */ - public static int computeIndex(float key, float keys[]) { - int index = Arrays.binarySearch(keys, key); - if (index >= 0) { - return index; - } - return Math.max(0, -index - 2); - } - - public float[] getKeys() { - return timesS; - } - - public abstract void update(float timeS); - - protected abstract float[] getListener(); + /** + * The key frame times, in seconds + */ + protected final float[] timesS; + + public InterpolatedChannel(float[] timesS) { + this.timesS = timesS; + } + + public float[] getKeys() { + return timesS; + } + + public abstract void update(float timeS); + + protected abstract float[] getListener(); + + /** + * Compute the index of the segment that the given key belongs to. + * If the given key is smaller than the smallest or larger than + * the largest key, then 0 or keys.length-1 will be returned, + * respectively. + * + * @param key The key + * @param keys The sorted keys + * @return The index for the key + */ + public static int computeIndex(float key, float keys[]) + { + int index = Arrays.binarySearch(keys, key); + if (index >= 0) + { + return index; + } + return Math.max(0, -index - 2); + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/LinearInterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/LinearInterpolatedChannel.java index 7d5fbfd..f7bce13 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/LinearInterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/LinearInterpolatedChannel.java @@ -2,41 +2,43 @@ public abstract class LinearInterpolatedChannel extends InterpolatedChannel { - /** - * The values. Each element of this array corresponds to one key - * frame time - */ - protected final float[][] values; - - public LinearInterpolatedChannel(float[] timesS, float[][] values) { - super(timesS); - this.values = values; - } - - @Override - public void update(float timeS) { - float[] output = getListener(); - if (timeS <= timesS[0]) { - System.arraycopy(values[0], 0, output, 0, output.length); - } else if (timeS >= timesS[timesS.length - 1]) { - System.arraycopy(values[timesS.length - 1], 0, output, 0, output.length); - } else { - int previousIndex = computeIndex(timeS, timesS); - int nextIndex = previousIndex + 1; - - float local = timeS - timesS[previousIndex]; - float delta = timesS[nextIndex] - timesS[previousIndex]; - float alpha = local / delta; - - float[] previousPoint = values[previousIndex]; - float[] nextPoint = values[nextIndex]; - - for (int i = 0; i < output.length; i++) { - float p = previousPoint[i]; - float n = nextPoint[i]; - output[i] = p + alpha * (n - p); - } - } - } + /** + * The values. Each element of this array corresponds to one key + * frame time + */ + protected final float[][] values; + + public LinearInterpolatedChannel(float[] timesS, float[][] values) { + super(timesS); + this.values = values; + } + + @Override + public void update(float timeS) { + float[] output = getListener(); + if(timeS <= timesS[0]) { + System.arraycopy(values[0], 0, output, 0, output.length); + } + else if(timeS >= timesS[timesS.length - 1]) { + System.arraycopy(values[timesS.length - 1], 0, output, 0, output.length); + } + else { + int previousIndex = computeIndex(timeS, timesS); + int nextIndex = previousIndex + 1; + + float local = timeS - timesS[previousIndex]; + float delta = timesS[nextIndex] - timesS[previousIndex]; + float alpha = local / delta; + + float[] previousPoint = values[previousIndex]; + float[] nextPoint = values[nextIndex]; + + for(int i = 0; i < output.length; i++) { + float p = previousPoint[i]; + float n = nextPoint[i]; + output[i] = p + alpha * (n - p); + } + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/SphericalLinearInterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/SphericalLinearInterpolatedChannel.java index 7ed682b..d220554 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/SphericalLinearInterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/SphericalLinearInterpolatedChannel.java @@ -2,74 +2,80 @@ public abstract class SphericalLinearInterpolatedChannel extends InterpolatedChannel { - /** - * The values. Each element of this array corresponds to one key - * frame time - */ - protected final float[][] values; + /** + * The values. Each element of this array corresponds to one key + * frame time + */ + protected final float[][] values; + + public SphericalLinearInterpolatedChannel(float[] timesS, float[][] values) { + super(timesS); + this.values = values; + } + + @Override + public void update(float timeS) { + float[] output = getListener(); + if(timeS <= timesS[0]) { + System.arraycopy(values[0], 0, output, 0, output.length); + } + else if(timeS >= timesS[timesS.length - 1]) { + System.arraycopy(values[timesS.length - 1], 0, output, 0, output.length); + } + else { + int previousIndex = computeIndex(timeS, timesS); + int nextIndex = previousIndex + 1; + + float local = timeS - timesS[previousIndex]; + float delta = timesS[nextIndex] - timesS[previousIndex]; + float alpha = local / delta; + + float[] previousPoint = values[previousIndex]; + float[] nextPoint = values[nextIndex]; + + // Adapted from javax.vecmath.Quat4f + float ax = previousPoint[0]; + float ay = previousPoint[1]; + float az = previousPoint[2]; + float aw = previousPoint[3]; + float bx = nextPoint[0]; + float by = nextPoint[1]; + float bz = nextPoint[2]; + float bw = nextPoint[3]; - public SphericalLinearInterpolatedChannel(float[] timesS, float[][] values) { - super(timesS); - this.values = values; - } - - @Override - public void update(float timeS) { - float[] output = getListener(); - if (timeS <= timesS[0]) { - System.arraycopy(values[0], 0, output, 0, output.length); - } else if (timeS >= timesS[timesS.length - 1]) { - System.arraycopy(values[timesS.length - 1], 0, output, 0, output.length); - } else { - int previousIndex = computeIndex(timeS, timesS); - int nextIndex = previousIndex + 1; - - float local = timeS - timesS[previousIndex]; - float delta = timesS[nextIndex] - timesS[previousIndex]; - float alpha = local / delta; - - float[] previousPoint = values[previousIndex]; - float[] nextPoint = values[nextIndex]; - - // Adapted from javax.vecmath.Quat4f - float ax = previousPoint[0]; - float ay = previousPoint[1]; - float az = previousPoint[2]; - float aw = previousPoint[3]; - float bx = nextPoint[0]; - float by = nextPoint[1]; - float bz = nextPoint[2]; - float bw = nextPoint[3]; - - float dot = ax * bx + ay * by + az * bz + aw * bw; - if (dot < 0) { - bx = -bx; - by = -by; - bz = -bz; - bw = -bw; - dot = -dot; - } - float epsilon = 1e-6f; - float s0, s1; - if ((1.0 - dot) > epsilon) { - float omega = (float) Math.acos(dot); - float invSinOmega = 1.0f / (float) Math.sin(omega); - s0 = (float) Math.sin((1.0 - alpha) * omega) * invSinOmega; - s1 = (float) Math.sin(alpha * omega) * invSinOmega; - } else { - s0 = 1.0f - alpha; - s1 = alpha; - } - float rx = s0 * ax + s1 * bx; - float ry = s0 * ay + s1 * by; - float rz = s0 * az + s1 * bz; - float rw = s0 * aw + s1 * bw; - - output[0] = rx; - output[1] = ry; - output[2] = rz; - output[3] = rw; - } - } + float dot = ax * bx + ay * by + az * bz + aw * bw; + if (dot < 0) + { + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + dot = -dot; + } + float epsilon = 1e-6f; + float s0, s1; + if ((1.0 - dot) > epsilon) + { + float omega = (float)Math.acos(dot); + float invSinOmega = 1.0f / (float)Math.sin(omega); + s0 = (float)Math.sin((1.0 - alpha) * omega) * invSinOmega; + s1 = (float)Math.sin(alpha * omega) * invSinOmega; + } + else + { + s0 = 1.0f - alpha; + s1 = alpha; + } + float rx = s0 * ax + s1 * bx; + float ry = s0 * ay + s1 * by; + float rz = s0 * az + s1 * bz; + float rw = s0 * aw + s1 * bw; + + output[0] = rx; + output[1] = ry; + output[2] = rz; + output[3] = rw; + } + } } diff --git a/src/main/java/com/modularmods/mcgltf/animation/StepInterpolatedChannel.java b/src/main/java/com/modularmods/mcgltf/animation/StepInterpolatedChannel.java index cc51bb5..cea61a5 100644 --- a/src/main/java/com/modularmods/mcgltf/animation/StepInterpolatedChannel.java +++ b/src/main/java/com/modularmods/mcgltf/animation/StepInterpolatedChannel.java @@ -2,21 +2,21 @@ public abstract class StepInterpolatedChannel extends InterpolatedChannel { - /** - * The values. Each element of this array corresponds to one key - * frame time - */ - protected final float[][] values; - - public StepInterpolatedChannel(float[] timesS, float[][] values) { - super(timesS); - this.values = values; - } - - @Override - public void update(float timeS) { - float[] output = getListener(); - System.arraycopy(values[computeIndex(timeS, timesS)], 0, output, 0, output.length); - } + /** + * The values. Each element of this array corresponds to one key + * frame time + */ + protected final float[][] values; + + public StepInterpolatedChannel(float[] timesS, float[][] values) { + super(timesS); + this.values = values; + } + + @Override + public void update(float timeS) { + float[] output = getListener(); + System.arraycopy(values[computeIndex(timeS, timesS)], 0, output, 0, output.length); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/IrisRenderingHook.java b/src/main/java/com/modularmods/mcgltf/iris/IrisRenderingHook.java index 2c2a777..89cedb6 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/IrisRenderingHook.java +++ b/src/main/java/com/modularmods/mcgltf/iris/IrisRenderingHook.java @@ -1,170 +1,182 @@ package com.modularmods.mcgltf.iris; +import java.util.EnumMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import net.irisshaders.batchedentityrendering.impl.WrappableRenderType; +import net.irisshaders.iris.Iris; +import net.irisshaders.iris.pipeline.WorldRenderingPhase; +import net.irisshaders.iris.pipeline.WorldRenderingPipeline; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; + import com.modularmods.mcgltf.RenderedGltfModel; import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.VertexFormat; -import net.irisshaders.batchedentityrendering.impl.WrappableRenderType; -import net.irisshaders.iris.Iris; -import net.irisshaders.iris.pipeline.WorldRenderingPhase; -import net.irisshaders.iris.pipeline.WorldRenderingPipeline; + import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShaderInstance; -import org.joml.Vector3f; -import org.lwjgl.opengl.*; - -import java.util.*; public class IrisRenderingHook { - private static final Map>> phaseRenderStateShardToCommands = new EnumMap>>(WorldRenderingPhase.class); - private static RenderStateShard currentRenderStateShard; - - public static void submitCommandForIrisRenderingByPhaseName(String phase, RenderType renderType, Runnable command) { - submitCommandForIrisRendering(WorldRenderingPhase.valueOf(phase), renderType, command); - } - - public static void submitCommandForIrisRendering(WorldRenderingPhase phase, RenderType renderType, Runnable command) { - Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); - if (renderStateShardToCommands == null) { - renderStateShardToCommands = new LinkedHashMap>(); - phaseRenderStateShardToCommands.put(phase, renderStateShardToCommands); - List commands = new LinkedList(); - renderStateShardToCommands.put(renderType, commands); - commands.add(command); - } else { - List commands = renderStateShardToCommands.get(renderType); - if (commands == null) { - commands = new LinkedList(); - renderStateShardToCommands.put(renderType, commands); - } - commands.add(command); - } - } - - public static void irisHookAfterSetupRenderState(RenderStateShard renderStateShard) { - currentRenderStateShard = ((renderStateShard instanceof WrappableRenderType) ? ((WrappableRenderType) renderStateShard).unwrap() : renderStateShard); - } - - public static void irisHookBypassBufferUploaderVextexCountCheck(BufferBuilder.RenderedBuffer renderedBuffer) { - WorldRenderingPipeline pipeline = Iris.getPipelineManager().getPipelineNullable(); - if (pipeline != null) { - WorldRenderingPhase phase = pipeline.getPhase(); - Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); - if (renderStateShardToCommands != null) { - List commands = renderStateShardToCommands.remove(currentRenderStateShard); - if (commands != null) { - ShaderInstance shaderInstance = RenderedGltfModel.CURRENT_SHADER_INSTANCE = RenderSystem.getShader(); - for (int i = 0; i < 12; ++i) { - int j = RenderSystem.getShaderTexture(i); - shaderInstance.setSampler("Sampler" + i, j); - } - if (shaderInstance.MODEL_VIEW_MATRIX != null) { - shaderInstance.MODEL_VIEW_MATRIX.set(RenderSystem.getModelViewMatrix()); - } - if (shaderInstance.PROJECTION_MATRIX != null) { - shaderInstance.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - } - if (shaderInstance.INVERSE_VIEW_ROTATION_MATRIX != null) { - shaderInstance.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); - } - if (shaderInstance.COLOR_MODULATOR != null) { - shaderInstance.COLOR_MODULATOR.set(RenderSystem.getShaderColor()); - } - if (shaderInstance.FOG_START != null) { - shaderInstance.FOG_START.set(RenderSystem.getShaderFogStart()); - } - if (shaderInstance.FOG_END != null) { - shaderInstance.FOG_END.set(RenderSystem.getShaderFogEnd()); - } - if (shaderInstance.FOG_COLOR != null) { - shaderInstance.FOG_COLOR.set(RenderSystem.getShaderFogColor()); - } - if (shaderInstance.FOG_SHAPE != null) { - shaderInstance.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); - } - if (shaderInstance.TEXTURE_MATRIX != null) { - shaderInstance.TEXTURE_MATRIX.set(RenderSystem.getTextureMatrix()); - } - if (shaderInstance.GAME_TIME != null) { - shaderInstance.GAME_TIME.set(RenderSystem.getShaderGameTime()); - } - if (shaderInstance.SCREEN_SIZE != null) { - Window window = Minecraft.getInstance().getWindow(); - shaderInstance.SCREEN_SIZE.set((float) window.getWidth(), (float) window.getHeight()); - } - if (shaderInstance.LINE_WIDTH != null) { - VertexFormat.Mode mode = renderedBuffer.drawState().mode(); - if (mode == VertexFormat.Mode.LINES || mode == VertexFormat.Mode.LINE_STRIP) { - shaderInstance.LINE_WIDTH.set(RenderSystem.getShaderLineWidth()); - } - } - RenderSystem.setupShaderLights(shaderInstance); - shaderInstance.apply(); - - setupAndRender(phase, shaderInstance, commands); - - shaderInstance.clear(); - } - } - } - } - - public static void irisHookAfterVertexBufferDraw() { - WorldRenderingPipeline pipeline = Iris.getPipelineManager().getPipelineNullable(); - if (pipeline != null) { - WorldRenderingPhase phase = pipeline.getPhase(); - Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); - if (renderStateShardToCommands != null) { - List commands = renderStateShardToCommands.remove(currentRenderStateShard); - if (commands != null) { - setupAndRender(phase, RenderedGltfModel.CURRENT_SHADER_INSTANCE = RenderSystem.getShader(), commands); - } - } - } - } - - private static void setupAndRender(WorldRenderingPhase phase, ShaderInstance shaderInstance, List commands) { - int currentVAO = GL11.glGetInteger(GL30.GL_VERTEX_ARRAY_BINDING); - int currentArrayBuffer = GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING); - int currentElementArrayBuffer = GL11.glGetInteger(GL15.GL_ELEMENT_ARRAY_BUFFER_BINDING); - - boolean currentCullFace = GL11.glGetBoolean(GL11.GL_CULL_FACE); - - int currentTextureColor = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0 + 2); - int currentTextureNormal = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); - int currentTextureSpecular = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - - try { - if (phase != WorldRenderingPhase.NONE) { - int currentProgram = shaderInstance.getId(); - RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "iris_ModelViewMat"); - RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "iris_NormalMat"); - } else { - RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(shaderInstance.LIGHT0_DIRECTION.getFloatBuffer()); - RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(shaderInstance.LIGHT1_DIRECTION.getFloatBuffer()); - } - commands.forEach(Runnable::run); - } finally { - GL20.glDisableVertexAttribArray(RenderedGltfModel.at_tangent); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureColor); - GL13.glActiveTexture(GL13.GL_TEXTURE0 + 2); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureNormal); - GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureSpecular); - } - - if (currentCullFace) GL11.glEnable(GL11.GL_CULL_FACE); - else GL11.glDisable(GL11.GL_CULL_FACE); - - GL30.glBindVertexArray(currentVAO); - GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, currentArrayBuffer); - GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, currentElementArrayBuffer); - } + private static final Map>> phaseRenderStateShardToCommands = new EnumMap>>(WorldRenderingPhase.class); + private static RenderStateShard currentRenderStateShard; + + public static void submitCommandForIrisRenderingByPhaseName(String phase, RenderType renderType, Runnable command) { + submitCommandForIrisRendering(WorldRenderingPhase.valueOf(phase), renderType, command); + } + + public static void submitCommandForIrisRendering(WorldRenderingPhase phase, RenderType renderType, Runnable command) { + Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); + if(renderStateShardToCommands == null) { + renderStateShardToCommands = new LinkedHashMap>(); + phaseRenderStateShardToCommands.put(phase, renderStateShardToCommands); + List commands = new LinkedList(); + renderStateShardToCommands.put(renderType, commands); + commands.add(command); + } + else { + List commands = renderStateShardToCommands.get(renderType); + if(commands == null) { + commands = new LinkedList(); + renderStateShardToCommands.put(renderType, commands); + } + commands.add(command); + } + } + + public static void irisHookAfterSetupRenderState(RenderStateShard renderStateShard) { + currentRenderStateShard = ((renderStateShard instanceof WrappableRenderType) ? ((WrappableRenderType)renderStateShard).unwrap() : renderStateShard); + } + + public static void irisHookBypassBufferUploaderVextexCountCheck(BufferBuilder.RenderedBuffer renderedBuffer) { + WorldRenderingPipeline pipeline = Iris.getPipelineManager().getPipelineNullable(); + if(pipeline != null) { + WorldRenderingPhase phase = pipeline.getPhase(); + Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); + if(renderStateShardToCommands != null) { + List commands = renderStateShardToCommands.remove(currentRenderStateShard); + if(commands != null) { + ShaderInstance shaderInstance = RenderedGltfModel.CURRENT_SHADER_INSTANCE = RenderSystem.getShader(); + for (int i = 0; i < 12; ++i) { + int j = RenderSystem.getShaderTexture(i); + shaderInstance.setSampler("Sampler" + i, j); + } + if (shaderInstance.MODEL_VIEW_MATRIX != null) { + shaderInstance.MODEL_VIEW_MATRIX.set(RenderSystem.getModelViewMatrix()); + } + if (shaderInstance.PROJECTION_MATRIX != null) { + shaderInstance.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + } + if (shaderInstance.INVERSE_VIEW_ROTATION_MATRIX != null) { + shaderInstance.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + } + if (shaderInstance.COLOR_MODULATOR != null) { + shaderInstance.COLOR_MODULATOR.set(RenderSystem.getShaderColor()); + } + if (shaderInstance.FOG_START != null) { + shaderInstance.FOG_START.set(RenderSystem.getShaderFogStart()); + } + if (shaderInstance.FOG_END != null) { + shaderInstance.FOG_END.set(RenderSystem.getShaderFogEnd()); + } + if (shaderInstance.FOG_COLOR != null) { + shaderInstance.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + } + if (shaderInstance.FOG_SHAPE != null) { + shaderInstance.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + } + if (shaderInstance.TEXTURE_MATRIX != null) { + shaderInstance.TEXTURE_MATRIX.set(RenderSystem.getTextureMatrix()); + } + if (shaderInstance.GAME_TIME != null) { + shaderInstance.GAME_TIME.set(RenderSystem.getShaderGameTime()); + } + if (shaderInstance.SCREEN_SIZE != null) { + Window window = Minecraft.getInstance().getWindow(); + shaderInstance.SCREEN_SIZE.set((float)window.getWidth(), (float)window.getHeight()); + } + if (shaderInstance.LINE_WIDTH != null) { + VertexFormat.Mode mode = renderedBuffer.drawState().mode(); + if(mode == VertexFormat.Mode.LINES || mode == VertexFormat.Mode.LINE_STRIP) { + shaderInstance.LINE_WIDTH.set(RenderSystem.getShaderLineWidth()); + } + } + RenderSystem.setupShaderLights(shaderInstance); + shaderInstance.apply(); + + setupAndRender(phase, shaderInstance, commands); + + shaderInstance.clear(); + } + } + } + } + + public static void irisHookAfterVertexBufferDraw() { + WorldRenderingPipeline pipeline = Iris.getPipelineManager().getPipelineNullable(); + if(pipeline != null) { + WorldRenderingPhase phase = pipeline.getPhase(); + Map> renderStateShardToCommands = phaseRenderStateShardToCommands.get(phase); + if(renderStateShardToCommands != null) { + List commands = renderStateShardToCommands.remove(currentRenderStateShard); + if(commands != null) { + setupAndRender(phase, RenderedGltfModel.CURRENT_SHADER_INSTANCE = RenderSystem.getShader(), commands); + } + } + } + } + + private static void setupAndRender(WorldRenderingPhase phase, ShaderInstance shaderInstance, List commands) { + int currentVAO = GL11.glGetInteger(GL30.GL_VERTEX_ARRAY_BINDING); + int currentArrayBuffer = GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING); + int currentElementArrayBuffer = GL11.glGetInteger(GL15.GL_ELEMENT_ARRAY_BUFFER_BINDING); + + boolean currentCullFace = GL11.glGetBoolean(GL11.GL_CULL_FACE); + + int currentTextureColor = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 2); + int currentTextureNormal = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); + int currentTextureSpecular = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); + + try { + if(phase != WorldRenderingPhase.NONE) { + int currentProgram = shaderInstance.getId(); + RenderedGltfModel.MODEL_VIEW_MATRIX = GL20.glGetUniformLocation(currentProgram, "iris_ModelViewMat"); + RenderedGltfModel.NORMAL_MATRIX = GL20.glGetUniformLocation(currentProgram, "iris_NormalMat"); + } + else { + RenderedGltfModel.LIGHT0_DIRECTION = new Vector3f(shaderInstance.LIGHT0_DIRECTION.getFloatBuffer()); + RenderedGltfModel.LIGHT1_DIRECTION = new Vector3f(shaderInstance.LIGHT1_DIRECTION.getFloatBuffer()); + } + commands.forEach(Runnable::run); + } finally { + GL20.glDisableVertexAttribArray(RenderedGltfModel.at_tangent); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureColor); + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 2); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureNormal); + GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTextureSpecular); + } + + if(currentCullFace) GL11.glEnable(GL11.GL_CULL_FACE); + else GL11.glDisable(GL11.GL_CULL_FACE); + + GL30.glBindVertexArray(currentVAO); + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, currentArrayBuffer); + GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, currentElementArrayBuffer); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL30Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL30Iris.java index 4b04cc2..b8aa780 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL30Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL30Iris.java @@ -1,85 +1,89 @@ package com.modularmods.mcgltf.iris; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.tuple.Triple; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL20; + import com.google.gson.Gson; import com.modularmods.mcgltf.RenderedGltfModelGL30; + import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.NodeModel; import de.javagl.jgltf.model.SceneModel; -import org.apache.commons.lang3.tuple.Triple; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.lwjgl.opengl.GL20; - -import java.util.ArrayList; -import java.util.List; public class RenderedGltfModelGL30Iris extends RenderedGltfModelGL30 { - public RenderedGltfModelGL30Iris(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for (SceneModel sceneModel : sceneModels) { - RenderedGltfSceneGL30Iris renderedGltfScene = new RenderedGltfSceneGL30Iris(); - renderedGltfScenes.add(renderedGltfScene); - - for (NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if (commands == null) { - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(null, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } else { - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - @Override - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - - if (NORMAL_MATRIX != -1) { - Matrix3f normal = new Matrix3f(pose); - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } + public RenderedGltfModelGL30Iris(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } - pose.transpose(); - pose.mulLocal(CURRENT_POSE); + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for(SceneModel sceneModel : sceneModels) { + RenderedGltfSceneGL30Iris renderedGltfScene = new RenderedGltfSceneGL30Iris(); + renderedGltfScenes.add(renderedGltfScene); + + for(NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if(commands == null) { + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(null, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } + else { + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - } + @Override + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + + if(NORMAL_MATRIX != -1) { + Matrix3f normal = new Matrix3f(pose); + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } + + pose.transpose(); + pose.mulLocal(CURRENT_POSE); + + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + } - @Override - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if (material == null) { - Object extras = materialModel.getExtras(); - if (extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); - } else material = new RenderedGltfModelIris.MaterialIris(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } + @Override + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if(material == null) { + Object extras = materialModel.getExtras(); + if(extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); + } + else material = new RenderedGltfModelIris.MaterialIris(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL33Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL33Iris.java index 81ca723..fecdf36 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL33Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL33Iris.java @@ -1,89 +1,93 @@ package com.modularmods.mcgltf.iris; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.tuple.Triple; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL20; + import com.google.gson.Gson; import com.modularmods.mcgltf.RenderedGltfModelGL33; + import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.NodeModel; import de.javagl.jgltf.model.SceneModel; -import org.apache.commons.lang3.tuple.Triple; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.lwjgl.opengl.GL20; - -import java.util.ArrayList; -import java.util.List; public class RenderedGltfModelGL33Iris extends RenderedGltfModelGL33 { - public RenderedGltfModelGL33Iris(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for (SceneModel sceneModel : sceneModels) { - RenderedGltfSceneGL33Iris renderedGltfScene = new RenderedGltfSceneGL33Iris(); - renderedGltfScenes.add(renderedGltfScene); - - for (NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if (commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - @Override - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - - if (NORMAL_MATRIX != -1) { - Matrix3f normal = new Matrix3f(pose); - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } + public RenderedGltfModelGL33Iris(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } - pose.transpose(); - pose.mulLocal(CURRENT_POSE); + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for(SceneModel sceneModel : sceneModels) { + RenderedGltfSceneGL33Iris renderedGltfScene = new RenderedGltfSceneGL33Iris(); + renderedGltfScenes.add(renderedGltfScene); + + for(NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if(commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } + else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - } + @Override + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + + if(NORMAL_MATRIX != -1) { + Matrix3f normal = new Matrix3f(pose); + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } + + pose.transpose(); + pose.mulLocal(CURRENT_POSE); + + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + } - @Override - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if (material == null) { - Object extras = materialModel.getExtras(); - if (extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); - } else material = new RenderedGltfModelIris.MaterialIris(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } + @Override + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if(material == null) { + Object extras = materialModel.getExtras(); + if(extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); + } + else material = new RenderedGltfModelIris.MaterialIris(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL40Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL40Iris.java index 5cbb597..a72e0a7 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL40Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelGL40Iris.java @@ -1,89 +1,93 @@ package com.modularmods.mcgltf.iris; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.tuple.Triple; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL20; + import com.google.gson.Gson; import com.modularmods.mcgltf.RenderedGltfModelGL40; + import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.NodeModel; import de.javagl.jgltf.model.SceneModel; -import org.apache.commons.lang3.tuple.Triple; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.lwjgl.opengl.GL20; - -import java.util.ArrayList; -import java.util.List; public class RenderedGltfModelGL40Iris extends RenderedGltfModelGL40 { - public RenderedGltfModelGL40Iris(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for (SceneModel sceneModel : sceneModels) { - RenderedGltfSceneGL40Iris renderedGltfScene = new RenderedGltfSceneGL40Iris(); - renderedGltfScenes.add(renderedGltfScene); - - for (NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if (commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - @Override - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - - if (NORMAL_MATRIX != -1) { - Matrix3f normal = new Matrix3f(pose); - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } + public RenderedGltfModelGL40Iris(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } - pose.transpose(); - pose.mulLocal(CURRENT_POSE); + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for(SceneModel sceneModel : sceneModels) { + RenderedGltfSceneGL40Iris renderedGltfScene = new RenderedGltfSceneGL40Iris(); + renderedGltfScenes.add(renderedGltfScene); + + for(NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if(commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } + else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - } + @Override + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + + if(NORMAL_MATRIX != -1) { + Matrix3f normal = new Matrix3f(pose); + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } + + pose.transpose(); + pose.mulLocal(CURRENT_POSE); + + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + } - @Override - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if (material == null) { - Object extras = materialModel.getExtras(); - if (extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); - } else material = new RenderedGltfModelIris.MaterialIris(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } + @Override + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if(material == null) { + Object extras = materialModel.getExtras(); + if(extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), RenderedGltfModelIris.MaterialIris.class); + } + else material = new RenderedGltfModelIris.MaterialIris(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelIris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelIris.java index bcbdf4b..8e3cdc3 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelIris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfModelIris.java @@ -1,10 +1,8 @@ package com.modularmods.mcgltf.iris; -import com.google.gson.Gson; -import com.modularmods.mcgltf.MCglTF; -import com.modularmods.mcgltf.RenderedGltfModel; -import de.javagl.jgltf.model.*; -import de.javagl.jgltf.model.v2.MaterialModelV2; +import java.util.ArrayList; +import java.util.List; + import org.apache.commons.lang3.tuple.Triple; import org.joml.Matrix3f; import org.joml.Matrix4f; @@ -12,234 +10,249 @@ import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL20; -import java.util.ArrayList; -import java.util.List; +import com.google.gson.Gson; +import com.modularmods.mcgltf.MCglTF; +import com.modularmods.mcgltf.RenderedGltfModel; + +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.MaterialModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.SceneModel; +import de.javagl.jgltf.model.TextureModel; +import de.javagl.jgltf.model.v2.MaterialModelV2; public class RenderedGltfModelIris extends RenderedGltfModel { - public RenderedGltfModelIris(List gltfRenderData, GltfModel gltfModel) { - super(gltfRenderData, gltfModel); - } - - @Override - protected void processSceneModels(List gltfRenderData, List sceneModels) { - for (SceneModel sceneModel : sceneModels) { - RenderedGltfSceneIris renderedGltfScene = new RenderedGltfSceneIris(); - renderedGltfScenes.add(renderedGltfScene); - - for (NodeModel nodeModel : sceneModel.getNodeModels()) { - Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); - List rootSkinningCommands; - List vanillaRootRenderCommands; - List shaderModRootRenderCommands; - if (commands == null) { - rootSkinningCommands = new ArrayList(); - vanillaRootRenderCommands = new ArrayList(); - shaderModRootRenderCommands = new ArrayList(); - processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); - rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); - } else { - rootSkinningCommands = commands.getLeft(); - vanillaRootRenderCommands = commands.getMiddle(); - shaderModRootRenderCommands = commands.getRight(); - } - renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); - renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); - renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); - } - } - } - - @Override - protected void applyTransformShaderMod(NodeModel nodeModel) { - float[] transform = findGlobalTransform(nodeModel); - Matrix4f pose = new Matrix4f(); - pose.setTransposed(transform); - - if (NORMAL_MATRIX != -1) { - Matrix3f normal = new Matrix3f(pose); - normal.transpose(); - normal.mulLocal(CURRENT_NORMAL); - - normal.get(BUF_FLOAT_9); - GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); - } - - pose.transpose(); - pose.mulLocal(CURRENT_POSE); - - pose.get(BUF_FLOAT_16); - GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); - } - - @Override - public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { - Material material = materialModelToRenderedMaterial.get(materialModel); - if (material == null) { - Object extras = materialModel.getExtras(); - if (extras != null) { - Gson gson = new Gson(); - material = gson.fromJson(gson.toJsonTree(extras), MaterialIris.class); - } else material = new MaterialIris(); - material.initMaterialCommand(gltfRenderData, this, materialModel); - materialModelToRenderedMaterial.put(materialModel, material); - } - return material; - } - - public static class MaterialIris extends Material { - - @Override - public void initMaterialCommand(List gltfRenderData, RenderedGltfModel renderedModel, MaterialModel materialModel) { - int colorMap; - int normalMap; - int specularMap; - List textureModels = renderedModel.gltfModel.getTextureModels(); - if (materialModel instanceof MaterialModelV2) { - MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; - - if (baseColorTexture == null) { - TextureModel textureModel = materialModelV2.getBaseColorTexture(); - if (textureModel != null) { - colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - baseColorTexture = new TextureInfo(); - baseColorTexture.index = textureModels.indexOf(textureModel); - } else colorMap = MCglTF.getInstance().getDefaultColorMap(); - } else - colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); - - if (normalTexture == null) { - TextureModel textureModel = materialModelV2.getNormalTexture(); - if (textureModel != null) { - normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - normalTexture = new TextureInfo(); - normalTexture.index = textureModels.indexOf(textureModel); - } else normalMap = MCglTF.getInstance().getDefaultNormalMap(); - } else - normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); - - if (specularTexture == null) { - TextureModel textureModel = materialModelV2.getMetallicRoughnessTexture(); - if (textureModel != null) { - specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); - specularTexture = new TextureInfo(); - specularTexture.index = textureModels.indexOf(textureModel); - } else specularMap = MCglTF.getInstance().getDefaultSpecularMap(); - } else - specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); - - if (baseColorFactor == null) baseColorFactor = materialModelV2.getBaseColorFactor(); - - if (doubleSided == null) doubleSided = materialModelV2.isDoubleSided(); - } else { - colorMap = baseColorTexture == null ? MCglTF.getInstance().getDefaultColorMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); - normalMap = normalTexture == null ? MCglTF.getInstance().getDefaultNormalMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); - specularMap = specularTexture == null ? MCglTF.getInstance().getDefaultSpecularMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); - if (baseColorFactor == null) baseColorFactor = new float[]{1.0F, 1.0F, 1.0F, 1.0F}; - if (doubleSided == null) doubleSided = false; - } - - if (doubleSided) { - vanillaMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - - // Enhanced transparency handling for vanilla rendering - if (baseColorFactor[3] < 1.0f) { - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - } else { - GL11.glDisable(GL11.GL_BLEND); - } - - GL11.glDisable(GL11.GL_CULL_FACE); - }; - shaderModMaterialCommand = () -> { - GL13.glActiveTexture(COLOR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - - if (NORMAL_MAP_INDEX != -1) { - GL13.glActiveTexture(NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); - } - if (SPECULAR_MAP_INDEX != -1) { - GL13.glActiveTexture(SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); - } - - // Enhanced color attribute with proper alpha handling - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], - baseColorFactor[2], baseColorFactor[3]); - - // Enhanced transparency handling for Iris shader rendering - if (baseColorFactor[3] < 1.0f) { - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - } else { - GL11.glDisable(GL11.GL_BLEND); - } - - // Add entityColor uniform support for shader packs like SEUS PTGI - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); - if (entityColorLocation != -1) { - GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); - } - - GL11.glDisable(GL11.GL_CULL_FACE); - }; - } else { - vanillaMaterialCommand = () -> { - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); - - // Enhanced transparency handling for vanilla rendering - if (baseColorFactor[3] < 1.0f) { - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - } else { - GL11.glDisable(GL11.GL_BLEND); - } - - GL11.glEnable(GL11.GL_CULL_FACE); - }; - shaderModMaterialCommand = () -> { - GL13.glActiveTexture(COLOR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); - - if (NORMAL_MAP_INDEX != -1) { - GL13.glActiveTexture(NORMAL_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); - } - if (SPECULAR_MAP_INDEX != -1) { - GL13.glActiveTexture(SPECULAR_MAP_INDEX); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); - } - - // Enhanced color attribute with proper alpha handling - GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], - baseColorFactor[2], baseColorFactor[3]); - - // Enhanced transparency handling for Iris shader rendering - if (baseColorFactor[3] < 1.0f) { - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - } else { - GL11.glDisable(GL11.GL_BLEND); - } - - // Add entityColor uniform support for shader packs like SEUS PTGI - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); - if (entityColorLocation != -1) { - GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); - } - - GL11.glEnable(GL11.GL_CULL_FACE); - }; - } - } - - } + public RenderedGltfModelIris(List gltfRenderData, GltfModel gltfModel) { + super(gltfRenderData, gltfModel); + } + + @Override + protected void processSceneModels(List gltfRenderData, List sceneModels) { + for(SceneModel sceneModel : sceneModels) { + RenderedGltfSceneIris renderedGltfScene = new RenderedGltfSceneIris(); + renderedGltfScenes.add(renderedGltfScene); + + for(NodeModel nodeModel : sceneModel.getNodeModels()) { + Triple, List, List> commands = rootNodeModelToCommands.get(nodeModel); + List rootSkinningCommands; + List vanillaRootRenderCommands; + List shaderModRootRenderCommands; + if(commands == null) { + rootSkinningCommands = new ArrayList(); + vanillaRootRenderCommands = new ArrayList(); + shaderModRootRenderCommands = new ArrayList(); + processNodeModel(gltfRenderData, nodeModel, rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands); + rootNodeModelToCommands.put(nodeModel, Triple.of(rootSkinningCommands, vanillaRootRenderCommands, shaderModRootRenderCommands)); + } + else { + rootSkinningCommands = commands.getLeft(); + vanillaRootRenderCommands = commands.getMiddle(); + shaderModRootRenderCommands = commands.getRight(); + } + renderedGltfScene.skinningCommands.addAll(rootSkinningCommands); + renderedGltfScene.vanillaRenderCommands.addAll(vanillaRootRenderCommands); + renderedGltfScene.shaderModRenderCommands.addAll(shaderModRootRenderCommands); + } + } + } + + @Override + protected void applyTransformShaderMod(NodeModel nodeModel) { + float[] transform = findGlobalTransform(nodeModel); + Matrix4f pose = new Matrix4f(); + pose.setTransposed(transform); + + if(NORMAL_MATRIX != -1) { + Matrix3f normal = new Matrix3f(pose); + normal.transpose(); + normal.mulLocal(CURRENT_NORMAL); + + normal.get(BUF_FLOAT_9); + GL20.glUniformMatrix3fv(NORMAL_MATRIX, false, BUF_FLOAT_9); + } + + pose.transpose(); + pose.mulLocal(CURRENT_POSE); + + pose.get(BUF_FLOAT_16); + GL20.glUniformMatrix4fv(MODEL_VIEW_MATRIX, false, BUF_FLOAT_16); + } + + @Override + public Material obtainMaterial(List gltfRenderData, MaterialModel materialModel) { + Material material = materialModelToRenderedMaterial.get(materialModel); + if(material == null) { + Object extras = materialModel.getExtras(); + if(extras != null) { + Gson gson = new Gson(); + material = gson.fromJson(gson.toJsonTree(extras), MaterialIris.class); + } + else material = new MaterialIris(); + material.initMaterialCommand(gltfRenderData, this, materialModel); + materialModelToRenderedMaterial.put(materialModel, material); + } + return material; + } + + public static class MaterialIris extends Material { + + @Override + public void initMaterialCommand(List gltfRenderData, RenderedGltfModel renderedModel, MaterialModel materialModel) { + int colorMap; + int normalMap; + int specularMap; + List textureModels = renderedModel.gltfModel.getTextureModels(); + if(materialModel instanceof MaterialModelV2) { + MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; + + if(baseColorTexture == null) { + TextureModel textureModel = materialModelV2.getBaseColorTexture(); + if(textureModel != null) { + colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + baseColorTexture = new TextureInfo(); + baseColorTexture.index = textureModels.indexOf(textureModel); + } + else colorMap = MCglTF.getInstance().getDefaultColorMap(); + } + else colorMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); + + if(normalTexture == null) { + TextureModel textureModel = materialModelV2.getNormalTexture(); + if(textureModel != null) { + normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + normalTexture = new TextureInfo(); + normalTexture.index = textureModels.indexOf(textureModel); + } + else normalMap = MCglTF.getInstance().getDefaultNormalMap(); + } + else normalMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); + + if(specularTexture == null) { + TextureModel textureModel = materialModelV2.getMetallicRoughnessTexture(); + if(textureModel != null) { + specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModel); + specularTexture = new TextureInfo(); + specularTexture.index = textureModels.indexOf(textureModel); + } + else specularMap = MCglTF.getInstance().getDefaultSpecularMap(); + } + else specularMap = renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); + + if(baseColorFactor == null) baseColorFactor = materialModelV2.getBaseColorFactor(); + + if(doubleSided == null) doubleSided = materialModelV2.isDoubleSided(); + } + else { + colorMap = baseColorTexture == null ? MCglTF.getInstance().getDefaultColorMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(baseColorTexture.index)); + normalMap = normalTexture == null ? MCglTF.getInstance().getDefaultNormalMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(normalTexture.index)); + specularMap = specularTexture == null ? MCglTF.getInstance().getDefaultSpecularMap() : renderedModel.obtainGlTexture(gltfRenderData, textureModels.get(specularTexture.index)); + if(baseColorFactor == null) baseColorFactor = new float[]{1.0F, 1.0F, 1.0F, 1.0F}; + if(doubleSided == null) doubleSided = false; + } + + if(doubleSided) { + vanillaMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + + // Enhanced transparency handling for vanilla rendering + if(baseColorFactor[3] < 1.0f) { + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } else { + GL11.glDisable(GL11.GL_BLEND); + } + + GL11.glDisable(GL11.GL_CULL_FACE); + }; + shaderModMaterialCommand = () -> { + GL13.glActiveTexture(COLOR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + + if(NORMAL_MAP_INDEX != -1) { + GL13.glActiveTexture(NORMAL_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); + } + if(SPECULAR_MAP_INDEX != -1) { + GL13.glActiveTexture(SPECULAR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); + } + + // Enhanced color attribute with proper alpha handling + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], + baseColorFactor[2], baseColorFactor[3]); + + // Enhanced transparency handling for Iris shader rendering + if(baseColorFactor[3] < 1.0f) { + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } else { + GL11.glDisable(GL11.GL_BLEND); + } + + // Add entityColor uniform support for shader packs like SEUS PTGI + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); + if (entityColorLocation != -1) { + GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); + } + + GL11.glDisable(GL11.GL_CULL_FACE); + }; + } + else { + vanillaMaterialCommand = () -> { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], baseColorFactor[2], baseColorFactor[3]); + + // Enhanced transparency handling for vanilla rendering + if(baseColorFactor[3] < 1.0f) { + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } else { + GL11.glDisable(GL11.GL_BLEND); + } + + GL11.glEnable(GL11.GL_CULL_FACE); + }; + shaderModMaterialCommand = () -> { + GL13.glActiveTexture(COLOR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorMap); + + if(NORMAL_MAP_INDEX != -1) { + GL13.glActiveTexture(NORMAL_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, normalMap); + } + if(SPECULAR_MAP_INDEX != -1) { + GL13.glActiveTexture(SPECULAR_MAP_INDEX); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, specularMap); + } + + // Enhanced color attribute with proper alpha handling + GL20.glVertexAttrib4f(vaColor, baseColorFactor[0], baseColorFactor[1], + baseColorFactor[2], baseColorFactor[3]); + + // Enhanced transparency handling for Iris shader rendering + if(baseColorFactor[3] < 1.0f) { + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } else { + GL11.glDisable(GL11.GL_BLEND); + } + + // Add entityColor uniform support for shader packs like SEUS PTGI + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + int entityColorLocation = GL20.glGetUniformLocation(currentProgram, "entityColor"); + if (entityColorLocation != -1) { + GL20.glUniform4f(entityColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); + } + + GL11.glEnable(GL11.GL_CULL_FACE); + }; + } + } + + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL30Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL30Iris.java index ea8c200..9ea4eec 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL30Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL30Iris.java @@ -1,26 +1,27 @@ package com.modularmods.mcgltf.iris; -import com.modularmods.mcgltf.RenderedGltfModel; -import com.modularmods.mcgltf.RenderedGltfSceneGL30; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL20; -public class RenderedGltfSceneGL30Iris extends RenderedGltfSceneGL30 { - - @Override - public void renderForVanilla() { - vanillaRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); +import com.modularmods.mcgltf.RenderedGltfModel; +import com.modularmods.mcgltf.RenderedGltfSceneGL30; - shaderModRenderCommands.forEach(Runnable::run); +public class RenderedGltfSceneGL30Iris extends RenderedGltfSceneGL30 { - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + vanillaRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + shaderModRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL33Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL33Iris.java index ccc275c..fec95b4 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL33Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL33Iris.java @@ -1,44 +1,49 @@ package com.modularmods.mcgltf.iris; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL31; + import com.modularmods.mcgltf.MCglTF; import com.modularmods.mcgltf.RenderedGltfModel; import com.modularmods.mcgltf.RenderedGltfSceneGL33; -import org.lwjgl.opengl.*; public class RenderedGltfSceneGL33Iris extends RenderedGltfSceneGL33 { - @Override - public void renderForVanilla() { - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); - } - - vanillaRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(currentProgram); - } - - shaderModRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); + } + + vanillaRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + shaderModRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL40Iris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL40Iris.java index 486ad29..8a93d76 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL40Iris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneGL40Iris.java @@ -1,46 +1,52 @@ package com.modularmods.mcgltf.iris; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL31; +import org.lwjgl.opengl.GL40; + import com.modularmods.mcgltf.MCglTF; import com.modularmods.mcgltf.RenderedGltfModel; import com.modularmods.mcgltf.RenderedGltfSceneGL40; -import org.lwjgl.opengl.*; public class RenderedGltfSceneGL40Iris extends RenderedGltfSceneGL40 { - @Override - public void renderForVanilla() { - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); - } - - vanillaRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(currentProgram); - } - - shaderModRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + @Override + public void renderForVanilla() { + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); + } + + vanillaRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL31.GL_TEXTURE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } + + shaderModRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneIris.java b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneIris.java index 0417ffb..9025d68 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneIris.java +++ b/src/main/java/com/modularmods/mcgltf/iris/RenderedGltfSceneIris.java @@ -1,46 +1,52 @@ package com.modularmods.mcgltf.iris; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.GL43; + import com.modularmods.mcgltf.MCglTF; import com.modularmods.mcgltf.RenderedGltfModel; import com.modularmods.mcgltf.RenderedGltfScene; -import org.lwjgl.opengl.*; public class RenderedGltfSceneIris extends RenderedGltfScene { - @Override - public void renderForVanilla() { - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); - } - - vanillaRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } - - @Override - public void renderForShaderMod() { - int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); - - if (!skinningCommands.isEmpty()) { - GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); - GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); - skinningCommands.forEach(Runnable::run); - GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); - GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); - GL20.glUseProgram(currentProgram); - } + @Override + public void renderForVanilla() { + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(RenderedGltfModel.CURRENT_SHADER_INSTANCE.getId()); + } + + vanillaRenderCommands.forEach(Runnable::run); + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } + + @Override + public void renderForShaderMod() { + int currentProgram = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM); + + if(!skinningCommands.isEmpty()) { + GL20.glUseProgram(MCglTF.getInstance().getGlProgramSkinnig()); + GL11.glEnable(GL30.GL_RASTERIZER_DISCARD); + skinningCommands.forEach(Runnable::run); + GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); + GL40.glBindTransformFeedback(GL40.GL_TRANSFORM_FEEDBACK, 0); + GL11.glDisable(GL30.GL_RASTERIZER_DISCARD); + GL20.glUseProgram(currentProgram); + } shaderModRenderCommands.forEach(Runnable::run); - - RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); - } + + RenderedGltfModel.NODE_GLOBAL_TRANSFORMATION_LOOKUP_CACHE.clear(); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/mixin/IrisCompatMixinPlugin.java b/src/main/java/com/modularmods/mcgltf/iris/mixin/IrisCompatMixinPlugin.java index 23eef9b..bd5012c 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/mixin/IrisCompatMixinPlugin.java +++ b/src/main/java/com/modularmods/mcgltf/iris/mixin/IrisCompatMixinPlugin.java @@ -1,44 +1,41 @@ package com.modularmods.mcgltf.iris.mixin; -import net.fabricmc.loader.api.FabricLoader; +import java.util.List; +import java.util.Set; + import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; -import java.util.List; -import java.util.Set; +import net.fabricmc.loader.api.FabricLoader; public class IrisCompatMixinPlugin implements IMixinConfigPlugin { - @Override - public void onLoad(String mixinPackage) { - } + @Override + public void onLoad(String mixinPackage) {} - @Override - public String getRefMapperConfig() { - return null; - } + @Override + public String getRefMapperConfig() { + return null; + } - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - return FabricLoader.getInstance().isModLoaded("iris"); - } + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + return FabricLoader.getInstance().isModLoaded("iris"); + } - @Override - public void acceptTargets(Set myTargets, Set otherTargets) { - } + @Override + public void acceptTargets(Set myTargets, Set otherTargets) {} - @Override - public List getMixins() { - return null; - } + @Override + public List getMixins() { + return null; + } - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - } + @Override + public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - } + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} } diff --git a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinBufferUploader.java b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinBufferUploader.java index 4ab3e94..189ea18 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinBufferUploader.java +++ b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinBufferUploader.java @@ -1,18 +1,19 @@ package com.modularmods.mcgltf.iris.mixin; -import com.modularmods.mcgltf.iris.IrisRenderingHook; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.BufferUploader; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.modularmods.mcgltf.iris.IrisRenderingHook; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.BufferUploader; + @Mixin(BufferUploader.class) public class MixinBufferUploader { - @Inject(method = "_drawWithShader(Lcom/mojang/blaze3d/vertex/BufferBuilder$RenderedBuffer;)V", at = @At("HEAD")) - private static void before_drawWithShader(BufferBuilder.RenderedBuffer renderedBuffer, CallbackInfo ci) { - if (renderedBuffer.isEmpty()) IrisRenderingHook.irisHookBypassBufferUploaderVextexCountCheck(renderedBuffer); - } + @Inject(method = "_drawWithShader(Lcom/mojang/blaze3d/vertex/BufferBuilder$RenderedBuffer;)V", at = @At("HEAD")) + private static void before_drawWithShader(BufferBuilder.RenderedBuffer renderedBuffer, CallbackInfo ci) { + if(renderedBuffer.isEmpty()) IrisRenderingHook.irisHookBypassBufferUploaderVextexCountCheck(renderedBuffer); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinRenderStateShard.java b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinRenderStateShard.java index 4fc5701..8d7f9ac 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinRenderStateShard.java +++ b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinRenderStateShard.java @@ -1,17 +1,19 @@ package com.modularmods.mcgltf.iris.mixin; -import com.modularmods.mcgltf.iris.IrisRenderingHook; -import net.minecraft.client.renderer.RenderStateShard; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.modularmods.mcgltf.iris.IrisRenderingHook; + +import net.minecraft.client.renderer.RenderStateShard; + @Mixin(RenderStateShard.class) public class MixinRenderStateShard { - @Inject(method = "setupRenderState()V", at = @At("TAIL")) - private void afterSetupRenderState(CallbackInfo ci) { - IrisRenderingHook.irisHookAfterSetupRenderState((RenderStateShard) (Object) this); - } + @Inject(method = "setupRenderState()V", at = @At("TAIL")) + private void afterSetupRenderState(CallbackInfo ci) { + IrisRenderingHook.irisHookAfterSetupRenderState((RenderStateShard)(Object)this); + } } diff --git a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinVertexBuffer.java b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinVertexBuffer.java index bc5940b..bb9ad41 100644 --- a/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinVertexBuffer.java +++ b/src/main/java/com/modularmods/mcgltf/iris/mixin/MixinVertexBuffer.java @@ -1,17 +1,18 @@ package com.modularmods.mcgltf.iris.mixin; -import com.modularmods.mcgltf.iris.IrisRenderingHook; -import com.mojang.blaze3d.vertex.VertexBuffer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.modularmods.mcgltf.iris.IrisRenderingHook; +import com.mojang.blaze3d.vertex.VertexBuffer; + @Mixin(VertexBuffer.class) public class MixinVertexBuffer { - @Inject(method = "draw()V", at = @At("TAIL")) - private void afterDraw(CallbackInfo ci) { - IrisRenderingHook.irisHookAfterVertexBufferDraw(); - } + @Inject(method = "draw()V", at = @At("TAIL")) + private void afterDraw(CallbackInfo ci) { + IrisRenderingHook.irisHookAfterVertexBufferDraw(); + } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Accessor.java b/src/main/java/de/javagl/jgltf/impl/v1/Accessor.java index f4851cd..94d8d6b 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Accessor.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Accessor.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,315 +9,303 @@ package de.javagl.jgltf.impl.v1; + /** - * A typed view into a bufferView. A bufferView contains raw binary data. - * An accessor provides a typed view into a bufferView or a subset of a - * bufferView similar to how WebGL's `vertexAttribPointer()` defines an - * attribute in a buffer. - *

    - * Auto-generated for accessor.schema.json - * + * A typed view into a bufferView. A bufferView contains raw binary data. + * An accessor provides a typed view into a bufferView or a subset of a + * bufferView similar to how WebGL's `vertexAttribPointer()` defines an + * attribute in a buffer. + * + * Auto-generated for accessor.schema.json + * */ public class Accessor - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The ID of the bufferView. (required) - * + * The ID of the bufferView. (required) + * */ private String bufferView; /** - * The offset relative to the start of the bufferView in bytes. - * (required)
    - * Minimum: 0 (inclusive) - * + * The offset relative to the start of the bufferView in bytes. + * (required)
    + * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The stride, in bytes, between attributes referenced by this accessor. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive)
    - * Maximum: 255 (inclusive) - * + * The stride, in bytes, between attributes referenced by this accessor. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive)
    + * Maximum: 255 (inclusive) + * */ private Integer byteStride; /** - * The datatype of components in the attribute. (required)
    - * Valid values: [5120, 5121, 5122, 5123, 5126] - * + * The datatype of components in the attribute. (required)
    + * Valid values: [5120, 5121, 5122, 5123, 5126] + * */ private Integer componentType; /** - * The number of attributes referenced by this accessor. (required)
    - * Minimum: 1 (inclusive) - * + * The number of attributes referenced by this accessor. (required)
    + * Minimum: 1 (inclusive) + * */ private Integer count; /** - * Specifies if the attribute is a scalar, vector, or matrix. - * (required)
    - * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", - * "MAT4"] - * + * Specifies if the attribute is a scalar, vector, or matrix. + * (required)
    + * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", + * "MAT4"] + * */ private String type; /** - * Maximum value of each component in this attribute. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Maximum value of each component in this attribute. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * */ private Number[] max; /** - * Minimum value of each component in this attribute. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Minimum value of each component in this attribute. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * */ private Number[] min; /** - * The ID of the bufferView. (required) - * - * @return The bufferView - * - */ - public String getBufferView() { - return this.bufferView; - } - - /** - * The ID of the bufferView. (required) - * + * The ID of the bufferView. (required) + * * @param bufferView The bufferView to set * @throws NullPointerException If the given value is null - * + * */ public void setBufferView(String bufferView) { if (bufferView == null) { - throw new NullPointerException((("Invalid value for bufferView: " + bufferView) + ", may not be null")); + throw new NullPointerException((("Invalid value for bufferView: "+ bufferView)+", may not be null")); } this.bufferView = bufferView; } /** - * The offset relative to the start of the bufferView in bytes. - * (required)
    - * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * The ID of the bufferView. (required) + * + * @return The bufferView + * */ - public Integer getByteOffset() { - return this.byteOffset; + public String getBufferView() { + return this.bufferView; } /** - * The offset relative to the start of the bufferView in bytes. - * (required)
    - * Minimum: 0 (inclusive) - * + * The offset relative to the start of the bufferView in bytes. + * (required)
    + * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { - throw new NullPointerException((("Invalid value for byteOffset: " + byteOffset) + ", may not be null")); + throw new NullPointerException((("Invalid value for byteOffset: "+ byteOffset)+", may not be null")); } - if (byteOffset < 0) { + if (byteOffset< 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * The stride, in bytes, between attributes referenced by this accessor. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive)
    - * Maximum: 255 (inclusive) - * - * @return The byteStride - * + * The offset relative to the start of the bufferView in bytes. + * (required)
    + * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public Integer getByteStride() { - return this.byteStride; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The stride, in bytes, between attributes referenced by this accessor. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive)
    - * Maximum: 255 (inclusive) - * + * The stride, in bytes, between attributes referenced by this accessor. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive)
    + * Maximum: 255 (inclusive) + * * @param byteStride The byteStride to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteStride(Integer byteStride) { if (byteStride == null) { this.byteStride = byteStride; - return; + return ; } if (byteStride > 255) { throw new IllegalArgumentException("byteStride > 255"); } - if (byteStride < 0) { + if (byteStride< 0) { throw new IllegalArgumentException("byteStride < 0"); } this.byteStride = byteStride; } /** - * Returns the default value of the byteStride
    - * - * @return The default byteStride - * @see #getByteStride - * + * The stride, in bytes, between attributes referenced by this accessor. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive)
    + * Maximum: 255 (inclusive) + * + * @return The byteStride + * */ - public Integer defaultByteStride() { - return 0; + public Integer getByteStride() { + return this.byteStride; } /** - * The datatype of components in the attribute. (required)
    - * Valid values: [5120, 5121, 5122, 5123, 5126] - * - * @return The componentType - * + * Returns the default value of the byteStride
    + * @see #getByteStride + * + * @return The default byteStride + * */ - public Integer getComponentType() { - return this.componentType; + public Integer defaultByteStride() { + return 0; } /** - * The datatype of components in the attribute. (required)
    - * Valid values: [5120, 5121, 5122, 5123, 5126] - * + * The datatype of components in the attribute. (required)
    + * Valid values: [5120, 5121, 5122, 5123, 5126] + * * @param componentType The componentType to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setComponentType(Integer componentType) { if (componentType == null) { - throw new NullPointerException((("Invalid value for componentType: " + componentType) + ", may not be null")); + throw new NullPointerException((("Invalid value for componentType: "+ componentType)+", may not be null")); } - if (((((componentType != 5120) && (componentType != 5121)) && (componentType != 5122)) && (componentType != 5123)) && (componentType != 5126)) { - throw new IllegalArgumentException((("Invalid value for componentType: " + componentType) + ", valid: [5120, 5121, 5122, 5123, 5126]")); + if (((((componentType!= 5120)&&(componentType!= 5121))&&(componentType!= 5122))&&(componentType!= 5123))&&(componentType!= 5126)) { + throw new IllegalArgumentException((("Invalid value for componentType: "+ componentType)+", valid: [5120, 5121, 5122, 5123, 5126]")); } this.componentType = componentType; } /** - * The number of attributes referenced by this accessor. (required)
    - * Minimum: 1 (inclusive) - * - * @return The count - * + * The datatype of components in the attribute. (required)
    + * Valid values: [5120, 5121, 5122, 5123, 5126] + * + * @return The componentType + * */ - public Integer getCount() { - return this.count; + public Integer getComponentType() { + return this.componentType; } /** - * The number of attributes referenced by this accessor. (required)
    - * Minimum: 1 (inclusive) - * + * The number of attributes referenced by this accessor. (required)
    + * Minimum: 1 (inclusive) + * * @param count The count to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCount(Integer count) { if (count == null) { - throw new NullPointerException((("Invalid value for count: " + count) + ", may not be null")); + throw new NullPointerException((("Invalid value for count: "+ count)+", may not be null")); } - if (count < 1) { + if (count< 1) { throw new IllegalArgumentException("count < 1"); } this.count = count; } /** - * Specifies if the attribute is a scalar, vector, or matrix. - * (required)
    - * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", - * "MAT4"] - * - * @return The type - * + * The number of attributes referenced by this accessor. (required)
    + * Minimum: 1 (inclusive) + * + * @return The count + * */ - public String getType() { - return this.type; + public Integer getCount() { + return this.count; } /** - * Specifies if the attribute is a scalar, vector, or matrix. - * (required)
    - * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", - * "MAT4"] - * + * Specifies if the attribute is a scalar, vector, or matrix. + * (required)
    + * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", + * "MAT4"] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); + throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); } - if (((((((!"SCALAR".equals(type)) && (!"VEC2".equals(type))) && (!"VEC3".equals(type))) && (!"VEC4".equals(type))) && (!"MAT2".equals(type))) && (!"MAT3".equals(type))) && (!"MAT4".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [\"SCALAR\", \"VEC2\", \"VEC3\", \"VEC4\", \"MAT2\", \"MAT3\", \"MAT4\"]")); + if (((((((!"SCALAR".equals(type))&&(!"VEC2".equals(type)))&&(!"VEC3".equals(type)))&&(!"VEC4".equals(type)))&&(!"MAT2".equals(type)))&&(!"MAT3".equals(type)))&&(!"MAT4".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [\"SCALAR\", \"VEC2\", \"VEC3\", \"VEC4\", \"MAT2\", \"MAT3\", \"MAT4\"]")); } this.type = type; } /** - * Maximum value of each component in this attribute. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The max - * + * Specifies if the attribute is a scalar, vector, or matrix. + * (required)
    + * Valid values: ["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", + * "MAT4"] + * + * @return The type + * */ - public Number[] getMax() { - return this.max; + public String getType() { + return this.type; } /** - * Maximum value of each component in this attribute. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Maximum value of each component in this attribute. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * * @param max The max to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMax(Number[] max) { if (max == null) { this.max = max; - return; + return ; } - if (max.length < 1) { + if (max.length< 1) { throw new IllegalArgumentException("Number of max elements is < 1"); } if (max.length > 16) { @@ -327,37 +315,37 @@ public void setMax(Number[] max) { } /** - * Minimum value of each component in this attribute. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The min - * + * Maximum value of each component in this attribute. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The max + * */ - public Number[] getMin() { - return this.min; + public Number[] getMax() { + return this.max; } /** - * Minimum value of each component in this attribute. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Minimum value of each component in this attribute. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * * @param min The min to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMin(Number[] min) { if (min == null) { this.min = min; - return; + return ; } - if (min.length < 1) { + if (min.length< 1) { throw new IllegalArgumentException("Number of min elements is < 1"); } if (min.length > 16) { @@ -366,4 +354,18 @@ public void setMin(Number[] min) { this.min = min; } + /** + * Minimum value of each component in this attribute. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The min + * + */ + public Number[] getMin() { + return this.min; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Animation.java b/src/main/java/de/javagl/jgltf/impl/v1/Animation.java index bc6adc2..59b6b45 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Animation.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Animation.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -15,82 +15,83 @@ /** - * A keyframe animation. - *

    - * Auto-generated for animation.schema.json - * + * A keyframe animation. + * + * Auto-generated for animation.schema.json + * */ public class Animation - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * An array of channels, each of which targets an animation's sampler at - * a node's property. (optional)
    - * Default: []
    - * Array elements:
    - *   Targets an animation's sampler at a node's property. - * (optional) - * + * An array of channels, each of which targets an animation's sampler at + * a node's property. (optional)
    + * Default: []
    + * Array elements:
    + *   Targets an animation's sampler at a node's property. + * (optional) + * */ private List channels; /** - * A dictionary object of strings whose values are IDs of accessors with - * keyframe data, e.g., time, translation, rotation, etc. (optional)
    - * Default: {} - * + * A dictionary object of strings whose values are IDs of accessors with + * keyframe data, e.g., time, translation, rotation, etc. (optional)
    + * Default: {} + * */ private Map parameters; /** - * A dictionary object of samplers that combines input and output - * parameters with an interpolation algorithm to define a keyframe graph - * (but not its target). (optional)
    - * Default: {} - * + * A dictionary object of samplers that combines input and output + * parameters with an interpolation algorithm to define a keyframe graph + * (but not its target). (optional)
    + * Default: {} + * */ private Map samplers; /** - * An array of channels, each of which targets an animation's sampler at - * a node's property. (optional)
    - * Default: []
    - * Array elements:
    - *   Targets an animation's sampler at a node's property. - * (optional) - * - * @return The channels - * - */ - public List getChannels() { - return this.channels; - } - - /** - * An array of channels, each of which targets an animation's sampler at - * a node's property. (optional)
    - * Default: []
    - * Array elements:
    - *   Targets an animation's sampler at a node's property. - * (optional) - * + * An array of channels, each of which targets an animation's sampler at + * a node's property. (optional)
    + * Default: []
    + * Array elements:
    + *   Targets an animation's sampler at a node's property. + * (optional) + * * @param channels The channels to set - * + * */ public void setChannels(List channels) { if (channels == null) { this.channels = channels; - return; + return ; } this.channels = channels; } /** - * Add the given channels. The channels of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of channels, each of which targets an animation's sampler at + * a node's property. (optional)
    + * Default: []
    + * Array elements:
    + *   Targets an animation's sampler at a node's property. + * (optional) + * + * @return The channels + * + */ + public List getChannels() { + return this.channels; + } + + /** + * Add the given channels. The channels of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addChannels(AnimationChannel element) { if (element == null) { @@ -98,7 +99,7 @@ public void addChannels(AnimationChannel element) { } List oldList = this.channels; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -106,15 +107,15 @@ public void addChannels(AnimationChannel element) { } /** - * Remove the given channels. The channels of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given channels. The channels of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeChannels(AnimationChannel element) { if (element == null) { @@ -122,7 +123,7 @@ public void removeChannels(AnimationChannel element) { } List oldList = this.channels; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -134,53 +135,53 @@ public void removeChannels(AnimationChannel element) { } /** - * Returns the default value of the channels
    - * + * Returns the default value of the channels
    + * @see #getChannels + * * @return The default channels - * @see #getChannels - * + * */ public List defaultChannels() { return new ArrayList(); } /** - * A dictionary object of strings whose values are IDs of accessors with - * keyframe data, e.g., time, translation, rotation, etc. (optional)
    - * Default: {} - * - * @return The parameters - * - */ - public Map getParameters() { - return this.parameters; - } - - /** - * A dictionary object of strings whose values are IDs of accessors with - * keyframe data, e.g., time, translation, rotation, etc. (optional)
    - * Default: {} - * + * A dictionary object of strings whose values are IDs of accessors with + * keyframe data, e.g., time, translation, rotation, etc. (optional)
    + * Default: {} + * * @param parameters The parameters to set - * + * */ public void setParameters(Map parameters) { if (parameters == null) { this.parameters = parameters; - return; + return ; } this.parameters = parameters; } /** - * Add the given parameters. The parameters of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A dictionary object of strings whose values are IDs of accessors with + * keyframe data, e.g., time, translation, rotation, etc. (optional)
    + * Default: {} + * + * @return The parameters + * + */ + public Map getParameters() { + return this.parameters; + } + + /** + * Add the given parameters. The parameters of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addParameters(String key, String value) { if (key == null) { @@ -191,7 +192,7 @@ public void addParameters(String key, String value) { } Map oldMap = this.parameters; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -199,15 +200,15 @@ public void addParameters(String key, String value) { } /** - * Remove the given parameters. The parameters of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given parameters. The parameters of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeParameters(String key) { if (key == null) { @@ -215,7 +216,7 @@ public void removeParameters(String key) { } Map oldMap = this.parameters; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -227,55 +228,55 @@ public void removeParameters(String key) { } /** - * Returns the default value of the parameters
    - * + * Returns the default value of the parameters
    + * @see #getParameters + * * @return The default parameters - * @see #getParameters - * + * */ public Map defaultParameters() { return new LinkedHashMap(); } /** - * A dictionary object of samplers that combines input and output - * parameters with an interpolation algorithm to define a keyframe graph - * (but not its target). (optional)
    - * Default: {} - * - * @return The samplers - * - */ - public Map getSamplers() { - return this.samplers; - } - - /** - * A dictionary object of samplers that combines input and output - * parameters with an interpolation algorithm to define a keyframe graph - * (but not its target). (optional)
    - * Default: {} - * + * A dictionary object of samplers that combines input and output + * parameters with an interpolation algorithm to define a keyframe graph + * (but not its target). (optional)
    + * Default: {} + * * @param samplers The samplers to set - * + * */ public void setSamplers(Map samplers) { if (samplers == null) { this.samplers = samplers; - return; + return ; } this.samplers = samplers; } /** - * Add the given samplers. The samplers of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of samplers that combines input and output + * parameters with an interpolation algorithm to define a keyframe graph + * (but not its target). (optional)
    + * Default: {} + * + * @return The samplers + * + */ + public Map getSamplers() { + return this.samplers; + } + + /** + * Add the given samplers. The samplers of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addSamplers(String key, AnimationSampler value) { if (key == null) { @@ -286,7 +287,7 @@ public void addSamplers(String key, AnimationSampler value) { } Map oldMap = this.samplers; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -294,15 +295,15 @@ public void addSamplers(String key, AnimationSampler value) { } /** - * Remove the given samplers. The samplers of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given samplers. The samplers of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeSamplers(String key) { if (key == null) { @@ -310,7 +311,7 @@ public void removeSamplers(String key) { } Map oldMap = this.samplers; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -322,11 +323,11 @@ public void removeSamplers(String key) { } /** - * Returns the default value of the samplers
    - * + * Returns the default value of the samplers
    + * @see #getSamplers + * * @return The default samplers - * @see #getSamplers - * + * */ public Map defaultSamplers() { return new LinkedHashMap(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannel.java b/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannel.java index 398a141..211d301 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannel.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannel.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,75 +9,77 @@ package de.javagl.jgltf.impl.v1; + /** - * Targets an animation's sampler at a node's property. - *

    - * Auto-generated for animation.channel.schema.json - * + * Targets an animation's sampler at a node's property. + * + * Auto-generated for animation.channel.schema.json + * */ public class AnimationChannel - extends GlTFProperty { + extends GlTFProperty +{ /** - * The ID of a sampler in this animation used to compute the value for - * the target. (required) - * + * The ID of a sampler in this animation used to compute the value for + * the target. (required) + * */ private String sampler; /** - * The ID of the node and TRS property to target. (required) - * + * The ID of the node and TRS property to target. (required) + * */ private AnimationChannelTarget target; /** - * The ID of a sampler in this animation used to compute the value for - * the target. (required) - * - * @return The sampler - * - */ - public String getSampler() { - return this.sampler; - } - - /** - * The ID of a sampler in this animation used to compute the value for - * the target. (required) - * + * The ID of a sampler in this animation used to compute the value for + * the target. (required) + * * @param sampler The sampler to set * @throws NullPointerException If the given value is null - * + * */ public void setSampler(String sampler) { if (sampler == null) { - throw new NullPointerException((("Invalid value for sampler: " + sampler) + ", may not be null")); + throw new NullPointerException((("Invalid value for sampler: "+ sampler)+", may not be null")); } this.sampler = sampler; } /** - * The ID of the node and TRS property to target. (required) - * - * @return The target - * + * The ID of a sampler in this animation used to compute the value for + * the target. (required) + * + * @return The sampler + * */ - public AnimationChannelTarget getTarget() { - return this.target; + public String getSampler() { + return this.sampler; } /** - * The ID of the node and TRS property to target. (required) - * + * The ID of the node and TRS property to target. (required) + * * @param target The target to set * @throws NullPointerException If the given value is null - * + * */ public void setTarget(AnimationChannelTarget target) { if (target == null) { - throw new NullPointerException((("Invalid value for target: " + target) + ", may not be null")); + throw new NullPointerException((("Invalid value for target: "+ target)+", may not be null")); } this.target = target; } + /** + * The ID of the node and TRS property to target. (required) + * + * @return The target + * + */ + public AnimationChannelTarget getTarget() { + return this.target; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannelTarget.java b/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannelTarget.java index 49e4312..ae6d9db 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannelTarget.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/AnimationChannelTarget.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,80 +9,82 @@ package de.javagl.jgltf.impl.v1; + /** - * The ID of the node and TRS property that an animation channel targets. - *

    - * Auto-generated for animation.channel.target.schema.json - * + * The ID of the node and TRS property that an animation channel targets. + * + * Auto-generated for animation.channel.target.schema.json + * */ public class AnimationChannelTarget - extends GlTFProperty { + extends GlTFProperty +{ /** - * The ID of the node to target. (required) - * + * The ID of the node to target. (required) + * */ private String id; /** - * The name of the node's TRS property to modify. (required)
    - * Valid values: ["translation", "rotation", "scale"] - * + * The name of the node's TRS property to modify. (required)
    + * Valid values: ["translation", "rotation", "scale"] + * */ private String path; /** - * The ID of the node to target. (required) - * - * @return The id - * - */ - public String getId() { - return this.id; - } - - /** - * The ID of the node to target. (required) - * + * The ID of the node to target. (required) + * * @param id The id to set * @throws NullPointerException If the given value is null - * + * */ public void setId(String id) { if (id == null) { - throw new NullPointerException((("Invalid value for id: " + id) + ", may not be null")); + throw new NullPointerException((("Invalid value for id: "+ id)+", may not be null")); } this.id = id; } /** - * The name of the node's TRS property to modify. (required)
    - * Valid values: ["translation", "rotation", "scale"] - * - * @return The path - * + * The ID of the node to target. (required) + * + * @return The id + * */ - public String getPath() { - return this.path; + public String getId() { + return this.id; } /** - * The name of the node's TRS property to modify. (required)
    - * Valid values: ["translation", "rotation", "scale"] - * + * The name of the node's TRS property to modify. (required)
    + * Valid values: ["translation", "rotation", "scale"] + * * @param path The path to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setPath(String path) { if (path == null) { - throw new NullPointerException((("Invalid value for path: " + path) + ", may not be null")); + throw new NullPointerException((("Invalid value for path: "+ path)+", may not be null")); } - if (((!"translation".equals(path)) && (!"rotation".equals(path))) && (!"scale".equals(path))) { - throw new IllegalArgumentException((("Invalid value for path: " + path) + ", valid: [\"translation\", \"rotation\", \"scale\"]")); + if (((!"translation".equals(path))&&(!"rotation".equals(path)))&&(!"scale".equals(path))) { + throw new IllegalArgumentException((("Invalid value for path: "+ path)+", valid: [\"translation\", \"rotation\", \"scale\"]")); } this.path = path; } + /** + * The name of the node's TRS property to modify. (required)
    + * Valid values: ["translation", "rotation", "scale"] + * + * @return The path + * + */ + public String getPath() { + return this.path; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/AnimationSampler.java b/src/main/java/de/javagl/jgltf/impl/v1/AnimationSampler.java index 5ec23aa..170377d 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/AnimationSampler.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/AnimationSampler.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,130 +9,132 @@ package de.javagl.jgltf.impl.v1; + /** - * Combines input and output parameters with an interpolation algorithm - * to define a keyframe graph (but not its target). - *

    - * Auto-generated for animation.sampler.schema.json - * + * Combines input and output parameters with an interpolation algorithm + * to define a keyframe graph (but not its target). + * + * Auto-generated for animation.sampler.schema.json + * */ public class AnimationSampler - extends GlTFProperty { + extends GlTFProperty +{ /** - * The ID of a parameter in this animation to use as keyframe input, - * e.g., time. (required) - * + * The ID of a parameter in this animation to use as keyframe input, + * e.g., time. (required) + * */ private String input; /** - * Interpolation algorithm. (optional)
    - * Default: "LINEAR"
    - * Valid values: ["LINEAR", "STEP"] - * + * Interpolation algorithm. (optional)
    + * Default: "LINEAR"
    + * Valid values: ["LINEAR", "STEP"] + * */ private String interpolation; /** - * The ID of a parameter in this animation to use as keyframe output. - * (required) - * + * The ID of a parameter in this animation to use as keyframe output. + * (required) + * */ private String output; /** - * The ID of a parameter in this animation to use as keyframe input, - * e.g., time. (required) - * - * @return The input - * - */ - public String getInput() { - return this.input; - } - - /** - * The ID of a parameter in this animation to use as keyframe input, - * e.g., time. (required) - * + * The ID of a parameter in this animation to use as keyframe input, + * e.g., time. (required) + * * @param input The input to set * @throws NullPointerException If the given value is null - * + * */ public void setInput(String input) { if (input == null) { - throw new NullPointerException((("Invalid value for input: " + input) + ", may not be null")); + throw new NullPointerException((("Invalid value for input: "+ input)+", may not be null")); } this.input = input; } /** - * Interpolation algorithm. (optional)
    - * Default: "LINEAR"
    - * Valid values: ["LINEAR"] - * - * @return The interpolation - * + * The ID of a parameter in this animation to use as keyframe input, + * e.g., time. (required) + * + * @return The input + * */ - public String getInterpolation() { - return this.interpolation; + public String getInput() { + return this.input; } /** - * Interpolation algorithm. (optional)
    - * Default: "LINEAR"
    - * Valid values: ["LINEAR"] - * + * Interpolation algorithm. (optional)
    + * Default: "LINEAR"
    + * Valid values: ["LINEAR"] + * * @param interpolation The interpolation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setInterpolation(String interpolation) { if (interpolation == null) { this.interpolation = interpolation; - return; + return ; } - if ((!"LINEAR".equals(interpolation)) && (!"STEP".equals(interpolation))) { - throw new IllegalArgumentException((("Invalid value for interpolation: " + interpolation) + ", valid: [\"LINEAR\", \"STEP\"]")); + if ((!"LINEAR".equals(interpolation))&&(!"STEP".equals(interpolation))) { + throw new IllegalArgumentException((("Invalid value for interpolation: "+ interpolation)+", valid: [\"LINEAR\", \"STEP\"]")); } this.interpolation = interpolation; } /** - * Returns the default value of the interpolation
    - * - * @return The default interpolation - * @see #getInterpolation - * + * Interpolation algorithm. (optional)
    + * Default: "LINEAR"
    + * Valid values: ["LINEAR"] + * + * @return The interpolation + * */ - public String defaultInterpolation() { - return "LINEAR"; + public String getInterpolation() { + return this.interpolation; } /** - * The ID of a parameter in this animation to use as keyframe output. - * (required) - * - * @return The output - * + * Returns the default value of the interpolation
    + * @see #getInterpolation + * + * @return The default interpolation + * */ - public String getOutput() { - return this.output; + public String defaultInterpolation() { + return "LINEAR"; } /** - * The ID of a parameter in this animation to use as keyframe output. - * (required) - * + * The ID of a parameter in this animation to use as keyframe output. + * (required) + * * @param output The output to set * @throws NullPointerException If the given value is null - * + * */ public void setOutput(String output) { if (output == null) { - throw new NullPointerException((("Invalid value for output: " + output) + ", may not be null")); + throw new NullPointerException((("Invalid value for output: "+ output)+", may not be null")); } this.output = output; } + /** + * The ID of a parameter in this animation to use as keyframe output. + * (required) + * + * @return The output + * + */ + public String getOutput() { + return this.output; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Asset.java b/src/main/java/de/javagl/jgltf/impl/v1/Asset.java index b951379..ea6360b 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Asset.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Asset.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,193 +9,195 @@ package de.javagl.jgltf.impl.v1; + /** - * Metadata about the glTF asset. - *

    - * Auto-generated for asset.schema.json - * + * Metadata about the glTF asset. + * + * Auto-generated for asset.schema.json + * */ public class Asset - extends GlTFProperty { + extends GlTFProperty +{ /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * */ private String copyright; /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * */ private String generator; /** - * Specifies if the shaders were generated with premultiplied alpha. - * (optional)
    - * Default: false - * + * Specifies if the shaders were generated with premultiplied alpha. + * (optional)
    + * Default: false + * */ private Boolean premultipliedAlpha; /** - * The profile of this Asset (optional)
    - * Default: {} - * + * The profile of this Asset (optional)
    + * Default: {} + * */ private AssetProfile profile; /** - * The glTF version. (required) - * + * The glTF version. (required) + * */ private String version; /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * - * @return The copyright - * - */ - public String getCopyright() { - return this.copyright; - } - - /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * * @param copyright The copyright to set - * + * */ public void setCopyright(String copyright) { if (copyright == null) { this.copyright = copyright; - return; + return ; } this.copyright = copyright; } /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * - * @return The generator - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * + * @return The copyright + * */ - public String getGenerator() { - return this.generator; + public String getCopyright() { + return this.copyright; } /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * * @param generator The generator to set - * + * */ public void setGenerator(String generator) { if (generator == null) { this.generator = generator; - return; + return ; } this.generator = generator; } /** - * Specifies if the shaders were generated with premultiplied alpha. - * (optional)
    - * Default: false - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * + * @return The generator + * + */ + public String getGenerator() { + return this.generator; + } + + /** + * Specifies if the shaders were generated with premultiplied alpha. + * (optional)
    + * Default: false + * * @param premultipliedAlpha The premultipliedAlpha to set - * + * */ public void setPremultipliedAlpha(Boolean premultipliedAlpha) { if (premultipliedAlpha == null) { this.premultipliedAlpha = premultipliedAlpha; - return; + return ; } this.premultipliedAlpha = premultipliedAlpha; } /** - * Specifies if the shaders were generated with premultiplied alpha. - * (optional)
    - * Default: false - * + * Specifies if the shaders were generated with premultiplied alpha. + * (optional)
    + * Default: false + * * @return The premultipliedAlpha - * + * */ public Boolean isPremultipliedAlpha() { return this.premultipliedAlpha; } /** - * Returns the default value of the premultipliedAlpha
    - * + * Returns the default value of the premultipliedAlpha
    + * @see #isPremultipliedAlpha + * * @return The default premultipliedAlpha - * @see #isPremultipliedAlpha - * + * */ public Boolean defaultPremultipliedAlpha() { return false; } /** - * The profile of this Asset (optional)
    - * Default: {} - * - * @return The profile - * - */ - public AssetProfile getProfile() { - return this.profile; - } - - /** - * The profile of this Asset (optional)
    - * Default: {} - * + * The profile of this Asset (optional)
    + * Default: {} + * * @param profile The profile to set - * + * */ public void setProfile(AssetProfile profile) { if (profile == null) { this.profile = profile; - return; + return ; } this.profile = profile; } /** - * Returns the default value of the profile
    - * - * @return The default profile - * @see #getProfile - * + * The profile of this Asset (optional)
    + * Default: {} + * + * @return The profile + * */ - public AssetProfile defaultProfile() { - return new AssetProfile(); + public AssetProfile getProfile() { + return this.profile; } /** - * The glTF version. (required) - * - * @return The version - * + * Returns the default value of the profile
    + * @see #getProfile + * + * @return The default profile + * */ - public String getVersion() { - return this.version; + public AssetProfile defaultProfile() { + return new AssetProfile(); } /** - * The glTF version. (required) - * + * The glTF version. (required) + * * @param version The version to set * @throws NullPointerException If the given value is null - * + * */ public void setVersion(String version) { if (version == null) { - throw new NullPointerException((("Invalid value for version: " + version) + ", may not be null")); + throw new NullPointerException((("Invalid value for version: "+ version)+", may not be null")); } this.version = version; } + /** + * The glTF version. (required) + * + * @return The version + * + */ + public String getVersion() { + return this.version; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/AssetProfile.java b/src/main/java/de/javagl/jgltf/impl/v1/AssetProfile.java index da44dcb..683b676 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/AssetProfile.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/AssetProfile.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,97 +9,99 @@ package de.javagl.jgltf.impl.v1; + /** - * Specifies the target rendering API and version, e.g., WebGL 1.0.3. - *

    - * Auto-generated for asset.profile.schema.json - * + * Specifies the target rendering API and version, e.g., WebGL 1.0.3. + * + * Auto-generated for asset.profile.schema.json + * */ public class AssetProfile - extends GlTFProperty { + extends GlTFProperty +{ /** - * Specifies the target rendering API. (optional)
    - * Default: "WebGL" - * + * Specifies the target rendering API. (optional)
    + * Default: "WebGL" + * */ private String api; /** - * The API version. (optional)
    - * Default: "1.0.3" - * + * The API version. (optional)
    + * Default: "1.0.3" + * */ private String version; /** - * Specifies the target rendering API. (optional)
    - * Default: "WebGL" - * - * @return The api - * - */ - public String getApi() { - return this.api; - } - - /** - * Specifies the target rendering API. (optional)
    - * Default: "WebGL" - * + * Specifies the target rendering API. (optional)
    + * Default: "WebGL" + * * @param api The api to set - * + * */ public void setApi(String api) { if (api == null) { this.api = api; - return; + return ; } this.api = api; } /** - * Returns the default value of the api
    - * - * @return The default api - * @see #getApi - * + * Specifies the target rendering API. (optional)
    + * Default: "WebGL" + * + * @return The api + * */ - public String defaultApi() { - return "WebGL"; + public String getApi() { + return this.api; } /** - * The API version. (optional)
    - * Default: "1.0.3" - * - * @return The version - * + * Returns the default value of the api
    + * @see #getApi + * + * @return The default api + * */ - public String getVersion() { - return this.version; + public String defaultApi() { + return "WebGL"; } /** - * The API version. (optional)
    - * Default: "1.0.3" - * + * The API version. (optional)
    + * Default: "1.0.3" + * * @param version The version to set - * + * */ public void setVersion(String version) { if (version == null) { this.version = version; - return; + return ; } this.version = version; } /** - * Returns the default value of the version
    - * + * The API version. (optional)
    + * Default: "1.0.3" + * + * @return The version + * + */ + public String getVersion() { + return this.version; + } + + /** + * Returns the default value of the version
    + * @see #getVersion + * * @return The default version - * @see #getVersion - * + * */ public String defaultVersion() { return "1.0.3"; diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Buffer.java b/src/main/java/de/javagl/jgltf/impl/v1/Buffer.java index 8227e7b..22ac00c 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Buffer.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Buffer.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,142 +9,144 @@ package de.javagl.jgltf.impl.v1; + /** - * A buffer points to binary geometry, animation, or skins. - *

    - * Auto-generated for buffer.schema.json - * + * A buffer points to binary geometry, animation, or skins. + * + * Auto-generated for buffer.schema.json + * */ public class Buffer - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The uri of the buffer. (required) - * + * The uri of the buffer. (required) + * */ private String uri; /** - * The length of the buffer in bytes. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The length of the buffer in bytes. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * */ private Integer byteLength; /** - * XMLHttpRequest `responseType`. (optional)
    - * Default: "arraybuffer"
    - * Valid values: ["arraybuffer", "text"] - * + * XMLHttpRequest `responseType`. (optional)
    + * Default: "arraybuffer"
    + * Valid values: ["arraybuffer", "text"] + * */ private String type; /** - * The uri of the buffer. (required) - * - * @return The uri - * - */ - public String getUri() { - return this.uri; - } - - /** - * The uri of the buffer. (required) - * + * The uri of the buffer. (required) + * * @param uri The uri to set * @throws NullPointerException If the given value is null - * + * */ public void setUri(String uri) { if (uri == null) { - throw new NullPointerException((("Invalid value for uri: " + uri) + ", may not be null")); + throw new NullPointerException((("Invalid value for uri: "+ uri)+", may not be null")); } this.uri = uri; } /** - * The length of the buffer in bytes. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * - * @return The byteLength - * + * The uri of the buffer. (required) + * + * @return The uri + * */ - public Integer getByteLength() { - return this.byteLength; + public String getUri() { + return this.uri; } /** - * The length of the buffer in bytes. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The length of the buffer in bytes. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * * @param byteLength The byteLength to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteLength(Integer byteLength) { if (byteLength == null) { this.byteLength = byteLength; - return; + return ; } - if (byteLength < 0) { + if (byteLength< 0) { throw new IllegalArgumentException("byteLength < 0"); } this.byteLength = byteLength; } /** - * Returns the default value of the byteLength
    - * - * @return The default byteLength - * @see #getByteLength - * + * The length of the buffer in bytes. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * + * @return The byteLength + * */ - public Integer defaultByteLength() { - return 0; + public Integer getByteLength() { + return this.byteLength; } /** - * XMLHttpRequest `responseType`. (optional)
    - * Default: "arraybuffer"
    - * Valid values: ["arraybuffer", "text"] - * - * @return The type - * + * Returns the default value of the byteLength
    + * @see #getByteLength + * + * @return The default byteLength + * */ - public String getType() { - return this.type; + public Integer defaultByteLength() { + return 0; } /** - * XMLHttpRequest `responseType`. (optional)
    - * Default: "arraybuffer"
    - * Valid values: ["arraybuffer", "text"] - * + * XMLHttpRequest `responseType`. (optional)
    + * Default: "arraybuffer"
    + * Valid values: ["arraybuffer", "text"] + * * @param type The type to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { this.type = type; - return; + return ; } - if ((!"arraybuffer".equals(type)) && (!"text".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [\"arraybuffer\", \"text\"]")); + if ((!"arraybuffer".equals(type))&&(!"text".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [\"arraybuffer\", \"text\"]")); } this.type = type; } /** - * Returns the default value of the type
    - * + * XMLHttpRequest `responseType`. (optional)
    + * Default: "arraybuffer"
    + * Valid values: ["arraybuffer", "text"] + * + * @return The type + * + */ + public String getType() { + return this.type; + } + + /** + * Returns the default value of the type
    + * @see #getType + * * @return The default type - * @see #getType - * + * */ public String defaultType() { return "arraybuffer"; diff --git a/src/main/java/de/javagl/jgltf/impl/v1/BufferView.java b/src/main/java/de/javagl/jgltf/impl/v1/BufferView.java index 446e796..4747a1d 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/BufferView.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/BufferView.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,168 +9,170 @@ package de.javagl.jgltf.impl.v1; + /** - * A view into a buffer generally representing a subset of the buffer. - *

    - * Auto-generated for bufferView.schema.json - * + * A view into a buffer generally representing a subset of the buffer. + * + * Auto-generated for bufferView.schema.json + * */ public class BufferView - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The ID of the buffer. (required) - * + * The ID of the buffer. (required) + * */ private String buffer; /** - * The offset into the buffer in bytes. (required)
    - * Minimum: 0 (inclusive) - * + * The offset into the buffer in bytes. (required)
    + * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The length of the bufferView in bytes. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The length of the bufferView in bytes. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * */ private Integer byteLength; /** - * The target that the WebGL buffer should be bound to. (optional)
    - * Valid values: [34962, 34963] - * + * The target that the WebGL buffer should be bound to. (optional)
    + * Valid values: [34962, 34963] + * */ private Integer target; /** - * The ID of the buffer. (required) - * - * @return The buffer - * - */ - public String getBuffer() { - return this.buffer; - } - - /** - * The ID of the buffer. (required) - * + * The ID of the buffer. (required) + * * @param buffer The buffer to set * @throws NullPointerException If the given value is null - * + * */ public void setBuffer(String buffer) { if (buffer == null) { - throw new NullPointerException((("Invalid value for buffer: " + buffer) + ", may not be null")); + throw new NullPointerException((("Invalid value for buffer: "+ buffer)+", may not be null")); } this.buffer = buffer; } /** - * The offset into the buffer in bytes. (required)
    - * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * The ID of the buffer. (required) + * + * @return The buffer + * */ - public Integer getByteOffset() { - return this.byteOffset; + public String getBuffer() { + return this.buffer; } /** - * The offset into the buffer in bytes. (required)
    - * Minimum: 0 (inclusive) - * + * The offset into the buffer in bytes. (required)
    + * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { - throw new NullPointerException((("Invalid value for byteOffset: " + byteOffset) + ", may not be null")); + throw new NullPointerException((("Invalid value for byteOffset: "+ byteOffset)+", may not be null")); } - if (byteOffset < 0) { + if (byteOffset< 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * The length of the bufferView in bytes. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * - * @return The byteLength - * + * The offset into the buffer in bytes. (required)
    + * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public Integer getByteLength() { - return this.byteLength; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The length of the bufferView in bytes. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The length of the bufferView in bytes. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * * @param byteLength The byteLength to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteLength(Integer byteLength) { if (byteLength == null) { this.byteLength = byteLength; - return; + return ; } - if (byteLength < 0) { + if (byteLength< 0) { throw new IllegalArgumentException("byteLength < 0"); } this.byteLength = byteLength; } /** - * Returns the default value of the byteLength
    - * - * @return The default byteLength - * @see #getByteLength - * + * The length of the bufferView in bytes. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * + * @return The byteLength + * */ - public Integer defaultByteLength() { - return 0; + public Integer getByteLength() { + return this.byteLength; } /** - * The target that the WebGL buffer should be bound to. (optional)
    - * Valid values: [34962, 34963] - * - * @return The target - * + * Returns the default value of the byteLength
    + * @see #getByteLength + * + * @return The default byteLength + * */ - public Integer getTarget() { - return this.target; + public Integer defaultByteLength() { + return 0; } /** - * The target that the WebGL buffer should be bound to. (optional)
    - * Valid values: [34962, 34963] - * + * The target that the WebGL buffer should be bound to. (optional)
    + * Valid values: [34962, 34963] + * * @param target The target to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTarget(Integer target) { if (target == null) { this.target = target; - return; + return ; } - if ((target != 34962) && (target != 34963)) { - throw new IllegalArgumentException((("Invalid value for target: " + target) + ", valid: [34962, 34963]")); + if ((target!= 34962)&&(target!= 34963)) { + throw new IllegalArgumentException((("Invalid value for target: "+ target)+", valid: [34962, 34963]")); } this.target = target; } + /** + * The target that the WebGL buffer should be bound to. (optional)
    + * Valid values: [34962, 34963] + * + * @return The target + * + */ + public Integer getTarget() { + return this.target; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Camera.java b/src/main/java/de/javagl/jgltf/impl/v1/Camera.java index f905c0d..c3ce0a7 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Camera.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Camera.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,119 +9,121 @@ package de.javagl.jgltf.impl.v1; + /** - * A camera's projection. A node can reference a camera ID to apply a - * transform to place the camera in the scene. - *

    - * Auto-generated for camera.schema.json - * + * A camera's projection. A node can reference a camera ID to apply a + * transform to place the camera in the scene. + * + * Auto-generated for camera.schema.json + * */ public class Camera - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. (optional) - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. (optional) + * */ private CameraOrthographic orthographic; /** - * A perspective camera containing properties to create a perspective - * projection matrix. (optional) - * + * A perspective camera containing properties to create a perspective + * projection matrix. (optional) + * */ private CameraPerspective perspective; /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
    - * Valid values: ["perspective", "orthographic"] - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
    + * Valid values: ["perspective", "orthographic"] + * */ private String type; /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. (optional) - * - * @return The orthographic - * - */ - public CameraOrthographic getOrthographic() { - return this.orthographic; - } - - /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. (optional) - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. (optional) + * * @param orthographic The orthographic to set - * + * */ public void setOrthographic(CameraOrthographic orthographic) { if (orthographic == null) { this.orthographic = orthographic; - return; + return ; } this.orthographic = orthographic; } /** - * A perspective camera containing properties to create a perspective - * projection matrix. (optional) - * - * @return The perspective - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. (optional) + * + * @return The orthographic + * */ - public CameraPerspective getPerspective() { - return this.perspective; + public CameraOrthographic getOrthographic() { + return this.orthographic; } /** - * A perspective camera containing properties to create a perspective - * projection matrix. (optional) - * + * A perspective camera containing properties to create a perspective + * projection matrix. (optional) + * * @param perspective The perspective to set - * + * */ public void setPerspective(CameraPerspective perspective) { if (perspective == null) { this.perspective = perspective; - return; + return ; } this.perspective = perspective; } /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
    - * Valid values: ["perspective", "orthographic"] - * - * @return The type - * + * A perspective camera containing properties to create a perspective + * projection matrix. (optional) + * + * @return The perspective + * */ - public String getType() { - return this.type; + public CameraPerspective getPerspective() { + return this.perspective; } /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
    - * Valid values: ["perspective", "orthographic"] - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
    + * Valid values: ["perspective", "orthographic"] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); + throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); } - if ((!"perspective".equals(type)) && (!"orthographic".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [\"perspective\", \"orthographic\"]")); + if ((!"perspective".equals(type))&&(!"orthographic".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [\"perspective\", \"orthographic\"]")); } this.type = type; } + /** + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
    + * Valid values: ["perspective", "orthographic"] + * + * @return The type + * + */ + public String getType() { + return this.type; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/CameraOrthographic.java b/src/main/java/de/javagl/jgltf/impl/v1/CameraOrthographic.java index 2fcec36..6287ffc 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/CameraOrthographic.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/CameraOrthographic.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,147 +9,149 @@ package de.javagl.jgltf.impl.v1; + /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. - *

    - * Auto-generated for camera.orthographic.schema.json - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. + * + * Auto-generated for camera.orthographic.schema.json + * */ public class CameraOrthographic - extends GlTFProperty { + extends GlTFProperty +{ /** - * The floating-point horizontal magnification of the view. (required) - * + * The floating-point horizontal magnification of the view. (required) + * */ private Float xmag; /** - * The floating-point vertical magnification of the view. (required) - * + * The floating-point vertical magnification of the view. (required) + * */ private Float ymag; /** - * The floating-point distance to the far clipping plane. (required)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the far clipping plane. (required)
    + * Minimum: 0.0 (inclusive) + * */ private Float zfar; /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (inclusive) + * */ private Float znear; /** - * The floating-point horizontal magnification of the view. (required) - * - * @return The xmag - * - */ - public Float getXmag() { - return this.xmag; - } - - /** - * The floating-point horizontal magnification of the view. (required) - * + * The floating-point horizontal magnification of the view. (required) + * * @param xmag The xmag to set * @throws NullPointerException If the given value is null - * + * */ public void setXmag(Float xmag) { if (xmag == null) { - throw new NullPointerException((("Invalid value for xmag: " + xmag) + ", may not be null")); + throw new NullPointerException((("Invalid value for xmag: "+ xmag)+", may not be null")); } this.xmag = xmag; } /** - * The floating-point vertical magnification of the view. (required) - * - * @return The ymag - * + * The floating-point horizontal magnification of the view. (required) + * + * @return The xmag + * */ - public Float getYmag() { - return this.ymag; + public Float getXmag() { + return this.xmag; } /** - * The floating-point vertical magnification of the view. (required) - * + * The floating-point vertical magnification of the view. (required) + * * @param ymag The ymag to set * @throws NullPointerException If the given value is null - * + * */ public void setYmag(Float ymag) { if (ymag == null) { - throw new NullPointerException((("Invalid value for ymag: " + ymag) + ", may not be null")); + throw new NullPointerException((("Invalid value for ymag: "+ ymag)+", may not be null")); } this.ymag = ymag; } /** - * The floating-point distance to the far clipping plane. (required)
    - * Minimum: 0.0 (inclusive) - * - * @return The zfar - * + * The floating-point vertical magnification of the view. (required) + * + * @return The ymag + * */ - public Float getZfar() { - return this.zfar; + public Float getYmag() { + return this.ymag; } /** - * The floating-point distance to the far clipping plane. (required)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the far clipping plane. (required)
    + * Minimum: 0.0 (inclusive) + * * @param zfar The zfar to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZfar(Float zfar) { if (zfar == null) { - throw new NullPointerException((("Invalid value for zfar: " + zfar) + ", may not be null")); + throw new NullPointerException((("Invalid value for zfar: "+ zfar)+", may not be null")); } - if (zfar < 0.0D) { + if (zfar< 0.0D) { throw new IllegalArgumentException("zfar < 0.0"); } this.zfar = zfar; } /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (inclusive) - * - * @return The znear - * + * The floating-point distance to the far clipping plane. (required)
    + * Minimum: 0.0 (inclusive) + * + * @return The zfar + * */ - public Float getZnear() { - return this.znear; + public Float getZfar() { + return this.zfar; } /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (inclusive) + * * @param znear The znear to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZnear(Float znear) { if (znear == null) { - throw new NullPointerException((("Invalid value for znear: " + znear) + ", may not be null")); + throw new NullPointerException((("Invalid value for znear: "+ znear)+", may not be null")); } - if (znear < 0.0D) { + if (znear< 0.0D) { throw new IllegalArgumentException("znear < 0.0"); } this.znear = znear; } + /** + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (inclusive) + * + * @return The znear + * + */ + public Float getZnear() { + return this.znear; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/CameraPerspective.java b/src/main/java/de/javagl/jgltf/impl/v1/CameraPerspective.java index 7c3f192..33deae6 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/CameraPerspective.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/CameraPerspective.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,163 +9,165 @@ package de.javagl.jgltf.impl.v1; + /** - * A perspective camera containing properties to create a perspective - * projection matrix. - *

    - * Auto-generated for camera.perspective.schema.json - * + * A perspective camera containing properties to create a perspective + * projection matrix. + * + * Auto-generated for camera.perspective.schema.json + * */ public class CameraPerspective - extends GlTFProperty { + extends GlTFProperty +{ /** - * The floating-point aspect ratio of the field of view. (optional)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point aspect ratio of the field of view. (optional)
    + * Minimum: 0.0 (inclusive) + * */ private Float aspectRatio; /** - * The floating-point vertical field of view in radians. (required)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point vertical field of view in radians. (required)
    + * Minimum: 0.0 (inclusive) + * */ private Float yfov; /** - * The floating-point distance to the far clipping plane. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. (required)
    + * Minimum: 0.0 (exclusive) + * */ private Float zfar; /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (exclusive) + * */ private Float znear; /** - * The floating-point aspect ratio of the field of view. (optional)
    - * Minimum: 0.0 (inclusive) - * - * @return The aspectRatio - * - */ - public Float getAspectRatio() { - return this.aspectRatio; - } - - /** - * The floating-point aspect ratio of the field of view. (optional)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point aspect ratio of the field of view. (optional)
    + * Minimum: 0.0 (inclusive) + * * @param aspectRatio The aspectRatio to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAspectRatio(Float aspectRatio) { if (aspectRatio == null) { this.aspectRatio = aspectRatio; - return; + return ; } - if (aspectRatio < 0.0D) { + if (aspectRatio< 0.0D) { throw new IllegalArgumentException("aspectRatio < 0.0"); } this.aspectRatio = aspectRatio; } /** - * The floating-point vertical field of view in radians. (required)
    - * Minimum: 0.0 (inclusive) - * - * @return The yfov - * + * The floating-point aspect ratio of the field of view. (optional)
    + * Minimum: 0.0 (inclusive) + * + * @return The aspectRatio + * */ - public Float getYfov() { - return this.yfov; + public Float getAspectRatio() { + return this.aspectRatio; } /** - * The floating-point vertical field of view in radians. (required)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point vertical field of view in radians. (required)
    + * Minimum: 0.0 (inclusive) + * * @param yfov The yfov to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setYfov(Float yfov) { if (yfov == null) { - throw new NullPointerException((("Invalid value for yfov: " + yfov) + ", may not be null")); + throw new NullPointerException((("Invalid value for yfov: "+ yfov)+", may not be null")); } - if (yfov < 0.0D) { + if (yfov< 0.0D) { throw new IllegalArgumentException("yfov < 0.0"); } this.yfov = yfov; } /** - * The floating-point distance to the far clipping plane. (required)
    - * Minimum: 0.0 (exclusive) - * - * @return The zfar - * + * The floating-point vertical field of view in radians. (required)
    + * Minimum: 0.0 (inclusive) + * + * @return The yfov + * */ - public Float getZfar() { - return this.zfar; + public Float getYfov() { + return this.yfov; } /** - * The floating-point distance to the far clipping plane. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. (required)
    + * Minimum: 0.0 (exclusive) + * * @param zfar The zfar to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZfar(Float zfar) { if (zfar == null) { - throw new NullPointerException((("Invalid value for zfar: " + zfar) + ", may not be null")); + throw new NullPointerException((("Invalid value for zfar: "+ zfar)+", may not be null")); } - if (zfar <= 0.0D) { + if (zfar<= 0.0D) { throw new IllegalArgumentException("zfar <= 0.0"); } this.zfar = zfar; } /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (exclusive) - * - * @return The znear - * + * The floating-point distance to the far clipping plane. (required)
    + * Minimum: 0.0 (exclusive) + * + * @return The zfar + * */ - public Float getZnear() { - return this.znear; + public Float getZfar() { + return this.zfar; } /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (exclusive) + * * @param znear The znear to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZnear(Float znear) { if (znear == null) { - throw new NullPointerException((("Invalid value for znear: " + znear) + ", may not be null")); + throw new NullPointerException((("Invalid value for znear: "+ znear)+", may not be null")); } - if (znear <= 0.0D) { + if (znear<= 0.0D) { throw new IllegalArgumentException("znear <= 0.0"); } this.znear = znear; } + /** + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (exclusive) + * + * @return The znear + * + */ + public Float getZnear() { + return this.znear; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/GlTF.java b/src/main/java/de/javagl/jgltf/impl/v1/GlTF.java index d7b0a1f..dfc5831 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/GlTF.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/GlTF.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -15,168 +15,169 @@ /** - * The root object for a glTF asset. - *

    - * Auto-generated for glTF.schema.json - * + * The root object for a glTF asset. + * + * Auto-generated for glTF.schema.json + * */ public class GlTF - extends GlTFProperty { + extends GlTFProperty +{ /** - * Names of extensions used somewhere in this asset. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * + * Names of extensions used somewhere in this asset. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List extensionsUsed; /** - * A dictionary object of accessors. (optional)
    - * Default: {} - * + * A dictionary object of accessors. (optional)
    + * Default: {} + * */ private Map accessors; /** - * A dictionary object of keyframe animations. (optional)
    - * Default: {} - * + * A dictionary object of keyframe animations. (optional)
    + * Default: {} + * */ private Map animations; /** - * Metadata about the glTF asset. (optional)
    - * Default: {} - * + * Metadata about the glTF asset. (optional)
    + * Default: {} + * */ private Asset asset; /** - * A dictionary object of buffers. (optional)
    - * Default: {} - * + * A dictionary object of buffers. (optional)
    + * Default: {} + * */ private Map buffers; /** - * A dictionary object of bufferViews. (optional)
    - * Default: {} - * + * A dictionary object of bufferViews. (optional)
    + * Default: {} + * */ private Map bufferViews; /** - * A dictionary object of cameras. (optional)
    - * Default: {} - * + * A dictionary object of cameras. (optional)
    + * Default: {} + * */ private Map cameras; /** - * A dictionary object of images. (optional)
    - * Default: {} - * + * A dictionary object of images. (optional)
    + * Default: {} + * */ private Map images; /** - * A dictionary object of materials. (optional)
    - * Default: {} - * + * A dictionary object of materials. (optional)
    + * Default: {} + * */ private Map materials; /** - * A dictionary object of meshes. (optional)
    - * Default: {} - * + * A dictionary object of meshes. (optional)
    + * Default: {} + * */ private Map meshes; /** - * A dictionary object of nodes. (optional)
    - * Default: {} - * + * A dictionary object of nodes. (optional)
    + * Default: {} + * */ private Map nodes; /** - * A dictionary object of programs. (optional)
    - * Default: {} - * + * A dictionary object of programs. (optional)
    + * Default: {} + * */ private Map programs; /** - * A dictionary object of samplers. (optional)
    - * Default: {} - * + * A dictionary object of samplers. (optional)
    + * Default: {} + * */ private Map samplers; /** - * The ID of the default scene. (optional) - * + * The ID of the default scene. (optional) + * */ private String scene; /** - * A dictionary object of scenes. (optional)
    - * Default: {} - * + * A dictionary object of scenes. (optional)
    + * Default: {} + * */ private Map scenes; /** - * A dictionary object of shaders. (optional)
    - * Default: {} - * + * A dictionary object of shaders. (optional)
    + * Default: {} + * */ private Map shaders; /** - * A dictionary object of skins. (optional)
    - * Default: {} - * + * A dictionary object of skins. (optional)
    + * Default: {} + * */ private Map skins; /** - * A dictionary object of techniques. (optional)
    - * Default: {} - * + * A dictionary object of techniques. (optional)
    + * Default: {} + * */ private Map techniques; /** - * A dictionary object of textures. (optional)
    - * Default: {} - * + * A dictionary object of textures. (optional)
    + * Default: {} + * */ private Map textures; /** - * Names of extensions used somewhere in this asset. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The extensionsUsed - * - */ - public List getExtensionsUsed() { - return this.extensionsUsed; - } - - /** - * Names of extensions used somewhere in this asset. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * + * Names of extensions used somewhere in this asset. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * * @param extensionsUsed The extensionsUsed to set - * + * */ public void setExtensionsUsed(List extensionsUsed) { if (extensionsUsed == null) { this.extensionsUsed = extensionsUsed; - return; + return ; } this.extensionsUsed = extensionsUsed; } /** - * Add the given extensionsUsed. The extensionsUsed of this instance will - * be replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Names of extensions used somewhere in this asset. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The extensionsUsed + * + */ + public List getExtensionsUsed() { + return this.extensionsUsed; + } + + /** + * Add the given extensionsUsed. The extensionsUsed of this instance will + * be replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addExtensionsUsed(String element) { if (element == null) { @@ -184,7 +185,7 @@ public void addExtensionsUsed(String element) { } List oldList = this.extensionsUsed; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -192,15 +193,15 @@ public void addExtensionsUsed(String element) { } /** - * Remove the given extensionsUsed. The extensionsUsed of this instance - * will be replaced with a list that contains all previous elements, - * except for the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given extensionsUsed. The extensionsUsed of this instance + * will be replaced with a list that contains all previous elements, + * except for the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeExtensionsUsed(String element) { if (element == null) { @@ -208,7 +209,7 @@ public void removeExtensionsUsed(String element) { } List oldList = this.extensionsUsed; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -220,51 +221,51 @@ public void removeExtensionsUsed(String element) { } /** - * Returns the default value of the extensionsUsed
    - * + * Returns the default value of the extensionsUsed
    + * @see #getExtensionsUsed + * * @return The default extensionsUsed - * @see #getExtensionsUsed - * + * */ public List defaultExtensionsUsed() { return new ArrayList(); } /** - * A dictionary object of accessors. (optional)
    - * Default: {} - * - * @return The accessors - * - */ - public Map getAccessors() { - return this.accessors; - } - - /** - * A dictionary object of accessors. (optional)
    - * Default: {} - * + * A dictionary object of accessors. (optional)
    + * Default: {} + * * @param accessors The accessors to set - * + * */ public void setAccessors(Map accessors) { if (accessors == null) { this.accessors = accessors; - return; + return ; } this.accessors = accessors; } /** - * Add the given accessors. The accessors of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A dictionary object of accessors. (optional)
    + * Default: {} + * + * @return The accessors + * + */ + public Map getAccessors() { + return this.accessors; + } + + /** + * Add the given accessors. The accessors of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAccessors(String key, Accessor value) { if (key == null) { @@ -275,7 +276,7 @@ public void addAccessors(String key, Accessor value) { } Map oldMap = this.accessors; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -283,15 +284,15 @@ public void addAccessors(String key, Accessor value) { } /** - * Remove the given accessors. The accessors of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given accessors. The accessors of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAccessors(String key) { if (key == null) { @@ -299,7 +300,7 @@ public void removeAccessors(String key) { } Map oldMap = this.accessors; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -311,51 +312,51 @@ public void removeAccessors(String key) { } /** - * Returns the default value of the accessors
    - * + * Returns the default value of the accessors
    + * @see #getAccessors + * * @return The default accessors - * @see #getAccessors - * + * */ public Map defaultAccessors() { return new LinkedHashMap(); } /** - * A dictionary object of keyframe animations. (optional)
    - * Default: {} - * - * @return The animations - * - */ - public Map getAnimations() { - return this.animations; - } - - /** - * A dictionary object of keyframe animations. (optional)
    - * Default: {} - * + * A dictionary object of keyframe animations. (optional)
    + * Default: {} + * * @param animations The animations to set - * + * */ public void setAnimations(Map animations) { if (animations == null) { this.animations = animations; - return; + return ; } this.animations = animations; } /** - * Add the given animations. The animations of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A dictionary object of keyframe animations. (optional)
    + * Default: {} + * + * @return The animations + * + */ + public Map getAnimations() { + return this.animations; + } + + /** + * Add the given animations. The animations of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAnimations(String key, Animation value) { if (key == null) { @@ -366,7 +367,7 @@ public void addAnimations(String key, Animation value) { } Map oldMap = this.animations; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -374,15 +375,15 @@ public void addAnimations(String key, Animation value) { } /** - * Remove the given animations. The animations of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given animations. The animations of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAnimations(String key) { if (key == null) { @@ -390,7 +391,7 @@ public void removeAnimations(String key) { } Map oldMap = this.animations; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -402,88 +403,88 @@ public void removeAnimations(String key) { } /** - * Returns the default value of the animations
    - * + * Returns the default value of the animations
    + * @see #getAnimations + * * @return The default animations - * @see #getAnimations - * + * */ public Map defaultAnimations() { return new LinkedHashMap(); } /** - * Metadata about the glTF asset. (optional)
    - * Default: {} - * - * @return The asset - * - */ - public Asset getAsset() { - return this.asset; - } - - /** - * Metadata about the glTF asset. (optional)
    - * Default: {} - * + * Metadata about the glTF asset. (optional)
    + * Default: {} + * * @param asset The asset to set - * + * */ public void setAsset(Asset asset) { if (asset == null) { this.asset = asset; - return; + return ; } this.asset = asset; } /** - * Returns the default value of the asset
    - * - * @return The default asset - * @see #getAsset - * + * Metadata about the glTF asset. (optional)
    + * Default: {} + * + * @return The asset + * */ - public Asset defaultAsset() { - return new Asset(); + public Asset getAsset() { + return this.asset; } /** - * A dictionary object of buffers. (optional)
    - * Default: {} - * - * @return The buffers - * + * Returns the default value of the asset
    + * @see #getAsset + * + * @return The default asset + * */ - public Map getBuffers() { - return this.buffers; + public Asset defaultAsset() { + return new Asset(); } /** - * A dictionary object of buffers. (optional)
    - * Default: {} - * + * A dictionary object of buffers. (optional)
    + * Default: {} + * * @param buffers The buffers to set - * + * */ public void setBuffers(Map buffers) { if (buffers == null) { this.buffers = buffers; - return; + return ; } this.buffers = buffers; } /** - * Add the given buffers. The buffers of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of buffers. (optional)
    + * Default: {} + * + * @return The buffers + * + */ + public Map getBuffers() { + return this.buffers; + } + + /** + * Add the given buffers. The buffers of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addBuffers(String key, Buffer value) { if (key == null) { @@ -494,7 +495,7 @@ public void addBuffers(String key, Buffer value) { } Map oldMap = this.buffers; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -502,15 +503,15 @@ public void addBuffers(String key, Buffer value) { } /** - * Remove the given buffers. The buffers of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given buffers. The buffers of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeBuffers(String key) { if (key == null) { @@ -518,7 +519,7 @@ public void removeBuffers(String key) { } Map oldMap = this.buffers; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -530,51 +531,51 @@ public void removeBuffers(String key) { } /** - * Returns the default value of the buffers
    - * + * Returns the default value of the buffers
    + * @see #getBuffers + * * @return The default buffers - * @see #getBuffers - * + * */ public Map defaultBuffers() { return new LinkedHashMap(); } /** - * A dictionary object of bufferViews. (optional)
    - * Default: {} - * - * @return The bufferViews - * - */ - public Map getBufferViews() { - return this.bufferViews; - } - - /** - * A dictionary object of bufferViews. (optional)
    - * Default: {} - * + * A dictionary object of bufferViews. (optional)
    + * Default: {} + * * @param bufferViews The bufferViews to set - * + * */ public void setBufferViews(Map bufferViews) { if (bufferViews == null) { this.bufferViews = bufferViews; - return; + return ; } this.bufferViews = bufferViews; } /** - * Add the given bufferViews. The bufferViews of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A dictionary object of bufferViews. (optional)
    + * Default: {} + * + * @return The bufferViews + * + */ + public Map getBufferViews() { + return this.bufferViews; + } + + /** + * Add the given bufferViews. The bufferViews of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addBufferViews(String key, BufferView value) { if (key == null) { @@ -585,7 +586,7 @@ public void addBufferViews(String key, BufferView value) { } Map oldMap = this.bufferViews; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -593,15 +594,15 @@ public void addBufferViews(String key, BufferView value) { } /** - * Remove the given bufferViews. The bufferViews of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given bufferViews. The bufferViews of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeBufferViews(String key) { if (key == null) { @@ -609,7 +610,7 @@ public void removeBufferViews(String key) { } Map oldMap = this.bufferViews; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -621,51 +622,51 @@ public void removeBufferViews(String key) { } /** - * Returns the default value of the bufferViews
    - * + * Returns the default value of the bufferViews
    + * @see #getBufferViews + * * @return The default bufferViews - * @see #getBufferViews - * + * */ public Map defaultBufferViews() { return new LinkedHashMap(); } /** - * A dictionary object of cameras. (optional)
    - * Default: {} - * - * @return The cameras - * - */ - public Map getCameras() { - return this.cameras; - } - - /** - * A dictionary object of cameras. (optional)
    - * Default: {} - * + * A dictionary object of cameras. (optional)
    + * Default: {} + * * @param cameras The cameras to set - * + * */ public void setCameras(Map cameras) { if (cameras == null) { this.cameras = cameras; - return; + return ; } this.cameras = cameras; } /** - * Add the given cameras. The cameras of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of cameras. (optional)
    + * Default: {} + * + * @return The cameras + * + */ + public Map getCameras() { + return this.cameras; + } + + /** + * Add the given cameras. The cameras of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addCameras(String key, Camera value) { if (key == null) { @@ -676,7 +677,7 @@ public void addCameras(String key, Camera value) { } Map oldMap = this.cameras; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -684,15 +685,15 @@ public void addCameras(String key, Camera value) { } /** - * Remove the given cameras. The cameras of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given cameras. The cameras of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeCameras(String key) { if (key == null) { @@ -700,7 +701,7 @@ public void removeCameras(String key) { } Map oldMap = this.cameras; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -712,51 +713,51 @@ public void removeCameras(String key) { } /** - * Returns the default value of the cameras
    - * + * Returns the default value of the cameras
    + * @see #getCameras + * * @return The default cameras - * @see #getCameras - * + * */ public Map defaultCameras() { return new LinkedHashMap(); } /** - * A dictionary object of images. (optional)
    - * Default: {} - * - * @return The images - * - */ - public Map getImages() { - return this.images; - } - - /** - * A dictionary object of images. (optional)
    - * Default: {} - * + * A dictionary object of images. (optional)
    + * Default: {} + * * @param images The images to set - * + * */ public void setImages(Map images) { if (images == null) { this.images = images; - return; + return ; } this.images = images; } /** - * Add the given images. The images of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of images. (optional)
    + * Default: {} + * + * @return The images + * + */ + public Map getImages() { + return this.images; + } + + /** + * Add the given images. The images of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addImages(String key, Image value) { if (key == null) { @@ -767,7 +768,7 @@ public void addImages(String key, Image value) { } Map oldMap = this.images; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -775,15 +776,15 @@ public void addImages(String key, Image value) { } /** - * Remove the given images. The images of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given images. The images of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeImages(String key) { if (key == null) { @@ -791,7 +792,7 @@ public void removeImages(String key) { } Map oldMap = this.images; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -803,51 +804,51 @@ public void removeImages(String key) { } /** - * Returns the default value of the images
    - * + * Returns the default value of the images
    + * @see #getImages + * * @return The default images - * @see #getImages - * + * */ public Map defaultImages() { return new LinkedHashMap(); } /** - * A dictionary object of materials. (optional)
    - * Default: {} - * - * @return The materials - * - */ - public Map getMaterials() { - return this.materials; - } - - /** - * A dictionary object of materials. (optional)
    - * Default: {} - * + * A dictionary object of materials. (optional)
    + * Default: {} + * * @param materials The materials to set - * + * */ public void setMaterials(Map materials) { if (materials == null) { this.materials = materials; - return; + return ; } this.materials = materials; } /** - * Add the given materials. The materials of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A dictionary object of materials. (optional)
    + * Default: {} + * + * @return The materials + * + */ + public Map getMaterials() { + return this.materials; + } + + /** + * Add the given materials. The materials of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addMaterials(String key, Material value) { if (key == null) { @@ -858,7 +859,7 @@ public void addMaterials(String key, Material value) { } Map oldMap = this.materials; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -866,15 +867,15 @@ public void addMaterials(String key, Material value) { } /** - * Remove the given materials. The materials of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given materials. The materials of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeMaterials(String key) { if (key == null) { @@ -882,7 +883,7 @@ public void removeMaterials(String key) { } Map oldMap = this.materials; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -894,51 +895,51 @@ public void removeMaterials(String key) { } /** - * Returns the default value of the materials
    - * + * Returns the default value of the materials
    + * @see #getMaterials + * * @return The default materials - * @see #getMaterials - * + * */ public Map defaultMaterials() { return new LinkedHashMap(); } /** - * A dictionary object of meshes. (optional)
    - * Default: {} - * - * @return The meshes - * - */ - public Map getMeshes() { - return this.meshes; - } - - /** - * A dictionary object of meshes. (optional)
    - * Default: {} - * + * A dictionary object of meshes. (optional)
    + * Default: {} + * * @param meshes The meshes to set - * + * */ public void setMeshes(Map meshes) { if (meshes == null) { this.meshes = meshes; - return; + return ; } this.meshes = meshes; } /** - * Add the given meshes. The meshes of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of meshes. (optional)
    + * Default: {} + * + * @return The meshes + * + */ + public Map getMeshes() { + return this.meshes; + } + + /** + * Add the given meshes. The meshes of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addMeshes(String key, Mesh value) { if (key == null) { @@ -949,7 +950,7 @@ public void addMeshes(String key, Mesh value) { } Map oldMap = this.meshes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -957,15 +958,15 @@ public void addMeshes(String key, Mesh value) { } /** - * Remove the given meshes. The meshes of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given meshes. The meshes of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeMeshes(String key) { if (key == null) { @@ -973,7 +974,7 @@ public void removeMeshes(String key) { } Map oldMap = this.meshes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -985,51 +986,51 @@ public void removeMeshes(String key) { } /** - * Returns the default value of the meshes
    - * + * Returns the default value of the meshes
    + * @see #getMeshes + * * @return The default meshes - * @see #getMeshes - * + * */ public Map defaultMeshes() { return new LinkedHashMap(); } /** - * A dictionary object of nodes. (optional)
    - * Default: {} - * - * @return The nodes - * - */ - public Map getNodes() { - return this.nodes; - } - - /** - * A dictionary object of nodes. (optional)
    - * Default: {} - * + * A dictionary object of nodes. (optional)
    + * Default: {} + * * @param nodes The nodes to set - * + * */ public void setNodes(Map nodes) { if (nodes == null) { this.nodes = nodes; - return; + return ; } this.nodes = nodes; } /** - * Add the given nodes. The nodes of this instance will be replaced with - * a map that contains all previous mappings, and additionally the new - * mapping. - * - * @param key The key + * A dictionary object of nodes. (optional)
    + * Default: {} + * + * @return The nodes + * + */ + public Map getNodes() { + return this.nodes; + } + + /** + * Add the given nodes. The nodes of this instance will be replaced with + * a map that contains all previous mappings, and additionally the new + * mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addNodes(String key, Node value) { if (key == null) { @@ -1040,7 +1041,7 @@ public void addNodes(String key, Node value) { } Map oldMap = this.nodes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1048,15 +1049,15 @@ public void addNodes(String key, Node value) { } /** - * Remove the given nodes. The nodes of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given nodes. The nodes of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeNodes(String key) { if (key == null) { @@ -1064,7 +1065,7 @@ public void removeNodes(String key) { } Map oldMap = this.nodes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1076,51 +1077,51 @@ public void removeNodes(String key) { } /** - * Returns the default value of the nodes
    - * + * Returns the default value of the nodes
    + * @see #getNodes + * * @return The default nodes - * @see #getNodes - * + * */ public Map defaultNodes() { return new LinkedHashMap(); } /** - * A dictionary object of programs. (optional)
    - * Default: {} - * - * @return The programs - * - */ - public Map getPrograms() { - return this.programs; - } - - /** - * A dictionary object of programs. (optional)
    - * Default: {} - * + * A dictionary object of programs. (optional)
    + * Default: {} + * * @param programs The programs to set - * + * */ public void setPrograms(Map programs) { if (programs == null) { this.programs = programs; - return; + return ; } this.programs = programs; } /** - * Add the given programs. The programs of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of programs. (optional)
    + * Default: {} + * + * @return The programs + * + */ + public Map getPrograms() { + return this.programs; + } + + /** + * Add the given programs. The programs of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addPrograms(String key, Program value) { if (key == null) { @@ -1131,7 +1132,7 @@ public void addPrograms(String key, Program value) { } Map oldMap = this.programs; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1139,15 +1140,15 @@ public void addPrograms(String key, Program value) { } /** - * Remove the given programs. The programs of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given programs. The programs of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removePrograms(String key) { if (key == null) { @@ -1155,7 +1156,7 @@ public void removePrograms(String key) { } Map oldMap = this.programs; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1167,51 +1168,51 @@ public void removePrograms(String key) { } /** - * Returns the default value of the programs
    - * + * Returns the default value of the programs
    + * @see #getPrograms + * * @return The default programs - * @see #getPrograms - * + * */ public Map defaultPrograms() { return new LinkedHashMap(); } /** - * A dictionary object of samplers. (optional)
    - * Default: {} - * - * @return The samplers - * - */ - public Map getSamplers() { - return this.samplers; - } - - /** - * A dictionary object of samplers. (optional)
    - * Default: {} - * + * A dictionary object of samplers. (optional)
    + * Default: {} + * * @param samplers The samplers to set - * + * */ public void setSamplers(Map samplers) { if (samplers == null) { this.samplers = samplers; - return; + return ; } this.samplers = samplers; } /** - * Add the given samplers. The samplers of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of samplers. (optional)
    + * Default: {} + * + * @return The samplers + * + */ + public Map getSamplers() { + return this.samplers; + } + + /** + * Add the given samplers. The samplers of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addSamplers(String key, Sampler value) { if (key == null) { @@ -1222,7 +1223,7 @@ public void addSamplers(String key, Sampler value) { } Map oldMap = this.samplers; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1230,15 +1231,15 @@ public void addSamplers(String key, Sampler value) { } /** - * Remove the given samplers. The samplers of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given samplers. The samplers of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeSamplers(String key) { if (key == null) { @@ -1246,7 +1247,7 @@ public void removeSamplers(String key) { } Map oldMap = this.samplers; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1258,75 +1259,75 @@ public void removeSamplers(String key) { } /** - * Returns the default value of the samplers
    - * + * Returns the default value of the samplers
    + * @see #getSamplers + * * @return The default samplers - * @see #getSamplers - * + * */ public Map defaultSamplers() { return new LinkedHashMap(); } /** - * The ID of the default scene. (optional) - * - * @return The scene - * - */ - public String getScene() { - return this.scene; - } - - /** - * The ID of the default scene. (optional) - * + * The ID of the default scene. (optional) + * * @param scene The scene to set - * + * */ public void setScene(String scene) { if (scene == null) { this.scene = scene; - return; + return ; } this.scene = scene; } /** - * A dictionary object of scenes. (optional)
    - * Default: {} - * - * @return The scenes - * + * The ID of the default scene. (optional) + * + * @return The scene + * */ - public Map getScenes() { - return this.scenes; + public String getScene() { + return this.scene; } /** - * A dictionary object of scenes. (optional)
    - * Default: {} - * + * A dictionary object of scenes. (optional)
    + * Default: {} + * * @param scenes The scenes to set - * + * */ public void setScenes(Map scenes) { if (scenes == null) { this.scenes = scenes; - return; + return ; } this.scenes = scenes; } /** - * Add the given scenes. The scenes of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of scenes. (optional)
    + * Default: {} + * + * @return The scenes + * + */ + public Map getScenes() { + return this.scenes; + } + + /** + * Add the given scenes. The scenes of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addScenes(String key, Scene value) { if (key == null) { @@ -1337,7 +1338,7 @@ public void addScenes(String key, Scene value) { } Map oldMap = this.scenes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1345,15 +1346,15 @@ public void addScenes(String key, Scene value) { } /** - * Remove the given scenes. The scenes of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given scenes. The scenes of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeScenes(String key) { if (key == null) { @@ -1361,7 +1362,7 @@ public void removeScenes(String key) { } Map oldMap = this.scenes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1373,51 +1374,51 @@ public void removeScenes(String key) { } /** - * Returns the default value of the scenes
    - * + * Returns the default value of the scenes
    + * @see #getScenes + * * @return The default scenes - * @see #getScenes - * + * */ public Map defaultScenes() { return new LinkedHashMap(); } /** - * A dictionary object of shaders. (optional)
    - * Default: {} - * - * @return The shaders - * - */ - public Map getShaders() { - return this.shaders; - } - - /** - * A dictionary object of shaders. (optional)
    - * Default: {} - * + * A dictionary object of shaders. (optional)
    + * Default: {} + * * @param shaders The shaders to set - * + * */ public void setShaders(Map shaders) { if (shaders == null) { this.shaders = shaders; - return; + return ; } this.shaders = shaders; } /** - * Add the given shaders. The shaders of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of shaders. (optional)
    + * Default: {} + * + * @return The shaders + * + */ + public Map getShaders() { + return this.shaders; + } + + /** + * Add the given shaders. The shaders of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addShaders(String key, Shader value) { if (key == null) { @@ -1428,7 +1429,7 @@ public void addShaders(String key, Shader value) { } Map oldMap = this.shaders; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1436,15 +1437,15 @@ public void addShaders(String key, Shader value) { } /** - * Remove the given shaders. The shaders of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given shaders. The shaders of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeShaders(String key) { if (key == null) { @@ -1452,7 +1453,7 @@ public void removeShaders(String key) { } Map oldMap = this.shaders; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1464,51 +1465,51 @@ public void removeShaders(String key) { } /** - * Returns the default value of the shaders
    - * + * Returns the default value of the shaders
    + * @see #getShaders + * * @return The default shaders - * @see #getShaders - * + * */ public Map defaultShaders() { return new LinkedHashMap(); } /** - * A dictionary object of skins. (optional)
    - * Default: {} - * - * @return The skins - * - */ - public Map getSkins() { - return this.skins; - } - - /** - * A dictionary object of skins. (optional)
    - * Default: {} - * + * A dictionary object of skins. (optional)
    + * Default: {} + * * @param skins The skins to set - * + * */ public void setSkins(Map skins) { if (skins == null) { this.skins = skins; - return; + return ; } this.skins = skins; } /** - * Add the given skins. The skins of this instance will be replaced with - * a map that contains all previous mappings, and additionally the new - * mapping. - * - * @param key The key + * A dictionary object of skins. (optional)
    + * Default: {} + * + * @return The skins + * + */ + public Map getSkins() { + return this.skins; + } + + /** + * Add the given skins. The skins of this instance will be replaced with + * a map that contains all previous mappings, and additionally the new + * mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addSkins(String key, Skin value) { if (key == null) { @@ -1519,7 +1520,7 @@ public void addSkins(String key, Skin value) { } Map oldMap = this.skins; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1527,15 +1528,15 @@ public void addSkins(String key, Skin value) { } /** - * Remove the given skins. The skins of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given skins. The skins of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeSkins(String key) { if (key == null) { @@ -1543,7 +1544,7 @@ public void removeSkins(String key) { } Map oldMap = this.skins; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1555,51 +1556,51 @@ public void removeSkins(String key) { } /** - * Returns the default value of the skins
    - * + * Returns the default value of the skins
    + * @see #getSkins + * * @return The default skins - * @see #getSkins - * + * */ public Map defaultSkins() { return new LinkedHashMap(); } /** - * A dictionary object of techniques. (optional)
    - * Default: {} - * - * @return The techniques - * - */ - public Map getTechniques() { - return this.techniques; - } - - /** - * A dictionary object of techniques. (optional)
    - * Default: {} - * + * A dictionary object of techniques. (optional)
    + * Default: {} + * * @param techniques The techniques to set - * + * */ public void setTechniques(Map techniques) { if (techniques == null) { this.techniques = techniques; - return; + return ; } this.techniques = techniques; } /** - * Add the given techniques. The techniques of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A dictionary object of techniques. (optional)
    + * Default: {} + * + * @return The techniques + * + */ + public Map getTechniques() { + return this.techniques; + } + + /** + * Add the given techniques. The techniques of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addTechniques(String key, Technique value) { if (key == null) { @@ -1610,7 +1611,7 @@ public void addTechniques(String key, Technique value) { } Map oldMap = this.techniques; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1618,15 +1619,15 @@ public void addTechniques(String key, Technique value) { } /** - * Remove the given techniques. The techniques of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given techniques. The techniques of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeTechniques(String key) { if (key == null) { @@ -1634,7 +1635,7 @@ public void removeTechniques(String key) { } Map oldMap = this.techniques; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1646,51 +1647,51 @@ public void removeTechniques(String key) { } /** - * Returns the default value of the techniques
    - * + * Returns the default value of the techniques
    + * @see #getTechniques + * * @return The default techniques - * @see #getTechniques - * + * */ public Map defaultTechniques() { return new LinkedHashMap(); } /** - * A dictionary object of textures. (optional)
    - * Default: {} - * - * @return The textures - * - */ - public Map getTextures() { - return this.textures; - } - - /** - * A dictionary object of textures. (optional)
    - * Default: {} - * + * A dictionary object of textures. (optional)
    + * Default: {} + * * @param textures The textures to set - * + * */ public void setTextures(Map textures) { if (textures == null) { this.textures = textures; - return; + return ; } this.textures = textures; } /** - * Add the given textures. The textures of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of textures. (optional)
    + * Default: {} + * + * @return The textures + * + */ + public Map getTextures() { + return this.textures; + } + + /** + * Add the given textures. The textures of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addTextures(String key, Texture value) { if (key == null) { @@ -1701,7 +1702,7 @@ public void addTextures(String key, Texture value) { } Map oldMap = this.textures; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -1709,15 +1710,15 @@ public void addTextures(String key, Texture value) { } /** - * Remove the given textures. The textures of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given textures. The textures of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeTextures(String key) { if (key == null) { @@ -1725,7 +1726,7 @@ public void removeTextures(String key) { } Map oldMap = this.textures; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -1737,11 +1738,11 @@ public void removeTextures(String key) { } /** - * Returns the default value of the textures
    - * + * Returns the default value of the textures
    + * @see #getTextures + * * @return The default textures - * @see #getTextures - * + * */ public Map defaultTextures() { return new LinkedHashMap(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/GlTFChildOfRootProperty.java b/src/main/java/de/javagl/jgltf/impl/v1/GlTFChildOfRootProperty.java index c266f72..f9f4351 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/GlTFChildOfRootProperty.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/GlTFChildOfRootProperty.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,41 +9,43 @@ package de.javagl.jgltf.impl.v1; + /** - * Auto-generated for glTFChildOfRootProperty.schema.json - * + * Auto-generated for glTFChildOfRootProperty.schema.json + * */ public class GlTFChildOfRootProperty - extends GlTFProperty { + extends GlTFProperty +{ /** - * The user-defined name of this object. (optional) - * + * The user-defined name of this object. (optional) + * */ private String name; /** - * The user-defined name of this object. (optional) - * - * @return The name - * - */ - public String getName() { - return this.name; - } - - /** - * The user-defined name of this object. (optional) - * + * The user-defined name of this object. (optional) + * * @param name The name to set - * + * */ public void setName(String name) { if (name == null) { this.name = name; - return; + return ; } this.name = name; } + /** + * The user-defined name of this object. (optional) + * + * @return The name + * + */ + public String getName() { + return this.name; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/GlTFProperty.java b/src/main/java/de/javagl/jgltf/impl/v1/GlTFProperty.java index 44998de..b9ba2b7 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/GlTFProperty.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/GlTFProperty.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,55 +13,55 @@ /** - * Auto-generated for glTFProperty.schema.json - * + * Auto-generated for glTFProperty.schema.json + * */ public class GlTFProperty { /** - * Dictionary object with extension-specific objects. (optional) - * + * Dictionary object with extension-specific objects. (optional) + * */ private Map extensions; /** - * Application-specific data. (optional) - * + * Application-specific data. (optional) + * */ private Object extras; /** - * Dictionary object with extension-specific objects. (optional) - * - * @return The extensions - * - */ - public Map getExtensions() { - return this.extensions; - } - - /** - * Dictionary object with extension-specific objects. (optional) - * + * Dictionary object with extension-specific objects. (optional) + * * @param extensions The extensions to set - * + * */ public void setExtensions(Map extensions) { if (extensions == null) { this.extensions = extensions; - return; + return ; } this.extensions = extensions; } /** - * Add the given extensions. The extensions of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * Dictionary object with extension-specific objects. (optional) + * + * @return The extensions + * + */ + public Map getExtensions() { + return this.extensions; + } + + /** + * Add the given extensions. The extensions of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addExtensions(String key, Object value) { if (key == null) { @@ -72,7 +72,7 @@ public void addExtensions(String key, Object value) { } Map oldMap = this.extensions; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -80,15 +80,15 @@ public void addExtensions(String key, Object value) { } /** - * Remove the given extensions. The extensions of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given extensions. The extensions of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeExtensions(String key) { if (key == null) { @@ -96,7 +96,7 @@ public void removeExtensions(String key) { } Map oldMap = this.extensions; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -108,27 +108,27 @@ public void removeExtensions(String key) { } /** - * Application-specific data. (optional) - * - * @return The extras - * - */ - public Object getExtras() { - return this.extras; - } - - /** - * Application-specific data. (optional) - * + * Application-specific data. (optional) + * * @param extras The extras to set - * + * */ public void setExtras(Object extras) { if (extras == null) { this.extras = extras; - return; + return ; } this.extras = extras; } + /** + * Application-specific data. (optional) + * + * @return The extras + * + */ + public Object getExtras() { + return this.extras; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Image.java b/src/main/java/de/javagl/jgltf/impl/v1/Image.java index 8a1b729..f83aa2d 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Image.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Image.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,43 +9,45 @@ package de.javagl.jgltf.impl.v1; + /** - * Image data used to create a texture. - *

    - * Auto-generated for image.schema.json - * + * Image data used to create a texture. + * + * Auto-generated for image.schema.json + * */ public class Image - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The uri of the image. (required) - * + * The uri of the image. (required) + * */ private String uri; /** - * The uri of the image. (required) - * - * @return The uri - * - */ - public String getUri() { - return this.uri; - } - - /** - * The uri of the image. (required) - * + * The uri of the image. (required) + * * @param uri The uri to set * @throws NullPointerException If the given value is null - * + * */ public void setUri(String uri) { if (uri == null) { - throw new NullPointerException((("Invalid value for uri: " + uri) + ", may not be null")); + throw new NullPointerException((("Invalid value for uri: "+ uri)+", may not be null")); } this.uri = uri; } + /** + * The uri of the image. (required) + * + * @return The uri + * + */ + public String getUri() { + return this.uri; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Material.java b/src/main/java/de/javagl/jgltf/impl/v1/Material.java index 677d37f..ae40cd0 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Material.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Material.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,85 +13,86 @@ /** - * The material appearance of a primitive. - *

    - * Auto-generated for material.schema.json - * + * The material appearance of a primitive. + * + * Auto-generated for material.schema.json + * */ public class Material - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The ID of the technique. (optional) - * + * The ID of the technique. (optional) + * */ private String technique; /** - * A dictionary object of parameter values. (optional)
    - * Default: {} - * + * A dictionary object of parameter values. (optional)
    + * Default: {} + * */ private Map values; /** - * The ID of the technique. (optional) - * - * @return The technique - * - */ - public String getTechnique() { - return this.technique; - } - - /** - * The ID of the technique. (optional) - * + * The ID of the technique. (optional) + * * @param technique The technique to set - * + * */ public void setTechnique(String technique) { if (technique == null) { this.technique = technique; - return; + return ; } this.technique = technique; } /** - * A dictionary object of parameter values. (optional)
    - * Default: {} - * - * @return The values - * + * The ID of the technique. (optional) + * + * @return The technique + * */ - public Map getValues() { - return this.values; + public String getTechnique() { + return this.technique; } /** - * A dictionary object of parameter values. (optional)
    - * Default: {} - * + * A dictionary object of parameter values. (optional)
    + * Default: {} + * * @param values The values to set - * + * */ public void setValues(Map values) { if (values == null) { this.values = values; - return; + return ; } this.values = values; } /** - * Add the given values. The values of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of parameter values. (optional)
    + * Default: {} + * + * @return The values + * + */ + public Map getValues() { + return this.values; + } + + /** + * Add the given values. The values of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addValues(String key, Object value) { if (key == null) { @@ -102,7 +103,7 @@ public void addValues(String key, Object value) { } Map oldMap = this.values; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -110,15 +111,15 @@ public void addValues(String key, Object value) { } /** - * Remove the given values. The values of this instance will be replaced - * with a map that contains all previous mappings, except for the one - * with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given values. The values of this instance will be replaced + * with a map that contains all previous mappings, except for the one + * with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeValues(String key) { if (key == null) { @@ -126,7 +127,7 @@ public void removeValues(String key) { } Map oldMap = this.values; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -138,11 +139,11 @@ public void removeValues(String key) { } /** - * Returns the default value of the values
    - * + * Returns the default value of the values
    + * @see #getValues + * * @return The default values - * @see #getValues - * + * */ public Map defaultValues() { return new LinkedHashMap(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Mesh.java b/src/main/java/de/javagl/jgltf/impl/v1/Mesh.java index 8034308..4fde1ea 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Mesh.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Mesh.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,68 +13,69 @@ /** - * A set of primitives to be rendered. A node can contain one or more - * meshes. A node's transform places the mesh in the scene. - *

    - * Auto-generated for mesh.schema.json - * + * A set of primitives to be rendered. A node can contain one or more + * meshes. A node's transform places the mesh in the scene. + * + * Auto-generated for mesh.schema.json + * */ public class Mesh - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * An array of primitives, each defining geometry to be rendered with a - * material. (optional)
    - * Default: []
    - * Array elements:
    - *   Geometry to be rendered with the given material. - * (optional) - * + * An array of primitives, each defining geometry to be rendered with a + * material. (optional)
    + * Default: []
    + * Array elements:
    + *   Geometry to be rendered with the given material. + * (optional) + * */ private List primitives; /** - * An array of primitives, each defining geometry to be rendered with a - * material. (optional)
    - * Default: []
    - * Array elements:
    - *   Geometry to be rendered with the given material. - * (optional) - * - * @return The primitives - * - */ - public List getPrimitives() { - return this.primitives; - } - - /** - * An array of primitives, each defining geometry to be rendered with a - * material. (optional)
    - * Default: []
    - * Array elements:
    - *   Geometry to be rendered with the given material. - * (optional) - * + * An array of primitives, each defining geometry to be rendered with a + * material. (optional)
    + * Default: []
    + * Array elements:
    + *   Geometry to be rendered with the given material. + * (optional) + * * @param primitives The primitives to set - * + * */ public void setPrimitives(List primitives) { if (primitives == null) { this.primitives = primitives; - return; + return ; } this.primitives = primitives; } /** - * Add the given primitives. The primitives of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * An array of primitives, each defining geometry to be rendered with a + * material. (optional)
    + * Default: []
    + * Array elements:
    + *   Geometry to be rendered with the given material. + * (optional) + * + * @return The primitives + * + */ + public List getPrimitives() { + return this.primitives; + } + + /** + * Add the given primitives. The primitives of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addPrimitives(MeshPrimitive element) { if (element == null) { @@ -82,7 +83,7 @@ public void addPrimitives(MeshPrimitive element) { } List oldList = this.primitives; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -90,15 +91,15 @@ public void addPrimitives(MeshPrimitive element) { } /** - * Remove the given primitives. The primitives of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given primitives. The primitives of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removePrimitives(MeshPrimitive element) { if (element == null) { @@ -106,7 +107,7 @@ public void removePrimitives(MeshPrimitive element) { } List oldList = this.primitives; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -118,11 +119,11 @@ public void removePrimitives(MeshPrimitive element) { } /** - * Returns the default value of the primitives
    - * + * Returns the default value of the primitives
    + * @see #getPrimitives + * * @return The default primitives - * @see #getPrimitives - * + * */ public List defaultPrimitives() { return new ArrayList(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/MeshPrimitive.java b/src/main/java/de/javagl/jgltf/impl/v1/MeshPrimitive.java index f17c41f..43499c3 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/MeshPrimitive.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/MeshPrimitive.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,77 +13,78 @@ /** - * Geometry to be rendered with the given material. - *

    - * Auto-generated for mesh.primitive.schema.json - * + * Geometry to be rendered with the given material. + * + * Auto-generated for mesh.primitive.schema.json + * */ public class MeshPrimitive - extends GlTFProperty { + extends GlTFProperty +{ /** - * A dictionary object of strings, where each string is the ID of the - * accessor containing an attribute. (optional)
    - * Default: {} - * + * A dictionary object of strings, where each string is the ID of the + * accessor containing an attribute. (optional)
    + * Default: {} + * */ private Map attributes; /** - * The ID of the accessor that contains the indices. (optional) - * + * The ID of the accessor that contains the indices. (optional) + * */ private String indices; /** - * The ID of the material to apply to this primitive when rendering. - * (required) - * + * The ID of the material to apply to this primitive when rendering. + * (required) + * */ private String material; /** - * The type of primitives to render. (optional)
    - * Default: 4
    - * Valid values: [0, 1, 2, 3, 4, 5, 6] - * + * The type of primitives to render. (optional)
    + * Default: 4
    + * Valid values: [0, 1, 2, 3, 4, 5, 6] + * */ private Integer mode; /** - * A dictionary object of strings, where each string is the ID of the - * accessor containing an attribute. (optional)
    - * Default: {} - * - * @return The attributes - * - */ - public Map getAttributes() { - return this.attributes; - } - - /** - * A dictionary object of strings, where each string is the ID of the - * accessor containing an attribute. (optional)
    - * Default: {} - * + * A dictionary object of strings, where each string is the ID of the + * accessor containing an attribute. (optional)
    + * Default: {} + * * @param attributes The attributes to set - * + * */ public void setAttributes(Map attributes) { if (attributes == null) { this.attributes = attributes; - return; + return ; } this.attributes = attributes; } /** - * Add the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A dictionary object of strings, where each string is the ID of the + * accessor containing an attribute. (optional)
    + * Default: {} + * + * @return The attributes + * + */ + public Map getAttributes() { + return this.attributes; + } + + /** + * Add the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAttributes(String key, String value) { if (key == null) { @@ -94,7 +95,7 @@ public void addAttributes(String key, String value) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -102,15 +103,15 @@ public void addAttributes(String key, String value) { } /** - * Remove the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAttributes(String key) { if (key == null) { @@ -118,7 +119,7 @@ public void removeAttributes(String key) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -130,108 +131,108 @@ public void removeAttributes(String key) { } /** - * Returns the default value of the attributes
    - * + * Returns the default value of the attributes
    + * @see #getAttributes + * * @return The default attributes - * @see #getAttributes - * + * */ public Map defaultAttributes() { return new LinkedHashMap(); } /** - * The ID of the accessor that contains the indices. (optional) - * - * @return The indices - * - */ - public String getIndices() { - return this.indices; - } - - /** - * The ID of the accessor that contains the indices. (optional) - * + * The ID of the accessor that contains the indices. (optional) + * * @param indices The indices to set - * + * */ public void setIndices(String indices) { if (indices == null) { this.indices = indices; - return; + return ; } this.indices = indices; } /** - * The ID of the material to apply to this primitive when rendering. - * (required) - * - * @return The material - * + * The ID of the accessor that contains the indices. (optional) + * + * @return The indices + * */ - public String getMaterial() { - return this.material; + public String getIndices() { + return this.indices; } /** - * The ID of the material to apply to this primitive when rendering. - * (required) - * + * The ID of the material to apply to this primitive when rendering. + * (required) + * * @param material The material to set * @throws NullPointerException If the given value is null - * + * */ public void setMaterial(String material) { if (material == null) { - throw new NullPointerException((("Invalid value for material: " + material) + ", may not be null")); + throw new NullPointerException((("Invalid value for material: "+ material)+", may not be null")); } this.material = material; } /** - * The type of primitives to render. (optional)
    - * Default: 4
    - * Valid values: [0, 1, 2, 3, 4, 5, 6] - * - * @return The mode - * + * The ID of the material to apply to this primitive when rendering. + * (required) + * + * @return The material + * */ - public Integer getMode() { - return this.mode; + public String getMaterial() { + return this.material; } /** - * The type of primitives to render. (optional)
    - * Default: 4
    - * Valid values: [0, 1, 2, 3, 4, 5, 6] - * + * The type of primitives to render. (optional)
    + * Default: 4
    + * Valid values: [0, 1, 2, 3, 4, 5, 6] + * * @param mode The mode to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMode(Integer mode) { if (mode == null) { this.mode = mode; - return; + return ; } - if (((((((mode != 0) && (mode != 1)) && (mode != 2)) && (mode != 3)) && (mode != 4)) && (mode != 5)) && (mode != 6)) { - throw new IllegalArgumentException((("Invalid value for mode: " + mode) + ", valid: [0, 1, 2, 3, 4, 5, 6]")); + if (((((((mode!= 0)&&(mode!= 1))&&(mode!= 2))&&(mode!= 3))&&(mode!= 4))&&(mode!= 5))&&(mode!= 6)) { + throw new IllegalArgumentException((("Invalid value for mode: "+ mode)+", valid: [0, 1, 2, 3, 4, 5, 6]")); } this.mode = mode; } /** - * Returns the default value of the mode
    - * + * The type of primitives to render. (optional)
    + * Default: 4
    + * Valid values: [0, 1, 2, 3, 4, 5, 6] + * + * @return The mode + * + */ + public Integer getMode() { + return this.mode; + } + + /** + * Returns the default value of the mode
    + * @see #getMode + * * @return The default mode - * @see #getMode - * + * */ public Integer defaultMode() { - return 4; + return 4; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Node.java b/src/main/java/de/javagl/jgltf/impl/v1/Node.java index 71eba3d..7e268f2 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Node.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Node.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,166 +13,167 @@ /** - * A node in the node hierarchy. A node can have either the `camera`, - * `meshes`, or `skeletons`/`skin`/`meshes` properties defined. In the - * later case, all `primitives` in the referenced `meshes` contain - * `JOINT` and `WEIGHT` attributes and the referenced - * `material`/`technique` from each `primitive` has parameters with - * `JOINT` and `WEIGHT` semantics. A node can have either a `matrix` or - * any combination of `translation`/`rotation`/`scale` (TRS) properties. - * TRS properties are converted to matrices and postmultiplied in the `T - * * R * S` order to compose the transformation matrix; first the scale - * is applied to the vertices, then the rotation, and then the - * translation. If none are provided, the transform is the identity. When - * a node is targeted for animation (referenced by an - * animation.channel.target), only TRS properties may be present; - * `matrix` will not be present. - *

    - * Auto-generated for node.schema.json - * + * A node in the node hierarchy. A node can have either the `camera`, + * `meshes`, or `skeletons`/`skin`/`meshes` properties defined. In the + * later case, all `primitives` in the referenced `meshes` contain + * `JOINT` and `WEIGHT` attributes and the referenced + * `material`/`technique` from each `primitive` has parameters with + * `JOINT` and `WEIGHT` semantics. A node can have either a `matrix` or + * any combination of `translation`/`rotation`/`scale` (TRS) properties. + * TRS properties are converted to matrices and postmultiplied in the `T + * * R * S` order to compose the transformation matrix; first the scale + * is applied to the vertices, then the rotation, and then the + * translation. If none are provided, the transform is the identity. When + * a node is targeted for animation (referenced by an + * animation.channel.target), only TRS properties may be present; + * `matrix` will not be present. + * + * Auto-generated for node.schema.json + * */ public class Node - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The ID of the camera referenced by this node. (optional) - * + * The ID of the camera referenced by this node. (optional) + * */ private String camera; /** - * The IDs of this node's children. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * + * The IDs of this node's children. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List children; /** - * The ID of skeleton nodes. (optional)
    - * Array elements:
    - *   The elements of this array (optional) - * + * The ID of skeleton nodes. (optional)
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List skeletons; /** - * The ID of the skin referenced by this node. (optional) - * + * The ID of the skin referenced by this node. (optional) + * */ private String skin; /** - * Name used when this node is a joint in a skin. (optional) - * + * Name used when this node is a joint in a skin. (optional) + * */ private String jointName; /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
    - * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    - * Number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
    + * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    + * Number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] matrix; /** - * The IDs of the meshes in this node. (optional)
    - * Array elements:
    - *   The elements of this array (optional) - * + * The IDs of the meshes in this node. (optional)
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List meshes; /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
    - * Default: [0.0,0.0,0.0,1.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
    + * Default: [0.0,0.0,0.0,1.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] rotation; /** - * The node's non-uniform scale. (optional)
    - * Default: [1.0,1.0,1.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's non-uniform scale. (optional)
    + * Default: [1.0,1.0,1.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] scale; /** - * The node's translation. (optional)
    - * Default: [0.0,0.0,0.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's translation. (optional)
    + * Default: [0.0,0.0,0.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] translation; /** - * The ID of the camera referenced by this node. (optional) - * - * @return The camera - * - */ - public String getCamera() { - return this.camera; - } - - /** - * The ID of the camera referenced by this node. (optional) - * + * The ID of the camera referenced by this node. (optional) + * * @param camera The camera to set - * + * */ public void setCamera(String camera) { if (camera == null) { this.camera = camera; - return; + return ; } this.camera = camera; } /** - * The IDs of this node's children. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The children - * + * The ID of the camera referenced by this node. (optional) + * + * @return The camera + * */ - public List getChildren() { - return this.children; + public String getCamera() { + return this.camera; } /** - * The IDs of this node's children. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * + * The IDs of this node's children. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * * @param children The children to set - * + * */ public void setChildren(List children) { if (children == null) { this.children = children; - return; + return ; } this.children = children; } /** - * Add the given children. The children of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * The IDs of this node's children. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The children + * + */ + public List getChildren() { + return this.children; + } + + /** + * Add the given children. The children of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addChildren(String element) { if (element == null) { @@ -180,7 +181,7 @@ public void addChildren(String element) { } List oldList = this.children; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -188,15 +189,15 @@ public void addChildren(String element) { } /** - * Remove the given children. The children of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given children. The children of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeChildren(String element) { if (element == null) { @@ -204,7 +205,7 @@ public void removeChildren(String element) { } List oldList = this.children; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -216,52 +217,52 @@ public void removeChildren(String element) { } /** - * Returns the default value of the children
    - * + * Returns the default value of the children
    + * @see #getChildren + * * @return The default children - * @see #getChildren - * + * */ public List defaultChildren() { return new ArrayList(); } /** - * The ID of skeleton nodes. (optional)
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The skeletons - * - */ - public List getSkeletons() { - return this.skeletons; - } - - /** - * The ID of skeleton nodes. (optional)
    - * Array elements:
    - *   The elements of this array (optional) - * + * The ID of skeleton nodes. (optional)
    + * Array elements:
    + *   The elements of this array (optional) + * * @param skeletons The skeletons to set - * + * */ public void setSkeletons(List skeletons) { if (skeletons == null) { this.skeletons = skeletons; - return; + return ; } this.skeletons = skeletons; } /** - * Add the given skeletons. The skeletons of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * The ID of skeleton nodes. (optional)
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The skeletons + * + */ + public List getSkeletons() { + return this.skeletons; + } + + /** + * Add the given skeletons. The skeletons of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addSkeletons(String element) { if (element == null) { @@ -269,7 +270,7 @@ public void addSkeletons(String element) { } List oldList = this.skeletons; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -277,15 +278,15 @@ public void addSkeletons(String element) { } /** - * Remove the given skeletons. The skeletons of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given skeletons. The skeletons of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeSkeletons(String element) { if (element == null) { @@ -293,7 +294,7 @@ public void removeSkeletons(String element) { } List oldList = this.skeletons; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -305,89 +306,73 @@ public void removeSkeletons(String element) { } /** - * The ID of the skin referenced by this node. (optional) - * - * @return The skin - * - */ - public String getSkin() { - return this.skin; - } - - /** - * The ID of the skin referenced by this node. (optional) - * + * The ID of the skin referenced by this node. (optional) + * * @param skin The skin to set - * + * */ public void setSkin(String skin) { if (skin == null) { this.skin = skin; - return; + return ; } this.skin = skin; } /** - * Name used when this node is a joint in a skin. (optional) - * - * @return The jointName - * + * The ID of the skin referenced by this node. (optional) + * + * @return The skin + * */ - public String getJointName() { - return this.jointName; + public String getSkin() { + return this.skin; } /** - * Name used when this node is a joint in a skin. (optional) - * + * Name used when this node is a joint in a skin. (optional) + * * @param jointName The jointName to set - * + * */ public void setJointName(String jointName) { if (jointName == null) { this.jointName = jointName; - return; + return ; } this.jointName = jointName; } /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
    - * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    - * Number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The matrix - * + * Name used when this node is a joint in a skin. (optional) + * + * @return The jointName + * */ - public float[] getMatrix() { - return this.matrix; + public String getJointName() { + return this.jointName; } /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
    - * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    - * Number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
    + * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    + * Number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * * @param matrix The matrix to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMatrix(float[] matrix) { if (matrix == null) { this.matrix = matrix; - return; + return ; } - if (matrix.length < 16) { + if (matrix.length< 16) { throw new IllegalArgumentException("Number of matrix elements is < 16"); } if (matrix.length > 16) { @@ -397,52 +382,68 @@ public void setMatrix(float[] matrix) { } /** - * Returns the default value of the matrix
    - * - * @return The default matrix - * @see #getMatrix - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
    + * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    + * Number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The matrix + * */ - public float[] defaultMatrix() { - return new float[]{1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F}; + public float[] getMatrix() { + return this.matrix; } /** - * The IDs of the meshes in this node. (optional)
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The meshes - * + * Returns the default value of the matrix
    + * @see #getMatrix + * + * @return The default matrix + * */ - public List getMeshes() { - return this.meshes; + public float[] defaultMatrix() { + return new float[] { 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F }; } /** - * The IDs of the meshes in this node. (optional)
    - * Array elements:
    - *   The elements of this array (optional) - * + * The IDs of the meshes in this node. (optional)
    + * Array elements:
    + *   The elements of this array (optional) + * * @param meshes The meshes to set - * + * */ public void setMeshes(List meshes) { if (meshes == null) { this.meshes = meshes; - return; + return ; } this.meshes = meshes; } /** - * Add the given meshes. The meshes of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * The IDs of the meshes in this node. (optional)
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The meshes + * + */ + public List getMeshes() { + return this.meshes; + } + + /** + * Add the given meshes. The meshes of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addMeshes(String element) { if (element == null) { @@ -450,7 +451,7 @@ public void addMeshes(String element) { } List oldList = this.meshes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -458,15 +459,15 @@ public void addMeshes(String element) { } /** - * Remove the given meshes. The meshes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given meshes. The meshes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeMeshes(String element) { if (element == null) { @@ -474,7 +475,7 @@ public void removeMeshes(String element) { } List oldList = this.meshes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -486,39 +487,24 @@ public void removeMeshes(String element) { } /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
    - * Default: [0.0,0.0,0.0,1.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The rotation - * - */ - public float[] getRotation() { - return this.rotation; - } - - /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
    - * Default: [0.0,0.0,0.0,1.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
    + * Default: [0.0,0.0,0.0,1.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * * @param rotation The rotation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setRotation(float[] rotation) { if (rotation == null) { this.rotation = rotation; - return; + return ; } - if (rotation.length < 4) { + if (rotation.length< 4) { throw new IllegalArgumentException("Number of rotation elements is < 4"); } if (rotation.length > 4) { @@ -528,48 +514,49 @@ public void setRotation(float[] rotation) { } /** - * Returns the default value of the rotation
    - * - * @return The default rotation - * @see #getRotation - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
    + * Default: [0.0,0.0,0.0,1.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The rotation + * */ - public float[] defaultRotation() { - return new float[]{0.0F, 0.0F, 0.0F, 1.0F}; + public float[] getRotation() { + return this.rotation; } /** - * The node's non-uniform scale. (optional)
    - * Default: [1.0,1.0,1.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The scale - * + * Returns the default value of the rotation
    + * @see #getRotation + * + * @return The default rotation + * */ - public float[] getScale() { - return this.scale; + public float[] defaultRotation() { + return new float[] { 0.0F, 0.0F, 0.0F, 1.0F }; } /** - * The node's non-uniform scale. (optional)
    - * Default: [1.0,1.0,1.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's non-uniform scale. (optional)
    + * Default: [1.0,1.0,1.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * * @param scale The scale to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setScale(float[] scale) { if (scale == null) { this.scale = scale; - return; + return ; } - if (scale.length < 3) { + if (scale.length< 3) { throw new IllegalArgumentException("Number of scale elements is < 3"); } if (scale.length > 3) { @@ -579,48 +566,48 @@ public void setScale(float[] scale) { } /** - * Returns the default value of the scale
    - * - * @return The default scale - * @see #getScale - * + * The node's non-uniform scale. (optional)
    + * Default: [1.0,1.0,1.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The scale + * */ - public float[] defaultScale() { - return new float[]{1.0F, 1.0F, 1.0F}; + public float[] getScale() { + return this.scale; } /** - * The node's translation. (optional)
    - * Default: [0.0,0.0,0.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The translation - * + * Returns the default value of the scale
    + * @see #getScale + * + * @return The default scale + * */ - public float[] getTranslation() { - return this.translation; + public float[] defaultScale() { + return new float[] { 1.0F, 1.0F, 1.0F }; } /** - * The node's translation. (optional)
    - * Default: [0.0,0.0,0.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's translation. (optional)
    + * Default: [0.0,0.0,0.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * * @param translation The translation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTranslation(float[] translation) { if (translation == null) { this.translation = translation; - return; + return ; } - if (translation.length < 3) { + if (translation.length< 3) { throw new IllegalArgumentException("Number of translation elements is < 3"); } if (translation.length > 3) { @@ -630,14 +617,28 @@ public void setTranslation(float[] translation) { } /** - * Returns the default value of the translation
    - * + * The node's translation. (optional)
    + * Default: [0.0,0.0,0.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The translation + * + */ + public float[] getTranslation() { + return this.translation; + } + + /** + * Returns the default value of the translation
    + * @see #getTranslation + * * @return The default translation - * @see #getTranslation - * + * */ public float[] defaultTranslation() { - return new float[]{0.0F, 0.0F, 0.0F}; + return new float[] { 0.0F, 0.0F, 0.0F }; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Program.java b/src/main/java/de/javagl/jgltf/impl/v1/Program.java index 014bb9b..7ae7762 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Program.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Program.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,72 +13,73 @@ /** - * A shader program, including its vertex and fragment shader, and names - * of vertex shader attributes. - *

    - * Auto-generated for program.schema.json - * + * A shader program, including its vertex and fragment shader, and names + * of vertex shader attributes. + * + * Auto-generated for program.schema.json + * */ public class Program - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * Names of GLSL vertex shader attributes. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * + * Names of GLSL vertex shader attributes. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List attributes; /** - * The ID of the fragment shader. (required) - * + * The ID of the fragment shader. (required) + * */ private String fragmentShader; /** - * The ID of the vertex shader. (required) - * + * The ID of the vertex shader. (required) + * */ private String vertexShader; /** - * Names of GLSL vertex shader attributes. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The attributes - * - */ - public List getAttributes() { - return this.attributes; - } - - /** - * Names of GLSL vertex shader attributes. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * + * Names of GLSL vertex shader attributes. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * * @param attributes The attributes to set - * + * */ public void setAttributes(List attributes) { if (attributes == null) { this.attributes = attributes; - return; + return ; } this.attributes = attributes; } /** - * Add the given attributes. The attributes of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Names of GLSL vertex shader attributes. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The attributes + * + */ + public List getAttributes() { + return this.attributes; + } + + /** + * Add the given attributes. The attributes of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addAttributes(String element) { if (element == null) { @@ -86,7 +87,7 @@ public void addAttributes(String element) { } List oldList = this.attributes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -94,15 +95,15 @@ public void addAttributes(String element) { } /** - * Remove the given attributes. The attributes of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given attributes. The attributes of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeAttributes(String element) { if (element == null) { @@ -110,7 +111,7 @@ public void removeAttributes(String element) { } List oldList = this.attributes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -122,62 +123,62 @@ public void removeAttributes(String element) { } /** - * Returns the default value of the attributes
    - * + * Returns the default value of the attributes
    + * @see #getAttributes + * * @return The default attributes - * @see #getAttributes - * + * */ public List defaultAttributes() { return new ArrayList(); } /** - * The ID of the fragment shader. (required) - * - * @return The fragmentShader - * - */ - public String getFragmentShader() { - return this.fragmentShader; - } - - /** - * The ID of the fragment shader. (required) - * + * The ID of the fragment shader. (required) + * * @param fragmentShader The fragmentShader to set * @throws NullPointerException If the given value is null - * + * */ public void setFragmentShader(String fragmentShader) { if (fragmentShader == null) { - throw new NullPointerException((("Invalid value for fragmentShader: " + fragmentShader) + ", may not be null")); + throw new NullPointerException((("Invalid value for fragmentShader: "+ fragmentShader)+", may not be null")); } this.fragmentShader = fragmentShader; } /** - * The ID of the vertex shader. (required) - * - * @return The vertexShader - * + * The ID of the fragment shader. (required) + * + * @return The fragmentShader + * */ - public String getVertexShader() { - return this.vertexShader; + public String getFragmentShader() { + return this.fragmentShader; } /** - * The ID of the vertex shader. (required) - * + * The ID of the vertex shader. (required) + * * @param vertexShader The vertexShader to set * @throws NullPointerException If the given value is null - * + * */ public void setVertexShader(String vertexShader) { if (vertexShader == null) { - throw new NullPointerException((("Invalid value for vertexShader: " + vertexShader) + ", may not be null")); + throw new NullPointerException((("Invalid value for vertexShader: "+ vertexShader)+", may not be null")); } this.vertexShader = vertexShader; } + /** + * The ID of the vertex shader. (required) + * + * @return The vertexShader + * + */ + public String getVertexShader() { + return this.vertexShader; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Sampler.java b/src/main/java/de/javagl/jgltf/impl/v1/Sampler.java index 63f4749..4126cab 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Sampler.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Sampler.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,218 +9,220 @@ package de.javagl.jgltf.impl.v1; + /** - * Texture sampler properties for filtering and wrapping modes. - *

    - * Auto-generated for sampler.schema.json - * + * Texture sampler properties for filtering and wrapping modes. + * + * Auto-generated for sampler.schema.json + * */ public class Sampler - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * Magnification filter. (optional)
    - * Default: 9729
    - * Valid values: [9728, 9729] - * + * Magnification filter. (optional)
    + * Default: 9729
    + * Valid values: [9728, 9729] + * */ private Integer magFilter; /** - * Minification filter. (optional)
    - * Default: 9986
    - * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * + * Minification filter. (optional)
    + * Default: 9986
    + * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * */ private Integer minFilter; /** - * s wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * + * s wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * */ private Integer wrapS; /** - * t wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * + * t wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * */ private Integer wrapT; /** - * Magnification filter. (optional)
    - * Default: 9729
    - * Valid values: [9728, 9729] - * - * @return The magFilter - * - */ - public Integer getMagFilter() { - return this.magFilter; - } - - /** - * Magnification filter. (optional)
    - * Default: 9729
    - * Valid values: [9728, 9729] - * + * Magnification filter. (optional)
    + * Default: 9729
    + * Valid values: [9728, 9729] + * * @param magFilter The magFilter to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMagFilter(Integer magFilter) { if (magFilter == null) { this.magFilter = magFilter; - return; + return ; } - if ((magFilter != 9728) && (magFilter != 9729)) { - throw new IllegalArgumentException((("Invalid value for magFilter: " + magFilter) + ", valid: [9728, 9729]")); + if ((magFilter!= 9728)&&(magFilter!= 9729)) { + throw new IllegalArgumentException((("Invalid value for magFilter: "+ magFilter)+", valid: [9728, 9729]")); } this.magFilter = magFilter; } /** - * Returns the default value of the magFilter
    - * - * @return The default magFilter - * @see #getMagFilter - * + * Magnification filter. (optional)
    + * Default: 9729
    + * Valid values: [9728, 9729] + * + * @return The magFilter + * */ - public Integer defaultMagFilter() { - return 9729; + public Integer getMagFilter() { + return this.magFilter; } /** - * Minification filter. (optional)
    - * Default: 9986
    - * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * - * @return The minFilter - * + * Returns the default value of the magFilter
    + * @see #getMagFilter + * + * @return The default magFilter + * */ - public Integer getMinFilter() { - return this.minFilter; + public Integer defaultMagFilter() { + return 9729; } /** - * Minification filter. (optional)
    - * Default: 9986
    - * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * + * Minification filter. (optional)
    + * Default: 9986
    + * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * * @param minFilter The minFilter to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMinFilter(Integer minFilter) { if (minFilter == null) { this.minFilter = minFilter; - return; + return ; } - if ((((((minFilter != 9728) && (minFilter != 9729)) && (minFilter != 9984)) && (minFilter != 9985)) && (minFilter != 9986)) && (minFilter != 9987)) { - throw new IllegalArgumentException((("Invalid value for minFilter: " + minFilter) + ", valid: [9728, 9729, 9984, 9985, 9986, 9987]")); + if ((((((minFilter!= 9728)&&(minFilter!= 9729))&&(minFilter!= 9984))&&(minFilter!= 9985))&&(minFilter!= 9986))&&(minFilter!= 9987)) { + throw new IllegalArgumentException((("Invalid value for minFilter: "+ minFilter)+", valid: [9728, 9729, 9984, 9985, 9986, 9987]")); } this.minFilter = minFilter; } /** - * Returns the default value of the minFilter
    - * - * @return The default minFilter - * @see #getMinFilter - * + * Minification filter. (optional)
    + * Default: 9986
    + * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * + * @return The minFilter + * */ - public Integer defaultMinFilter() { - return 9986; + public Integer getMinFilter() { + return this.minFilter; } /** - * s wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * - * @return The wrapS - * + * Returns the default value of the minFilter
    + * @see #getMinFilter + * + * @return The default minFilter + * */ - public Integer getWrapS() { - return this.wrapS; + public Integer defaultMinFilter() { + return 9986; } /** - * s wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * + * s wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * * @param wrapS The wrapS to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWrapS(Integer wrapS) { if (wrapS == null) { this.wrapS = wrapS; - return; + return ; } - if (((wrapS != 33071) && (wrapS != 33648)) && (wrapS != 10497)) { - throw new IllegalArgumentException((("Invalid value for wrapS: " + wrapS) + ", valid: [33071, 33648, 10497]")); + if (((wrapS!= 33071)&&(wrapS!= 33648))&&(wrapS!= 10497)) { + throw new IllegalArgumentException((("Invalid value for wrapS: "+ wrapS)+", valid: [33071, 33648, 10497]")); } this.wrapS = wrapS; } /** - * Returns the default value of the wrapS
    - * - * @return The default wrapS - * @see #getWrapS - * + * s wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * + * @return The wrapS + * */ - public Integer defaultWrapS() { - return 10497; + public Integer getWrapS() { + return this.wrapS; } /** - * t wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * - * @return The wrapT - * + * Returns the default value of the wrapS
    + * @see #getWrapS + * + * @return The default wrapS + * */ - public Integer getWrapT() { - return this.wrapT; + public Integer defaultWrapS() { + return 10497; } /** - * t wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * + * t wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * * @param wrapT The wrapT to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWrapT(Integer wrapT) { if (wrapT == null) { this.wrapT = wrapT; - return; + return ; } - if (((wrapT != 33071) && (wrapT != 33648)) && (wrapT != 10497)) { - throw new IllegalArgumentException((("Invalid value for wrapT: " + wrapT) + ", valid: [33071, 33648, 10497]")); + if (((wrapT!= 33071)&&(wrapT!= 33648))&&(wrapT!= 10497)) { + throw new IllegalArgumentException((("Invalid value for wrapT: "+ wrapT)+", valid: [33071, 33648, 10497]")); } this.wrapT = wrapT; } /** - * Returns the default value of the wrapT
    - * + * t wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * + * @return The wrapT + * + */ + public Integer getWrapT() { + return this.wrapT; + } + + /** + * Returns the default value of the wrapT
    + * @see #getWrapT + * * @return The default wrapT - * @see #getWrapT - * + * */ public Integer defaultWrapT() { - return 10497; + return 10497; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Scene.java b/src/main/java/de/javagl/jgltf/impl/v1/Scene.java index 323ce8f..07e8e83 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Scene.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Scene.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,61 +13,62 @@ /** - * The root nodes of a scene. - *

    - * Auto-generated for scene.schema.json - * + * The root nodes of a scene. + * + * Auto-generated for scene.schema.json + * */ public class Scene - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The IDs of each root node. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * + * The IDs of each root node. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List nodes; /** - * The IDs of each root node. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The nodes - * - */ - public List getNodes() { - return this.nodes; - } - - /** - * The IDs of each root node. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional) - * + * The IDs of each root node. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * * @param nodes The nodes to set - * + * */ public void setNodes(List nodes) { if (nodes == null) { this.nodes = nodes; - return; + return ; } this.nodes = nodes; } /** - * Add the given nodes. The nodes of this instance will be replaced with - * a list that contains all previous elements, and additionally the new - * element. - * + * The IDs of each root node. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The nodes + * + */ + public List getNodes() { + return this.nodes; + } + + /** + * Add the given nodes. The nodes of this instance will be replaced with + * a list that contains all previous elements, and additionally the new + * element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addNodes(String element) { if (element == null) { @@ -75,7 +76,7 @@ public void addNodes(String element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -83,15 +84,15 @@ public void addNodes(String element) { } /** - * Remove the given nodes. The nodes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given nodes. The nodes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeNodes(String element) { if (element == null) { @@ -99,7 +100,7 @@ public void removeNodes(String element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -111,11 +112,11 @@ public void removeNodes(String element) { } /** - * Returns the default value of the nodes
    - * + * Returns the default value of the nodes
    + * @see #getNodes + * * @return The default nodes - * @see #getNodes - * + * */ public List defaultNodes() { return new ArrayList(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Shader.java b/src/main/java/de/javagl/jgltf/impl/v1/Shader.java index ee9ac33..b644917 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Shader.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Shader.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,80 +9,82 @@ package de.javagl.jgltf.impl.v1; + /** - * A vertex or fragment shader. - *

    - * Auto-generated for shader.schema.json - * + * A vertex or fragment shader. + * + * Auto-generated for shader.schema.json + * */ public class Shader - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The uri of the GLSL source. (required) - * + * The uri of the GLSL source. (required) + * */ private String uri; /** - * The shader stage. (required)
    - * Valid values: [35632, 35633] - * + * The shader stage. (required)
    + * Valid values: [35632, 35633] + * */ private Integer type; /** - * The uri of the GLSL source. (required) - * - * @return The uri - * - */ - public String getUri() { - return this.uri; - } - - /** - * The uri of the GLSL source. (required) - * + * The uri of the GLSL source. (required) + * * @param uri The uri to set * @throws NullPointerException If the given value is null - * + * */ public void setUri(String uri) { if (uri == null) { - throw new NullPointerException((("Invalid value for uri: " + uri) + ", may not be null")); + throw new NullPointerException((("Invalid value for uri: "+ uri)+", may not be null")); } this.uri = uri; } /** - * The shader stage. (required)
    - * Valid values: [35632, 35633] - * - * @return The type - * + * The uri of the GLSL source. (required) + * + * @return The uri + * */ - public Integer getType() { - return this.type; + public String getUri() { + return this.uri; } /** - * The shader stage. (required)
    - * Valid values: [35632, 35633] - * + * The shader stage. (required)
    + * Valid values: [35632, 35633] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(Integer type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); + throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); } - if ((type != 35632) && (type != 35633)) { - throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [35632, 35633]")); + if ((type!= 35632)&&(type!= 35633)) { + throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [35632, 35633]")); } this.type = type; } + /** + * The shader stage. (required)
    + * Valid values: [35632, 35633] + * + * @return The type + * + */ + public Integer getType() { + return this.type; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Skin.java b/src/main/java/de/javagl/jgltf/impl/v1/Skin.java index 2b431fc..10895a1 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Skin.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Skin.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,76 +13,61 @@ /** - * Joints and matrices defining a skin. - *

    - * Auto-generated for skin.schema.json - * + * Joints and matrices defining a skin. + * + * Auto-generated for skin.schema.json + * */ public class Skin - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * Floating-point 4x4 transformation matrix stored in column-major order. - * (optional)
    - * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    - * Number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point 4x4 transformation matrix stored in column-major order. + * (optional)
    + * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    + * Number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] bindShapeMatrix; /** - * The ID of the accessor containing the floating-point 4x4 inverse-bind - * matrices. (required) - * + * The ID of the accessor containing the floating-point 4x4 inverse-bind + * matrices. (required) + * */ private String inverseBindMatrices; /** - * Joint names of the joints (nodes with a `jointName` property) in this - * skin. (required)
    - * Array elements:
    - *   The elements of this array (optional) - * + * Joint names of the joints (nodes with a `jointName` property) in this + * skin. (required)
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List jointNames; /** - * Floating-point 4x4 transformation matrix stored in column-major order. - * (optional)
    - * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    - * Number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The bindShapeMatrix - * - */ - public float[] getBindShapeMatrix() { - return this.bindShapeMatrix; - } - - /** - * Floating-point 4x4 transformation matrix stored in column-major order. - * (optional)
    - * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    - * Number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point 4x4 transformation matrix stored in column-major order. + * (optional)
    + * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    + * Number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * * @param bindShapeMatrix The bindShapeMatrix to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBindShapeMatrix(float[] bindShapeMatrix) { if (bindShapeMatrix == null) { this.bindShapeMatrix = bindShapeMatrix; - return; + return ; } - if (bindShapeMatrix.length < 16) { + if (bindShapeMatrix.length< 16) { throw new IllegalArgumentException("Number of bindShapeMatrix elements is < 16"); } if (bindShapeMatrix.length > 16) { @@ -92,80 +77,96 @@ public void setBindShapeMatrix(float[] bindShapeMatrix) { } /** - * Returns the default value of the bindShapeMatrix
    - * - * @return The default bindShapeMatrix - * @see #getBindShapeMatrix - * + * Floating-point 4x4 transformation matrix stored in column-major order. + * (optional)
    + * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    + * Number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The bindShapeMatrix + * */ - public float[] defaultBindShapeMatrix() { - return new float[]{1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F}; + public float[] getBindShapeMatrix() { + return this.bindShapeMatrix; } /** - * The ID of the accessor containing the floating-point 4x4 inverse-bind - * matrices. (required) - * - * @return The inverseBindMatrices - * + * Returns the default value of the bindShapeMatrix
    + * @see #getBindShapeMatrix + * + * @return The default bindShapeMatrix + * */ - public String getInverseBindMatrices() { - return this.inverseBindMatrices; + public float[] defaultBindShapeMatrix() { + return new float[] { 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F }; } /** - * The ID of the accessor containing the floating-point 4x4 inverse-bind - * matrices. (required) - * + * The ID of the accessor containing the floating-point 4x4 inverse-bind + * matrices. (required) + * * @param inverseBindMatrices The inverseBindMatrices to set * @throws NullPointerException If the given value is null - * + * */ public void setInverseBindMatrices(String inverseBindMatrices) { if (inverseBindMatrices == null) { - throw new NullPointerException((("Invalid value for inverseBindMatrices: " + inverseBindMatrices) + ", may not be null")); + throw new NullPointerException((("Invalid value for inverseBindMatrices: "+ inverseBindMatrices)+", may not be null")); } this.inverseBindMatrices = inverseBindMatrices; } /** - * Joint names of the joints (nodes with a `jointName` property) in this - * skin. (required)
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The jointNames - * + * The ID of the accessor containing the floating-point 4x4 inverse-bind + * matrices. (required) + * + * @return The inverseBindMatrices + * */ - public List getJointNames() { - return this.jointNames; + public String getInverseBindMatrices() { + return this.inverseBindMatrices; } /** - * Joint names of the joints (nodes with a `jointName` property) in this - * skin. (required)
    - * Array elements:
    - *   The elements of this array (optional) - * + * Joint names of the joints (nodes with a `jointName` property) in this + * skin. (required)
    + * Array elements:
    + *   The elements of this array (optional) + * * @param jointNames The jointNames to set * @throws NullPointerException If the given value is null - * + * */ public void setJointNames(List jointNames) { if (jointNames == null) { - throw new NullPointerException((("Invalid value for jointNames: " + jointNames) + ", may not be null")); + throw new NullPointerException((("Invalid value for jointNames: "+ jointNames)+", may not be null")); } this.jointNames = jointNames; } /** - * Add the given jointNames. The jointNames of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Joint names of the joints (nodes with a `jointName` property) in this + * skin. (required)
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The jointNames + * + */ + public List getJointNames() { + return this.jointNames; + } + + /** + * Add the given jointNames. The jointNames of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addJointNames(String element) { if (element == null) { @@ -173,7 +174,7 @@ public void addJointNames(String element) { } List oldList = this.jointNames; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -181,13 +182,13 @@ public void addJointNames(String element) { } /** - * Remove the given jointNames. The jointNames of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one. - * + * Remove the given jointNames. The jointNames of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeJointNames(String element) { if (element == null) { @@ -195,7 +196,7 @@ public void removeJointNames(String element) { } List oldList = this.jointNames; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Technique.java b/src/main/java/de/javagl/jgltf/impl/v1/Technique.java index 4d20d78..b2469bb 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Technique.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Technique.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,81 +13,82 @@ /** - * A template for material appearances. - *

    - * Auto-generated for technique.schema.json - * + * A template for material appearances. + * + * Auto-generated for technique.schema.json + * */ public class Technique - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * A dictionary object of technique.parameters objects. (optional)
    - * Default: {} - * + * A dictionary object of technique.parameters objects. (optional)
    + * Default: {} + * */ private Map parameters; /** - * A dictionary object of strings that maps GLSL attribute names to - * technique parameter IDs. (optional)
    - * Default: {} - * + * A dictionary object of strings that maps GLSL attribute names to + * technique parameter IDs. (optional)
    + * Default: {} + * */ private Map attributes; /** - * The ID of the program. (required) - * + * The ID of the program. (required) + * */ private String program; /** - * A dictionary object of strings that maps GLSL uniform names to - * technique parameter IDs. (optional)
    - * Default: {} - * + * A dictionary object of strings that maps GLSL uniform names to + * technique parameter IDs. (optional)
    + * Default: {} + * */ private Map uniforms; /** - * Fixed-function rendering states. (optional)
    - * Default: {} - * + * Fixed-function rendering states. (optional)
    + * Default: {} + * */ private TechniqueStates states; /** - * A dictionary object of technique.parameters objects. (optional)
    - * Default: {} - * - * @return The parameters - * - */ - public Map getParameters() { - return this.parameters; - } - - /** - * A dictionary object of technique.parameters objects. (optional)
    - * Default: {} - * + * A dictionary object of technique.parameters objects. (optional)
    + * Default: {} + * * @param parameters The parameters to set - * + * */ public void setParameters(Map parameters) { if (parameters == null) { this.parameters = parameters; - return; + return ; } this.parameters = parameters; } /** - * Add the given parameters. The parameters of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A dictionary object of technique.parameters objects. (optional)
    + * Default: {} + * + * @return The parameters + * + */ + public Map getParameters() { + return this.parameters; + } + + /** + * Add the given parameters. The parameters of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addParameters(String key, TechniqueParameters value) { if (key == null) { @@ -98,7 +99,7 @@ public void addParameters(String key, TechniqueParameters value) { } Map oldMap = this.parameters; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -106,15 +107,15 @@ public void addParameters(String key, TechniqueParameters value) { } /** - * Remove the given parameters. The parameters of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given parameters. The parameters of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeParameters(String key) { if (key == null) { @@ -122,7 +123,7 @@ public void removeParameters(String key) { } Map oldMap = this.parameters; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -134,53 +135,53 @@ public void removeParameters(String key) { } /** - * Returns the default value of the parameters
    - * + * Returns the default value of the parameters
    + * @see #getParameters + * * @return The default parameters - * @see #getParameters - * + * */ public Map defaultParameters() { return new LinkedHashMap(); } /** - * A dictionary object of strings that maps GLSL attribute names to - * technique parameter IDs. (optional)
    - * Default: {} - * - * @return The attributes - * - */ - public Map getAttributes() { - return this.attributes; - } - - /** - * A dictionary object of strings that maps GLSL attribute names to - * technique parameter IDs. (optional)
    - * Default: {} - * + * A dictionary object of strings that maps GLSL attribute names to + * technique parameter IDs. (optional)
    + * Default: {} + * * @param attributes The attributes to set - * + * */ public void setAttributes(Map attributes) { if (attributes == null) { this.attributes = attributes; - return; + return ; } this.attributes = attributes; } /** - * Add the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A dictionary object of strings that maps GLSL attribute names to + * technique parameter IDs. (optional)
    + * Default: {} + * + * @return The attributes + * + */ + public Map getAttributes() { + return this.attributes; + } + + /** + * Add the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAttributes(String key, String value) { if (key == null) { @@ -191,7 +192,7 @@ public void addAttributes(String key, String value) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -199,15 +200,15 @@ public void addAttributes(String key, String value) { } /** - * Remove the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAttributes(String key) { if (key == null) { @@ -215,7 +216,7 @@ public void removeAttributes(String key) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -227,77 +228,77 @@ public void removeAttributes(String key) { } /** - * Returns the default value of the attributes
    - * + * Returns the default value of the attributes
    + * @see #getAttributes + * * @return The default attributes - * @see #getAttributes - * + * */ public Map defaultAttributes() { return new LinkedHashMap(); } /** - * The ID of the program. (required) - * - * @return The program - * - */ - public String getProgram() { - return this.program; - } - - /** - * The ID of the program. (required) - * + * The ID of the program. (required) + * * @param program The program to set * @throws NullPointerException If the given value is null - * + * */ public void setProgram(String program) { if (program == null) { - throw new NullPointerException((("Invalid value for program: " + program) + ", may not be null")); + throw new NullPointerException((("Invalid value for program: "+ program)+", may not be null")); } this.program = program; } /** - * A dictionary object of strings that maps GLSL uniform names to - * technique parameter IDs. (optional)
    - * Default: {} - * - * @return The uniforms - * + * The ID of the program. (required) + * + * @return The program + * */ - public Map getUniforms() { - return this.uniforms; + public String getProgram() { + return this.program; } /** - * A dictionary object of strings that maps GLSL uniform names to - * technique parameter IDs. (optional)
    - * Default: {} - * + * A dictionary object of strings that maps GLSL uniform names to + * technique parameter IDs. (optional)
    + * Default: {} + * * @param uniforms The uniforms to set - * + * */ public void setUniforms(Map uniforms) { if (uniforms == null) { this.uniforms = uniforms; - return; + return ; } this.uniforms = uniforms; } /** - * Add the given uniforms. The uniforms of this instance will be replaced - * with a map that contains all previous mappings, and additionally the - * new mapping. - * - * @param key The key + * A dictionary object of strings that maps GLSL uniform names to + * technique parameter IDs. (optional)
    + * Default: {} + * + * @return The uniforms + * + */ + public Map getUniforms() { + return this.uniforms; + } + + /** + * Add the given uniforms. The uniforms of this instance will be replaced + * with a map that contains all previous mappings, and additionally the + * new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addUniforms(String key, String value) { if (key == null) { @@ -308,7 +309,7 @@ public void addUniforms(String key, String value) { } Map oldMap = this.uniforms; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -316,15 +317,15 @@ public void addUniforms(String key, String value) { } /** - * Remove the given uniforms. The uniforms of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given uniforms. The uniforms of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeUniforms(String key) { if (key == null) { @@ -332,7 +333,7 @@ public void removeUniforms(String key) { } Map oldMap = this.uniforms; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -344,48 +345,48 @@ public void removeUniforms(String key) { } /** - * Returns the default value of the uniforms
    - * + * Returns the default value of the uniforms
    + * @see #getUniforms + * * @return The default uniforms - * @see #getUniforms - * + * */ public Map defaultUniforms() { return new LinkedHashMap(); } /** - * Fixed-function rendering states. (optional)
    - * Default: {} - * - * @return The states - * - */ - public TechniqueStates getStates() { - return this.states; - } - - /** - * Fixed-function rendering states. (optional)
    - * Default: {} - * + * Fixed-function rendering states. (optional)
    + * Default: {} + * * @param states The states to set - * + * */ public void setStates(TechniqueStates states) { if (states == null) { this.states = states; - return; + return ; } this.states = states; } /** - * Returns the default value of the states
    - * + * Fixed-function rendering states. (optional)
    + * Default: {} + * + * @return The states + * + */ + public TechniqueStates getStates() { + return this.states; + } + + /** + * Returns the default value of the states
    + * @see #getStates + * * @return The default states - * @see #getStates - * + * */ public TechniqueStates defaultStates() { return new TechniqueStates(); diff --git a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueParameters.java b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueParameters.java index 63b40a9..f3f80fd 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueParameters.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueParameters.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,191 +9,193 @@ package de.javagl.jgltf.impl.v1; + /** - * An attribute or uniform input to a technique, and an optional semantic - * and value. - *

    - * Auto-generated for technique.parameters.schema.json - * + * An attribute or uniform input to a technique, and an optional semantic + * and value. + * + * Auto-generated for technique.parameters.schema.json + * */ public class TechniqueParameters - extends GlTFProperty { + extends GlTFProperty +{ /** - * When defined, the parameter is an array of count elements of the - * specified type. Otherwise, the parameter is not an array. - * (optional)
    - * Minimum: 1 (inclusive) - * + * When defined, the parameter is an array of count elements of the + * specified type. Otherwise, the parameter is not an array. + * (optional)
    + * Minimum: 1 (inclusive) + * */ private Integer count; /** - * The id of the node whose transform is used as the parameter's value. - * (optional) - * + * The id of the node whose transform is used as the parameter's value. + * (optional) + * */ private String node; /** - * The datatype. (required)
    - * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, - * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, - * 35676, 35678] - * + * The datatype. (required)
    + * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, + * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, + * 35676, 35678] + * */ private Integer type; /** - * Identifies a parameter with a well-known meaning. (optional) - * + * Identifies a parameter with a well-known meaning. (optional) + * */ private String semantic; /** - * The value of the parameter. (optional) - * + * The value of the parameter. (optional) + * */ private Object value; /** - * When defined, the parameter is an array of count elements of the - * specified type. Otherwise, the parameter is not an array. - * (optional)
    - * Minimum: 1 (inclusive) - * - * @return The count - * - */ - public Integer getCount() { - return this.count; - } - - /** - * When defined, the parameter is an array of count elements of the - * specified type. Otherwise, the parameter is not an array. - * (optional)
    - * Minimum: 1 (inclusive) - * + * When defined, the parameter is an array of count elements of the + * specified type. Otherwise, the parameter is not an array. + * (optional)
    + * Minimum: 1 (inclusive) + * * @param count The count to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCount(Integer count) { if (count == null) { this.count = count; - return; + return ; } - if (count < 1) { + if (count< 1) { throw new IllegalArgumentException("count < 1"); } this.count = count; } /** - * The id of the node whose transform is used as the parameter's value. - * (optional) - * - * @return The node - * + * When defined, the parameter is an array of count elements of the + * specified type. Otherwise, the parameter is not an array. + * (optional)
    + * Minimum: 1 (inclusive) + * + * @return The count + * */ - public String getNode() { - return this.node; + public Integer getCount() { + return this.count; } /** - * The id of the node whose transform is used as the parameter's value. - * (optional) - * + * The id of the node whose transform is used as the parameter's value. + * (optional) + * * @param node The node to set - * + * */ public void setNode(String node) { if (node == null) { this.node = node; - return; + return ; } this.node = node; } /** - * The datatype. (required)
    - * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, - * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, - * 35676, 35678] - * - * @return The type - * + * The id of the node whose transform is used as the parameter's value. + * (optional) + * + * @return The node + * */ - public Integer getType() { - return this.type; + public String getNode() { + return this.node; } /** - * The datatype. (required)
    - * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, - * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, - * 35676, 35678] - * + * The datatype. (required)
    + * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, + * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, + * 35676, 35678] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(Integer type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); + throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); } - if (((((((((((((((((((((type != 5120) && (type != 5121)) && (type != 5122)) && (type != 5123)) && (type != 5124)) && (type != 5125)) && (type != 5126)) && (type != 35664)) && (type != 35665)) && (type != 35666)) && (type != 35667)) && (type != 35668)) && (type != 35669)) && (type != 35670)) && (type != 35671)) && (type != 35672)) && (type != 35673)) && (type != 35674)) && (type != 35675)) && (type != 35676)) && (type != 35678)) { - throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, 35676, 35678]")); + if (((((((((((((((((((((type!= 5120)&&(type!= 5121))&&(type!= 5122))&&(type!= 5123))&&(type!= 5124))&&(type!= 5125))&&(type!= 5126))&&(type!= 35664))&&(type!= 35665))&&(type!= 35666))&&(type!= 35667))&&(type!= 35668))&&(type!= 35669))&&(type!= 35670))&&(type!= 35671))&&(type!= 35672))&&(type!= 35673))&&(type!= 35674))&&(type!= 35675))&&(type!= 35676))&&(type!= 35678)) { + throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, 35676, 35678]")); } this.type = type; } /** - * Identifies a parameter with a well-known meaning. (optional) - * - * @return The semantic - * + * The datatype. (required)
    + * Valid values: [5120, 5121, 5122, 5123, 5124, 5125, 5126, 35664, 35665, + * 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, + * 35676, 35678] + * + * @return The type + * */ - public String getSemantic() { - return this.semantic; + public Integer getType() { + return this.type; } /** - * Identifies a parameter with a well-known meaning. (optional) - * + * Identifies a parameter with a well-known meaning. (optional) + * * @param semantic The semantic to set - * + * */ public void setSemantic(String semantic) { if (semantic == null) { this.semantic = semantic; - return; + return ; } this.semantic = semantic; } /** - * The value of the parameter. (optional) - * - * @return The value - * + * Identifies a parameter with a well-known meaning. (optional) + * + * @return The semantic + * */ - public Object getValue() { - return this.value; + public String getSemantic() { + return this.semantic; } /** - * The value of the parameter. (optional) - * + * The value of the parameter. (optional) + * * @param value The value to set - * + * */ public void setValue(Object value) { if (value == null) { this.value = value; - return; + return ; } this.value = value; } + /** + * The value of the parameter. (optional) + * + * @return The value + * + */ + public Object getValue() { + return this.value; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStates.java b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStates.java index 3ad3874..dc2b1ef 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStates.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStates.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -13,77 +13,78 @@ /** - * Fixed-function rendering states. - *

    - * Auto-generated for technique.states.schema.json - * + * Fixed-function rendering states. + * + * Auto-generated for technique.states.schema.json + * */ public class TechniqueStates - extends GlTFProperty { + extends GlTFProperty +{ /** - * WebGL states to enable. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] - * + * WebGL states to enable. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] + * */ private List enable; /** - * Arguments for fixed-function rendering state functions other than - * `enable()`/`disable()`. (optional) - * + * Arguments for fixed-function rendering state functions other than + * `enable()`/`disable()`. (optional) + * */ private TechniqueStatesFunctions functions; /** - * WebGL states to enable. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] - * - * @return The enable - * - */ - public List getEnable() { - return this.enable; - } - - /** - * WebGL states to enable. (optional)
    - * Default: []
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] - * + * WebGL states to enable. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] + * * @param enable The enable to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setEnable(List enable) { if (enable == null) { this.enable = enable; - return; + return ; } - for (Integer enableElement : enable) { - if ((((((enableElement != 3042) && (enableElement != 2884)) && (enableElement != 2929)) && (enableElement != 32823)) && (enableElement != 32926)) && (enableElement != 3089)) { - throw new IllegalArgumentException((("Invalid value for enableElement: " + enableElement) + ", valid: [3042, 2884, 2929, 32823, 32926, 3089]")); + for (Integer enableElement: enable) { + if ((((((enableElement!= 3042)&&(enableElement!= 2884))&&(enableElement!= 2929))&&(enableElement!= 32823))&&(enableElement!= 32926))&&(enableElement!= 3089)) { + throw new IllegalArgumentException((("Invalid value for enableElement: "+ enableElement)+", valid: [3042, 2884, 2929, 32823, 32926, 3089]")); } } this.enable = enable; } /** - * Add the given enable. The enable of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * WebGL states to enable. (optional)
    + * Default: []
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [3042, 2884, 2929, 32823, 32926, 3089] + * + * @return The enable + * + */ + public List getEnable() { + return this.enable; + } + + /** + * Add the given enable. The enable of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addEnable(Integer element) { if (element == null) { @@ -91,7 +92,7 @@ public void addEnable(Integer element) { } List oldList = this.enable; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -99,15 +100,15 @@ public void addEnable(Integer element) { } /** - * Remove the given enable. The enable of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given enable. The enable of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeEnable(Integer element) { if (element == null) { @@ -115,7 +116,7 @@ public void removeEnable(Integer element) { } List oldList = this.enable; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -127,40 +128,40 @@ public void removeEnable(Integer element) { } /** - * Returns the default value of the enable
    - * + * Returns the default value of the enable
    + * @see #getEnable + * * @return The default enable - * @see #getEnable - * + * */ public List defaultEnable() { return new ArrayList(); } /** - * Arguments for fixed-function rendering state functions other than - * `enable()`/`disable()`. (optional) - * - * @return The functions - * - */ - public TechniqueStatesFunctions getFunctions() { - return this.functions; - } - - /** - * Arguments for fixed-function rendering state functions other than - * `enable()`/`disable()`. (optional) - * + * Arguments for fixed-function rendering state functions other than + * `enable()`/`disable()`. (optional) + * * @param functions The functions to set - * + * */ public void setFunctions(TechniqueStatesFunctions functions) { if (functions == null) { this.functions = functions; - return; + return ; } this.functions = functions; } + /** + * Arguments for fixed-function rendering state functions other than + * `enable()`/`disable()`. (optional) + * + * @return The functions + * + */ + public TechniqueStatesFunctions getFunctions() { + return this.functions; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStatesFunctions.java b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStatesFunctions.java index 9294293..fe8c30e 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStatesFunctions.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/TechniqueStatesFunctions.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,171 +9,158 @@ package de.javagl.jgltf.impl.v1; + /** - * Arguments for fixed-function rendering state functions other than - * `enable()`/`disable()`. - *

    - * Auto-generated for technique.states.functions.schema.json - * + * Arguments for fixed-function rendering state functions other than + * `enable()`/`disable()`. + * + * Auto-generated for technique.states.functions.schema.json + * */ public class TechniqueStatesFunctions - extends GlTFProperty { + extends GlTFProperty +{ /** - * Floating-point values passed to `blendColor()`. [red, green, blue, - * alpha] (optional)
    - * Default: [0.0,0.0,0.0,0.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point values passed to `blendColor()`. [red, green, blue, + * alpha] (optional)
    + * Default: [0.0,0.0,0.0,0.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] blendColor; /** - * Integer values passed to `blendEquationSeparate()`. (optional)
    - * Default: [32774,32774]
    - * Number of items: 2
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [32774, 32778, 32779] - * + * Integer values passed to `blendEquationSeparate()`. (optional)
    + * Default: [32774,32774]
    + * Number of items: 2
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [32774, 32778, 32779] + * */ private int[] blendEquationSeparate; /** - * Integer values passed to `blendFuncSeparate()`. (optional)
    - * Default: [1,0,1,0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, - * 773, 32769, 32770, 32771, 32772, 776] - * + * Integer values passed to `blendFuncSeparate()`. (optional)
    + * Default: [1,0,1,0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, + * 773, 32769, 32770, 32771, 32772, 776] + * */ private int[] blendFuncSeparate; /** - * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. - * (optional)
    - * Default: [true,true,true,true]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * + * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. + * (optional)
    + * Default: [true,true,true,true]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * */ private boolean[] colorMask; /** - * Integer value passed to `cullFace()`. (optional)
    - * Default: [1029]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [1028, 1029, 1032] - * + * Integer value passed to `cullFace()`. (optional)
    + * Default: [1029]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [1028, 1029, 1032] + * */ private int[] cullFace; /** - * Integer values passed to `depthFunc()`. (optional)
    - * Default: [513]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] - * + * Integer values passed to `depthFunc()`. (optional)
    + * Default: [513]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] + * */ private int[] depthFunc; /** - * Boolean value passed to `depthMask()`. (optional)
    - * Default: [true]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * Boolean value passed to `depthMask()`. (optional)
    + * Default: [true]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * */ private boolean[] depthMask; /** - * Floating-point values passed to `depthRange()`. [zNear, zFar] - * (optional)
    - * Default: [0.0,1.0]
    - * Number of items: 2
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point values passed to `depthRange()`. [zNear, zFar] + * (optional)
    + * Default: [0.0,1.0]
    + * Number of items: 2
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] depthRange; /** - * Integer value passed to `frontFace()`. (optional)
    - * Default: [2305]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [2304, 2305] - * + * Integer value passed to `frontFace()`. (optional)
    + * Default: [2305]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [2304, 2305] + * */ private int[] frontFace; /** - * Floating-point value passed to `lineWidth()`. (optional)
    - * Default: [1.0]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0.0 (exclusive) - * + * Floating-point value passed to `lineWidth()`. (optional)
    + * Default: [1.0]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0.0 (exclusive) + * */ private float[] lineWidth; /** - * Floating-point value passed to `polygonOffset()`. [factor, units] - * (optional)
    - * Default: [0.0,0.0]
    - * Number of items: 2
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point value passed to `polygonOffset()`. [factor, units] + * (optional)
    + * Default: [0.0,0.0]
    + * Number of items: 2
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] polygonOffset; /** - * Floating-point value passed to `scissor()`. [x, y, width, height]. - * (optional)
    - * Default: [0.0,0.0,0.0,0.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point value passed to `scissor()`. [x, y, width, height]. + * (optional)
    + * Default: [0.0,0.0,0.0,0.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] scissor; /** - * Floating-point values passed to `blendColor()`. [red, green, blue, - * alpha] (optional)
    - * Default: [0.0,0.0,0.0,0.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The blendColor - * - */ - public float[] getBlendColor() { - return this.blendColor; - } - - /** - * Floating-point values passed to `blendColor()`. [red, green, blue, - * alpha] (optional)
    - * Default: [0.0,0.0,0.0,0.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point values passed to `blendColor()`. [red, green, blue, + * alpha] (optional)
    + * Default: [0.0,0.0,0.0,0.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * * @param blendColor The blendColor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBlendColor(float[] blendColor) { if (blendColor == null) { this.blendColor = blendColor; - return; + return ; } - if (blendColor.length < 4) { + if (blendColor.length< 4) { throw new IllegalArgumentException("Number of blendColor elements is < 4"); } if (blendColor.length > 4) { @@ -183,168 +170,168 @@ public void setBlendColor(float[] blendColor) { } /** - * Returns the default value of the blendColor
    - * - * @return The default blendColor - * @see #getBlendColor - * + * Floating-point values passed to `blendColor()`. [red, green, blue, + * alpha] (optional)
    + * Default: [0.0,0.0,0.0,0.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The blendColor + * */ - public float[] defaultBlendColor() { - return new float[]{0.0F, 0.0F, 0.0F, 0.0F}; + public float[] getBlendColor() { + return this.blendColor; } /** - * Integer values passed to `blendEquationSeparate()`. (optional)
    - * Default: [32774,32774]
    - * Number of items: 2
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [32774, 32778, 32779] - * - * @return The blendEquationSeparate - * + * Returns the default value of the blendColor
    + * @see #getBlendColor + * + * @return The default blendColor + * */ - public int[] getBlendEquationSeparate() { - return this.blendEquationSeparate; + public float[] defaultBlendColor() { + return new float[] { 0.0F, 0.0F, 0.0F, 0.0F }; } /** - * Integer values passed to `blendEquationSeparate()`. (optional)
    - * Default: [32774,32774]
    - * Number of items: 2
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [32774, 32778, 32779] - * + * Integer values passed to `blendEquationSeparate()`. (optional)
    + * Default: [32774,32774]
    + * Number of items: 2
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [32774, 32778, 32779] + * * @param blendEquationSeparate The blendEquationSeparate to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBlendEquationSeparate(int[] blendEquationSeparate) { if (blendEquationSeparate == null) { this.blendEquationSeparate = blendEquationSeparate; - return; + return ; } - if (blendEquationSeparate.length < 2) { + if (blendEquationSeparate.length< 2) { throw new IllegalArgumentException("Number of blendEquationSeparate elements is < 2"); } if (blendEquationSeparate.length > 2) { throw new IllegalArgumentException("Number of blendEquationSeparate elements is > 2"); } - for (int blendEquationSeparateElement : blendEquationSeparate) { - if (((blendEquationSeparateElement != 32774) && (blendEquationSeparateElement != 32778)) && (blendEquationSeparateElement != 32779)) { - throw new IllegalArgumentException((("Invalid value for blendEquationSeparateElement: " + blendEquationSeparateElement) + ", valid: [32774, 32778, 32779]")); + for (int blendEquationSeparateElement: blendEquationSeparate) { + if (((blendEquationSeparateElement!= 32774)&&(blendEquationSeparateElement!= 32778))&&(blendEquationSeparateElement!= 32779)) { + throw new IllegalArgumentException((("Invalid value for blendEquationSeparateElement: "+ blendEquationSeparateElement)+", valid: [32774, 32778, 32779]")); } } this.blendEquationSeparate = blendEquationSeparate; } /** - * Returns the default value of the blendEquationSeparate
    - * - * @return The default blendEquationSeparate - * @see #getBlendEquationSeparate - * + * Integer values passed to `blendEquationSeparate()`. (optional)
    + * Default: [32774,32774]
    + * Number of items: 2
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [32774, 32778, 32779] + * + * @return The blendEquationSeparate + * */ - public int[] defaultBlendEquationSeparate() { - return new int[]{32774, 32774}; + public int[] getBlendEquationSeparate() { + return this.blendEquationSeparate; } /** - * Integer values passed to `blendFuncSeparate()`. (optional)
    - * Default: [1,0,1,0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, - * 773, 32769, 32770, 32771, 32772, 776] - * - * @return The blendFuncSeparate - * + * Returns the default value of the blendEquationSeparate
    + * @see #getBlendEquationSeparate + * + * @return The default blendEquationSeparate + * */ - public int[] getBlendFuncSeparate() { - return this.blendFuncSeparate; + public int[] defaultBlendEquationSeparate() { + return new int[] { 32774, 32774 }; } /** - * Integer values passed to `blendFuncSeparate()`. (optional)
    - * Default: [1,0,1,0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, - * 773, 32769, 32770, 32771, 32772, 776] - * + * Integer values passed to `blendFuncSeparate()`. (optional)
    + * Default: [1,0,1,0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, + * 773, 32769, 32770, 32771, 32772, 776] + * * @param blendFuncSeparate The blendFuncSeparate to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBlendFuncSeparate(int[] blendFuncSeparate) { if (blendFuncSeparate == null) { this.blendFuncSeparate = blendFuncSeparate; - return; + return ; } - if (blendFuncSeparate.length < 4) { + if (blendFuncSeparate.length< 4) { throw new IllegalArgumentException("Number of blendFuncSeparate elements is < 4"); } if (blendFuncSeparate.length > 4) { throw new IllegalArgumentException("Number of blendFuncSeparate elements is > 4"); } - for (int blendFuncSeparateElement : blendFuncSeparate) { - if (((((((((((((((blendFuncSeparateElement != 0) && (blendFuncSeparateElement != 1)) && (blendFuncSeparateElement != 768)) && (blendFuncSeparateElement != 769)) && (blendFuncSeparateElement != 774)) && (blendFuncSeparateElement != 775)) && (blendFuncSeparateElement != 770)) && (blendFuncSeparateElement != 771)) && (blendFuncSeparateElement != 772)) && (blendFuncSeparateElement != 773)) && (blendFuncSeparateElement != 32769)) && (blendFuncSeparateElement != 32770)) && (blendFuncSeparateElement != 32771)) && (blendFuncSeparateElement != 32772)) && (blendFuncSeparateElement != 776)) { - throw new IllegalArgumentException((("Invalid value for blendFuncSeparateElement: " + blendFuncSeparateElement) + ", valid: [0, 1, 768, 769, 774, 775, 770, 771, 772, 773, 32769, 32770, 32771, 32772, 776]")); + for (int blendFuncSeparateElement: blendFuncSeparate) { + if (((((((((((((((blendFuncSeparateElement!= 0)&&(blendFuncSeparateElement!= 1))&&(blendFuncSeparateElement!= 768))&&(blendFuncSeparateElement!= 769))&&(blendFuncSeparateElement!= 774))&&(blendFuncSeparateElement!= 775))&&(blendFuncSeparateElement!= 770))&&(blendFuncSeparateElement!= 771))&&(blendFuncSeparateElement!= 772))&&(blendFuncSeparateElement!= 773))&&(blendFuncSeparateElement!= 32769))&&(blendFuncSeparateElement!= 32770))&&(blendFuncSeparateElement!= 32771))&&(blendFuncSeparateElement!= 32772))&&(blendFuncSeparateElement!= 776)) { + throw new IllegalArgumentException((("Invalid value for blendFuncSeparateElement: "+ blendFuncSeparateElement)+", valid: [0, 1, 768, 769, 774, 775, 770, 771, 772, 773, 32769, 32770, 32771, 32772, 776]")); } } this.blendFuncSeparate = blendFuncSeparate; } /** - * Returns the default value of the blendFuncSeparate
    - * - * @return The default blendFuncSeparate - * @see #getBlendFuncSeparate - * + * Integer values passed to `blendFuncSeparate()`. (optional)
    + * Default: [1,0,1,0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [0, 1, 768, 769, 774, 775, 770, 771, 772, + * 773, 32769, 32770, 32771, 32772, 776] + * + * @return The blendFuncSeparate + * */ - public int[] defaultBlendFuncSeparate() { - return new int[]{1, 0, 1, 0}; + public int[] getBlendFuncSeparate() { + return this.blendFuncSeparate; } /** - * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. - * (optional)
    - * Default: [true,true,true,true]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The colorMask - * + * Returns the default value of the blendFuncSeparate
    + * @see #getBlendFuncSeparate + * + * @return The default blendFuncSeparate + * */ - public boolean[] getColorMask() { - return this.colorMask; + public int[] defaultBlendFuncSeparate() { + return new int[] { 1, 0, 1, 0 }; } /** - * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. - * (optional)
    - * Default: [true,true,true,true]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * + * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. + * (optional)
    + * Default: [true,true,true,true]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * * @param colorMask The colorMask to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setColorMask(boolean[] colorMask) { if (colorMask == null) { this.colorMask = colorMask; - return; + return ; } - if (colorMask.length < 4) { + if (colorMask.length< 4) { throw new IllegalArgumentException("Number of colorMask elements is < 4"); } if (colorMask.length > 4) { @@ -354,164 +341,165 @@ public void setColorMask(boolean[] colorMask) { } /** - * Returns the default value of the colorMask
    - * - * @return The default colorMask - * @see #getColorMask - * + * Boolean values passed to `colorMask()`. [red, green, blue, alpha]. + * (optional)
    + * Default: [true,true,true,true]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The colorMask + * */ - public boolean[] defaultColorMask() { - return new boolean[]{true, true, true, true}; + public boolean[] getColorMask() { + return this.colorMask; } /** - * Integer value passed to `cullFace()`. (optional)
    - * Default: [1029]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [1028, 1029, 1032] - * - * @return The cullFace - * + * Returns the default value of the colorMask
    + * @see #getColorMask + * + * @return The default colorMask + * */ - public int[] getCullFace() { - return this.cullFace; + public boolean[] defaultColorMask() { + return new boolean[] {true, true, true, true }; } /** - * Integer value passed to `cullFace()`. (optional)
    - * Default: [1029]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [1028, 1029, 1032] - * + * Integer value passed to `cullFace()`. (optional)
    + * Default: [1029]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [1028, 1029, 1032] + * * @param cullFace The cullFace to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCullFace(int[] cullFace) { if (cullFace == null) { this.cullFace = cullFace; - return; + return ; } - if (cullFace.length < 1) { + if (cullFace.length< 1) { throw new IllegalArgumentException("Number of cullFace elements is < 1"); } if (cullFace.length > 1) { throw new IllegalArgumentException("Number of cullFace elements is > 1"); } - for (int cullFaceElement : cullFace) { - if (((cullFaceElement != 1028) && (cullFaceElement != 1029)) && (cullFaceElement != 1032)) { - throw new IllegalArgumentException((("Invalid value for cullFaceElement: " + cullFaceElement) + ", valid: [1028, 1029, 1032]")); + for (int cullFaceElement: cullFace) { + if (((cullFaceElement!= 1028)&&(cullFaceElement!= 1029))&&(cullFaceElement!= 1032)) { + throw new IllegalArgumentException((("Invalid value for cullFaceElement: "+ cullFaceElement)+", valid: [1028, 1029, 1032]")); } } this.cullFace = cullFace; } /** - * Returns the default value of the cullFace
    - * - * @return The default cullFace - * @see #getCullFace - * + * Integer value passed to `cullFace()`. (optional)
    + * Default: [1029]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [1028, 1029, 1032] + * + * @return The cullFace + * */ - public int[] defaultCullFace() { - return new int[]{1029}; + public int[] getCullFace() { + return this.cullFace; } /** - * Integer values passed to `depthFunc()`. (optional)
    - * Default: [513]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] - * - * @return The depthFunc - * + * Returns the default value of the cullFace
    + * @see #getCullFace + * + * @return The default cullFace + * */ - public int[] getDepthFunc() { - return this.depthFunc; + public int[] defaultCullFace() { + return new int[] { 1029 }; } /** - * Integer values passed to `depthFunc()`. (optional)
    - * Default: [513]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] - * + * Integer values passed to `depthFunc()`. (optional)
    + * Default: [513]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] + * * @param depthFunc The depthFunc to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setDepthFunc(int[] depthFunc) { if (depthFunc == null) { this.depthFunc = depthFunc; - return; + return ; } - if (depthFunc.length < 1) { + if (depthFunc.length< 1) { throw new IllegalArgumentException("Number of depthFunc elements is < 1"); } if (depthFunc.length > 1) { throw new IllegalArgumentException("Number of depthFunc elements is > 1"); } - for (int depthFuncElement : depthFunc) { - if ((((((((depthFuncElement != 512) && (depthFuncElement != 513)) && (depthFuncElement != 515)) && (depthFuncElement != 514)) && (depthFuncElement != 516)) && (depthFuncElement != 517)) && (depthFuncElement != 518)) && (depthFuncElement != 519)) { - throw new IllegalArgumentException((("Invalid value for depthFuncElement: " + depthFuncElement) + ", valid: [512, 513, 515, 514, 516, 517, 518, 519]")); + for (int depthFuncElement: depthFunc) { + if ((((((((depthFuncElement!= 512)&&(depthFuncElement!= 513))&&(depthFuncElement!= 515))&&(depthFuncElement!= 514))&&(depthFuncElement!= 516))&&(depthFuncElement!= 517))&&(depthFuncElement!= 518))&&(depthFuncElement!= 519)) { + throw new IllegalArgumentException((("Invalid value for depthFuncElement: "+ depthFuncElement)+", valid: [512, 513, 515, 514, 516, 517, 518, 519]")); } } this.depthFunc = depthFunc; } /** - * Returns the default value of the depthFunc
    - * - * @return The default depthFunc - * @see #getDepthFunc - * + * Integer values passed to `depthFunc()`. (optional)
    + * Default: [513]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [512, 513, 515, 514, 516, 517, 518, 519] + * + * @return The depthFunc + * */ - public int[] defaultDepthFunc() { - return new int[]{513}; + public int[] getDepthFunc() { + return this.depthFunc; } /** - * Boolean value passed to `depthMask()`. (optional)
    - * Default: [true]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The depthMask - * + * Returns the default value of the depthFunc
    + * @see #getDepthFunc + * + * @return The default depthFunc + * */ - public boolean[] getDepthMask() { - return this.depthMask; + public int[] defaultDepthFunc() { + return new int[] { 513 }; } /** - * Boolean value passed to `depthMask()`. (optional)
    - * Default: [true]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * Boolean value passed to `depthMask()`. (optional)
    + * Default: [true]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * * @param depthMask The depthMask to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setDepthMask(boolean[] depthMask) { if (depthMask == null) { this.depthMask = depthMask; - return; + return ; } - if (depthMask.length < 1) { + if (depthMask.length< 1) { throw new IllegalArgumentException("Number of depthMask elements is < 1"); } if (depthMask.length > 1) { @@ -521,50 +509,49 @@ public void setDepthMask(boolean[] depthMask) { } /** - * Returns the default value of the depthMask
    - * - * @return The default depthMask - * @see #getDepthMask - * + * Boolean value passed to `depthMask()`. (optional)
    + * Default: [true]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The depthMask + * */ - public boolean[] defaultDepthMask() { - return new boolean[]{true}; + public boolean[] getDepthMask() { + return this.depthMask; } /** - * Floating-point values passed to `depthRange()`. [zNear, zFar] - * (optional)
    - * Default: [0.0,1.0]
    - * Number of items: 2
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The depthRange - * + * Returns the default value of the depthMask
    + * @see #getDepthMask + * + * @return The default depthMask + * */ - public float[] getDepthRange() { - return this.depthRange; + public boolean[] defaultDepthMask() { + return new boolean[] {true }; } /** - * Floating-point values passed to `depthRange()`. [zNear, zFar] - * (optional)
    - * Default: [0.0,1.0]
    - * Number of items: 2
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point values passed to `depthRange()`. [zNear, zFar] + * (optional)
    + * Default: [0.0,1.0]
    + * Number of items: 2
    + * Array elements:
    + *   The elements of this array (optional) + * * @param depthRange The depthRange to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setDepthRange(float[] depthRange) { if (depthRange == null) { this.depthRange = depthRange; - return; + return ; } - if (depthRange.length < 2) { + if (depthRange.length< 2) { throw new IllegalArgumentException("Number of depthRange elements is < 2"); } if (depthRange.length > 2) { @@ -574,115 +561,115 @@ public void setDepthRange(float[] depthRange) { } /** - * Returns the default value of the depthRange
    - * - * @return The default depthRange - * @see #getDepthRange - * + * Floating-point values passed to `depthRange()`. [zNear, zFar] + * (optional)
    + * Default: [0.0,1.0]
    + * Number of items: 2
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The depthRange + * */ - public float[] defaultDepthRange() { - return new float[]{0.0F, 1.0F}; + public float[] getDepthRange() { + return this.depthRange; } /** - * Integer value passed to `frontFace()`. (optional)
    - * Default: [2305]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [2304, 2305] - * - * @return The frontFace - * + * Returns the default value of the depthRange
    + * @see #getDepthRange + * + * @return The default depthRange + * */ - public int[] getFrontFace() { - return this.frontFace; + public float[] defaultDepthRange() { + return new float[] { 0.0F, 1.0F }; } /** - * Integer value passed to `frontFace()`. (optional)
    - * Default: [2305]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Valid values: [2304, 2305] - * + * Integer value passed to `frontFace()`. (optional)
    + * Default: [2305]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [2304, 2305] + * * @param frontFace The frontFace to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setFrontFace(int[] frontFace) { if (frontFace == null) { this.frontFace = frontFace; - return; + return ; } - if (frontFace.length < 1) { + if (frontFace.length< 1) { throw new IllegalArgumentException("Number of frontFace elements is < 1"); } if (frontFace.length > 1) { throw new IllegalArgumentException("Number of frontFace elements is > 1"); } - for (int frontFaceElement : frontFace) { - if ((frontFaceElement != 2304) && (frontFaceElement != 2305)) { - throw new IllegalArgumentException((("Invalid value for frontFaceElement: " + frontFaceElement) + ", valid: [2304, 2305]")); + for (int frontFaceElement: frontFace) { + if ((frontFaceElement!= 2304)&&(frontFaceElement!= 2305)) { + throw new IllegalArgumentException((("Invalid value for frontFaceElement: "+ frontFaceElement)+", valid: [2304, 2305]")); } } this.frontFace = frontFace; } /** - * Returns the default value of the frontFace
    - * - * @return The default frontFace - * @see #getFrontFace - * + * Integer value passed to `frontFace()`. (optional)
    + * Default: [2305]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Valid values: [2304, 2305] + * + * @return The frontFace + * */ - public int[] defaultFrontFace() { - return new int[]{2305}; + public int[] getFrontFace() { + return this.frontFace; } /** - * Floating-point value passed to `lineWidth()`. (optional)
    - * Default: [1.0]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0.0 (exclusive) - * - * @return The lineWidth - * + * Returns the default value of the frontFace
    + * @see #getFrontFace + * + * @return The default frontFace + * */ - public float[] getLineWidth() { - return this.lineWidth; + public int[] defaultFrontFace() { + return new int[] { 2305 }; } /** - * Floating-point value passed to `lineWidth()`. (optional)
    - * Default: [1.0]
    - * Number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0.0 (exclusive) - * + * Floating-point value passed to `lineWidth()`. (optional)
    + * Default: [1.0]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0.0 (exclusive) + * * @param lineWidth The lineWidth to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setLineWidth(float[] lineWidth) { if (lineWidth == null) { this.lineWidth = lineWidth; - return; + return ; } - if (lineWidth.length < 1) { + if (lineWidth.length< 1) { throw new IllegalArgumentException("Number of lineWidth elements is < 1"); } if (lineWidth.length > 1) { throw new IllegalArgumentException("Number of lineWidth elements is > 1"); } - for (float lineWidthElement : lineWidth) { - if (lineWidthElement <= 0.0D) { + for (float lineWidthElement: lineWidth) { + if (lineWidthElement<= 0.0D) { throw new IllegalArgumentException("lineWidthElement <= 0.0"); } } @@ -690,50 +677,50 @@ public void setLineWidth(float[] lineWidth) { } /** - * Returns the default value of the lineWidth
    - * - * @return The default lineWidth - * @see #getLineWidth - * + * Floating-point value passed to `lineWidth()`. (optional)
    + * Default: [1.0]
    + * Number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0.0 (exclusive) + * + * @return The lineWidth + * */ - public float[] defaultLineWidth() { - return new float[]{1.0F}; + public float[] getLineWidth() { + return this.lineWidth; } /** - * Floating-point value passed to `polygonOffset()`. [factor, units] - * (optional)
    - * Default: [0.0,0.0]
    - * Number of items: 2
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The polygonOffset - * + * Returns the default value of the lineWidth
    + * @see #getLineWidth + * + * @return The default lineWidth + * */ - public float[] getPolygonOffset() { - return this.polygonOffset; + public float[] defaultLineWidth() { + return new float[] { 1.0F }; } /** - * Floating-point value passed to `polygonOffset()`. [factor, units] - * (optional)
    - * Default: [0.0,0.0]
    - * Number of items: 2
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point value passed to `polygonOffset()`. [factor, units] + * (optional)
    + * Default: [0.0,0.0]
    + * Number of items: 2
    + * Array elements:
    + *   The elements of this array (optional) + * * @param polygonOffset The polygonOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setPolygonOffset(float[] polygonOffset) { if (polygonOffset == null) { this.polygonOffset = polygonOffset; - return; + return ; } - if (polygonOffset.length < 2) { + if (polygonOffset.length< 2) { throw new IllegalArgumentException("Number of polygonOffset elements is < 2"); } if (polygonOffset.length > 2) { @@ -743,50 +730,50 @@ public void setPolygonOffset(float[] polygonOffset) { } /** - * Returns the default value of the polygonOffset
    - * - * @return The default polygonOffset - * @see #getPolygonOffset - * + * Floating-point value passed to `polygonOffset()`. [factor, units] + * (optional)
    + * Default: [0.0,0.0]
    + * Number of items: 2
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The polygonOffset + * */ - public float[] defaultPolygonOffset() { - return new float[]{0.0F, 0.0F}; + public float[] getPolygonOffset() { + return this.polygonOffset; } /** - * Floating-point value passed to `scissor()`. [x, y, width, height]. - * (optional)
    - * Default: [0.0,0.0,0.0,0.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The scissor - * + * Returns the default value of the polygonOffset
    + * @see #getPolygonOffset + * + * @return The default polygonOffset + * */ - public float[] getScissor() { - return this.scissor; + public float[] defaultPolygonOffset() { + return new float[] { 0.0F, 0.0F }; } /** - * Floating-point value passed to `scissor()`. [x, y, width, height]. - * (optional)
    - * Default: [0.0,0.0,0.0,0.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional) - * + * Floating-point value passed to `scissor()`. [x, y, width, height]. + * (optional)
    + * Default: [0.0,0.0,0.0,0.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * * @param scissor The scissor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setScissor(float[] scissor) { if (scissor == null) { this.scissor = scissor; - return; + return ; } - if (scissor.length < 4) { + if (scissor.length< 4) { throw new IllegalArgumentException("Number of scissor elements is < 4"); } if (scissor.length > 4) { @@ -796,14 +783,29 @@ public void setScissor(float[] scissor) { } /** - * Returns the default value of the scissor
    - * + * Floating-point value passed to `scissor()`. [x, y, width, height]. + * (optional)
    + * Default: [0.0,0.0,0.0,0.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The scissor + * + */ + public float[] getScissor() { + return this.scissor; + } + + /** + * Returns the default value of the scissor
    + * @see #getScissor + * * @return The default scissor - * @see #getScissor - * + * */ public float[] defaultScissor() { - return new float[]{0.0F, 0.0F, 0.0F, 0.0F}; + return new float[] { 0.0F, 0.0F, 0.0F, 0.0F }; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v1/Texture.java b/src/main/java/de/javagl/jgltf/impl/v1/Texture.java index c617247..750a112 100644 --- a/src/main/java/de/javagl/jgltf/impl/v1/Texture.java +++ b/src/main/java/de/javagl/jgltf/impl/v1/Texture.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016 Marco Hutter - http://www.javagl.de @@ -9,276 +9,278 @@ package de.javagl.jgltf.impl.v1; + /** - * A texture and its sampler. - *

    - * Auto-generated for texture.schema.json - * + * A texture and its sampler. + * + * Auto-generated for texture.schema.json + * */ public class Texture - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The texture's format. (optional)
    - * Default: 6408
    - * Valid values: [6406, 6407, 6408, 6409, 6410] - * + * The texture's format. (optional)
    + * Default: 6408
    + * Valid values: [6406, 6407, 6408, 6409, 6410] + * */ private Integer format; /** - * The texture's internal format. (optional)
    - * Default: 6408
    - * Valid values: [6406, 6407, 6408, 6409, 6410] - * + * The texture's internal format. (optional)
    + * Default: 6408
    + * Valid values: [6406, 6407, 6408, 6409, 6410] + * */ private Integer internalFormat; /** - * The ID of the sampler used by this texture. (required) - * + * The ID of the sampler used by this texture. (required) + * */ private String sampler; /** - * The ID of the image used by this texture. (required) - * + * The ID of the image used by this texture. (required) + * */ private String source; /** - * The target that the WebGL texture should be bound to. (optional)
    - * Default: 3553
    - * Valid values: [3553] - * + * The target that the WebGL texture should be bound to. (optional)
    + * Default: 3553
    + * Valid values: [3553] + * */ private Integer target; /** - * Texel datatype. (optional)
    - * Default: 5121
    - * Valid values: [5121, 33635, 32819, 32820] - * + * Texel datatype. (optional)
    + * Default: 5121
    + * Valid values: [5121, 33635, 32819, 32820] + * */ private Integer type; /** - * The texture's format. (optional)
    - * Default: 6408
    - * Valid values: [6406, 6407, 6408, 6409, 6410] - * - * @return The format - * - */ - public Integer getFormat() { - return this.format; - } - - /** - * The texture's format. (optional)
    - * Default: 6408
    - * Valid values: [6406, 6407, 6408, 6409, 6410] - * + * The texture's format. (optional)
    + * Default: 6408
    + * Valid values: [6406, 6407, 6408, 6409, 6410] + * * @param format The format to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setFormat(Integer format) { if (format == null) { this.format = format; - return; + return ; } - if (((((format != 6406) && (format != 6407)) && (format != 6408)) && (format != 6409)) && (format != 6410)) { - throw new IllegalArgumentException((("Invalid value for format: " + format) + ", valid: [6406, 6407, 6408, 6409, 6410]")); + if (((((format!= 6406)&&(format!= 6407))&&(format!= 6408))&&(format!= 6409))&&(format!= 6410)) { + throw new IllegalArgumentException((("Invalid value for format: "+ format)+", valid: [6406, 6407, 6408, 6409, 6410]")); } this.format = format; } /** - * Returns the default value of the format
    - * - * @return The default format - * @see #getFormat - * + * The texture's format. (optional)
    + * Default: 6408
    + * Valid values: [6406, 6407, 6408, 6409, 6410] + * + * @return The format + * */ - public Integer defaultFormat() { - return 6408; + public Integer getFormat() { + return this.format; } /** - * The texture's internal format. (optional)
    - * Default: 6408
    - * Valid values: [6406, 6407, 6408, 6409, 6410] - * - * @return The internalFormat - * + * Returns the default value of the format
    + * @see #getFormat + * + * @return The default format + * */ - public Integer getInternalFormat() { - return this.internalFormat; + public Integer defaultFormat() { + return 6408; } /** - * The texture's internal format. (optional)
    - * Default: 6408
    - * Valid values: [6406, 6407, 6408, 6409, 6410] - * + * The texture's internal format. (optional)
    + * Default: 6408
    + * Valid values: [6406, 6407, 6408, 6409, 6410] + * * @param internalFormat The internalFormat to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setInternalFormat(Integer internalFormat) { if (internalFormat == null) { this.internalFormat = internalFormat; - return; + return ; } - if (((((internalFormat != 6406) && (internalFormat != 6407)) && (internalFormat != 6408)) && (internalFormat != 6409)) && (internalFormat != 6410)) { - throw new IllegalArgumentException((("Invalid value for internalFormat: " + internalFormat) + ", valid: [6406, 6407, 6408, 6409, 6410]")); + if (((((internalFormat!= 6406)&&(internalFormat!= 6407))&&(internalFormat!= 6408))&&(internalFormat!= 6409))&&(internalFormat!= 6410)) { + throw new IllegalArgumentException((("Invalid value for internalFormat: "+ internalFormat)+", valid: [6406, 6407, 6408, 6409, 6410]")); } this.internalFormat = internalFormat; } /** - * Returns the default value of the internalFormat
    - * - * @return The default internalFormat - * @see #getInternalFormat - * + * The texture's internal format. (optional)
    + * Default: 6408
    + * Valid values: [6406, 6407, 6408, 6409, 6410] + * + * @return The internalFormat + * */ - public Integer defaultInternalFormat() { - return 6408; + public Integer getInternalFormat() { + return this.internalFormat; } /** - * The ID of the sampler used by this texture. (required) - * - * @return The sampler - * + * Returns the default value of the internalFormat
    + * @see #getInternalFormat + * + * @return The default internalFormat + * */ - public String getSampler() { - return this.sampler; + public Integer defaultInternalFormat() { + return 6408; } /** - * The ID of the sampler used by this texture. (required) - * + * The ID of the sampler used by this texture. (required) + * * @param sampler The sampler to set * @throws NullPointerException If the given value is null - * + * */ public void setSampler(String sampler) { if (sampler == null) { - throw new NullPointerException((("Invalid value for sampler: " + sampler) + ", may not be null")); + throw new NullPointerException((("Invalid value for sampler: "+ sampler)+", may not be null")); } this.sampler = sampler; } /** - * The ID of the image used by this texture. (required) - * - * @return The source - * + * The ID of the sampler used by this texture. (required) + * + * @return The sampler + * */ - public String getSource() { - return this.source; + public String getSampler() { + return this.sampler; } /** - * The ID of the image used by this texture. (required) - * + * The ID of the image used by this texture. (required) + * * @param source The source to set * @throws NullPointerException If the given value is null - * + * */ public void setSource(String source) { if (source == null) { - throw new NullPointerException((("Invalid value for source: " + source) + ", may not be null")); + throw new NullPointerException((("Invalid value for source: "+ source)+", may not be null")); } this.source = source; } /** - * The target that the WebGL texture should be bound to. (optional)
    - * Default: 3553
    - * Valid values: [3553] - * - * @return The target - * + * The ID of the image used by this texture. (required) + * + * @return The source + * */ - public Integer getTarget() { - return this.target; + public String getSource() { + return this.source; } /** - * The target that the WebGL texture should be bound to. (optional)
    - * Default: 3553
    - * Valid values: [3553] - * + * The target that the WebGL texture should be bound to. (optional)
    + * Default: 3553
    + * Valid values: [3553] + * * @param target The target to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTarget(Integer target) { if (target == null) { this.target = target; - return; + return ; } - if (target != 3553) { - throw new IllegalArgumentException((("Invalid value for target: " + target) + ", valid: [3553]")); + if (target!= 3553) { + throw new IllegalArgumentException((("Invalid value for target: "+ target)+", valid: [3553]")); } this.target = target; } /** - * Returns the default value of the target
    - * - * @return The default target - * @see #getTarget - * + * The target that the WebGL texture should be bound to. (optional)
    + * Default: 3553
    + * Valid values: [3553] + * + * @return The target + * */ - public Integer defaultTarget() { - return 3553; + public Integer getTarget() { + return this.target; } /** - * Texel datatype. (optional)
    - * Default: 5121
    - * Valid values: [5121, 33635, 32819, 32820] - * - * @return The type - * + * Returns the default value of the target
    + * @see #getTarget + * + * @return The default target + * */ - public Integer getType() { - return this.type; + public Integer defaultTarget() { + return 3553; } /** - * Texel datatype. (optional)
    - * Default: 5121
    - * Valid values: [5121, 33635, 32819, 32820] - * + * Texel datatype. (optional)
    + * Default: 5121
    + * Valid values: [5121, 33635, 32819, 32820] + * * @param type The type to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(Integer type) { if (type == null) { this.type = type; - return; + return ; } - if ((((type != 5121) && (type != 33635)) && (type != 32819)) && (type != 32820)) { - throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [5121, 33635, 32819, 32820]")); + if ((((type!= 5121)&&(type!= 33635))&&(type!= 32819))&&(type!= 32820)) { + throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [5121, 33635, 32819, 32820]")); } this.type = type; } /** - * Returns the default value of the type
    - * + * Texel datatype. (optional)
    + * Default: 5121
    + * Valid values: [5121, 33635, 32819, 32820] + * + * @return The type + * + */ + public Integer getType() { + return this.type; + } + + /** + * Returns the default value of the type
    + * @see #getType + * * @return The default type - * @see #getType - * + * */ public Integer defaultType() { - return 5121; + return 5121; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Accessor.java b/src/main/java/de/javagl/jgltf/impl/v2/Accessor.java index ba909ed..5c4af63 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Accessor.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Accessor.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,315 +9,303 @@ package de.javagl.jgltf.impl.v2; + /** - * A typed view into a buffer view that contains raw binary data. - *

    - * Auto-generated for accessor.schema.json - * + * A typed view into a buffer view that contains raw binary data. + * + * Auto-generated for accessor.schema.json + * */ public class Accessor - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The index of the bufferView. (optional) - * + * The index of the bufferView. (optional) + * */ private Integer bufferView; /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The datatype of the accessor's components. (required)
    - * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] - * + * The datatype of the accessor's components. (required)
    + * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] + * */ private Integer componentType; /** - * Specifies whether integer data values are normalized before usage. - * (optional)
    - * Default: false - * + * Specifies whether integer data values are normalized before usage. + * (optional)
    + * Default: false + * */ private Boolean normalized; /** - * The number of elements referenced by this accessor. (required)
    - * Minimum: 1 (inclusive) - * + * The number of elements referenced by this accessor. (required)
    + * Minimum: 1 (inclusive) + * */ private Integer count; /** - * Specifies if the accessor's elements are scalars, vectors, or - * matrices. (required)
    - * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] - * + * Specifies if the accessor's elements are scalars, vectors, or + * matrices. (required)
    + * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] + * */ private String type; /** - * Maximum value of each component in this accessor. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Maximum value of each component in this accessor. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * */ private Number[] max; /** - * Minimum value of each component in this accessor. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Minimum value of each component in this accessor. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * */ private Number[] min; /** - * Sparse storage of elements that deviate from their initialization - * value. (optional) - * + * Sparse storage of elements that deviate from their initialization + * value. (optional) + * */ private AccessorSparse sparse; /** - * The index of the bufferView. (optional) - * - * @return The bufferView - * - */ - public Integer getBufferView() { - return this.bufferView; - } - - /** - * The index of the bufferView. (optional) - * + * The index of the bufferView. (optional) + * * @param bufferView The bufferView to set - * + * */ public void setBufferView(Integer bufferView) { if (bufferView == null) { this.bufferView = bufferView; - return; + return ; } this.bufferView = bufferView; } /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * The index of the bufferView. (optional) + * + * @return The bufferView + * */ - public Integer getByteOffset() { - return this.byteOffset; + public Integer getBufferView() { + return this.bufferView; } /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { this.byteOffset = byteOffset; - return; + return ; } - if (byteOffset < 0) { + if (byteOffset< 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * Returns the default value of the byteOffset
    - * - * @return The default byteOffset - * @see #getByteOffset - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public Integer defaultByteOffset() { - return 0; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The datatype of the accessor's components. (required)
    - * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] - * - * @return The componentType - * + * Returns the default value of the byteOffset
    + * @see #getByteOffset + * + * @return The default byteOffset + * */ - public Integer getComponentType() { - return this.componentType; + public Integer defaultByteOffset() { + return 0; } /** - * The datatype of the accessor's components. (required)
    - * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] - * + * The datatype of the accessor's components. (required)
    + * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] + * * @param componentType The componentType to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setComponentType(Integer componentType) { if (componentType == null) { - throw new NullPointerException((("Invalid value for componentType: " + componentType) + ", may not be null")); + throw new NullPointerException((("Invalid value for componentType: "+ componentType)+", may not be null")); } - if ((((((componentType != 5120) && (componentType != 5121)) && (componentType != 5122)) && (componentType != 5123)) && (componentType != 5125)) && (componentType != 5126)) { - throw new IllegalArgumentException((("Invalid value for componentType: " + componentType) + ", valid: [5120, 5121, 5122, 5123, 5125, 5126]")); + if ((((((componentType!= 5120)&&(componentType!= 5121))&&(componentType!= 5122))&&(componentType!= 5123))&&(componentType!= 5125))&&(componentType!= 5126)) { + throw new IllegalArgumentException((("Invalid value for componentType: "+ componentType)+", valid: [5120, 5121, 5122, 5123, 5125, 5126]")); } this.componentType = componentType; } /** - * Specifies whether integer data values are normalized before usage. - * (optional)
    - * Default: false - * + * The datatype of the accessor's components. (required)
    + * Valid values: [5120, 5121, 5122, 5123, 5125, 5126] + * + * @return The componentType + * + */ + public Integer getComponentType() { + return this.componentType; + } + + /** + * Specifies whether integer data values are normalized before usage. + * (optional)
    + * Default: false + * * @param normalized The normalized to set - * + * */ public void setNormalized(Boolean normalized) { if (normalized == null) { this.normalized = normalized; - return; + return ; } this.normalized = normalized; } /** - * Specifies whether integer data values are normalized before usage. - * (optional)
    - * Default: false - * + * Specifies whether integer data values are normalized before usage. + * (optional)
    + * Default: false + * * @return The normalized - * + * */ public Boolean isNormalized() { return this.normalized; } /** - * Returns the default value of the normalized
    - * + * Returns the default value of the normalized
    + * @see #isNormalized + * * @return The default normalized - * @see #isNormalized - * + * */ public Boolean defaultNormalized() { return false; } /** - * The number of elements referenced by this accessor. (required)
    - * Minimum: 1 (inclusive) - * - * @return The count - * - */ - public Integer getCount() { - return this.count; - } - - /** - * The number of elements referenced by this accessor. (required)
    - * Minimum: 1 (inclusive) - * + * The number of elements referenced by this accessor. (required)
    + * Minimum: 1 (inclusive) + * * @param count The count to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCount(Integer count) { if (count == null) { - throw new NullPointerException((("Invalid value for count: " + count) + ", may not be null")); + throw new NullPointerException((("Invalid value for count: "+ count)+", may not be null")); } - if (count < 1) { + if (count< 1) { throw new IllegalArgumentException("count < 1"); } this.count = count; } /** - * Specifies if the accessor's elements are scalars, vectors, or - * matrices. (required)
    - * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] - * - * @return The type - * + * The number of elements referenced by this accessor. (required)
    + * Minimum: 1 (inclusive) + * + * @return The count + * */ - public String getType() { - return this.type; + public Integer getCount() { + return this.count; } /** - * Specifies if the accessor's elements are scalars, vectors, or - * matrices. (required)
    - * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] - * + * Specifies if the accessor's elements are scalars, vectors, or + * matrices. (required)
    + * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); + throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); } - if (((((((!"SCALAR".equals(type)) && (!"VEC2".equals(type))) && (!"VEC3".equals(type))) && (!"VEC4".equals(type))) && (!"MAT2".equals(type))) && (!"MAT3".equals(type))) && (!"MAT4".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4]")); + if (((((((!"SCALAR".equals(type))&&(!"VEC2".equals(type)))&&(!"VEC3".equals(type)))&&(!"VEC4".equals(type)))&&(!"MAT2".equals(type)))&&(!"MAT3".equals(type)))&&(!"MAT4".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4]")); } this.type = type; } /** - * Maximum value of each component in this accessor. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The max - * + * Specifies if the accessor's elements are scalars, vectors, or + * matrices. (required)
    + * Valid values: [SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4] + * + * @return The type + * */ - public Number[] getMax() { - return this.max; + public String getType() { + return this.type; } /** - * Maximum value of each component in this accessor. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Maximum value of each component in this accessor. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * * @param max The max to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMax(Number[] max) { if (max == null) { this.max = max; - return; + return ; } - if (max.length < 1) { + if (max.length< 1) { throw new IllegalArgumentException("Number of max elements is < 1"); } if (max.length > 16) { @@ -327,37 +315,37 @@ public void setMax(Number[] max) { } /** - * Minimum value of each component in this accessor. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The min - * + * Maximum value of each component in this accessor. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The max + * */ - public Number[] getMin() { - return this.min; + public Number[] getMax() { + return this.max; } /** - * Minimum value of each component in this accessor. (optional)
    - * Minimum number of items: 1
    - * Maximum number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * Minimum value of each component in this accessor. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * * @param min The min to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMin(Number[] min) { if (min == null) { this.min = min; - return; + return ; } - if (min.length < 1) { + if (min.length< 1) { throw new IllegalArgumentException("Number of min elements is < 1"); } if (min.length > 16) { @@ -367,29 +355,43 @@ public void setMin(Number[] min) { } /** - * Sparse storage of elements that deviate from their initialization - * value. (optional) - * - * @return The sparse - * + * Minimum value of each component in this accessor. (optional)
    + * Minimum number of items: 1
    + * Maximum number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The min + * */ - public AccessorSparse getSparse() { - return this.sparse; + public Number[] getMin() { + return this.min; } /** - * Sparse storage of elements that deviate from their initialization - * value. (optional) - * + * Sparse storage of elements that deviate from their initialization + * value. (optional) + * * @param sparse The sparse to set - * + * */ public void setSparse(AccessorSparse sparse) { if (sparse == null) { this.sparse = sparse; - return; + return ; } this.sparse = sparse; } + /** + * Sparse storage of elements that deviate from their initialization + * value. (optional) + * + * @return The sparse + * + */ + public AccessorSparse getSparse() { + return this.sparse; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparse.java b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparse.java index 2307c6a..165aba7 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparse.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparse.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,122 +9,124 @@ package de.javagl.jgltf.impl.v2; + /** - * Sparse storage of accessor values that deviate from their - * initialization value. - *

    - * Auto-generated for accessor.sparse.schema.json - * + * Sparse storage of accessor values that deviate from their + * initialization value. + * + * Auto-generated for accessor.sparse.schema.json + * */ public class AccessorSparse - extends GlTFProperty { + extends GlTFProperty +{ /** - * Number of deviating accessor values stored in the sparse array. - * (required)
    - * Minimum: 1 (inclusive) - * + * Number of deviating accessor values stored in the sparse array. + * (required)
    + * Minimum: 1 (inclusive) + * */ private Integer count; /** - * An object pointing to a buffer view containing the indices of - * deviating accessor values. The number of indices is equal to `count`. - * Indices **MUST** strictly increase. (required) - * + * An object pointing to a buffer view containing the indices of + * deviating accessor values. The number of indices is equal to `count`. + * Indices **MUST** strictly increase. (required) + * */ private AccessorSparseIndices indices; /** - * An object pointing to a buffer view containing the deviating accessor - * values. (required) - * + * An object pointing to a buffer view containing the deviating accessor + * values. (required) + * */ private AccessorSparseValues values; /** - * Number of deviating accessor values stored in the sparse array. - * (required)
    - * Minimum: 1 (inclusive) - * - * @return The count - * - */ - public Integer getCount() { - return this.count; - } - - /** - * Number of deviating accessor values stored in the sparse array. - * (required)
    - * Minimum: 1 (inclusive) - * + * Number of deviating accessor values stored in the sparse array. + * (required)
    + * Minimum: 1 (inclusive) + * * @param count The count to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCount(Integer count) { if (count == null) { - throw new NullPointerException((("Invalid value for count: " + count) + ", may not be null")); + throw new NullPointerException((("Invalid value for count: "+ count)+", may not be null")); } - if (count < 1) { + if (count< 1) { throw new IllegalArgumentException("count < 1"); } this.count = count; } /** - * An object pointing to a buffer view containing the indices of - * deviating accessor values. The number of indices is equal to `count`. - * Indices **MUST** strictly increase. (required) - * - * @return The indices - * + * Number of deviating accessor values stored in the sparse array. + * (required)
    + * Minimum: 1 (inclusive) + * + * @return The count + * */ - public AccessorSparseIndices getIndices() { - return this.indices; + public Integer getCount() { + return this.count; } /** - * An object pointing to a buffer view containing the indices of - * deviating accessor values. The number of indices is equal to `count`. - * Indices **MUST** strictly increase. (required) - * + * An object pointing to a buffer view containing the indices of + * deviating accessor values. The number of indices is equal to `count`. + * Indices **MUST** strictly increase. (required) + * * @param indices The indices to set * @throws NullPointerException If the given value is null - * + * */ public void setIndices(AccessorSparseIndices indices) { if (indices == null) { - throw new NullPointerException((("Invalid value for indices: " + indices) + ", may not be null")); + throw new NullPointerException((("Invalid value for indices: "+ indices)+", may not be null")); } this.indices = indices; } /** - * An object pointing to a buffer view containing the deviating accessor - * values. (required) - * - * @return The values - * + * An object pointing to a buffer view containing the indices of + * deviating accessor values. The number of indices is equal to `count`. + * Indices **MUST** strictly increase. (required) + * + * @return The indices + * */ - public AccessorSparseValues getValues() { - return this.values; + public AccessorSparseIndices getIndices() { + return this.indices; } /** - * An object pointing to a buffer view containing the deviating accessor - * values. (required) - * + * An object pointing to a buffer view containing the deviating accessor + * values. (required) + * * @param values The values to set * @throws NullPointerException If the given value is null - * + * */ public void setValues(AccessorSparseValues values) { if (values == null) { - throw new NullPointerException((("Invalid value for values: " + values) + ", may not be null")); + throw new NullPointerException((("Invalid value for values: "+ values)+", may not be null")); } this.values = values; } + /** + * An object pointing to a buffer view containing the deviating accessor + * values. (required) + * + * @return The values + * + */ + public AccessorSparseValues getValues() { + return this.values; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseIndices.java b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseIndices.java index e6172af..a6b933b 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseIndices.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseIndices.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,145 +9,147 @@ package de.javagl.jgltf.impl.v2; + /** - * An object pointing to a buffer view containing the indices of - * deviating accessor values. The number of indices is equal to - * `accessor.sparse.count`. Indices **MUST** strictly increase. - *

    - * Auto-generated for accessor.sparse.indices.schema.json - * + * An object pointing to a buffer view containing the indices of + * deviating accessor values. The number of indices is equal to + * `accessor.sparse.count`. Indices **MUST** strictly increase. + * + * Auto-generated for accessor.sparse.indices.schema.json + * */ public class AccessorSparseIndices - extends GlTFProperty { + extends GlTFProperty +{ /** - * The index of the buffer view with sparse indices. The referenced - * buffer view **MUST NOT** have its `target` or `byteStride` properties - * defined. The buffer view and the optional `byteOffset` **MUST** be - * aligned to the `componentType` byte length. (required) - * + * The index of the buffer view with sparse indices. The referenced + * buffer view **MUST NOT** have its `target` or `byteStride` properties + * defined. The buffer view and the optional `byteOffset` **MUST** be + * aligned to the `componentType` byte length. (required) + * */ private Integer bufferView; /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The indices data type. (required)
    - * Valid values: [5121, 5123, 5125] - * + * The indices data type. (required)
    + * Valid values: [5121, 5123, 5125] + * */ private Integer componentType; /** - * The index of the buffer view with sparse indices. The referenced - * buffer view **MUST NOT** have its `target` or `byteStride` properties - * defined. The buffer view and the optional `byteOffset` **MUST** be - * aligned to the `componentType` byte length. (required) - * - * @return The bufferView - * - */ - public Integer getBufferView() { - return this.bufferView; - } - - /** - * The index of the buffer view with sparse indices. The referenced - * buffer view **MUST NOT** have its `target` or `byteStride` properties - * defined. The buffer view and the optional `byteOffset` **MUST** be - * aligned to the `componentType` byte length. (required) - * + * The index of the buffer view with sparse indices. The referenced + * buffer view **MUST NOT** have its `target` or `byteStride` properties + * defined. The buffer view and the optional `byteOffset` **MUST** be + * aligned to the `componentType` byte length. (required) + * * @param bufferView The bufferView to set * @throws NullPointerException If the given value is null - * + * */ public void setBufferView(Integer bufferView) { if (bufferView == null) { - throw new NullPointerException((("Invalid value for bufferView: " + bufferView) + ", may not be null")); + throw new NullPointerException((("Invalid value for bufferView: "+ bufferView)+", may not be null")); } this.bufferView = bufferView; } /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * The index of the buffer view with sparse indices. The referenced + * buffer view **MUST NOT** have its `target` or `byteStride` properties + * defined. The buffer view and the optional `byteOffset` **MUST** be + * aligned to the `componentType` byte length. (required) + * + * @return The bufferView + * */ - public Integer getByteOffset() { - return this.byteOffset; + public Integer getBufferView() { + return this.bufferView; } /** - * The offset relative to the start of the buffer view in bytes. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { this.byteOffset = byteOffset; - return; + return ; } - if (byteOffset < 0) { + if (byteOffset< 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * Returns the default value of the byteOffset
    - * - * @return The default byteOffset - * @see #getByteOffset - * + * The offset relative to the start of the buffer view in bytes. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public Integer defaultByteOffset() { - return 0; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The indices data type. (required)
    - * Valid values: [5121, 5123, 5125] - * - * @return The componentType - * + * Returns the default value of the byteOffset
    + * @see #getByteOffset + * + * @return The default byteOffset + * */ - public Integer getComponentType() { - return this.componentType; + public Integer defaultByteOffset() { + return 0; } /** - * The indices data type. (required)
    - * Valid values: [5121, 5123, 5125] - * + * The indices data type. (required)
    + * Valid values: [5121, 5123, 5125] + * * @param componentType The componentType to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setComponentType(Integer componentType) { if (componentType == null) { - throw new NullPointerException((("Invalid value for componentType: " + componentType) + ", may not be null")); + throw new NullPointerException((("Invalid value for componentType: "+ componentType)+", may not be null")); } - if (((componentType != 5121) && (componentType != 5123)) && (componentType != 5125)) { - throw new IllegalArgumentException((("Invalid value for componentType: " + componentType) + ", valid: [5121, 5123, 5125]")); + if (((componentType!= 5121)&&(componentType!= 5123))&&(componentType!= 5125)) { + throw new IllegalArgumentException((("Invalid value for componentType: "+ componentType)+", valid: [5121, 5123, 5125]")); } this.componentType = componentType; } + /** + * The indices data type. (required)
    + * Valid values: [5121, 5123, 5125] + * + * @return The componentType + * + */ + public Integer getComponentType() { + return this.componentType; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseValues.java b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseValues.java index 10e834d..5437971 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseValues.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AccessorSparseValues.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,107 +9,109 @@ package de.javagl.jgltf.impl.v2; + /** - * An object pointing to a buffer view containing the deviating accessor - * values. The number of elements is equal to `accessor.sparse.count` - * times number of components. The elements have the same component type - * as the base accessor. The elements are tightly packed. Data **MUST** - * be aligned following the same rules as the base accessor. - *

    - * Auto-generated for accessor.sparse.values.schema.json - * + * An object pointing to a buffer view containing the deviating accessor + * values. The number of elements is equal to `accessor.sparse.count` + * times number of components. The elements have the same component type + * as the base accessor. The elements are tightly packed. Data **MUST** + * be aligned following the same rules as the base accessor. + * + * Auto-generated for accessor.sparse.values.schema.json + * */ public class AccessorSparseValues - extends GlTFProperty { + extends GlTFProperty +{ /** - * The index of the bufferView with sparse values. The referenced buffer - * view **MUST NOT** have its `target` or `byteStride` properties - * defined. (required) - * + * The index of the bufferView with sparse values. The referenced buffer + * view **MUST NOT** have its `target` or `byteStride` properties + * defined. (required) + * */ private Integer bufferView; /** - * The offset relative to the start of the bufferView in bytes. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The offset relative to the start of the bufferView in bytes. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The index of the bufferView with sparse values. The referenced buffer - * view **MUST NOT** have its `target` or `byteStride` properties - * defined. (required) - * - * @return The bufferView - * - */ - public Integer getBufferView() { - return this.bufferView; - } - - /** - * The index of the bufferView with sparse values. The referenced buffer - * view **MUST NOT** have its `target` or `byteStride` properties - * defined. (required) - * + * The index of the bufferView with sparse values. The referenced buffer + * view **MUST NOT** have its `target` or `byteStride` properties + * defined. (required) + * * @param bufferView The bufferView to set * @throws NullPointerException If the given value is null - * + * */ public void setBufferView(Integer bufferView) { if (bufferView == null) { - throw new NullPointerException((("Invalid value for bufferView: " + bufferView) + ", may not be null")); + throw new NullPointerException((("Invalid value for bufferView: "+ bufferView)+", may not be null")); } this.bufferView = bufferView; } /** - * The offset relative to the start of the bufferView in bytes. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * The index of the bufferView with sparse values. The referenced buffer + * view **MUST NOT** have its `target` or `byteStride` properties + * defined. (required) + * + * @return The bufferView + * */ - public Integer getByteOffset() { - return this.byteOffset; + public Integer getBufferView() { + return this.bufferView; } /** - * The offset relative to the start of the bufferView in bytes. - * (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The offset relative to the start of the bufferView in bytes. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { this.byteOffset = byteOffset; - return; + return ; } - if (byteOffset < 0) { + if (byteOffset< 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * Returns the default value of the byteOffset
    - * + * The offset relative to the start of the bufferView in bytes. + * (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * + * @return The byteOffset + * + */ + public Integer getByteOffset() { + return this.byteOffset; + } + + /** + * Returns the default value of the byteOffset
    + * @see #getByteOffset + * * @return The default byteOffset - * @see #getByteOffset - * + * */ public Integer defaultByteOffset() { - return 0; + return 0; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Animation.java b/src/main/java/de/javagl/jgltf/impl/v2/Animation.java index b8e24e0..161c8f6 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Animation.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Animation.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,89 +13,90 @@ /** - * A keyframe animation. - *

    - * Auto-generated for animation.schema.json - * + * A keyframe animation. + * + * Auto-generated for animation.schema.json + * */ public class Animation - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * An array of animation channels. An animation channel combines an - * animation sampler with a target property being animated. Different - * channels of the same animation **MUST NOT** have the same targets. - * (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   An animation channel combines an animation sampler with a - * target property being animated. (optional) - * + * An array of animation channels. An animation channel combines an + * animation sampler with a target property being animated. Different + * channels of the same animation **MUST NOT** have the same targets. + * (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   An animation channel combines an animation sampler with a + * target property being animated. (optional) + * */ private List channels; /** - * An array of animation samplers. An animation sampler combines - * timestamps with a sequence of output values and defines an - * interpolation algorithm. (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   An animation sampler combines timestamps with a sequence - * of output values and defines an interpolation algorithm. (optional) - * + * An array of animation samplers. An animation sampler combines + * timestamps with a sequence of output values and defines an + * interpolation algorithm. (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   An animation sampler combines timestamps with a sequence + * of output values and defines an interpolation algorithm. (optional) + * */ private List samplers; /** - * An array of animation channels. An animation channel combines an - * animation sampler with a target property being animated. Different - * channels of the same animation **MUST NOT** have the same targets. - * (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   An animation channel combines an animation sampler with a - * target property being animated. (optional) - * - * @return The channels - * - */ - public List getChannels() { - return this.channels; - } - - /** - * An array of animation channels. An animation channel combines an - * animation sampler with a target property being animated. Different - * channels of the same animation **MUST NOT** have the same targets. - * (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   An animation channel combines an animation sampler with a - * target property being animated. (optional) - * + * An array of animation channels. An animation channel combines an + * animation sampler with a target property being animated. Different + * channels of the same animation **MUST NOT** have the same targets. + * (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   An animation channel combines an animation sampler with a + * target property being animated. (optional) + * * @param channels The channels to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setChannels(List channels) { if (channels == null) { - throw new NullPointerException((("Invalid value for channels: " + channels) + ", may not be null")); + throw new NullPointerException((("Invalid value for channels: "+ channels)+", may not be null")); } - if (channels.size() < 1) { + if (channels.size()< 1) { throw new IllegalArgumentException("Number of channels elements is < 1"); } this.channels = channels; } /** - * Add the given channels. The channels of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of animation channels. An animation channel combines an + * animation sampler with a target property being animated. Different + * channels of the same animation **MUST NOT** have the same targets. + * (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   An animation channel combines an animation sampler with a + * target property being animated. (optional) + * + * @return The channels + * + */ + public List getChannels() { + return this.channels; + } + + /** + * Add the given channels. The channels of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addChannels(AnimationChannel element) { if (element == null) { @@ -103,7 +104,7 @@ public void addChannels(AnimationChannel element) { } List oldList = this.channels; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -111,13 +112,13 @@ public void addChannels(AnimationChannel element) { } /** - * Remove the given channels. The channels of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one. - * + * Remove the given channels. The channels of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeChannels(AnimationChannel element) { if (element == null) { @@ -125,7 +126,7 @@ public void removeChannels(AnimationChannel element) { } List oldList = this.channels; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -133,54 +134,54 @@ public void removeChannels(AnimationChannel element) { } /** - * An array of animation samplers. An animation sampler combines - * timestamps with a sequence of output values and defines an - * interpolation algorithm. (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   An animation sampler combines timestamps with a sequence - * of output values and defines an interpolation algorithm. (optional) - * - * @return The samplers - * - */ - public List getSamplers() { - return this.samplers; - } - - /** - * An array of animation samplers. An animation sampler combines - * timestamps with a sequence of output values and defines an - * interpolation algorithm. (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   An animation sampler combines timestamps with a sequence - * of output values and defines an interpolation algorithm. (optional) - * + * An array of animation samplers. An animation sampler combines + * timestamps with a sequence of output values and defines an + * interpolation algorithm. (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   An animation sampler combines timestamps with a sequence + * of output values and defines an interpolation algorithm. (optional) + * * @param samplers The samplers to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setSamplers(List samplers) { if (samplers == null) { - throw new NullPointerException((("Invalid value for samplers: " + samplers) + ", may not be null")); + throw new NullPointerException((("Invalid value for samplers: "+ samplers)+", may not be null")); } - if (samplers.size() < 1) { + if (samplers.size()< 1) { throw new IllegalArgumentException("Number of samplers elements is < 1"); } this.samplers = samplers; } /** - * Add the given samplers. The samplers of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of animation samplers. An animation sampler combines + * timestamps with a sequence of output values and defines an + * interpolation algorithm. (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   An animation sampler combines timestamps with a sequence + * of output values and defines an interpolation algorithm. (optional) + * + * @return The samplers + * + */ + public List getSamplers() { + return this.samplers; + } + + /** + * Add the given samplers. The samplers of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addSamplers(AnimationSampler element) { if (element == null) { @@ -188,7 +189,7 @@ public void addSamplers(AnimationSampler element) { } List oldList = this.samplers; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -196,13 +197,13 @@ public void addSamplers(AnimationSampler element) { } /** - * Remove the given samplers. The samplers of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one. - * + * Remove the given samplers. The samplers of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeSamplers(AnimationSampler element) { if (element == null) { @@ -210,7 +211,7 @@ public void removeSamplers(AnimationSampler element) { } List oldList = this.samplers; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannel.java b/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannel.java index 5fe3068..527a281 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannel.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannel.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,76 +9,78 @@ package de.javagl.jgltf.impl.v2; + /** - * An animation channel combines an animation sampler with a target - * property being animated. - *

    - * Auto-generated for animation.channel.schema.json - * + * An animation channel combines an animation sampler with a target + * property being animated. + * + * Auto-generated for animation.channel.schema.json + * */ public class AnimationChannel - extends GlTFProperty { + extends GlTFProperty +{ /** - * The index of a sampler in this animation used to compute the value for - * the target. (required) - * + * The index of a sampler in this animation used to compute the value for + * the target. (required) + * */ private Integer sampler; /** - * The descriptor of the animated property. (required) - * + * The descriptor of the animated property. (required) + * */ private AnimationChannelTarget target; /** - * The index of a sampler in this animation used to compute the value for - * the target. (required) - * - * @return The sampler - * - */ - public Integer getSampler() { - return this.sampler; - } - - /** - * The index of a sampler in this animation used to compute the value for - * the target. (required) - * + * The index of a sampler in this animation used to compute the value for + * the target. (required) + * * @param sampler The sampler to set * @throws NullPointerException If the given value is null - * + * */ public void setSampler(Integer sampler) { if (sampler == null) { - throw new NullPointerException((("Invalid value for sampler: " + sampler) + ", may not be null")); + throw new NullPointerException((("Invalid value for sampler: "+ sampler)+", may not be null")); } this.sampler = sampler; } /** - * The descriptor of the animated property. (required) - * - * @return The target - * + * The index of a sampler in this animation used to compute the value for + * the target. (required) + * + * @return The sampler + * */ - public AnimationChannelTarget getTarget() { - return this.target; + public Integer getSampler() { + return this.sampler; } /** - * The descriptor of the animated property. (required) - * + * The descriptor of the animated property. (required) + * * @param target The target to set * @throws NullPointerException If the given value is null - * + * */ public void setTarget(AnimationChannelTarget target) { if (target == null) { - throw new NullPointerException((("Invalid value for target: " + target) + ", may not be null")); + throw new NullPointerException((("Invalid value for target: "+ target)+", may not be null")); } this.target = target; } + /** + * The descriptor of the animated property. (required) + * + * @return The target + * + */ + public AnimationChannelTarget getTarget() { + return this.target; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannelTarget.java b/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannelTarget.java index 0b5fd80..a9b297b 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannelTarget.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AnimationChannelTarget.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,101 +9,103 @@ package de.javagl.jgltf.impl.v2; + /** - * The descriptor of the animated property. - *

    - * Auto-generated for animation.channel.target.schema.json - * + * The descriptor of the animated property. + * + * Auto-generated for animation.channel.target.schema.json + * */ public class AnimationChannelTarget - extends GlTFProperty { + extends GlTFProperty +{ /** - * The index of the node to animate. When undefined, the animated object - * **MAY** be defined by an extension. (optional) - * + * The index of the node to animate. When undefined, the animated object + * **MAY** be defined by an extension. (optional) + * */ private Integer node; /** - * The name of the node's TRS property to animate, or the `"weights"` of - * the Morph Targets it instantiates. For the `"translation"` property, - * the values that are provided by the sampler are the translation along - * the X, Y, and Z axes. For the `"rotation"` property, the values are a - * quaternion in the order (x, y, z, w), where w is the scalar. For the - * `"scale"` property, the values are the scaling factors along the X, Y, - * and Z axes. (required)
    - * Valid values: [translation, rotation, scale, weights] - * + * The name of the node's TRS property to animate, or the `"weights"` of + * the Morph Targets it instantiates. For the `"translation"` property, + * the values that are provided by the sampler are the translation along + * the X, Y, and Z axes. For the `"rotation"` property, the values are a + * quaternion in the order (x, y, z, w), where w is the scalar. For the + * `"scale"` property, the values are the scaling factors along the X, Y, + * and Z axes. (required)
    + * Valid values: [translation, rotation, scale, weights] + * */ private String path; /** - * The index of the node to animate. When undefined, the animated object - * **MAY** be defined by an extension. (optional) - * - * @return The node - * - */ - public Integer getNode() { - return this.node; - } - - /** - * The index of the node to animate. When undefined, the animated object - * **MAY** be defined by an extension. (optional) - * + * The index of the node to animate. When undefined, the animated object + * **MAY** be defined by an extension. (optional) + * * @param node The node to set - * + * */ public void setNode(Integer node) { if (node == null) { this.node = node; - return; + return ; } this.node = node; } /** - * The name of the node's TRS property to animate, or the `"weights"` of - * the Morph Targets it instantiates. For the `"translation"` property, - * the values that are provided by the sampler are the translation along - * the X, Y, and Z axes. For the `"rotation"` property, the values are a - * quaternion in the order (x, y, z, w), where w is the scalar. For the - * `"scale"` property, the values are the scaling factors along the X, Y, - * and Z axes. (required)
    - * Valid values: [translation, rotation, scale, weights] - * - * @return The path - * + * The index of the node to animate. When undefined, the animated object + * **MAY** be defined by an extension. (optional) + * + * @return The node + * */ - public String getPath() { - return this.path; + public Integer getNode() { + return this.node; } /** - * The name of the node's TRS property to animate, or the `"weights"` of - * the Morph Targets it instantiates. For the `"translation"` property, - * the values that are provided by the sampler are the translation along - * the X, Y, and Z axes. For the `"rotation"` property, the values are a - * quaternion in the order (x, y, z, w), where w is the scalar. For the - * `"scale"` property, the values are the scaling factors along the X, Y, - * and Z axes. (required)
    - * Valid values: [translation, rotation, scale, weights] - * + * The name of the node's TRS property to animate, or the `"weights"` of + * the Morph Targets it instantiates. For the `"translation"` property, + * the values that are provided by the sampler are the translation along + * the X, Y, and Z axes. For the `"rotation"` property, the values are a + * quaternion in the order (x, y, z, w), where w is the scalar. For the + * `"scale"` property, the values are the scaling factors along the X, Y, + * and Z axes. (required)
    + * Valid values: [translation, rotation, scale, weights] + * * @param path The path to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setPath(String path) { if (path == null) { - throw new NullPointerException((("Invalid value for path: " + path) + ", may not be null")); + throw new NullPointerException((("Invalid value for path: "+ path)+", may not be null")); } - if ((((!"translation".equals(path)) && (!"rotation".equals(path))) && (!"scale".equals(path))) && (!"weights".equals(path))) { - throw new IllegalArgumentException((("Invalid value for path: " + path) + ", valid: [translation, rotation, scale, weights]")); + if ((((!"translation".equals(path))&&(!"rotation".equals(path)))&&(!"scale".equals(path)))&&(!"weights".equals(path))) { + throw new IllegalArgumentException((("Invalid value for path: "+ path)+", valid: [translation, rotation, scale, weights]")); } this.path = path; } + /** + * The name of the node's TRS property to animate, or the `"weights"` of + * the Morph Targets it instantiates. For the `"translation"` property, + * the values that are provided by the sampler are the translation along + * the X, Y, and Z axes. For the `"rotation"` property, the values are a + * quaternion in the order (x, y, z, w), where w is the scalar. For the + * `"scale"` property, the values are the scaling factors along the X, Y, + * and Z axes. (required)
    + * Valid values: [translation, rotation, scale, weights] + * + * @return The path + * + */ + public String getPath() { + return this.path; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/AnimationSampler.java b/src/main/java/de/javagl/jgltf/impl/v2/AnimationSampler.java index 6e9c899..4b52b36 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/AnimationSampler.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/AnimationSampler.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,127 +9,129 @@ package de.javagl.jgltf.impl.v2; + /** - * An animation sampler combines timestamps with a sequence of output - * values and defines an interpolation algorithm. - *

    - * Auto-generated for animation.sampler.schema.json - * + * An animation sampler combines timestamps with a sequence of output + * values and defines an interpolation algorithm. + * + * Auto-generated for animation.sampler.schema.json + * */ public class AnimationSampler - extends GlTFProperty { + extends GlTFProperty +{ /** - * The index of an accessor containing keyframe timestamps. (required) - * + * The index of an accessor containing keyframe timestamps. (required) + * */ private Integer input; /** - * Interpolation algorithm. (optional)
    - * Default: "LINEAR"
    - * Valid values: [LINEAR, STEP, CUBICSPLINE] - * + * Interpolation algorithm. (optional)
    + * Default: "LINEAR"
    + * Valid values: [LINEAR, STEP, CUBICSPLINE] + * */ private String interpolation; /** - * The index of an accessor, containing keyframe output values. - * (required) - * + * The index of an accessor, containing keyframe output values. + * (required) + * */ private Integer output; /** - * The index of an accessor containing keyframe timestamps. (required) - * - * @return The input - * - */ - public Integer getInput() { - return this.input; - } - - /** - * The index of an accessor containing keyframe timestamps. (required) - * + * The index of an accessor containing keyframe timestamps. (required) + * * @param input The input to set * @throws NullPointerException If the given value is null - * + * */ public void setInput(Integer input) { if (input == null) { - throw new NullPointerException((("Invalid value for input: " + input) + ", may not be null")); + throw new NullPointerException((("Invalid value for input: "+ input)+", may not be null")); } this.input = input; } /** - * Interpolation algorithm. (optional)
    - * Default: "LINEAR"
    - * Valid values: [LINEAR, STEP, CUBICSPLINE] - * - * @return The interpolation - * + * The index of an accessor containing keyframe timestamps. (required) + * + * @return The input + * */ - public String getInterpolation() { - return this.interpolation; + public Integer getInput() { + return this.input; } /** - * Interpolation algorithm. (optional)
    - * Default: "LINEAR"
    - * Valid values: [LINEAR, STEP, CUBICSPLINE] - * + * Interpolation algorithm. (optional)
    + * Default: "LINEAR"
    + * Valid values: [LINEAR, STEP, CUBICSPLINE] + * * @param interpolation The interpolation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setInterpolation(String interpolation) { if (interpolation == null) { this.interpolation = interpolation; - return; + return ; } - if (((!"LINEAR".equals(interpolation)) && (!"STEP".equals(interpolation))) && (!"CUBICSPLINE".equals(interpolation))) { - throw new IllegalArgumentException((("Invalid value for interpolation: " + interpolation) + ", valid: [LINEAR, STEP, CUBICSPLINE]")); + if (((!"LINEAR".equals(interpolation))&&(!"STEP".equals(interpolation)))&&(!"CUBICSPLINE".equals(interpolation))) { + throw new IllegalArgumentException((("Invalid value for interpolation: "+ interpolation)+", valid: [LINEAR, STEP, CUBICSPLINE]")); } this.interpolation = interpolation; } /** - * Returns the default value of the interpolation
    - * - * @return The default interpolation - * @see #getInterpolation - * + * Interpolation algorithm. (optional)
    + * Default: "LINEAR"
    + * Valid values: [LINEAR, STEP, CUBICSPLINE] + * + * @return The interpolation + * */ - public String defaultInterpolation() { - return "LINEAR"; + public String getInterpolation() { + return this.interpolation; } /** - * The index of an accessor, containing keyframe output values. - * (required) - * - * @return The output - * + * Returns the default value of the interpolation
    + * @see #getInterpolation + * + * @return The default interpolation + * */ - public Integer getOutput() { - return this.output; + public String defaultInterpolation() { + return "LINEAR"; } /** - * The index of an accessor, containing keyframe output values. - * (required) - * + * The index of an accessor, containing keyframe output values. + * (required) + * * @param output The output to set * @throws NullPointerException If the given value is null - * + * */ public void setOutput(Integer output) { if (output == null) { - throw new NullPointerException((("Invalid value for output: " + output) + ", may not be null")); + throw new NullPointerException((("Invalid value for output: "+ output)+", may not be null")); } this.output = output; } + /** + * The index of an accessor, containing keyframe output values. + * (required) + * + * @return The output + * + */ + public Integer getOutput() { + return this.output; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Asset.java b/src/main/java/de/javagl/jgltf/impl/v2/Asset.java index d4434a3..3b067f5 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Asset.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Asset.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,142 +9,144 @@ package de.javagl.jgltf.impl.v2; + /** - * Metadata about the glTF asset. - *

    - * Auto-generated for asset.schema.json - * + * Metadata about the glTF asset. + * + * Auto-generated for asset.schema.json + * */ public class Asset - extends GlTFProperty { + extends GlTFProperty +{ /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * */ private String copyright; /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * */ private String generator; /** - * The glTF version in the form of `<major>.<minor>` that - * this asset targets. (required) - * + * The glTF version in the form of `<major>.<minor>` that + * this asset targets. (required) + * */ private String version; /** - * The minimum glTF version in the form of `<major>.<minor>` - * that this asset targets. This property **MUST NOT** be greater than - * the asset version. (optional) - * + * The minimum glTF version in the form of `<major>.<minor>` + * that this asset targets. This property **MUST NOT** be greater than + * the asset version. (optional) + * */ private String minVersion; /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * - * @return The copyright - * - */ - public String getCopyright() { - return this.copyright; - } - - /** - * A copyright message suitable for display to credit the content - * creator. (optional) - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * * @param copyright The copyright to set - * + * */ public void setCopyright(String copyright) { if (copyright == null) { this.copyright = copyright; - return; + return ; } this.copyright = copyright; } /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * - * @return The generator - * + * A copyright message suitable for display to credit the content + * creator. (optional) + * + * @return The copyright + * */ - public String getGenerator() { - return this.generator; + public String getCopyright() { + return this.copyright; } /** - * Tool that generated this glTF model. Useful for debugging. (optional) - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * * @param generator The generator to set - * + * */ public void setGenerator(String generator) { if (generator == null) { this.generator = generator; - return; + return ; } this.generator = generator; } /** - * The glTF version in the form of `<major>.<minor>` that - * this asset targets. (required) - * - * @return The version - * + * Tool that generated this glTF model. Useful for debugging. (optional) + * + * @return The generator + * */ - public String getVersion() { - return this.version; + public String getGenerator() { + return this.generator; } /** - * The glTF version in the form of `<major>.<minor>` that - * this asset targets. (required) - * + * The glTF version in the form of `<major>.<minor>` that + * this asset targets. (required) + * * @param version The version to set * @throws NullPointerException If the given value is null - * + * */ public void setVersion(String version) { if (version == null) { - throw new NullPointerException((("Invalid value for version: " + version) + ", may not be null")); + throw new NullPointerException((("Invalid value for version: "+ version)+", may not be null")); } this.version = version; } /** - * The minimum glTF version in the form of `<major>.<minor>` - * that this asset targets. This property **MUST NOT** be greater than - * the asset version. (optional) - * - * @return The minVersion - * + * The glTF version in the form of `<major>.<minor>` that + * this asset targets. (required) + * + * @return The version + * */ - public String getMinVersion() { - return this.minVersion; + public String getVersion() { + return this.version; } /** - * The minimum glTF version in the form of `<major>.<minor>` - * that this asset targets. This property **MUST NOT** be greater than - * the asset version. (optional) - * + * The minimum glTF version in the form of `<major>.<minor>` + * that this asset targets. This property **MUST NOT** be greater than + * the asset version. (optional) + * * @param minVersion The minVersion to set - * + * */ public void setMinVersion(String minVersion) { if (minVersion == null) { this.minVersion = minVersion; - return; + return ; } this.minVersion = minVersion; } + /** + * The minimum glTF version in the form of `<major>.<minor>` + * that this asset targets. This property **MUST NOT** be greater than + * the asset version. (optional) + * + * @return The minVersion + * + */ + public String getMinVersion() { + return this.minVersion; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Buffer.java b/src/main/java/de/javagl/jgltf/impl/v2/Buffer.java index 5e5635a..76af0d3 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Buffer.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Buffer.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,80 +9,82 @@ package de.javagl.jgltf.impl.v2; + /** - * A buffer points to binary geometry, animation, or skins. - *

    - * Auto-generated for buffer.schema.json - * + * A buffer points to binary geometry, animation, or skins. + * + * Auto-generated for buffer.schema.json + * */ public class Buffer - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The URI (or IRI) of the buffer. (optional) - * + * The URI (or IRI) of the buffer. (optional) + * */ private String uri; /** - * The length of the buffer in bytes. (required)
    - * Minimum: 1 (inclusive) - * + * The length of the buffer in bytes. (required)
    + * Minimum: 1 (inclusive) + * */ private Integer byteLength; /** - * The URI (or IRI) of the buffer. (optional) - * - * @return The uri - * - */ - public String getUri() { - return this.uri; - } - - /** - * The URI (or IRI) of the buffer. (optional) - * + * The URI (or IRI) of the buffer. (optional) + * * @param uri The uri to set - * + * */ public void setUri(String uri) { if (uri == null) { this.uri = uri; - return; + return ; } this.uri = uri; } /** - * The length of the buffer in bytes. (required)
    - * Minimum: 1 (inclusive) - * - * @return The byteLength - * + * The URI (or IRI) of the buffer. (optional) + * + * @return The uri + * */ - public Integer getByteLength() { - return this.byteLength; + public String getUri() { + return this.uri; } /** - * The length of the buffer in bytes. (required)
    - * Minimum: 1 (inclusive) - * + * The length of the buffer in bytes. (required)
    + * Minimum: 1 (inclusive) + * * @param byteLength The byteLength to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteLength(Integer byteLength) { if (byteLength == null) { - throw new NullPointerException((("Invalid value for byteLength: " + byteLength) + ", may not be null")); + throw new NullPointerException((("Invalid value for byteLength: "+ byteLength)+", may not be null")); } - if (byteLength < 1) { + if (byteLength< 1) { throw new IllegalArgumentException("byteLength < 1"); } this.byteLength = byteLength; } + /** + * The length of the buffer in bytes. (required)
    + * Minimum: 1 (inclusive) + * + * @return The byteLength + * + */ + public Integer getByteLength() { + return this.byteLength; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/BufferView.java b/src/main/java/de/javagl/jgltf/impl/v2/BufferView.java index 059181f..9b0b25c 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/BufferView.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/BufferView.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,214 +9,216 @@ package de.javagl.jgltf.impl.v2; + /** - * A view into a buffer generally representing a subset of the buffer. - *

    - * Auto-generated for bufferView.schema.json - * + * A view into a buffer generally representing a subset of the buffer. + * + * Auto-generated for bufferView.schema.json + * */ public class BufferView - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The index of the buffer. (required) - * + * The index of the buffer. (required) + * */ private Integer buffer; /** - * The offset into the buffer in bytes. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The offset into the buffer in bytes. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * */ private Integer byteOffset; /** - * The length of the bufferView in bytes. (required)
    - * Minimum: 1 (inclusive) - * + * The length of the bufferView in bytes. (required)
    + * Minimum: 1 (inclusive) + * */ private Integer byteLength; /** - * The stride, in bytes. (optional)
    - * Minimum: 4 (inclusive)
    - * Maximum: 252 (inclusive) - * + * The stride, in bytes. (optional)
    + * Minimum: 4 (inclusive)
    + * Maximum: 252 (inclusive) + * */ private Integer byteStride; /** - * The hint representing the intended GPU buffer type to use with this - * buffer view. (optional)
    - * Valid values: [34962, 34963] - * + * The hint representing the intended GPU buffer type to use with this + * buffer view. (optional)
    + * Valid values: [34962, 34963] + * */ private Integer target; /** - * The index of the buffer. (required) - * - * @return The buffer - * - */ - public Integer getBuffer() { - return this.buffer; - } - - /** - * The index of the buffer. (required) - * + * The index of the buffer. (required) + * * @param buffer The buffer to set * @throws NullPointerException If the given value is null - * + * */ public void setBuffer(Integer buffer) { if (buffer == null) { - throw new NullPointerException((("Invalid value for buffer: " + buffer) + ", may not be null")); + throw new NullPointerException((("Invalid value for buffer: "+ buffer)+", may not be null")); } this.buffer = buffer; } /** - * The offset into the buffer in bytes. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * - * @return The byteOffset - * + * The index of the buffer. (required) + * + * @return The buffer + * */ - public Integer getByteOffset() { - return this.byteOffset; + public Integer getBuffer() { + return this.buffer; } /** - * The offset into the buffer in bytes. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The offset into the buffer in bytes. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * * @param byteOffset The byteOffset to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteOffset(Integer byteOffset) { if (byteOffset == null) { this.byteOffset = byteOffset; - return; + return ; } - if (byteOffset < 0) { + if (byteOffset< 0) { throw new IllegalArgumentException("byteOffset < 0"); } this.byteOffset = byteOffset; } /** - * Returns the default value of the byteOffset
    - * - * @return The default byteOffset - * @see #getByteOffset - * + * The offset into the buffer in bytes. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * + * @return The byteOffset + * */ - public Integer defaultByteOffset() { - return 0; + public Integer getByteOffset() { + return this.byteOffset; } /** - * The length of the bufferView in bytes. (required)
    - * Minimum: 1 (inclusive) - * - * @return The byteLength - * + * Returns the default value of the byteOffset
    + * @see #getByteOffset + * + * @return The default byteOffset + * */ - public Integer getByteLength() { - return this.byteLength; + public Integer defaultByteOffset() { + return 0; } /** - * The length of the bufferView in bytes. (required)
    - * Minimum: 1 (inclusive) - * + * The length of the bufferView in bytes. (required)
    + * Minimum: 1 (inclusive) + * * @param byteLength The byteLength to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteLength(Integer byteLength) { if (byteLength == null) { - throw new NullPointerException((("Invalid value for byteLength: " + byteLength) + ", may not be null")); + throw new NullPointerException((("Invalid value for byteLength: "+ byteLength)+", may not be null")); } - if (byteLength < 1) { + if (byteLength< 1) { throw new IllegalArgumentException("byteLength < 1"); } this.byteLength = byteLength; } /** - * The stride, in bytes. (optional)
    - * Minimum: 4 (inclusive)
    - * Maximum: 252 (inclusive) - * - * @return The byteStride - * + * The length of the bufferView in bytes. (required)
    + * Minimum: 1 (inclusive) + * + * @return The byteLength + * */ - public Integer getByteStride() { - return this.byteStride; + public Integer getByteLength() { + return this.byteLength; } /** - * The stride, in bytes. (optional)
    - * Minimum: 4 (inclusive)
    - * Maximum: 252 (inclusive) - * + * The stride, in bytes. (optional)
    + * Minimum: 4 (inclusive)
    + * Maximum: 252 (inclusive) + * * @param byteStride The byteStride to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setByteStride(Integer byteStride) { if (byteStride == null) { this.byteStride = byteStride; - return; + return ; } if (byteStride > 252) { throw new IllegalArgumentException("byteStride > 252"); } - if (byteStride < 4) { + if (byteStride< 4) { throw new IllegalArgumentException("byteStride < 4"); } this.byteStride = byteStride; } /** - * The hint representing the intended GPU buffer type to use with this - * buffer view. (optional)
    - * Valid values: [34962, 34963] - * - * @return The target - * + * The stride, in bytes. (optional)
    + * Minimum: 4 (inclusive)
    + * Maximum: 252 (inclusive) + * + * @return The byteStride + * */ - public Integer getTarget() { - return this.target; + public Integer getByteStride() { + return this.byteStride; } /** - * The hint representing the intended GPU buffer type to use with this - * buffer view. (optional)
    - * Valid values: [34962, 34963] - * + * The hint representing the intended GPU buffer type to use with this + * buffer view. (optional)
    + * Valid values: [34962, 34963] + * * @param target The target to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTarget(Integer target) { if (target == null) { this.target = target; - return; + return ; } - if ((target != 34962) && (target != 34963)) { - throw new IllegalArgumentException((("Invalid value for target: " + target) + ", valid: [34962, 34963]")); + if ((target!= 34962)&&(target!= 34963)) { + throw new IllegalArgumentException((("Invalid value for target: "+ target)+", valid: [34962, 34963]")); } this.target = target; } + /** + * The hint representing the intended GPU buffer type to use with this + * buffer view. (optional)
    + * Valid values: [34962, 34963] + * + * @return The target + * + */ + public Integer getTarget() { + return this.target; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Camera.java b/src/main/java/de/javagl/jgltf/impl/v2/Camera.java index bfcd256..65473d8 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Camera.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Camera.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,125 +9,127 @@ package de.javagl.jgltf.impl.v2; + /** - * A camera's projection. A node **MAY** reference a camera to apply a - * transform to place the camera in the scene. - *

    - * Auto-generated for camera.schema.json - * + * A camera's projection. A node **MAY** reference a camera to apply a + * transform to place the camera in the scene. + * + * Auto-generated for camera.schema.json + * */ public class Camera - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. This property **MUST NOT** be defined when - * `perspective` is defined. (optional) - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. This property **MUST NOT** be defined when + * `perspective` is defined. (optional) + * */ private CameraOrthographic orthographic; /** - * A perspective camera containing properties to create a perspective - * projection matrix. This property **MUST NOT** be defined when - * `orthographic` is defined. (optional) - * + * A perspective camera containing properties to create a perspective + * projection matrix. This property **MUST NOT** be defined when + * `orthographic` is defined. (optional) + * */ private CameraPerspective perspective; /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
    - * Valid values: [perspective, orthographic] - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
    + * Valid values: [perspective, orthographic] + * */ private String type; /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. This property **MUST NOT** be defined when - * `perspective` is defined. (optional) - * - * @return The orthographic - * - */ - public CameraOrthographic getOrthographic() { - return this.orthographic; - } - - /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. This property **MUST NOT** be defined when - * `perspective` is defined. (optional) - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. This property **MUST NOT** be defined when + * `perspective` is defined. (optional) + * * @param orthographic The orthographic to set - * + * */ public void setOrthographic(CameraOrthographic orthographic) { if (orthographic == null) { this.orthographic = orthographic; - return; + return ; } this.orthographic = orthographic; } /** - * A perspective camera containing properties to create a perspective - * projection matrix. This property **MUST NOT** be defined when - * `orthographic` is defined. (optional) - * - * @return The perspective - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. This property **MUST NOT** be defined when + * `perspective` is defined. (optional) + * + * @return The orthographic + * */ - public CameraPerspective getPerspective() { - return this.perspective; + public CameraOrthographic getOrthographic() { + return this.orthographic; } /** - * A perspective camera containing properties to create a perspective - * projection matrix. This property **MUST NOT** be defined when - * `orthographic` is defined. (optional) - * + * A perspective camera containing properties to create a perspective + * projection matrix. This property **MUST NOT** be defined when + * `orthographic` is defined. (optional) + * * @param perspective The perspective to set - * + * */ public void setPerspective(CameraPerspective perspective) { if (perspective == null) { this.perspective = perspective; - return; + return ; } this.perspective = perspective; } /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
    - * Valid values: [perspective, orthographic] - * - * @return The type - * + * A perspective camera containing properties to create a perspective + * projection matrix. This property **MUST NOT** be defined when + * `orthographic` is defined. (optional) + * + * @return The perspective + * */ - public String getType() { - return this.type; + public CameraPerspective getPerspective() { + return this.perspective; } /** - * Specifies if the camera uses a perspective or orthographic projection. - * (required)
    - * Valid values: [perspective, orthographic] - * + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
    + * Valid values: [perspective, orthographic] + * * @param type The type to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setType(String type) { if (type == null) { - throw new NullPointerException((("Invalid value for type: " + type) + ", may not be null")); + throw new NullPointerException((("Invalid value for type: "+ type)+", may not be null")); } - if ((!"perspective".equals(type)) && (!"orthographic".equals(type))) { - throw new IllegalArgumentException((("Invalid value for type: " + type) + ", valid: [perspective, orthographic]")); + if ((!"perspective".equals(type))&&(!"orthographic".equals(type))) { + throw new IllegalArgumentException((("Invalid value for type: "+ type)+", valid: [perspective, orthographic]")); } this.type = type; } + /** + * Specifies if the camera uses a perspective or orthographic projection. + * (required)
    + * Valid values: [perspective, orthographic] + * + * @return The type + * + */ + public String getType() { + return this.type; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/CameraOrthographic.java b/src/main/java/de/javagl/jgltf/impl/v2/CameraOrthographic.java index be71da7..b4c3225 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/CameraOrthographic.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/CameraOrthographic.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,165 +9,167 @@ package de.javagl.jgltf.impl.v2; + /** - * An orthographic camera containing properties to create an orthographic - * projection matrix. - *

    - * Auto-generated for camera.orthographic.schema.json - * + * An orthographic camera containing properties to create an orthographic + * projection matrix. + * + * Auto-generated for camera.orthographic.schema.json + * */ public class CameraOrthographic - extends GlTFProperty { + extends GlTFProperty +{ /** - * The floating-point horizontal magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * + * The floating-point horizontal magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * */ private Float xmag; /** - * The floating-point vertical magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * + * The floating-point vertical magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * */ private Float ymag; /** - * The floating-point distance to the far clipping plane. This value - * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than - * `znear`. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. This value + * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than + * `znear`. (required)
    + * Minimum: 0.0 (exclusive) + * */ private Float zfar; /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (inclusive) + * */ private Float znear; /** - * The floating-point horizontal magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * - * @return The xmag - * - */ - public Float getXmag() { - return this.xmag; - } - - /** - * The floating-point horizontal magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * + * The floating-point horizontal magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * * @param xmag The xmag to set * @throws NullPointerException If the given value is null - * + * */ public void setXmag(Float xmag) { if (xmag == null) { - throw new NullPointerException((("Invalid value for xmag: " + xmag) + ", may not be null")); + throw new NullPointerException((("Invalid value for xmag: "+ xmag)+", may not be null")); } this.xmag = xmag; } /** - * The floating-point vertical magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * - * @return The ymag - * + * The floating-point horizontal magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * + * @return The xmag + * */ - public Float getYmag() { - return this.ymag; + public Float getXmag() { + return this.xmag; } /** - * The floating-point vertical magnification of the view. This value - * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. - * (required) - * + * The floating-point vertical magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * * @param ymag The ymag to set * @throws NullPointerException If the given value is null - * + * */ public void setYmag(Float ymag) { if (ymag == null) { - throw new NullPointerException((("Invalid value for ymag: " + ymag) + ", may not be null")); + throw new NullPointerException((("Invalid value for ymag: "+ ymag)+", may not be null")); } this.ymag = ymag; } /** - * The floating-point distance to the far clipping plane. This value - * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than - * `znear`. (required)
    - * Minimum: 0.0 (exclusive) - * - * @return The zfar - * + * The floating-point vertical magnification of the view. This value + * **MUST NOT** be equal to zero. This value **SHOULD NOT** be negative. + * (required) + * + * @return The ymag + * */ - public Float getZfar() { - return this.zfar; + public Float getYmag() { + return this.ymag; } /** - * The floating-point distance to the far clipping plane. This value - * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than - * `znear`. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. This value + * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than + * `znear`. (required)
    + * Minimum: 0.0 (exclusive) + * * @param zfar The zfar to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZfar(Float zfar) { if (zfar == null) { - throw new NullPointerException((("Invalid value for zfar: " + zfar) + ", may not be null")); + throw new NullPointerException((("Invalid value for zfar: "+ zfar)+", may not be null")); } - if (zfar <= 0.0D) { + if (zfar<= 0.0D) { throw new IllegalArgumentException("zfar <= 0.0"); } this.zfar = zfar; } /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (inclusive) - * - * @return The znear - * + * The floating-point distance to the far clipping plane. This value + * **MUST NOT** be equal to zero. `zfar` **MUST** be greater than + * `znear`. (required)
    + * Minimum: 0.0 (exclusive) + * + * @return The zfar + * */ - public Float getZnear() { - return this.znear; + public Float getZfar() { + return this.zfar; } /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (inclusive) - * + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (inclusive) + * * @param znear The znear to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZnear(Float znear) { if (znear == null) { - throw new NullPointerException((("Invalid value for znear: " + znear) + ", may not be null")); + throw new NullPointerException((("Invalid value for znear: "+ znear)+", may not be null")); } - if (znear < 0.0D) { + if (znear< 0.0D) { throw new IllegalArgumentException("znear < 0.0"); } this.znear = znear; } + /** + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (inclusive) + * + * @return The znear + * + */ + public Float getZnear() { + return this.znear; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/CameraPerspective.java b/src/main/java/de/javagl/jgltf/impl/v2/CameraPerspective.java index 57cb721..01434ca 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/CameraPerspective.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/CameraPerspective.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,166 +9,168 @@ package de.javagl.jgltf.impl.v2; + /** - * A perspective camera containing properties to create a perspective - * projection matrix. - *

    - * Auto-generated for camera.perspective.schema.json - * + * A perspective camera containing properties to create a perspective + * projection matrix. + * + * Auto-generated for camera.perspective.schema.json + * */ public class CameraPerspective - extends GlTFProperty { + extends GlTFProperty +{ /** - * The floating-point aspect ratio of the field of view. (optional)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point aspect ratio of the field of view. (optional)
    + * Minimum: 0.0 (exclusive) + * */ private Float aspectRatio; /** - * The floating-point vertical field of view in radians. This value - * **SHOULD** be less than π. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point vertical field of view in radians. This value + * **SHOULD** be less than π. (required)
    + * Minimum: 0.0 (exclusive) + * */ private Float yfov; /** - * The floating-point distance to the far clipping plane. (optional)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. (optional)
    + * Minimum: 0.0 (exclusive) + * */ private Float zfar; /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (exclusive) + * */ private Float znear; /** - * The floating-point aspect ratio of the field of view. (optional)
    - * Minimum: 0.0 (exclusive) - * - * @return The aspectRatio - * - */ - public Float getAspectRatio() { - return this.aspectRatio; - } - - /** - * The floating-point aspect ratio of the field of view. (optional)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point aspect ratio of the field of view. (optional)
    + * Minimum: 0.0 (exclusive) + * * @param aspectRatio The aspectRatio to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAspectRatio(Float aspectRatio) { if (aspectRatio == null) { this.aspectRatio = aspectRatio; - return; + return ; } - if (aspectRatio <= 0.0D) { + if (aspectRatio<= 0.0D) { throw new IllegalArgumentException("aspectRatio <= 0.0"); } this.aspectRatio = aspectRatio; } /** - * The floating-point vertical field of view in radians. This value - * **SHOULD** be less than π. (required)
    - * Minimum: 0.0 (exclusive) - * - * @return The yfov - * + * The floating-point aspect ratio of the field of view. (optional)
    + * Minimum: 0.0 (exclusive) + * + * @return The aspectRatio + * */ - public Float getYfov() { - return this.yfov; + public Float getAspectRatio() { + return this.aspectRatio; } /** - * The floating-point vertical field of view in radians. This value - * **SHOULD** be less than π. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point vertical field of view in radians. This value + * **SHOULD** be less than π. (required)
    + * Minimum: 0.0 (exclusive) + * * @param yfov The yfov to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setYfov(Float yfov) { if (yfov == null) { - throw new NullPointerException((("Invalid value for yfov: " + yfov) + ", may not be null")); + throw new NullPointerException((("Invalid value for yfov: "+ yfov)+", may not be null")); } - if (yfov <= 0.0D) { + if (yfov<= 0.0D) { throw new IllegalArgumentException("yfov <= 0.0"); } this.yfov = yfov; } /** - * The floating-point distance to the far clipping plane. (optional)
    - * Minimum: 0.0 (exclusive) - * - * @return The zfar - * + * The floating-point vertical field of view in radians. This value + * **SHOULD** be less than π. (required)
    + * Minimum: 0.0 (exclusive) + * + * @return The yfov + * */ - public Float getZfar() { - return this.zfar; + public Float getYfov() { + return this.yfov; } /** - * The floating-point distance to the far clipping plane. (optional)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the far clipping plane. (optional)
    + * Minimum: 0.0 (exclusive) + * * @param zfar The zfar to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZfar(Float zfar) { if (zfar == null) { this.zfar = zfar; - return; + return ; } - if (zfar <= 0.0D) { + if (zfar<= 0.0D) { throw new IllegalArgumentException("zfar <= 0.0"); } this.zfar = zfar; } /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (exclusive) - * - * @return The znear - * + * The floating-point distance to the far clipping plane. (optional)
    + * Minimum: 0.0 (exclusive) + * + * @return The zfar + * */ - public Float getZnear() { - return this.znear; + public Float getZfar() { + return this.zfar; } /** - * The floating-point distance to the near clipping plane. (required)
    - * Minimum: 0.0 (exclusive) - * + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (exclusive) + * * @param znear The znear to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setZnear(Float znear) { if (znear == null) { - throw new NullPointerException((("Invalid value for znear: " + znear) + ", may not be null")); + throw new NullPointerException((("Invalid value for znear: "+ znear)+", may not be null")); } - if (znear <= 0.0D) { + if (znear<= 0.0D) { throw new IllegalArgumentException("znear <= 0.0"); } this.znear = znear; } + /** + * The floating-point distance to the near clipping plane. (required)
    + * Minimum: 0.0 (exclusive) + * + * @return The znear + * + */ + public Float getZnear() { + return this.znear; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/GlTF.java b/src/main/java/de/javagl/jgltf/impl/v2/GlTF.java index 879b1b8..9cf71fc 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/GlTF.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/GlTF.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,205 +13,206 @@ /** - * The root object for a glTF asset. - *

    - * Auto-generated for glTF.schema.json - * + * The root object for a glTF asset. + * + * Auto-generated for glTF.schema.json + * */ public class GlTF - extends GlTFProperty { + extends GlTFProperty +{ /** - * Names of glTF extensions used in this asset. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * Names of glTF extensions used in this asset. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List extensionsUsed; /** - * Names of glTF extensions required to properly load this asset. - * (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * Names of glTF extensions required to properly load this asset. + * (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List extensionsRequired; /** - * An array of accessors. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A typed view into a buffer view that contains raw binary - * data. (optional) - * + * An array of accessors. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A typed view into a buffer view that contains raw binary + * data. (optional) + * */ private List accessors; /** - * An array of keyframe animations. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A keyframe animation. (optional) - * + * An array of keyframe animations. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A keyframe animation. (optional) + * */ private List animations; /** - * Metadata about the glTF asset. (required) - * + * Metadata about the glTF asset. (required) + * */ private Asset asset; /** - * An array of buffers. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A buffer points to binary geometry, animation, or skins. - * (optional) - * + * An array of buffers. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A buffer points to binary geometry, animation, or skins. + * (optional) + * */ private List buffers; /** - * An array of bufferViews. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A view into a buffer generally representing a subset of - * the buffer. (optional) - * + * An array of bufferViews. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A view into a buffer generally representing a subset of + * the buffer. (optional) + * */ private List bufferViews; /** - * An array of cameras. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A camera's projection. A node **MAY** reference a camera - * to apply a transform to place the camera in the scene. (optional) - * + * An array of cameras. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A camera's projection. A node **MAY** reference a camera + * to apply a transform to place the camera in the scene. (optional) + * */ private List cameras; /** - * An array of images. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Image data used to create a texture. Image **MAY** be - * referenced by an URI (or IRI) or a buffer view index. (optional) - * + * An array of images. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Image data used to create a texture. Image **MAY** be + * referenced by an URI (or IRI) or a buffer view index. (optional) + * */ private List images; /** - * An array of materials. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The material appearance of a primitive. (optional) - * + * An array of materials. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The material appearance of a primitive. (optional) + * */ private List materials; /** - * An array of meshes. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A set of primitives to be rendered. Its global transform - * is defined by a node that references it. (optional) - * + * An array of meshes. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A set of primitives to be rendered. Its global transform + * is defined by a node that references it. (optional) + * */ private List meshes; /** - * An array of nodes. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A node in the node hierarchy. When the node contains - * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and - * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any - * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS - * properties are converted to matrices and postmultiplied in the `T * R - * * S` order to compose the transformation matrix; first the scale is - * applied to the vertices, then the rotation, and then the translation. - * If none are provided, the transform is the identity. When a node is - * targeted for animation (referenced by an animation.channel.target), - * `matrix` **MUST NOT** be present. (optional) - * + * An array of nodes. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A node in the node hierarchy. When the node contains + * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and + * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any + * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS + * properties are converted to matrices and postmultiplied in the `T * R + * * S` order to compose the transformation matrix; first the scale is + * applied to the vertices, then the rotation, and then the translation. + * If none are provided, the transform is the identity. When a node is + * targeted for animation (referenced by an animation.channel.target), + * `matrix` **MUST NOT** be present. (optional) + * */ private List nodes; /** - * An array of samplers. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Texture sampler properties for filtering and wrapping - * modes. (optional) - * + * An array of samplers. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Texture sampler properties for filtering and wrapping + * modes. (optional) + * */ private List samplers; /** - * The index of the default scene. (optional) - * + * The index of the default scene. (optional) + * */ private Integer scene; /** - * An array of scenes. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The root nodes of a scene. (optional) - * + * An array of scenes. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The root nodes of a scene. (optional) + * */ private List scenes; /** - * An array of skins. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Joints and matrices defining a skin. (optional) - * + * An array of skins. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Joints and matrices defining a skin. (optional) + * */ private List skins; /** - * An array of textures. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A texture and its sampler. (optional) - * + * An array of textures. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A texture and its sampler. (optional) + * */ private List textures; /** - * Names of glTF extensions used in this asset. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The extensionsUsed - * - */ - public List getExtensionsUsed() { - return this.extensionsUsed; - } - - /** - * Names of glTF extensions used in this asset. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * Names of glTF extensions used in this asset. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * * @param extensionsUsed The extensionsUsed to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setExtensionsUsed(List extensionsUsed) { if (extensionsUsed == null) { this.extensionsUsed = extensionsUsed; - return; + return ; } - if (extensionsUsed.size() < 1) { + if (extensionsUsed.size()< 1) { throw new IllegalArgumentException("Number of extensionsUsed elements is < 1"); } this.extensionsUsed = extensionsUsed; } /** - * Add the given extensionsUsed. The extensionsUsed of this instance will - * be replaced with a list that contains all previous elements, and - * additionally the new element. - * + * Names of glTF extensions used in this asset. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The extensionsUsed + * + */ + public List getExtensionsUsed() { + return this.extensionsUsed; + } + + /** + * Add the given extensionsUsed. The extensionsUsed of this instance will + * be replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addExtensionsUsed(String element) { if (element == null) { @@ -219,7 +220,7 @@ public void addExtensionsUsed(String element) { } List oldList = this.extensionsUsed; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -227,15 +228,15 @@ public void addExtensionsUsed(String element) { } /** - * Remove the given extensionsUsed. The extensionsUsed of this instance - * will be replaced with a list that contains all previous elements, - * except for the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given extensionsUsed. The extensionsUsed of this instance + * will be replaced with a list that contains all previous elements, + * except for the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeExtensionsUsed(String element) { if (element == null) { @@ -243,7 +244,7 @@ public void removeExtensionsUsed(String element) { } List oldList = this.extensionsUsed; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -255,50 +256,50 @@ public void removeExtensionsUsed(String element) { } /** - * Names of glTF extensions required to properly load this asset. - * (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The extensionsRequired - * - */ - public List getExtensionsRequired() { - return this.extensionsRequired; - } - - /** - * Names of glTF extensions required to properly load this asset. - * (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * Names of glTF extensions required to properly load this asset. + * (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * * @param extensionsRequired The extensionsRequired to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setExtensionsRequired(List extensionsRequired) { if (extensionsRequired == null) { this.extensionsRequired = extensionsRequired; - return; + return ; } - if (extensionsRequired.size() < 1) { + if (extensionsRequired.size()< 1) { throw new IllegalArgumentException("Number of extensionsRequired elements is < 1"); } this.extensionsRequired = extensionsRequired; } /** - * Add the given extensionsRequired. The extensionsRequired of this - * instance will be replaced with a list that contains all previous - * elements, and additionally the new element. - * + * Names of glTF extensions required to properly load this asset. + * (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The extensionsRequired + * + */ + public List getExtensionsRequired() { + return this.extensionsRequired; + } + + /** + * Add the given extensionsRequired. The extensionsRequired of this + * instance will be replaced with a list that contains all previous + * elements, and additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addExtensionsRequired(String element) { if (element == null) { @@ -306,7 +307,7 @@ public void addExtensionsRequired(String element) { } List oldList = this.extensionsRequired; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -314,15 +315,15 @@ public void addExtensionsRequired(String element) { } /** - * Remove the given extensionsRequired. The extensionsRequired of this - * instance will be replaced with a list that contains all previous - * elements, except for the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given extensionsRequired. The extensionsRequired of this + * instance will be replaced with a list that contains all previous + * elements, except for the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeExtensionsRequired(String element) { if (element == null) { @@ -330,7 +331,7 @@ public void removeExtensionsRequired(String element) { } List oldList = this.extensionsRequired; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -342,50 +343,50 @@ public void removeExtensionsRequired(String element) { } /** - * An array of accessors. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A typed view into a buffer view that contains raw binary - * data. (optional) - * - * @return The accessors - * - */ - public List getAccessors() { - return this.accessors; - } - - /** - * An array of accessors. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A typed view into a buffer view that contains raw binary - * data. (optional) - * + * An array of accessors. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A typed view into a buffer view that contains raw binary + * data. (optional) + * * @param accessors The accessors to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAccessors(List accessors) { if (accessors == null) { this.accessors = accessors; - return; + return ; } - if (accessors.size() < 1) { + if (accessors.size()< 1) { throw new IllegalArgumentException("Number of accessors elements is < 1"); } this.accessors = accessors; } /** - * Add the given accessors. The accessors of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * An array of accessors. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A typed view into a buffer view that contains raw binary + * data. (optional) + * + * @return The accessors + * + */ + public List getAccessors() { + return this.accessors; + } + + /** + * Add the given accessors. The accessors of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addAccessors(Accessor element) { if (element == null) { @@ -393,7 +394,7 @@ public void addAccessors(Accessor element) { } List oldList = this.accessors; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -401,15 +402,15 @@ public void addAccessors(Accessor element) { } /** - * Remove the given accessors. The accessors of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given accessors. The accessors of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeAccessors(Accessor element) { if (element == null) { @@ -417,7 +418,7 @@ public void removeAccessors(Accessor element) { } List oldList = this.accessors; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -429,48 +430,48 @@ public void removeAccessors(Accessor element) { } /** - * An array of keyframe animations. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A keyframe animation. (optional) - * - * @return The animations - * - */ - public List getAnimations() { - return this.animations; - } - - /** - * An array of keyframe animations. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A keyframe animation. (optional) - * + * An array of keyframe animations. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A keyframe animation. (optional) + * * @param animations The animations to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAnimations(List animations) { if (animations == null) { this.animations = animations; - return; + return ; } - if (animations.size() < 1) { + if (animations.size()< 1) { throw new IllegalArgumentException("Number of animations elements is < 1"); } this.animations = animations; } /** - * Add the given animations. The animations of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * An array of keyframe animations. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A keyframe animation. (optional) + * + * @return The animations + * + */ + public List getAnimations() { + return this.animations; + } + + /** + * Add the given animations. The animations of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addAnimations(Animation element) { if (element == null) { @@ -478,7 +479,7 @@ public void addAnimations(Animation element) { } List oldList = this.animations; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -486,15 +487,15 @@ public void addAnimations(Animation element) { } /** - * Remove the given animations. The animations of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given animations. The animations of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeAnimations(Animation element) { if (element == null) { @@ -502,7 +503,7 @@ public void removeAnimations(Animation element) { } List oldList = this.animations; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -514,74 +515,74 @@ public void removeAnimations(Animation element) { } /** - * Metadata about the glTF asset. (required) - * - * @return The asset - * - */ - public Asset getAsset() { - return this.asset; - } - - /** - * Metadata about the glTF asset. (required) - * + * Metadata about the glTF asset. (required) + * * @param asset The asset to set * @throws NullPointerException If the given value is null - * + * */ public void setAsset(Asset asset) { if (asset == null) { - throw new NullPointerException((("Invalid value for asset: " + asset) + ", may not be null")); + throw new NullPointerException((("Invalid value for asset: "+ asset)+", may not be null")); } this.asset = asset; } /** - * An array of buffers. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A buffer points to binary geometry, animation, or skins. - * (optional) - * - * @return The buffers - * + * Metadata about the glTF asset. (required) + * + * @return The asset + * */ - public List getBuffers() { - return this.buffers; + public Asset getAsset() { + return this.asset; } /** - * An array of buffers. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A buffer points to binary geometry, animation, or skins. - * (optional) - * + * An array of buffers. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A buffer points to binary geometry, animation, or skins. + * (optional) + * * @param buffers The buffers to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBuffers(List buffers) { if (buffers == null) { this.buffers = buffers; - return; + return ; } - if (buffers.size() < 1) { + if (buffers.size()< 1) { throw new IllegalArgumentException("Number of buffers elements is < 1"); } this.buffers = buffers; } /** - * Add the given buffers. The buffers of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of buffers. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A buffer points to binary geometry, animation, or skins. + * (optional) + * + * @return The buffers + * + */ + public List getBuffers() { + return this.buffers; + } + + /** + * Add the given buffers. The buffers of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addBuffers(Buffer element) { if (element == null) { @@ -589,7 +590,7 @@ public void addBuffers(Buffer element) { } List oldList = this.buffers; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -597,15 +598,15 @@ public void addBuffers(Buffer element) { } /** - * Remove the given buffers. The buffers of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given buffers. The buffers of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeBuffers(Buffer element) { if (element == null) { @@ -613,7 +614,7 @@ public void removeBuffers(Buffer element) { } List oldList = this.buffers; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -625,50 +626,50 @@ public void removeBuffers(Buffer element) { } /** - * An array of bufferViews. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A view into a buffer generally representing a subset of - * the buffer. (optional) - * - * @return The bufferViews - * - */ - public List getBufferViews() { - return this.bufferViews; - } - - /** - * An array of bufferViews. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A view into a buffer generally representing a subset of - * the buffer. (optional) - * + * An array of bufferViews. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A view into a buffer generally representing a subset of + * the buffer. (optional) + * * @param bufferViews The bufferViews to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBufferViews(List bufferViews) { if (bufferViews == null) { this.bufferViews = bufferViews; - return; + return ; } - if (bufferViews.size() < 1) { + if (bufferViews.size()< 1) { throw new IllegalArgumentException("Number of bufferViews elements is < 1"); } this.bufferViews = bufferViews; } /** - * Add the given bufferViews. The bufferViews of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * An array of bufferViews. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A view into a buffer generally representing a subset of + * the buffer. (optional) + * + * @return The bufferViews + * + */ + public List getBufferViews() { + return this.bufferViews; + } + + /** + * Add the given bufferViews. The bufferViews of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addBufferViews(BufferView element) { if (element == null) { @@ -676,7 +677,7 @@ public void addBufferViews(BufferView element) { } List oldList = this.bufferViews; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -684,15 +685,15 @@ public void addBufferViews(BufferView element) { } /** - * Remove the given bufferViews. The bufferViews of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given bufferViews. The bufferViews of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeBufferViews(BufferView element) { if (element == null) { @@ -700,7 +701,7 @@ public void removeBufferViews(BufferView element) { } List oldList = this.bufferViews; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -712,50 +713,50 @@ public void removeBufferViews(BufferView element) { } /** - * An array of cameras. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A camera's projection. A node **MAY** reference a camera - * to apply a transform to place the camera in the scene. (optional) - * - * @return The cameras - * - */ - public List getCameras() { - return this.cameras; - } - - /** - * An array of cameras. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A camera's projection. A node **MAY** reference a camera - * to apply a transform to place the camera in the scene. (optional) - * + * An array of cameras. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A camera's projection. A node **MAY** reference a camera + * to apply a transform to place the camera in the scene. (optional) + * * @param cameras The cameras to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setCameras(List cameras) { if (cameras == null) { this.cameras = cameras; - return; + return ; } - if (cameras.size() < 1) { + if (cameras.size()< 1) { throw new IllegalArgumentException("Number of cameras elements is < 1"); } this.cameras = cameras; } /** - * Add the given cameras. The cameras of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of cameras. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A camera's projection. A node **MAY** reference a camera + * to apply a transform to place the camera in the scene. (optional) + * + * @return The cameras + * + */ + public List getCameras() { + return this.cameras; + } + + /** + * Add the given cameras. The cameras of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addCameras(Camera element) { if (element == null) { @@ -763,7 +764,7 @@ public void addCameras(Camera element) { } List oldList = this.cameras; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -771,15 +772,15 @@ public void addCameras(Camera element) { } /** - * Remove the given cameras. The cameras of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given cameras. The cameras of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeCameras(Camera element) { if (element == null) { @@ -787,7 +788,7 @@ public void removeCameras(Camera element) { } List oldList = this.cameras; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -799,50 +800,50 @@ public void removeCameras(Camera element) { } /** - * An array of images. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Image data used to create a texture. Image **MAY** be - * referenced by an URI (or IRI) or a buffer view index. (optional) - * - * @return The images - * - */ - public List getImages() { - return this.images; - } - - /** - * An array of images. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Image data used to create a texture. Image **MAY** be - * referenced by an URI (or IRI) or a buffer view index. (optional) - * + * An array of images. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Image data used to create a texture. Image **MAY** be + * referenced by an URI (or IRI) or a buffer view index. (optional) + * * @param images The images to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setImages(List images) { if (images == null) { this.images = images; - return; + return ; } - if (images.size() < 1) { + if (images.size()< 1) { throw new IllegalArgumentException("Number of images elements is < 1"); } this.images = images; } /** - * Add the given images. The images of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of images. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Image data used to create a texture. Image **MAY** be + * referenced by an URI (or IRI) or a buffer view index. (optional) + * + * @return The images + * + */ + public List getImages() { + return this.images; + } + + /** + * Add the given images. The images of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addImages(Image element) { if (element == null) { @@ -850,7 +851,7 @@ public void addImages(Image element) { } List oldList = this.images; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -858,15 +859,15 @@ public void addImages(Image element) { } /** - * Remove the given images. The images of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given images. The images of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeImages(Image element) { if (element == null) { @@ -874,7 +875,7 @@ public void removeImages(Image element) { } List oldList = this.images; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -886,48 +887,48 @@ public void removeImages(Image element) { } /** - * An array of materials. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The material appearance of a primitive. (optional) - * - * @return The materials - * - */ - public List getMaterials() { - return this.materials; - } - - /** - * An array of materials. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The material appearance of a primitive. (optional) - * + * An array of materials. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The material appearance of a primitive. (optional) + * * @param materials The materials to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMaterials(List materials) { if (materials == null) { this.materials = materials; - return; + return ; } - if (materials.size() < 1) { + if (materials.size()< 1) { throw new IllegalArgumentException("Number of materials elements is < 1"); } this.materials = materials; } /** - * Add the given materials. The materials of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * An array of materials. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The material appearance of a primitive. (optional) + * + * @return The materials + * + */ + public List getMaterials() { + return this.materials; + } + + /** + * Add the given materials. The materials of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addMaterials(Material element) { if (element == null) { @@ -935,7 +936,7 @@ public void addMaterials(Material element) { } List oldList = this.materials; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -943,15 +944,15 @@ public void addMaterials(Material element) { } /** - * Remove the given materials. The materials of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given materials. The materials of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeMaterials(Material element) { if (element == null) { @@ -959,7 +960,7 @@ public void removeMaterials(Material element) { } List oldList = this.materials; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -971,50 +972,50 @@ public void removeMaterials(Material element) { } /** - * An array of meshes. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A set of primitives to be rendered. Its global transform - * is defined by a node that references it. (optional) - * - * @return The meshes - * - */ - public List getMeshes() { - return this.meshes; - } - - /** - * An array of meshes. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A set of primitives to be rendered. Its global transform - * is defined by a node that references it. (optional) - * + * An array of meshes. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A set of primitives to be rendered. Its global transform + * is defined by a node that references it. (optional) + * * @param meshes The meshes to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMeshes(List meshes) { if (meshes == null) { this.meshes = meshes; - return; + return ; } - if (meshes.size() < 1) { + if (meshes.size()< 1) { throw new IllegalArgumentException("Number of meshes elements is < 1"); } this.meshes = meshes; } /** - * Add the given meshes. The meshes of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of meshes. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A set of primitives to be rendered. Its global transform + * is defined by a node that references it. (optional) + * + * @return The meshes + * + */ + public List getMeshes() { + return this.meshes; + } + + /** + * Add the given meshes. The meshes of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addMeshes(Mesh element) { if (element == null) { @@ -1022,7 +1023,7 @@ public void addMeshes(Mesh element) { } List oldList = this.meshes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -1030,15 +1031,15 @@ public void addMeshes(Mesh element) { } /** - * Remove the given meshes. The meshes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given meshes. The meshes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeMeshes(Mesh element) { if (element == null) { @@ -1046,7 +1047,7 @@ public void removeMeshes(Mesh element) { } List oldList = this.meshes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -1058,66 +1059,66 @@ public void removeMeshes(Mesh element) { } /** - * An array of nodes. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A node in the node hierarchy. When the node contains - * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and - * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any - * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS - * properties are converted to matrices and postmultiplied in the `T * R - * * S` order to compose the transformation matrix; first the scale is - * applied to the vertices, then the rotation, and then the translation. - * If none are provided, the transform is the identity. When a node is - * targeted for animation (referenced by an animation.channel.target), - * `matrix` **MUST NOT** be present. (optional) - * - * @return The nodes - * - */ - public List getNodes() { - return this.nodes; - } - - /** - * An array of nodes. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A node in the node hierarchy. When the node contains - * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and - * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any - * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS - * properties are converted to matrices and postmultiplied in the `T * R - * * S` order to compose the transformation matrix; first the scale is - * applied to the vertices, then the rotation, and then the translation. - * If none are provided, the transform is the identity. When a node is - * targeted for animation (referenced by an animation.channel.target), - * `matrix` **MUST NOT** be present. (optional) - * + * An array of nodes. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A node in the node hierarchy. When the node contains + * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and + * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any + * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS + * properties are converted to matrices and postmultiplied in the `T * R + * * S` order to compose the transformation matrix; first the scale is + * applied to the vertices, then the rotation, and then the translation. + * If none are provided, the transform is the identity. When a node is + * targeted for animation (referenced by an animation.channel.target), + * `matrix` **MUST NOT** be present. (optional) + * * @param nodes The nodes to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setNodes(List nodes) { if (nodes == null) { this.nodes = nodes; - return; + return ; } - if (nodes.size() < 1) { + if (nodes.size()< 1) { throw new IllegalArgumentException("Number of nodes elements is < 1"); } this.nodes = nodes; } /** - * Add the given nodes. The nodes of this instance will be replaced with - * a list that contains all previous elements, and additionally the new - * element. - * + * An array of nodes. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A node in the node hierarchy. When the node contains + * `skin`, all `mesh.primitives` **MUST** contain `JOINTS_0` and + * `WEIGHTS_0` attributes. A node **MAY** have either a `matrix` or any + * combination of `translation`/`rotation`/`scale` (TRS) properties. TRS + * properties are converted to matrices and postmultiplied in the `T * R + * * S` order to compose the transformation matrix; first the scale is + * applied to the vertices, then the rotation, and then the translation. + * If none are provided, the transform is the identity. When a node is + * targeted for animation (referenced by an animation.channel.target), + * `matrix` **MUST NOT** be present. (optional) + * + * @return The nodes + * + */ + public List getNodes() { + return this.nodes; + } + + /** + * Add the given nodes. The nodes of this instance will be replaced with + * a list that contains all previous elements, and additionally the new + * element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addNodes(Node element) { if (element == null) { @@ -1125,7 +1126,7 @@ public void addNodes(Node element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -1133,15 +1134,15 @@ public void addNodes(Node element) { } /** - * Remove the given nodes. The nodes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given nodes. The nodes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeNodes(Node element) { if (element == null) { @@ -1149,7 +1150,7 @@ public void removeNodes(Node element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -1161,50 +1162,50 @@ public void removeNodes(Node element) { } /** - * An array of samplers. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Texture sampler properties for filtering and wrapping - * modes. (optional) - * - * @return The samplers - * - */ - public List getSamplers() { - return this.samplers; - } - - /** - * An array of samplers. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Texture sampler properties for filtering and wrapping - * modes. (optional) - * + * An array of samplers. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Texture sampler properties for filtering and wrapping + * modes. (optional) + * * @param samplers The samplers to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setSamplers(List samplers) { if (samplers == null) { this.samplers = samplers; - return; + return ; } - if (samplers.size() < 1) { + if (samplers.size()< 1) { throw new IllegalArgumentException("Number of samplers elements is < 1"); } this.samplers = samplers; } /** - * Add the given samplers. The samplers of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of samplers. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Texture sampler properties for filtering and wrapping + * modes. (optional) + * + * @return The samplers + * + */ + public List getSamplers() { + return this.samplers; + } + + /** + * Add the given samplers. The samplers of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addSamplers(Sampler element) { if (element == null) { @@ -1212,7 +1213,7 @@ public void addSamplers(Sampler element) { } List oldList = this.samplers; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -1220,15 +1221,15 @@ public void addSamplers(Sampler element) { } /** - * Remove the given samplers. The samplers of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given samplers. The samplers of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeSamplers(Sampler element) { if (element == null) { @@ -1236,7 +1237,7 @@ public void removeSamplers(Sampler element) { } List oldList = this.samplers; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -1248,72 +1249,72 @@ public void removeSamplers(Sampler element) { } /** - * The index of the default scene. (optional) - * - * @return The scene - * - */ - public Integer getScene() { - return this.scene; - } - - /** - * The index of the default scene. (optional) - * + * The index of the default scene. (optional) + * * @param scene The scene to set - * + * */ public void setScene(Integer scene) { if (scene == null) { this.scene = scene; - return; + return ; } this.scene = scene; } /** - * An array of scenes. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The root nodes of a scene. (optional) - * - * @return The scenes - * + * The index of the default scene. (optional) + * + * @return The scene + * */ - public List getScenes() { - return this.scenes; + public Integer getScene() { + return this.scene; } /** - * An array of scenes. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The root nodes of a scene. (optional) - * + * An array of scenes. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The root nodes of a scene. (optional) + * * @param scenes The scenes to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setScenes(List scenes) { if (scenes == null) { this.scenes = scenes; - return; + return ; } - if (scenes.size() < 1) { + if (scenes.size()< 1) { throw new IllegalArgumentException("Number of scenes elements is < 1"); } this.scenes = scenes; } /** - * Add the given scenes. The scenes of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of scenes. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The root nodes of a scene. (optional) + * + * @return The scenes + * + */ + public List getScenes() { + return this.scenes; + } + + /** + * Add the given scenes. The scenes of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addScenes(Scene element) { if (element == null) { @@ -1321,7 +1322,7 @@ public void addScenes(Scene element) { } List oldList = this.scenes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -1329,15 +1330,15 @@ public void addScenes(Scene element) { } /** - * Remove the given scenes. The scenes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given scenes. The scenes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeScenes(Scene element) { if (element == null) { @@ -1345,7 +1346,7 @@ public void removeScenes(Scene element) { } List oldList = this.scenes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -1357,48 +1358,48 @@ public void removeScenes(Scene element) { } /** - * An array of skins. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Joints and matrices defining a skin. (optional) - * - * @return The skins - * - */ - public List getSkins() { - return this.skins; - } - - /** - * An array of skins. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Joints and matrices defining a skin. (optional) - * + * An array of skins. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Joints and matrices defining a skin. (optional) + * * @param skins The skins to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setSkins(List skins) { if (skins == null) { this.skins = skins; - return; + return ; } - if (skins.size() < 1) { + if (skins.size()< 1) { throw new IllegalArgumentException("Number of skins elements is < 1"); } this.skins = skins; } /** - * Add the given skins. The skins of this instance will be replaced with - * a list that contains all previous elements, and additionally the new - * element. - * + * An array of skins. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Joints and matrices defining a skin. (optional) + * + * @return The skins + * + */ + public List getSkins() { + return this.skins; + } + + /** + * Add the given skins. The skins of this instance will be replaced with + * a list that contains all previous elements, and additionally the new + * element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addSkins(Skin element) { if (element == null) { @@ -1406,7 +1407,7 @@ public void addSkins(Skin element) { } List oldList = this.skins; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -1414,15 +1415,15 @@ public void addSkins(Skin element) { } /** - * Remove the given skins. The skins of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given skins. The skins of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeSkins(Skin element) { if (element == null) { @@ -1430,7 +1431,7 @@ public void removeSkins(Skin element) { } List oldList = this.skins; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -1442,48 +1443,48 @@ public void removeSkins(Skin element) { } /** - * An array of textures. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A texture and its sampler. (optional) - * - * @return The textures - * - */ - public List getTextures() { - return this.textures; - } - - /** - * An array of textures. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A texture and its sampler. (optional) - * + * An array of textures. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A texture and its sampler. (optional) + * * @param textures The textures to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTextures(List textures) { if (textures == null) { this.textures = textures; - return; + return ; } - if (textures.size() < 1) { + if (textures.size()< 1) { throw new IllegalArgumentException("Number of textures elements is < 1"); } this.textures = textures; } /** - * Add the given textures. The textures of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of textures. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A texture and its sampler. (optional) + * + * @return The textures + * + */ + public List getTextures() { + return this.textures; + } + + /** + * Add the given textures. The textures of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addTextures(Texture element) { if (element == null) { @@ -1491,7 +1492,7 @@ public void addTextures(Texture element) { } List oldList = this.textures; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -1499,15 +1500,15 @@ public void addTextures(Texture element) { } /** - * Remove the given textures. The textures of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given textures. The textures of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeTextures(Texture element) { if (element == null) { @@ -1515,7 +1516,7 @@ public void removeTextures(Texture element) { } List oldList = this.textures; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/GlTFChildOfRootProperty.java b/src/main/java/de/javagl/jgltf/impl/v2/GlTFChildOfRootProperty.java index fccd6ac..ae63ce2 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/GlTFChildOfRootProperty.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/GlTFChildOfRootProperty.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,41 +9,43 @@ package de.javagl.jgltf.impl.v2; + /** - * Auto-generated for glTFChildOfRootProperty.schema.json - * + * Auto-generated for glTFChildOfRootProperty.schema.json + * */ public class GlTFChildOfRootProperty - extends GlTFProperty { + extends GlTFProperty +{ /** - * The user-defined name of this object. (optional) - * + * The user-defined name of this object. (optional) + * */ private String name; /** - * The user-defined name of this object. (optional) - * - * @return The name - * - */ - public String getName() { - return this.name; - } - - /** - * The user-defined name of this object. (optional) - * + * The user-defined name of this object. (optional) + * * @param name The name to set - * + * */ public void setName(String name) { if (name == null) { this.name = name; - return; + return ; } this.name = name; } + /** + * The user-defined name of this object. (optional) + * + * @return The name + * + */ + public String getName() { + return this.name; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/GlTFProperty.java b/src/main/java/de/javagl/jgltf/impl/v2/GlTFProperty.java index d444aea..ca055cb 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/GlTFProperty.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/GlTFProperty.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,55 +13,55 @@ /** - * Auto-generated for glTFProperty.schema.json - * + * Auto-generated for glTFProperty.schema.json + * */ public class GlTFProperty { /** - * JSON object with extension-specific objects. (optional) - * + * JSON object with extension-specific objects. (optional) + * */ private Map extensions; /** - * Application-specific data. (optional) - * + * Application-specific data. (optional) + * */ private Object extras; /** - * JSON object with extension-specific objects. (optional) - * - * @return The extensions - * - */ - public Map getExtensions() { - return this.extensions; - } - - /** - * JSON object with extension-specific objects. (optional) - * + * JSON object with extension-specific objects. (optional) + * * @param extensions The extensions to set - * + * */ public void setExtensions(Map extensions) { if (extensions == null) { this.extensions = extensions; - return; + return ; } this.extensions = extensions; } /** - * Add the given extensions. The extensions of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * JSON object with extension-specific objects. (optional) + * + * @return The extensions + * + */ + public Map getExtensions() { + return this.extensions; + } + + /** + * Add the given extensions. The extensions of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addExtensions(String key, Object value) { if (key == null) { @@ -72,7 +72,7 @@ public void addExtensions(String key, Object value) { } Map oldMap = this.extensions; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -80,15 +80,15 @@ public void addExtensions(String key, Object value) { } /** - * Remove the given extensions. The extensions of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key.
    - * If this new map would be empty, then it will be set to - * null. - * + * Remove the given extensions. The extensions of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key.
    + * If this new map would be empty, then it will be set to + * null. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeExtensions(String key) { if (key == null) { @@ -96,7 +96,7 @@ public void removeExtensions(String key) { } Map oldMap = this.extensions; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -108,27 +108,27 @@ public void removeExtensions(String key) { } /** - * Application-specific data. (optional) - * - * @return The extras - * - */ - public Object getExtras() { - return this.extras; - } - - /** - * Application-specific data. (optional) - * + * Application-specific data. (optional) + * * @param extras The extras to set - * + * */ public void setExtras(Object extras) { if (extras == null) { this.extras = extras; - return; + return ; } this.extras = extras; } + /** + * Application-specific data. (optional) + * + * @return The extras + * + */ + public Object getExtras() { + return this.extras; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Image.java b/src/main/java/de/javagl/jgltf/impl/v2/Image.java index 16e670c..3e82a67 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Image.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Image.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,111 +9,113 @@ package de.javagl.jgltf.impl.v2; + /** - * Image data used to create a texture. Image **MAY** be referenced by an - * URI (or IRI) or a buffer view index. - *

    - * Auto-generated for image.schema.json - * + * Image data used to create a texture. Image **MAY** be referenced by an + * URI (or IRI) or a buffer view index. + * + * Auto-generated for image.schema.json + * */ public class Image - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The URI (or IRI) of the image. (optional) - * + * The URI (or IRI) of the image. (optional) + * */ private String uri; /** - * The image's media type. This field **MUST** be defined when - * `bufferView` is defined. (optional)
    - * Valid values: [image/jpeg, image/png] - * + * The image's media type. This field **MUST** be defined when + * `bufferView` is defined. (optional)
    + * Valid values: [image/jpeg, image/png] + * */ private String mimeType; /** - * The index of the bufferView that contains the image. This field **MUST - * NOT** be defined when `uri` is defined. (optional) - * + * The index of the bufferView that contains the image. This field **MUST + * NOT** be defined when `uri` is defined. (optional) + * */ private Integer bufferView; /** - * The URI (or IRI) of the image. (optional) - * - * @return The uri - * - */ - public String getUri() { - return this.uri; - } - - /** - * The URI (or IRI) of the image. (optional) - * + * The URI (or IRI) of the image. (optional) + * * @param uri The uri to set - * + * */ public void setUri(String uri) { if (uri == null) { this.uri = uri; - return; + return ; } this.uri = uri; } /** - * The image's media type. This field **MUST** be defined when - * `bufferView` is defined. (optional)
    - * Valid values: [image/jpeg, image/png] - * - * @return The mimeType - * + * The URI (or IRI) of the image. (optional) + * + * @return The uri + * */ - public String getMimeType() { - return this.mimeType; + public String getUri() { + return this.uri; } /** - * The image's media type. This field **MUST** be defined when - * `bufferView` is defined. (optional)
    - * Valid values: [image/jpeg, image/png] - * + * The image's media type. This field **MUST** be defined when + * `bufferView` is defined. (optional)
    + * Valid values: [image/jpeg, image/png] + * * @param mimeType The mimeType to set - * + * */ public void setMimeType(String mimeType) { if (mimeType == null) { this.mimeType = mimeType; - return; + return ; } this.mimeType = mimeType; } /** - * The index of the bufferView that contains the image. This field **MUST - * NOT** be defined when `uri` is defined. (optional) - * - * @return The bufferView - * + * The image's media type. This field **MUST** be defined when + * `bufferView` is defined. (optional)
    + * Valid values: [image/jpeg, image/png] + * + * @return The mimeType + * */ - public Integer getBufferView() { - return this.bufferView; + public String getMimeType() { + return this.mimeType; } /** - * The index of the bufferView that contains the image. This field **MUST - * NOT** be defined when `uri` is defined. (optional) - * + * The index of the bufferView that contains the image. This field **MUST + * NOT** be defined when `uri` is defined. (optional) + * * @param bufferView The bufferView to set - * + * */ public void setBufferView(Integer bufferView) { if (bufferView == null) { this.bufferView = bufferView; - return; + return ; } this.bufferView = bufferView; } + /** + * The index of the bufferView that contains the image. This field **MUST + * NOT** be defined when `uri` is defined. (optional) + * + * @return The bufferView + * + */ + public Integer getBufferView() { + return this.bufferView; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Material.java b/src/main/java/de/javagl/jgltf/impl/v2/Material.java index 61dfbb8..18cd6a9 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Material.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Material.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,218 +9,204 @@ package de.javagl.jgltf.impl.v2; + /** - * The material appearance of a primitive. - *

    - * Auto-generated for material.schema.json - * + * The material appearance of a primitive. + * + * Auto-generated for material.schema.json + * */ public class Material - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * A set of parameter values that are used to define the - * metallic-roughness material model from Physically Based Rendering - * (PBR) methodology. When undefined, all the default values of - * `pbrMetallicRoughness` **MUST** apply. (optional) - * + * A set of parameter values that are used to define the + * metallic-roughness material model from Physically Based Rendering + * (PBR) methodology. When undefined, all the default values of + * `pbrMetallicRoughness` **MUST** apply. (optional) + * */ private MaterialPbrMetallicRoughness pbrMetallicRoughness; /** - * The tangent space normal texture. (optional) - * + * The tangent space normal texture. (optional) + * */ private MaterialNormalTextureInfo normalTexture; /** - * The occlusion texture. (optional) - * + * The occlusion texture. (optional) + * */ private MaterialOcclusionTextureInfo occlusionTexture; /** - * The emissive texture. (optional) - * + * The emissive texture. (optional) + * */ private TextureInfo emissiveTexture; /** - * The factors for the emissive color of the material. (optional)
    - * Default: [0.0,0.0,0.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0.0 (inclusive)
    - *   Maximum: 1.0 (inclusive) - * + * The factors for the emissive color of the material. (optional)
    + * Default: [0.0,0.0,0.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0.0 (inclusive)
    + *   Maximum: 1.0 (inclusive) + * */ private float[] emissiveFactor; /** - * The alpha rendering mode of the material. (optional)
    - * Default: "OPAQUE"
    - * Valid values: [OPAQUE, MASK, BLEND] - * + * The alpha rendering mode of the material. (optional)
    + * Default: "OPAQUE"
    + * Valid values: [OPAQUE, MASK, BLEND] + * */ private String alphaMode; /** - * The alpha cutoff value of the material. (optional)
    - * Default: 0.5
    - * Minimum: 0.0 (inclusive) - * + * The alpha cutoff value of the material. (optional)
    + * Default: 0.5
    + * Minimum: 0.0 (inclusive) + * */ private Float alphaCutoff; /** - * Specifies whether the material is double sided. (optional)
    - * Default: false - * + * Specifies whether the material is double sided. (optional)
    + * Default: false + * */ private Boolean doubleSided; /** - * A set of parameter values that are used to define the - * metallic-roughness material model from Physically Based Rendering - * (PBR) methodology. When undefined, all the default values of - * `pbrMetallicRoughness` **MUST** apply. (optional) - * - * @return The pbrMetallicRoughness - * - */ - public MaterialPbrMetallicRoughness getPbrMetallicRoughness() { - return this.pbrMetallicRoughness; - } - - /** - * A set of parameter values that are used to define the - * metallic-roughness material model from Physically Based Rendering - * (PBR) methodology. When undefined, all the default values of - * `pbrMetallicRoughness` **MUST** apply. (optional) - * + * A set of parameter values that are used to define the + * metallic-roughness material model from Physically Based Rendering + * (PBR) methodology. When undefined, all the default values of + * `pbrMetallicRoughness` **MUST** apply. (optional) + * * @param pbrMetallicRoughness The pbrMetallicRoughness to set - * + * */ public void setPbrMetallicRoughness(MaterialPbrMetallicRoughness pbrMetallicRoughness) { if (pbrMetallicRoughness == null) { this.pbrMetallicRoughness = pbrMetallicRoughness; - return; + return ; } this.pbrMetallicRoughness = pbrMetallicRoughness; } /** - * The tangent space normal texture. (optional) - * - * @return The normalTexture - * + * A set of parameter values that are used to define the + * metallic-roughness material model from Physically Based Rendering + * (PBR) methodology. When undefined, all the default values of + * `pbrMetallicRoughness` **MUST** apply. (optional) + * + * @return The pbrMetallicRoughness + * */ - public MaterialNormalTextureInfo getNormalTexture() { - return this.normalTexture; + public MaterialPbrMetallicRoughness getPbrMetallicRoughness() { + return this.pbrMetallicRoughness; } /** - * The tangent space normal texture. (optional) - * + * The tangent space normal texture. (optional) + * * @param normalTexture The normalTexture to set - * + * */ public void setNormalTexture(MaterialNormalTextureInfo normalTexture) { if (normalTexture == null) { this.normalTexture = normalTexture; - return; + return ; } this.normalTexture = normalTexture; } /** - * The occlusion texture. (optional) - * - * @return The occlusionTexture - * + * The tangent space normal texture. (optional) + * + * @return The normalTexture + * */ - public MaterialOcclusionTextureInfo getOcclusionTexture() { - return this.occlusionTexture; + public MaterialNormalTextureInfo getNormalTexture() { + return this.normalTexture; } /** - * The occlusion texture. (optional) - * + * The occlusion texture. (optional) + * * @param occlusionTexture The occlusionTexture to set - * + * */ public void setOcclusionTexture(MaterialOcclusionTextureInfo occlusionTexture) { if (occlusionTexture == null) { this.occlusionTexture = occlusionTexture; - return; + return ; } this.occlusionTexture = occlusionTexture; } /** - * The emissive texture. (optional) - * - * @return The emissiveTexture - * + * The occlusion texture. (optional) + * + * @return The occlusionTexture + * */ - public TextureInfo getEmissiveTexture() { - return this.emissiveTexture; + public MaterialOcclusionTextureInfo getOcclusionTexture() { + return this.occlusionTexture; } /** - * The emissive texture. (optional) - * + * The emissive texture. (optional) + * * @param emissiveTexture The emissiveTexture to set - * + * */ public void setEmissiveTexture(TextureInfo emissiveTexture) { if (emissiveTexture == null) { this.emissiveTexture = emissiveTexture; - return; + return ; } this.emissiveTexture = emissiveTexture; } /** - * The factors for the emissive color of the material. (optional)
    - * Default: [0.0,0.0,0.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0.0 (inclusive)
    - *   Maximum: 1.0 (inclusive) - * - * @return The emissiveFactor - * + * The emissive texture. (optional) + * + * @return The emissiveTexture + * */ - public float[] getEmissiveFactor() { - return this.emissiveFactor; + public TextureInfo getEmissiveTexture() { + return this.emissiveTexture; } /** - * The factors for the emissive color of the material. (optional)
    - * Default: [0.0,0.0,0.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0.0 (inclusive)
    - *   Maximum: 1.0 (inclusive) - * + * The factors for the emissive color of the material. (optional)
    + * Default: [0.0,0.0,0.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0.0 (inclusive)
    + *   Maximum: 1.0 (inclusive) + * * @param emissiveFactor The emissiveFactor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setEmissiveFactor(float[] emissiveFactor) { if (emissiveFactor == null) { this.emissiveFactor = emissiveFactor; - return; + return ; } - if (emissiveFactor.length < 3) { + if (emissiveFactor.length< 3) { throw new IllegalArgumentException("Number of emissiveFactor elements is < 3"); } if (emissiveFactor.length > 3) { throw new IllegalArgumentException("Number of emissiveFactor elements is > 3"); } - for (float emissiveFactorElement : emissiveFactor) { + for (float emissiveFactorElement: emissiveFactor) { if (emissiveFactorElement > 1.0D) { throw new IllegalArgumentException("emissiveFactorElement > 1.0"); } - if (emissiveFactorElement < 0.0D) { + if (emissiveFactorElement< 0.0D) { throw new IllegalArgumentException("emissiveFactorElement < 0.0"); } } @@ -228,136 +214,152 @@ public void setEmissiveFactor(float[] emissiveFactor) { } /** - * Returns the default value of the emissiveFactor
    - * - * @return The default emissiveFactor - * @see #getEmissiveFactor - * + * The factors for the emissive color of the material. (optional)
    + * Default: [0.0,0.0,0.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0.0 (inclusive)
    + *   Maximum: 1.0 (inclusive) + * + * @return The emissiveFactor + * */ - public float[] defaultEmissiveFactor() { - return new float[]{0.0F, 0.0F, 0.0F}; + public float[] getEmissiveFactor() { + return this.emissiveFactor; } /** - * The alpha rendering mode of the material. (optional)
    - * Default: "OPAQUE"
    - * Valid values: [OPAQUE, MASK, BLEND] - * - * @return The alphaMode - * + * Returns the default value of the emissiveFactor
    + * @see #getEmissiveFactor + * + * @return The default emissiveFactor + * */ - public String getAlphaMode() { - return this.alphaMode; + public float[] defaultEmissiveFactor() { + return new float[] { 0.0F, 0.0F, 0.0F }; } /** - * The alpha rendering mode of the material. (optional)
    - * Default: "OPAQUE"
    - * Valid values: [OPAQUE, MASK, BLEND] - * + * The alpha rendering mode of the material. (optional)
    + * Default: "OPAQUE"
    + * Valid values: [OPAQUE, MASK, BLEND] + * * @param alphaMode The alphaMode to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAlphaMode(String alphaMode) { if (alphaMode == null) { this.alphaMode = alphaMode; - return; + return ; } - if (((!"OPAQUE".equals(alphaMode)) && (!"MASK".equals(alphaMode))) && (!"BLEND".equals(alphaMode))) { - throw new IllegalArgumentException((("Invalid value for alphaMode: " + alphaMode) + ", valid: [OPAQUE, MASK, BLEND]")); + if (((!"OPAQUE".equals(alphaMode))&&(!"MASK".equals(alphaMode)))&&(!"BLEND".equals(alphaMode))) { + throw new IllegalArgumentException((("Invalid value for alphaMode: "+ alphaMode)+", valid: [OPAQUE, MASK, BLEND]")); } this.alphaMode = alphaMode; } /** - * Returns the default value of the alphaMode
    - * - * @return The default alphaMode - * @see #getAlphaMode - * + * The alpha rendering mode of the material. (optional)
    + * Default: "OPAQUE"
    + * Valid values: [OPAQUE, MASK, BLEND] + * + * @return The alphaMode + * */ - public String defaultAlphaMode() { - return "OPAQUE"; + public String getAlphaMode() { + return this.alphaMode; } /** - * The alpha cutoff value of the material. (optional)
    - * Default: 0.5
    - * Minimum: 0.0 (inclusive) - * - * @return The alphaCutoff - * + * Returns the default value of the alphaMode
    + * @see #getAlphaMode + * + * @return The default alphaMode + * */ - public Float getAlphaCutoff() { - return this.alphaCutoff; + public String defaultAlphaMode() { + return "OPAQUE"; } /** - * The alpha cutoff value of the material. (optional)
    - * Default: 0.5
    - * Minimum: 0.0 (inclusive) - * + * The alpha cutoff value of the material. (optional)
    + * Default: 0.5
    + * Minimum: 0.0 (inclusive) + * * @param alphaCutoff The alphaCutoff to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setAlphaCutoff(Float alphaCutoff) { if (alphaCutoff == null) { this.alphaCutoff = alphaCutoff; - return; + return ; } - if (alphaCutoff < 0.0D) { + if (alphaCutoff< 0.0D) { throw new IllegalArgumentException("alphaCutoff < 0.0"); } this.alphaCutoff = alphaCutoff; } /** - * Returns the default value of the alphaCutoff
    - * + * The alpha cutoff value of the material. (optional)
    + * Default: 0.5
    + * Minimum: 0.0 (inclusive) + * + * @return The alphaCutoff + * + */ + public Float getAlphaCutoff() { + return this.alphaCutoff; + } + + /** + * Returns the default value of the alphaCutoff
    + * @see #getAlphaCutoff + * * @return The default alphaCutoff - * @see #getAlphaCutoff - * + * */ public Float defaultAlphaCutoff() { - return 0.5F; + return 0.5F; } /** - * Specifies whether the material is double sided. (optional)
    - * Default: false - * + * Specifies whether the material is double sided. (optional)
    + * Default: false + * * @param doubleSided The doubleSided to set - * + * */ public void setDoubleSided(Boolean doubleSided) { if (doubleSided == null) { this.doubleSided = doubleSided; - return; + return ; } this.doubleSided = doubleSided; } /** - * Specifies whether the material is double sided. (optional)
    - * Default: false - * + * Specifies whether the material is double sided. (optional)
    + * Default: false + * * @return The doubleSided - * + * */ public Boolean isDoubleSided() { return this.doubleSided; } /** - * Returns the default value of the doubleSided
    - * + * Returns the default value of the doubleSided
    + * @see #isDoubleSided + * * @return The default doubleSided - * @see #isDoubleSided - * + * */ public Boolean defaultDoubleSided() { return false; diff --git a/src/main/java/de/javagl/jgltf/impl/v2/MaterialNormalTextureInfo.java b/src/main/java/de/javagl/jgltf/impl/v2/MaterialNormalTextureInfo.java index b10b41c..082dea0 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/MaterialNormalTextureInfo.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/MaterialNormalTextureInfo.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,58 +9,60 @@ package de.javagl.jgltf.impl.v2; + /** - * Auto-generated for material.normalTextureInfo.schema.json - * + * Auto-generated for material.normalTextureInfo.schema.json + * */ public class MaterialNormalTextureInfo - extends TextureInfo { + extends TextureInfo +{ /** - * The scalar parameter applied to each normal vector of the normal - * texture. (optional)
    - * Default: 1.0 - * + * The scalar parameter applied to each normal vector of the normal + * texture. (optional)
    + * Default: 1.0 + * */ private Float scale; /** - * The scalar parameter applied to each normal vector of the normal - * texture. (optional)
    - * Default: 1.0 - * - * @return The scale - * - */ - public Float getScale() { - return this.scale; - } - - /** - * The scalar parameter applied to each normal vector of the normal - * texture. (optional)
    - * Default: 1.0 - * + * The scalar parameter applied to each normal vector of the normal + * texture. (optional)
    + * Default: 1.0 + * * @param scale The scale to set - * + * */ public void setScale(Float scale) { if (scale == null) { this.scale = scale; - return; + return ; } this.scale = scale; } /** - * Returns the default value of the scale
    - * + * The scalar parameter applied to each normal vector of the normal + * texture. (optional)
    + * Default: 1.0 + * + * @return The scale + * + */ + public Float getScale() { + return this.scale; + } + + /** + * Returns the default value of the scale
    + * @see #getScale + * * @return The default scale - * @see #getScale - * + * */ public Float defaultScale() { - return 1.0F; + return 1.0F; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/MaterialOcclusionTextureInfo.java b/src/main/java/de/javagl/jgltf/impl/v2/MaterialOcclusionTextureInfo.java index b383262..c5052d6 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/MaterialOcclusionTextureInfo.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/MaterialOcclusionTextureInfo.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,72 +9,74 @@ package de.javagl.jgltf.impl.v2; + /** - * Auto-generated for material.occlusionTextureInfo.schema.json - * + * Auto-generated for material.occlusionTextureInfo.schema.json + * */ public class MaterialOcclusionTextureInfo - extends TextureInfo { + extends TextureInfo +{ /** - * A scalar multiplier controlling the amount of occlusion applied. - * (optional)
    - * Default: 1.0
    - * Minimum: 0.0 (inclusive)
    - * Maximum: 1.0 (inclusive) - * + * A scalar multiplier controlling the amount of occlusion applied. + * (optional)
    + * Default: 1.0
    + * Minimum: 0.0 (inclusive)
    + * Maximum: 1.0 (inclusive) + * */ private Float strength; /** - * A scalar multiplier controlling the amount of occlusion applied. - * (optional)
    - * Default: 1.0
    - * Minimum: 0.0 (inclusive)
    - * Maximum: 1.0 (inclusive) - * - * @return The strength - * - */ - public Float getStrength() { - return this.strength; - } - - /** - * A scalar multiplier controlling the amount of occlusion applied. - * (optional)
    - * Default: 1.0
    - * Minimum: 0.0 (inclusive)
    - * Maximum: 1.0 (inclusive) - * + * A scalar multiplier controlling the amount of occlusion applied. + * (optional)
    + * Default: 1.0
    + * Minimum: 0.0 (inclusive)
    + * Maximum: 1.0 (inclusive) + * * @param strength The strength to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setStrength(Float strength) { if (strength == null) { this.strength = strength; - return; + return ; } if (strength > 1.0D) { throw new IllegalArgumentException("strength > 1.0"); } - if (strength < 0.0D) { + if (strength< 0.0D) { throw new IllegalArgumentException("strength < 0.0"); } this.strength = strength; } /** - * Returns the default value of the strength
    - * + * A scalar multiplier controlling the amount of occlusion applied. + * (optional)
    + * Default: 1.0
    + * Minimum: 0.0 (inclusive)
    + * Maximum: 1.0 (inclusive) + * + * @return The strength + * + */ + public Float getStrength() { + return this.strength; + } + + /** + * Returns the default value of the strength
    + * @see #getStrength + * * @return The default strength - * @see #getStrength - * + * */ public Float defaultStrength() { - return 1.0F; + return 1.0F; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/MaterialPbrMetallicRoughness.java b/src/main/java/de/javagl/jgltf/impl/v2/MaterialPbrMetallicRoughness.java index 73797dd..b539f5d 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/MaterialPbrMetallicRoughness.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/MaterialPbrMetallicRoughness.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,101 +9,87 @@ package de.javagl.jgltf.impl.v2; + /** - * A set of parameter values that are used to define the - * metallic-roughness material model from Physically-Based Rendering - * (PBR) methodology. - *

    - * Auto-generated for material.pbrMetallicRoughness.schema.json - * + * A set of parameter values that are used to define the + * metallic-roughness material model from Physically-Based Rendering + * (PBR) methodology. + * + * Auto-generated for material.pbrMetallicRoughness.schema.json + * */ public class MaterialPbrMetallicRoughness - extends GlTFProperty { + extends GlTFProperty +{ /** - * The factors for the base color of the material. (optional)
    - * Default: [1.0,1.0,1.0,1.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0.0 (inclusive)
    - *   Maximum: 1.0 (inclusive) - * + * The factors for the base color of the material. (optional)
    + * Default: [1.0,1.0,1.0,1.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0.0 (inclusive)
    + *   Maximum: 1.0 (inclusive) + * */ private float[] baseColorFactor; /** - * The base color texture. (optional) - * + * The base color texture. (optional) + * */ private TextureInfo baseColorTexture; /** - * The factor for the metalness of the material. (optional)
    - * Default: 1.0
    - * Minimum: 0.0 (inclusive)
    - * Maximum: 1.0 (inclusive) - * + * The factor for the metalness of the material. (optional)
    + * Default: 1.0
    + * Minimum: 0.0 (inclusive)
    + * Maximum: 1.0 (inclusive) + * */ private Float metallicFactor; /** - * The factor for the roughness of the material. (optional)
    - * Default: 1.0
    - * Minimum: 0.0 (inclusive)
    - * Maximum: 1.0 (inclusive) - * + * The factor for the roughness of the material. (optional)
    + * Default: 1.0
    + * Minimum: 0.0 (inclusive)
    + * Maximum: 1.0 (inclusive) + * */ private Float roughnessFactor; /** - * The metallic-roughness texture. (optional) - * + * The metallic-roughness texture. (optional) + * */ private TextureInfo metallicRoughnessTexture; /** - * The factors for the base color of the material. (optional)
    - * Default: [1.0,1.0,1.0,1.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0.0 (inclusive)
    - *   Maximum: 1.0 (inclusive) - * - * @return The baseColorFactor - * - */ - public float[] getBaseColorFactor() { - return this.baseColorFactor; - } - - /** - * The factors for the base color of the material. (optional)
    - * Default: [1.0,1.0,1.0,1.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0.0 (inclusive)
    - *   Maximum: 1.0 (inclusive) - * + * The factors for the base color of the material. (optional)
    + * Default: [1.0,1.0,1.0,1.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0.0 (inclusive)
    + *   Maximum: 1.0 (inclusive) + * * @param baseColorFactor The baseColorFactor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setBaseColorFactor(float[] baseColorFactor) { if (baseColorFactor == null) { this.baseColorFactor = baseColorFactor; - return; + return ; } - if (baseColorFactor.length < 4) { + if (baseColorFactor.length< 4) { throw new IllegalArgumentException("Number of baseColorFactor elements is < 4"); } if (baseColorFactor.length > 4) { throw new IllegalArgumentException("Number of baseColorFactor elements is > 4"); } - for (float baseColorFactorElement : baseColorFactor) { + for (float baseColorFactorElement: baseColorFactor) { if (baseColorFactorElement > 1.0D) { throw new IllegalArgumentException("baseColorFactorElement > 1.0"); } - if (baseColorFactorElement < 0.0D) { + if (baseColorFactorElement< 0.0D) { throw new IllegalArgumentException("baseColorFactorElement < 0.0"); } } @@ -111,160 +97,176 @@ public void setBaseColorFactor(float[] baseColorFactor) { } /** - * Returns the default value of the baseColorFactor
    - * - * @return The default baseColorFactor - * @see #getBaseColorFactor - * + * The factors for the base color of the material. (optional)
    + * Default: [1.0,1.0,1.0,1.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0.0 (inclusive)
    + *   Maximum: 1.0 (inclusive) + * + * @return The baseColorFactor + * */ - public float[] defaultBaseColorFactor() { - return new float[]{1.0F, 1.0F, 1.0F, 1.0F}; + public float[] getBaseColorFactor() { + return this.baseColorFactor; } /** - * The base color texture. (optional) - * - * @return The baseColorTexture - * + * Returns the default value of the baseColorFactor
    + * @see #getBaseColorFactor + * + * @return The default baseColorFactor + * */ - public TextureInfo getBaseColorTexture() { - return this.baseColorTexture; + public float[] defaultBaseColorFactor() { + return new float[] { 1.0F, 1.0F, 1.0F, 1.0F }; } /** - * The base color texture. (optional) - * + * The base color texture. (optional) + * * @param baseColorTexture The baseColorTexture to set - * + * */ public void setBaseColorTexture(TextureInfo baseColorTexture) { if (baseColorTexture == null) { this.baseColorTexture = baseColorTexture; - return; + return ; } this.baseColorTexture = baseColorTexture; } /** - * The factor for the metalness of the material. (optional)
    - * Default: 1.0
    - * Minimum: 0.0 (inclusive)
    - * Maximum: 1.0 (inclusive) - * - * @return The metallicFactor - * + * The base color texture. (optional) + * + * @return The baseColorTexture + * */ - public Float getMetallicFactor() { - return this.metallicFactor; + public TextureInfo getBaseColorTexture() { + return this.baseColorTexture; } /** - * The factor for the metalness of the material. (optional)
    - * Default: 1.0
    - * Minimum: 0.0 (inclusive)
    - * Maximum: 1.0 (inclusive) - * + * The factor for the metalness of the material. (optional)
    + * Default: 1.0
    + * Minimum: 0.0 (inclusive)
    + * Maximum: 1.0 (inclusive) + * * @param metallicFactor The metallicFactor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMetallicFactor(Float metallicFactor) { if (metallicFactor == null) { this.metallicFactor = metallicFactor; - return; + return ; } if (metallicFactor > 1.0D) { throw new IllegalArgumentException("metallicFactor > 1.0"); } - if (metallicFactor < 0.0D) { + if (metallicFactor< 0.0D) { throw new IllegalArgumentException("metallicFactor < 0.0"); } this.metallicFactor = metallicFactor; } /** - * Returns the default value of the metallicFactor
    - * - * @return The default metallicFactor - * @see #getMetallicFactor - * + * The factor for the metalness of the material. (optional)
    + * Default: 1.0
    + * Minimum: 0.0 (inclusive)
    + * Maximum: 1.0 (inclusive) + * + * @return The metallicFactor + * */ - public Float defaultMetallicFactor() { - return 1.0F; + public Float getMetallicFactor() { + return this.metallicFactor; } /** - * The factor for the roughness of the material. (optional)
    - * Default: 1.0
    - * Minimum: 0.0 (inclusive)
    - * Maximum: 1.0 (inclusive) - * - * @return The roughnessFactor - * + * Returns the default value of the metallicFactor
    + * @see #getMetallicFactor + * + * @return The default metallicFactor + * */ - public Float getRoughnessFactor() { - return this.roughnessFactor; + public Float defaultMetallicFactor() { + return 1.0F; } /** - * The factor for the roughness of the material. (optional)
    - * Default: 1.0
    - * Minimum: 0.0 (inclusive)
    - * Maximum: 1.0 (inclusive) - * + * The factor for the roughness of the material. (optional)
    + * Default: 1.0
    + * Minimum: 0.0 (inclusive)
    + * Maximum: 1.0 (inclusive) + * * @param roughnessFactor The roughnessFactor to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setRoughnessFactor(Float roughnessFactor) { if (roughnessFactor == null) { this.roughnessFactor = roughnessFactor; - return; + return ; } if (roughnessFactor > 1.0D) { throw new IllegalArgumentException("roughnessFactor > 1.0"); } - if (roughnessFactor < 0.0D) { + if (roughnessFactor< 0.0D) { throw new IllegalArgumentException("roughnessFactor < 0.0"); } this.roughnessFactor = roughnessFactor; } /** - * Returns the default value of the roughnessFactor
    - * - * @return The default roughnessFactor - * @see #getRoughnessFactor - * + * The factor for the roughness of the material. (optional)
    + * Default: 1.0
    + * Minimum: 0.0 (inclusive)
    + * Maximum: 1.0 (inclusive) + * + * @return The roughnessFactor + * */ - public Float defaultRoughnessFactor() { - return 1.0F; + public Float getRoughnessFactor() { + return this.roughnessFactor; } /** - * The metallic-roughness texture. (optional) - * - * @return The metallicRoughnessTexture - * + * Returns the default value of the roughnessFactor
    + * @see #getRoughnessFactor + * + * @return The default roughnessFactor + * */ - public TextureInfo getMetallicRoughnessTexture() { - return this.metallicRoughnessTexture; + public Float defaultRoughnessFactor() { + return 1.0F; } /** - * The metallic-roughness texture. (optional) - * + * The metallic-roughness texture. (optional) + * * @param metallicRoughnessTexture The metallicRoughnessTexture to set - * + * */ public void setMetallicRoughnessTexture(TextureInfo metallicRoughnessTexture) { if (metallicRoughnessTexture == null) { this.metallicRoughnessTexture = metallicRoughnessTexture; - return; + return ; } this.metallicRoughnessTexture = metallicRoughnessTexture; } + /** + * The metallic-roughness texture. (optional) + * + * @return The metallicRoughnessTexture + * + */ + public TextureInfo getMetallicRoughnessTexture() { + return this.metallicRoughnessTexture; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Mesh.java b/src/main/java/de/javagl/jgltf/impl/v2/Mesh.java index 756ab15..a99ae4f 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Mesh.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Mesh.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,83 +13,84 @@ /** - * A set of primitives to be rendered. Its global transform is defined by - * a node that references it. - *

    - * Auto-generated for mesh.schema.json - * + * A set of primitives to be rendered. Its global transform is defined by + * a node that references it. + * + * Auto-generated for mesh.schema.json + * */ public class Mesh - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * An array of primitives, each defining geometry to be rendered. - * (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Geometry to be rendered with the given material. - * (optional) - * + * An array of primitives, each defining geometry to be rendered. + * (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Geometry to be rendered with the given material. + * (optional) + * */ private List primitives; /** - * Array of weights to be applied to the morph targets. The number of - * array elements **MUST** match the number of morph targets. - * (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * Array of weights to be applied to the morph targets. The number of + * array elements **MUST** match the number of morph targets. + * (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List weights; /** - * An array of primitives, each defining geometry to be rendered. - * (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Geometry to be rendered with the given material. - * (optional) - * - * @return The primitives - * - */ - public List getPrimitives() { - return this.primitives; - } - - /** - * An array of primitives, each defining geometry to be rendered. - * (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   Geometry to be rendered with the given material. - * (optional) - * + * An array of primitives, each defining geometry to be rendered. + * (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Geometry to be rendered with the given material. + * (optional) + * * @param primitives The primitives to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setPrimitives(List primitives) { if (primitives == null) { - throw new NullPointerException((("Invalid value for primitives: " + primitives) + ", may not be null")); + throw new NullPointerException((("Invalid value for primitives: "+ primitives)+", may not be null")); } - if (primitives.size() < 1) { + if (primitives.size()< 1) { throw new IllegalArgumentException("Number of primitives elements is < 1"); } this.primitives = primitives; } /** - * Add the given primitives. The primitives of this instance will be - * replaced with a list that contains all previous elements, and - * additionally the new element. - * + * An array of primitives, each defining geometry to be rendered. + * (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   Geometry to be rendered with the given material. + * (optional) + * + * @return The primitives + * + */ + public List getPrimitives() { + return this.primitives; + } + + /** + * Add the given primitives. The primitives of this instance will be + * replaced with a list that contains all previous elements, and + * additionally the new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addPrimitives(MeshPrimitive element) { if (element == null) { @@ -97,7 +98,7 @@ public void addPrimitives(MeshPrimitive element) { } List oldList = this.primitives; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -105,13 +106,13 @@ public void addPrimitives(MeshPrimitive element) { } /** - * Remove the given primitives. The primitives of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one. - * + * Remove the given primitives. The primitives of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removePrimitives(MeshPrimitive element) { if (element == null) { @@ -119,7 +120,7 @@ public void removePrimitives(MeshPrimitive element) { } List oldList = this.primitives; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -127,52 +128,52 @@ public void removePrimitives(MeshPrimitive element) { } /** - * Array of weights to be applied to the morph targets. The number of - * array elements **MUST** match the number of morph targets. - * (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The weights - * - */ - public List getWeights() { - return this.weights; - } - - /** - * Array of weights to be applied to the morph targets. The number of - * array elements **MUST** match the number of morph targets. - * (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * Array of weights to be applied to the morph targets. The number of + * array elements **MUST** match the number of morph targets. + * (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * * @param weights The weights to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWeights(List weights) { if (weights == null) { this.weights = weights; - return; + return ; } - if (weights.size() < 1) { + if (weights.size()< 1) { throw new IllegalArgumentException("Number of weights elements is < 1"); } this.weights = weights; } /** - * Add the given weights. The weights of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Array of weights to be applied to the morph targets. The number of + * array elements **MUST** match the number of morph targets. + * (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The weights + * + */ + public List getWeights() { + return this.weights; + } + + /** + * Add the given weights. The weights of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addWeights(Float element) { if (element == null) { @@ -180,7 +181,7 @@ public void addWeights(Float element) { } List oldList = this.weights; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -188,15 +189,15 @@ public void addWeights(Float element) { } /** - * Remove the given weights. The weights of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given weights. The weights of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeWeights(Float element) { if (element == null) { @@ -204,7 +205,7 @@ public void removeWeights(Float element) { } List oldList = this.weights; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/MeshPrimitive.java b/src/main/java/de/javagl/jgltf/impl/v2/MeshPrimitive.java index 860519e..4fd57a3 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/MeshPrimitive.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/MeshPrimitive.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -15,89 +15,90 @@ /** - * Geometry to be rendered with the given material. - *

    - * Auto-generated for mesh.primitive.schema.json - * + * Geometry to be rendered with the given material. + * + * Auto-generated for mesh.primitive.schema.json + * */ public class MeshPrimitive - extends GlTFProperty { + extends GlTFProperty +{ /** - * A plain JSON object, where each key corresponds to a mesh attribute - * semantic and each value is the index of the accessor containing - * attribute's data. (required) - * + * A plain JSON object, where each key corresponds to a mesh attribute + * semantic and each value is the index of the accessor containing + * attribute's data. (required) + * */ private Map attributes; /** - * The index of the accessor that contains the vertex indices. (optional) - * + * The index of the accessor that contains the vertex indices. (optional) + * */ private Integer indices; /** - * The index of the material to apply to this primitive when rendering. - * (optional) - * + * The index of the material to apply to this primitive when rendering. + * (optional) + * */ private Integer material; /** - * The topology type of primitives to render. (optional)
    - * Default: 4
    - * Valid values: [0, 1, 2, 3, 4, 5, 6] - * + * The topology type of primitives to render. (optional)
    + * Default: 4
    + * Valid values: [0, 1, 2, 3, 4, 5, 6] + * */ private Integer mode; /** - * An array of morph targets. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A plain JSON object specifying attributes displacements in - * a morph target, where each key corresponds to one of the three - * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and - * each value is the index of the accessor containing the attribute - * displacements' data. (optional) - * + * An array of morph targets. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A plain JSON object specifying attributes displacements in + * a morph target, where each key corresponds to one of the three + * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and + * each value is the index of the accessor containing the attribute + * displacements' data. (optional) + * */ private List> targets; /** - * A plain JSON object, where each key corresponds to a mesh attribute - * semantic and each value is the index of the accessor containing - * attribute's data. (required) - * - * @return The attributes - * - */ - public Map getAttributes() { - return this.attributes; - } - - /** - * A plain JSON object, where each key corresponds to a mesh attribute - * semantic and each value is the index of the accessor containing - * attribute's data. (required) - * + * A plain JSON object, where each key corresponds to a mesh attribute + * semantic and each value is the index of the accessor containing + * attribute's data. (required) + * * @param attributes The attributes to set * @throws NullPointerException If the given value is null - * + * */ public void setAttributes(Map attributes) { if (attributes == null) { - throw new NullPointerException((("Invalid value for attributes: " + attributes) + ", may not be null")); + throw new NullPointerException((("Invalid value for attributes: "+ attributes)+", may not be null")); } this.attributes = attributes; } /** - * Add the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, and - * additionally the new mapping. - * - * @param key The key + * A plain JSON object, where each key corresponds to a mesh attribute + * semantic and each value is the index of the accessor containing + * attribute's data. (required) + * + * @return The attributes + * + */ + public Map getAttributes() { + return this.attributes; + } + + /** + * Add the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, and + * additionally the new mapping. + * + * @param key The key * @param value The value * @throws NullPointerException If the given key or value is null - * + * */ public void addAttributes(String key, Integer value) { if (key == null) { @@ -108,7 +109,7 @@ public void addAttributes(String key, Integer value) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.put(key, value); @@ -116,13 +117,13 @@ public void addAttributes(String key, Integer value) { } /** - * Remove the given attributes. The attributes of this instance will be - * replaced with a map that contains all previous mappings, except for - * the one with the given key. - * + * Remove the given attributes. The attributes of this instance will be + * replaced with a map that contains all previous mappings, except for + * the one with the given key. + * * @param key The key * @throws NullPointerException If the given key is null - * + * */ public void removeAttributes(String key) { if (key == null) { @@ -130,7 +131,7 @@ public void removeAttributes(String key) { } Map oldMap = this.attributes; Map newMap = new LinkedHashMap(); - if (oldMap != null) { + if (oldMap!= null) { newMap.putAll(oldMap); } newMap.remove(key); @@ -138,150 +139,150 @@ public void removeAttributes(String key) { } /** - * The index of the accessor that contains the vertex indices. (optional) - * - * @return The indices - * - */ - public Integer getIndices() { - return this.indices; - } - - /** - * The index of the accessor that contains the vertex indices. (optional) - * + * The index of the accessor that contains the vertex indices. (optional) + * * @param indices The indices to set - * + * */ public void setIndices(Integer indices) { if (indices == null) { this.indices = indices; - return; + return ; } this.indices = indices; } /** - * The index of the material to apply to this primitive when rendering. - * (optional) - * - * @return The material - * + * The index of the accessor that contains the vertex indices. (optional) + * + * @return The indices + * */ - public Integer getMaterial() { - return this.material; + public Integer getIndices() { + return this.indices; } /** - * The index of the material to apply to this primitive when rendering. - * (optional) - * + * The index of the material to apply to this primitive when rendering. + * (optional) + * * @param material The material to set - * + * */ public void setMaterial(Integer material) { if (material == null) { this.material = material; - return; + return ; } this.material = material; } /** - * The topology type of primitives to render. (optional)
    - * Default: 4
    - * Valid values: [0, 1, 2, 3, 4, 5, 6] - * - * @return The mode - * + * The index of the material to apply to this primitive when rendering. + * (optional) + * + * @return The material + * */ - public Integer getMode() { - return this.mode; + public Integer getMaterial() { + return this.material; } /** - * The topology type of primitives to render. (optional)
    - * Default: 4
    - * Valid values: [0, 1, 2, 3, 4, 5, 6] - * + * The topology type of primitives to render. (optional)
    + * Default: 4
    + * Valid values: [0, 1, 2, 3, 4, 5, 6] + * * @param mode The mode to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMode(Integer mode) { if (mode == null) { this.mode = mode; - return; + return ; } - if (((((((mode != 0) && (mode != 1)) && (mode != 2)) && (mode != 3)) && (mode != 4)) && (mode != 5)) && (mode != 6)) { - throw new IllegalArgumentException((("Invalid value for mode: " + mode) + ", valid: [0, 1, 2, 3, 4, 5, 6]")); + if (((((((mode!= 0)&&(mode!= 1))&&(mode!= 2))&&(mode!= 3))&&(mode!= 4))&&(mode!= 5))&&(mode!= 6)) { + throw new IllegalArgumentException((("Invalid value for mode: "+ mode)+", valid: [0, 1, 2, 3, 4, 5, 6]")); } this.mode = mode; } /** - * Returns the default value of the mode
    - * - * @return The default mode - * @see #getMode - * + * The topology type of primitives to render. (optional)
    + * Default: 4
    + * Valid values: [0, 1, 2, 3, 4, 5, 6] + * + * @return The mode + * */ - public Integer defaultMode() { - return 4; + public Integer getMode() { + return this.mode; } /** - * An array of morph targets. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A plain JSON object specifying attributes displacements in - * a morph target, where each key corresponds to one of the three - * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and - * each value is the index of the accessor containing the attribute - * displacements' data. (optional) - * - * @return The targets - * + * Returns the default value of the mode
    + * @see #getMode + * + * @return The default mode + * */ - public List> getTargets() { - return this.targets; + public Integer defaultMode() { + return 4; } /** - * An array of morph targets. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   A plain JSON object specifying attributes displacements in - * a morph target, where each key corresponds to one of the three - * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and - * each value is the index of the accessor containing the attribute - * displacements' data. (optional) - * + * An array of morph targets. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A plain JSON object specifying attributes displacements in + * a morph target, where each key corresponds to one of the three + * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and + * each value is the index of the accessor containing the attribute + * displacements' data. (optional) + * * @param targets The targets to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTargets(List> targets) { if (targets == null) { this.targets = targets; - return; + return ; } - if (targets.size() < 1) { + if (targets.size()< 1) { throw new IllegalArgumentException("Number of targets elements is < 1"); } this.targets = targets; } /** - * Add the given targets. The targets of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * An array of morph targets. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   A plain JSON object specifying attributes displacements in + * a morph target, where each key corresponds to one of the three + * supported attribute semantic (`POSITION`, `NORMAL`, or `TANGENT`) and + * each value is the index of the accessor containing the attribute + * displacements' data. (optional) + * + * @return The targets + * + */ + public List> getTargets() { + return this.targets; + } + + /** + * Add the given targets. The targets of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addTargets(Map element) { if (element == null) { @@ -289,7 +290,7 @@ public void addTargets(Map element) { } List> oldList = this.targets; List> newList = new ArrayList>(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -297,15 +298,15 @@ public void addTargets(Map element) { } /** - * Remove the given targets. The targets of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given targets. The targets of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeTargets(Map element) { if (element == null) { @@ -313,7 +314,7 @@ public void removeTargets(Map element) { } List> oldList = this.targets; List> newList = new ArrayList>(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Node.java b/src/main/java/de/javagl/jgltf/impl/v2/Node.java index 0f40dbe..ab2a9fe 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Node.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Node.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,160 +13,147 @@ /** - * A node in the node hierarchy. When the node contains `skin`, all - * `mesh.primitives` **MUST** contain `JOINTS_0` and `WEIGHTS_0` - * attributes. A node **MAY** have either a `matrix` or any combination - * of `translation`/`rotation`/`scale` (TRS) properties. TRS properties - * are converted to matrices and postmultiplied in the `T * R * S` order - * to compose the transformation matrix; first the scale is applied to - * the vertices, then the rotation, and then the translation. If none are - * provided, the transform is the identity. When a node is targeted for - * animation (referenced by an animation.channel.target), `matrix` **MUST - * NOT** be present. - *

    - * Auto-generated for node.schema.json - * + * A node in the node hierarchy. When the node contains `skin`, all + * `mesh.primitives` **MUST** contain `JOINTS_0` and `WEIGHTS_0` + * attributes. A node **MAY** have either a `matrix` or any combination + * of `translation`/`rotation`/`scale` (TRS) properties. TRS properties + * are converted to matrices and postmultiplied in the `T * R * S` order + * to compose the transformation matrix; first the scale is applied to + * the vertices, then the rotation, and then the translation. If none are + * provided, the transform is the identity. When a node is targeted for + * animation (referenced by an animation.channel.target), `matrix` **MUST + * NOT** be present. + * + * Auto-generated for node.schema.json + * */ public class Node - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The index of the camera referenced by this node. (optional) - * + * The index of the camera referenced by this node. (optional) + * */ private Integer camera; /** - * The indices of this node's children. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0 (inclusive) - * + * The indices of this node's children. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0 (inclusive) + * */ private List children; /** - * The index of the skin referenced by this node. (optional) - * + * The index of the skin referenced by this node. (optional) + * */ private Integer skin; /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
    - * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    - * Number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
    + * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    + * Number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] matrix; /** - * The index of the mesh in this node. (optional) - * + * The index of the mesh in this node. (optional) + * */ private Integer mesh; /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
    - * Default: [0.0,0.0,0.0,1.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: -1.0 (inclusive)
    - *   Maximum: 1.0 (inclusive) - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
    + * Default: [0.0,0.0,0.0,1.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: -1.0 (inclusive)
    + *   Maximum: 1.0 (inclusive) + * */ private float[] rotation; /** - * The node's non-uniform scale, given as the scaling factors along the - * x, y, and z axes. (optional)
    - * Default: [1.0,1.0,1.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's non-uniform scale, given as the scaling factors along the + * x, y, and z axes. (optional)
    + * Default: [1.0,1.0,1.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] scale; /** - * The node's translation along the x, y, and z axes. (optional)
    - * Default: [0.0,0.0,0.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's translation along the x, y, and z axes. (optional)
    + * Default: [0.0,0.0,0.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * */ private float[] translation; /** - * The weights of the instantiated morph target. The number of array - * elements **MUST** match the number of morph targets of the referenced - * mesh. When defined, `mesh` **MUST** also be defined. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * The weights of the instantiated morph target. The number of array + * elements **MUST** match the number of morph targets of the referenced + * mesh. When defined, `mesh` **MUST** also be defined. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * */ private List weights; /** - * The index of the camera referenced by this node. (optional) - * - * @return The camera - * - */ - public Integer getCamera() { - return this.camera; - } - - /** - * The index of the camera referenced by this node. (optional) - * + * The index of the camera referenced by this node. (optional) + * * @param camera The camera to set - * + * */ public void setCamera(Integer camera) { if (camera == null) { this.camera = camera; - return; + return ; } this.camera = camera; } /** - * The indices of this node's children. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0 (inclusive) - * - * @return The children - * + * The index of the camera referenced by this node. (optional) + * + * @return The camera + * */ - public List getChildren() { - return this.children; + public Integer getCamera() { + return this.camera; } /** - * The indices of this node's children. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0 (inclusive) - * + * The indices of this node's children. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0 (inclusive) + * * @param children The children to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setChildren(List children) { if (children == null) { this.children = children; - return; + return ; } - if (children.size() < 1) { + if (children.size()< 1) { throw new IllegalArgumentException("Number of children elements is < 1"); } - for (Integer childrenElement : children) { - if (childrenElement < 0) { + for (Integer childrenElement: children) { + if (childrenElement< 0) { throw new IllegalArgumentException("childrenElement < 0"); } } @@ -174,13 +161,27 @@ public void setChildren(List children) { } /** - * Add the given children. The children of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * The indices of this node's children. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0 (inclusive) + * + * @return The children + * + */ + public List getChildren() { + return this.children; + } + + /** + * Add the given children. The children of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addChildren(Integer element) { if (element == null) { @@ -188,7 +189,7 @@ public void addChildren(Integer element) { } List oldList = this.children; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -196,15 +197,15 @@ public void addChildren(Integer element) { } /** - * Remove the given children. The children of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given children. The children of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeChildren(Integer element) { if (element == null) { @@ -212,7 +213,7 @@ public void removeChildren(Integer element) { } List oldList = this.children; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); @@ -224,65 +225,49 @@ public void removeChildren(Integer element) { } /** - * The index of the skin referenced by this node. (optional) - * - * @return The skin - * - */ - public Integer getSkin() { - return this.skin; - } - - /** - * The index of the skin referenced by this node. (optional) - * + * The index of the skin referenced by this node. (optional) + * * @param skin The skin to set - * + * */ public void setSkin(Integer skin) { if (skin == null) { this.skin = skin; - return; + return ; } this.skin = skin; } /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
    - * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    - * Number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The matrix - * + * The index of the skin referenced by this node. (optional) + * + * @return The skin + * */ - public float[] getMatrix() { - return this.matrix; + public Integer getSkin() { + return this.skin; } /** - * A floating-point 4x4 transformation matrix stored in column-major - * order. (optional)
    - * Default: - * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    - * Number of items: 16
    - * Array elements:
    - *   The elements of this array (optional) - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
    + * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    + * Number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * * @param matrix The matrix to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMatrix(float[] matrix) { if (matrix == null) { this.matrix = matrix; - return; + return ; } - if (matrix.length < 16) { + if (matrix.length< 16) { throw new IllegalArgumentException("Number of matrix elements is < 16"); } if (matrix.length > 16) { @@ -292,88 +277,87 @@ public void setMatrix(float[] matrix) { } /** - * Returns the default value of the matrix
    - * - * @return The default matrix - * @see #getMatrix - * + * A floating-point 4x4 transformation matrix stored in column-major + * order. (optional)
    + * Default: + * [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
    + * Number of items: 16
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The matrix + * */ - public float[] defaultMatrix() { - return new float[]{1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F}; + public float[] getMatrix() { + return this.matrix; } /** - * The index of the mesh in this node. (optional) - * - * @return The mesh - * + * Returns the default value of the matrix
    + * @see #getMatrix + * + * @return The default matrix + * */ - public Integer getMesh() { - return this.mesh; + public float[] defaultMatrix() { + return new float[] { 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F }; } /** - * The index of the mesh in this node. (optional) - * + * The index of the mesh in this node. (optional) + * * @param mesh The mesh to set - * + * */ public void setMesh(Integer mesh) { if (mesh == null) { this.mesh = mesh; - return; + return ; } this.mesh = mesh; } /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
    - * Default: [0.0,0.0,0.0,1.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: -1.0 (inclusive)
    - *   Maximum: 1.0 (inclusive) - * - * @return The rotation - * + * The index of the mesh in this node. (optional) + * + * @return The mesh + * */ - public float[] getRotation() { - return this.rotation; + public Integer getMesh() { + return this.mesh; } /** - * The node's unit quaternion rotation in the order (x, y, z, w), where w - * is the scalar. (optional)
    - * Default: [0.0,0.0,0.0,1.0]
    - * Number of items: 4
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: -1.0 (inclusive)
    - *   Maximum: 1.0 (inclusive) - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
    + * Default: [0.0,0.0,0.0,1.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: -1.0 (inclusive)
    + *   Maximum: 1.0 (inclusive) + * * @param rotation The rotation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setRotation(float[] rotation) { if (rotation == null) { this.rotation = rotation; - return; + return ; } - if (rotation.length < 4) { + if (rotation.length< 4) { throw new IllegalArgumentException("Number of rotation elements is < 4"); } if (rotation.length > 4) { throw new IllegalArgumentException("Number of rotation elements is > 4"); } - for (float rotationElement : rotation) { + for (float rotationElement: rotation) { if (rotationElement > 1.0D) { throw new IllegalArgumentException("rotationElement > 1.0"); } - if (rotationElement < -1.0D) { + if (rotationElement<-1.0D) { throw new IllegalArgumentException("rotationElement < -1.0"); } } @@ -381,50 +365,52 @@ public void setRotation(float[] rotation) { } /** - * Returns the default value of the rotation
    - * - * @return The default rotation - * @see #getRotation - * + * The node's unit quaternion rotation in the order (x, y, z, w), where w + * is the scalar. (optional)
    + * Default: [0.0,0.0,0.0,1.0]
    + * Number of items: 4
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: -1.0 (inclusive)
    + *   Maximum: 1.0 (inclusive) + * + * @return The rotation + * */ - public float[] defaultRotation() { - return new float[]{0.0F, 0.0F, 0.0F, 1.0F}; + public float[] getRotation() { + return this.rotation; } /** - * The node's non-uniform scale, given as the scaling factors along the - * x, y, and z axes. (optional)
    - * Default: [1.0,1.0,1.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The scale - * + * Returns the default value of the rotation
    + * @see #getRotation + * + * @return The default rotation + * */ - public float[] getScale() { - return this.scale; + public float[] defaultRotation() { + return new float[] { 0.0F, 0.0F, 0.0F, 1.0F }; } /** - * The node's non-uniform scale, given as the scaling factors along the - * x, y, and z axes. (optional)
    - * Default: [1.0,1.0,1.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's non-uniform scale, given as the scaling factors along the + * x, y, and z axes. (optional)
    + * Default: [1.0,1.0,1.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * * @param scale The scale to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setScale(float[] scale) { if (scale == null) { this.scale = scale; - return; + return ; } - if (scale.length < 3) { + if (scale.length< 3) { throw new IllegalArgumentException("Number of scale elements is < 3"); } if (scale.length > 3) { @@ -434,48 +420,49 @@ public void setScale(float[] scale) { } /** - * Returns the default value of the scale
    - * - * @return The default scale - * @see #getScale - * + * The node's non-uniform scale, given as the scaling factors along the + * x, y, and z axes. (optional)
    + * Default: [1.0,1.0,1.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The scale + * */ - public float[] defaultScale() { - return new float[]{1.0F, 1.0F, 1.0F}; + public float[] getScale() { + return this.scale; } /** - * The node's translation along the x, y, and z axes. (optional)
    - * Default: [0.0,0.0,0.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The translation - * + * Returns the default value of the scale
    + * @see #getScale + * + * @return The default scale + * */ - public float[] getTranslation() { - return this.translation; + public float[] defaultScale() { + return new float[] { 1.0F, 1.0F, 1.0F }; } /** - * The node's translation along the x, y, and z axes. (optional)
    - * Default: [0.0,0.0,0.0]
    - * Number of items: 3
    - * Array elements:
    - *   The elements of this array (optional) - * + * The node's translation along the x, y, and z axes. (optional)
    + * Default: [0.0,0.0,0.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * * @param translation The translation to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTranslation(float[] translation) { if (translation == null) { this.translation = translation; - return; + return ; } - if (translation.length < 3) { + if (translation.length< 3) { throw new IllegalArgumentException("Number of translation elements is < 3"); } if (translation.length > 3) { @@ -485,63 +472,77 @@ public void setTranslation(float[] translation) { } /** - * Returns the default value of the translation
    - * - * @return The default translation - * @see #getTranslation - * + * The node's translation along the x, y, and z axes. (optional)
    + * Default: [0.0,0.0,0.0]
    + * Number of items: 3
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The translation + * */ - public float[] defaultTranslation() { - return new float[]{0.0F, 0.0F, 0.0F}; + public float[] getTranslation() { + return this.translation; } /** - * The weights of the instantiated morph target. The number of array - * elements **MUST** match the number of morph targets of the referenced - * mesh. When defined, `mesh` **MUST** also be defined. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * - * @return The weights - * + * Returns the default value of the translation
    + * @see #getTranslation + * + * @return The default translation + * */ - public List getWeights() { - return this.weights; + public float[] defaultTranslation() { + return new float[] { 0.0F, 0.0F, 0.0F }; } /** - * The weights of the instantiated morph target. The number of array - * elements **MUST** match the number of morph targets of the referenced - * mesh. When defined, `mesh` **MUST** also be defined. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional) - * + * The weights of the instantiated morph target. The number of array + * elements **MUST** match the number of morph targets of the referenced + * mesh. When defined, `mesh` **MUST** also be defined. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * * @param weights The weights to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWeights(List weights) { if (weights == null) { this.weights = weights; - return; + return ; } - if (weights.size() < 1) { + if (weights.size()< 1) { throw new IllegalArgumentException("Number of weights elements is < 1"); } this.weights = weights; } /** - * Add the given weights. The weights of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * The weights of the instantiated morph target. The number of array + * elements **MUST** match the number of morph targets of the referenced + * mesh. When defined, `mesh` **MUST** also be defined. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional) + * + * @return The weights + * + */ + public List getWeights() { + return this.weights; + } + + /** + * Add the given weights. The weights of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addWeights(Float element) { if (element == null) { @@ -549,7 +550,7 @@ public void addWeights(Float element) { } List oldList = this.weights; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -557,15 +558,15 @@ public void addWeights(Float element) { } /** - * Remove the given weights. The weights of this instance will be - * replaced with a list that contains all previous elements, except for - * the removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given weights. The weights of this instance will be + * replaced with a list that contains all previous elements, except for + * the removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeWeights(Float element) { if (element == null) { @@ -573,7 +574,7 @@ public void removeWeights(Float element) { } List oldList = this.weights; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Sampler.java b/src/main/java/de/javagl/jgltf/impl/v2/Sampler.java index fd9226e..9a0f350 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Sampler.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Sampler.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,190 +9,192 @@ package de.javagl.jgltf.impl.v2; + /** - * Texture sampler properties for filtering and wrapping modes. - *

    - * Auto-generated for sampler.schema.json - * + * Texture sampler properties for filtering and wrapping modes. + * + * Auto-generated for sampler.schema.json + * */ public class Sampler - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * Magnification filter. (optional)
    - * Valid values: [9728, 9729] - * + * Magnification filter. (optional)
    + * Valid values: [9728, 9729] + * */ private Integer magFilter; /** - * Minification filter. (optional)
    - * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * + * Minification filter. (optional)
    + * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * */ private Integer minFilter; /** - * S (U) wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * + * S (U) wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * */ private Integer wrapS; /** - * T (V) wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * + * T (V) wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * */ private Integer wrapT; /** - * Magnification filter. (optional)
    - * Valid values: [9728, 9729] - * - * @return The magFilter - * - */ - public Integer getMagFilter() { - return this.magFilter; - } - - /** - * Magnification filter. (optional)
    - * Valid values: [9728, 9729] - * + * Magnification filter. (optional)
    + * Valid values: [9728, 9729] + * * @param magFilter The magFilter to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMagFilter(Integer magFilter) { if (magFilter == null) { this.magFilter = magFilter; - return; + return ; } - if ((magFilter != 9728) && (magFilter != 9729)) { - throw new IllegalArgumentException((("Invalid value for magFilter: " + magFilter) + ", valid: [9728, 9729]")); + if ((magFilter!= 9728)&&(magFilter!= 9729)) { + throw new IllegalArgumentException((("Invalid value for magFilter: "+ magFilter)+", valid: [9728, 9729]")); } this.magFilter = magFilter; } /** - * Minification filter. (optional)
    - * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * - * @return The minFilter - * + * Magnification filter. (optional)
    + * Valid values: [9728, 9729] + * + * @return The magFilter + * */ - public Integer getMinFilter() { - return this.minFilter; + public Integer getMagFilter() { + return this.magFilter; } /** - * Minification filter. (optional)
    - * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] - * + * Minification filter. (optional)
    + * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * * @param minFilter The minFilter to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setMinFilter(Integer minFilter) { if (minFilter == null) { this.minFilter = minFilter; - return; + return ; } - if ((((((minFilter != 9728) && (minFilter != 9729)) && (minFilter != 9984)) && (minFilter != 9985)) && (minFilter != 9986)) && (minFilter != 9987)) { - throw new IllegalArgumentException((("Invalid value for minFilter: " + minFilter) + ", valid: [9728, 9729, 9984, 9985, 9986, 9987]")); + if ((((((minFilter!= 9728)&&(minFilter!= 9729))&&(minFilter!= 9984))&&(minFilter!= 9985))&&(minFilter!= 9986))&&(minFilter!= 9987)) { + throw new IllegalArgumentException((("Invalid value for minFilter: "+ minFilter)+", valid: [9728, 9729, 9984, 9985, 9986, 9987]")); } this.minFilter = minFilter; } /** - * S (U) wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * - * @return The wrapS - * + * Minification filter. (optional)
    + * Valid values: [9728, 9729, 9984, 9985, 9986, 9987] + * + * @return The minFilter + * */ - public Integer getWrapS() { - return this.wrapS; + public Integer getMinFilter() { + return this.minFilter; } /** - * S (U) wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * + * S (U) wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * * @param wrapS The wrapS to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWrapS(Integer wrapS) { if (wrapS == null) { this.wrapS = wrapS; - return; + return ; } - if (((wrapS != 33071) && (wrapS != 33648)) && (wrapS != 10497)) { - throw new IllegalArgumentException((("Invalid value for wrapS: " + wrapS) + ", valid: [33071, 33648, 10497]")); + if (((wrapS!= 33071)&&(wrapS!= 33648))&&(wrapS!= 10497)) { + throw new IllegalArgumentException((("Invalid value for wrapS: "+ wrapS)+", valid: [33071, 33648, 10497]")); } this.wrapS = wrapS; } /** - * Returns the default value of the wrapS
    - * - * @return The default wrapS - * @see #getWrapS - * + * S (U) wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * + * @return The wrapS + * */ - public Integer defaultWrapS() { - return 10497; + public Integer getWrapS() { + return this.wrapS; } /** - * T (V) wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * - * @return The wrapT - * + * Returns the default value of the wrapS
    + * @see #getWrapS + * + * @return The default wrapS + * */ - public Integer getWrapT() { - return this.wrapT; + public Integer defaultWrapS() { + return 10497; } /** - * T (V) wrapping mode. (optional)
    - * Default: 10497
    - * Valid values: [33071, 33648, 10497] - * + * T (V) wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * * @param wrapT The wrapT to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setWrapT(Integer wrapT) { if (wrapT == null) { this.wrapT = wrapT; - return; + return ; } - if (((wrapT != 33071) && (wrapT != 33648)) && (wrapT != 10497)) { - throw new IllegalArgumentException((("Invalid value for wrapT: " + wrapT) + ", valid: [33071, 33648, 10497]")); + if (((wrapT!= 33071)&&(wrapT!= 33648))&&(wrapT!= 10497)) { + throw new IllegalArgumentException((("Invalid value for wrapT: "+ wrapT)+", valid: [33071, 33648, 10497]")); } this.wrapT = wrapT; } /** - * Returns the default value of the wrapT
    - * + * T (V) wrapping mode. (optional)
    + * Default: 10497
    + * Valid values: [33071, 33648, 10497] + * + * @return The wrapT + * + */ + public Integer getWrapT() { + return this.wrapT; + } + + /** + * Returns the default value of the wrapT
    + * @see #getWrapT + * * @return The default wrapT - * @see #getWrapT - * + * */ public Integer defaultWrapT() { - return 10497; + return 10497; } } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Scene.java b/src/main/java/de/javagl/jgltf/impl/v2/Scene.java index 769e28d..c064edf 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Scene.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Scene.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,60 +13,47 @@ /** - * The root nodes of a scene. - *

    - * Auto-generated for scene.schema.json - * + * The root nodes of a scene. + * + * Auto-generated for scene.schema.json + * */ public class Scene - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The indices of each root node. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0 (inclusive) - * + * The indices of each root node. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0 (inclusive) + * */ private List nodes; /** - * The indices of each root node. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0 (inclusive) - * - * @return The nodes - * - */ - public List getNodes() { - return this.nodes; - } - - /** - * The indices of each root node. (optional)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0 (inclusive) - * + * The indices of each root node. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0 (inclusive) + * * @param nodes The nodes to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setNodes(List nodes) { if (nodes == null) { this.nodes = nodes; - return; + return ; } - if (nodes.size() < 1) { + if (nodes.size()< 1) { throw new IllegalArgumentException("Number of nodes elements is < 1"); } - for (Integer nodesElement : nodes) { - if (nodesElement < 0) { + for (Integer nodesElement: nodes) { + if (nodesElement< 0) { throw new IllegalArgumentException("nodesElement < 0"); } } @@ -74,13 +61,27 @@ public void setNodes(List nodes) { } /** - * Add the given nodes. The nodes of this instance will be replaced with - * a list that contains all previous elements, and additionally the new - * element. - * + * The indices of each root node. (optional)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0 (inclusive) + * + * @return The nodes + * + */ + public List getNodes() { + return this.nodes; + } + + /** + * Add the given nodes. The nodes of this instance will be replaced with + * a list that contains all previous elements, and additionally the new + * element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addNodes(Integer element) { if (element == null) { @@ -88,7 +89,7 @@ public void addNodes(Integer element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -96,15 +97,15 @@ public void addNodes(Integer element) { } /** - * Remove the given nodes. The nodes of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one.
    - * If this new list would be empty, then it will be set to - * null. - * + * Remove the given nodes. The nodes of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one.
    + * If this new list would be empty, then it will be set to + * null. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeNodes(Integer element) { if (element == null) { @@ -112,7 +113,7 @@ public void removeNodes(Integer element) { } List oldList = this.nodes; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Skin.java b/src/main/java/de/javagl/jgltf/impl/v2/Skin.java index fa72721..8b1ccdd 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Skin.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Skin.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -13,121 +13,108 @@ /** - * Joints and matrices defining a skin. - *

    - * Auto-generated for skin.schema.json - * + * Joints and matrices defining a skin. + * + * Auto-generated for skin.schema.json + * */ public class Skin - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The index of the accessor containing the floating-point 4x4 - * inverse-bind matrices. (optional) - * + * The index of the accessor containing the floating-point 4x4 + * inverse-bind matrices. (optional) + * */ private Integer inverseBindMatrices; /** - * The index of the node used as a skeleton root. (optional) - * + * The index of the node used as a skeleton root. (optional) + * */ private Integer skeleton; /** - * Indices of skeleton nodes, used as joints in this skin. (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0 (inclusive) - * + * Indices of skeleton nodes, used as joints in this skin. (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0 (inclusive) + * */ private List joints; /** - * The index of the accessor containing the floating-point 4x4 - * inverse-bind matrices. (optional) - * - * @return The inverseBindMatrices - * - */ - public Integer getInverseBindMatrices() { - return this.inverseBindMatrices; - } - - /** - * The index of the accessor containing the floating-point 4x4 - * inverse-bind matrices. (optional) - * + * The index of the accessor containing the floating-point 4x4 + * inverse-bind matrices. (optional) + * * @param inverseBindMatrices The inverseBindMatrices to set - * + * */ public void setInverseBindMatrices(Integer inverseBindMatrices) { if (inverseBindMatrices == null) { this.inverseBindMatrices = inverseBindMatrices; - return; + return ; } this.inverseBindMatrices = inverseBindMatrices; } /** - * The index of the node used as a skeleton root. (optional) - * - * @return The skeleton - * + * The index of the accessor containing the floating-point 4x4 + * inverse-bind matrices. (optional) + * + * @return The inverseBindMatrices + * */ - public Integer getSkeleton() { - return this.skeleton; + public Integer getInverseBindMatrices() { + return this.inverseBindMatrices; } /** - * The index of the node used as a skeleton root. (optional) - * + * The index of the node used as a skeleton root. (optional) + * * @param skeleton The skeleton to set - * + * */ public void setSkeleton(Integer skeleton) { if (skeleton == null) { this.skeleton = skeleton; - return; + return ; } this.skeleton = skeleton; } /** - * Indices of skeleton nodes, used as joints in this skin. (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0 (inclusive) - * - * @return The joints - * + * The index of the node used as a skeleton root. (optional) + * + * @return The skeleton + * */ - public List getJoints() { - return this.joints; + public Integer getSkeleton() { + return this.skeleton; } /** - * Indices of skeleton nodes, used as joints in this skin. (required)
    - * Minimum number of items: 1
    - * Array elements:
    - *   The elements of this array (optional)
    - *   Minimum: 0 (inclusive) - * + * Indices of skeleton nodes, used as joints in this skin. (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0 (inclusive) + * * @param joints The joints to set - * @throws NullPointerException If the given value is null + * @throws NullPointerException If the given value is null * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setJoints(List joints) { if (joints == null) { - throw new NullPointerException((("Invalid value for joints: " + joints) + ", may not be null")); + throw new NullPointerException((("Invalid value for joints: "+ joints)+", may not be null")); } - if (joints.size() < 1) { + if (joints.size()< 1) { throw new IllegalArgumentException("Number of joints elements is < 1"); } - for (Integer jointsElement : joints) { - if (jointsElement < 0) { + for (Integer jointsElement: joints) { + if (jointsElement< 0) { throw new IllegalArgumentException("jointsElement < 0"); } } @@ -135,13 +122,27 @@ public void setJoints(List joints) { } /** - * Add the given joints. The joints of this instance will be replaced - * with a list that contains all previous elements, and additionally the - * new element. - * + * Indices of skeleton nodes, used as joints in this skin. (required)
    + * Minimum number of items: 1
    + * Array elements:
    + *   The elements of this array (optional)
    + *   Minimum: 0 (inclusive) + * + * @return The joints + * + */ + public List getJoints() { + return this.joints; + } + + /** + * Add the given joints. The joints of this instance will be replaced + * with a list that contains all previous elements, and additionally the + * new element. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void addJoints(Integer element) { if (element == null) { @@ -149,7 +150,7 @@ public void addJoints(Integer element) { } List oldList = this.joints; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.add(element); @@ -157,13 +158,13 @@ public void addJoints(Integer element) { } /** - * Remove the given joints. The joints of this instance will be replaced - * with a list that contains all previous elements, except for the - * removed one. - * + * Remove the given joints. The joints of this instance will be replaced + * with a list that contains all previous elements, except for the + * removed one. + * * @param element The element * @throws NullPointerException If the given element is null - * + * */ public void removeJoints(Integer element) { if (element == null) { @@ -171,7 +172,7 @@ public void removeJoints(Integer element) { } List oldList = this.joints; List newList = new ArrayList(); - if (oldList != null) { + if (oldList!= null) { newList.addAll(oldList); } newList.remove(element); diff --git a/src/main/java/de/javagl/jgltf/impl/v2/Texture.java b/src/main/java/de/javagl/jgltf/impl/v2/Texture.java index f7cd642..bf1f5a3 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/Texture.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/Texture.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,84 +9,86 @@ package de.javagl.jgltf.impl.v2; + /** - * A texture and its sampler. - *

    - * Auto-generated for texture.schema.json - * + * A texture and its sampler. + * + * Auto-generated for texture.schema.json + * */ public class Texture - extends GlTFChildOfRootProperty { + extends GlTFChildOfRootProperty +{ /** - * The index of the sampler used by this texture. When undefined, a - * sampler with repeat wrapping and auto filtering **SHOULD** be used. - * (optional) - * + * The index of the sampler used by this texture. When undefined, a + * sampler with repeat wrapping and auto filtering **SHOULD** be used. + * (optional) + * */ private Integer sampler; /** - * The index of the image used by this texture. When undefined, an - * extension or other mechanism **SHOULD** supply an alternate texture - * source, otherwise behavior is undefined. (optional) - * + * The index of the image used by this texture. When undefined, an + * extension or other mechanism **SHOULD** supply an alternate texture + * source, otherwise behavior is undefined. (optional) + * */ private Integer source; /** - * The index of the sampler used by this texture. When undefined, a - * sampler with repeat wrapping and auto filtering **SHOULD** be used. - * (optional) - * - * @return The sampler - * - */ - public Integer getSampler() { - return this.sampler; - } - - /** - * The index of the sampler used by this texture. When undefined, a - * sampler with repeat wrapping and auto filtering **SHOULD** be used. - * (optional) - * + * The index of the sampler used by this texture. When undefined, a + * sampler with repeat wrapping and auto filtering **SHOULD** be used. + * (optional) + * * @param sampler The sampler to set - * + * */ public void setSampler(Integer sampler) { if (sampler == null) { this.sampler = sampler; - return; + return ; } this.sampler = sampler; } /** - * The index of the image used by this texture. When undefined, an - * extension or other mechanism **SHOULD** supply an alternate texture - * source, otherwise behavior is undefined. (optional) - * - * @return The source - * + * The index of the sampler used by this texture. When undefined, a + * sampler with repeat wrapping and auto filtering **SHOULD** be used. + * (optional) + * + * @return The sampler + * */ - public Integer getSource() { - return this.source; + public Integer getSampler() { + return this.sampler; } /** - * The index of the image used by this texture. When undefined, an - * extension or other mechanism **SHOULD** supply an alternate texture - * source, otherwise behavior is undefined. (optional) - * + * The index of the image used by this texture. When undefined, an + * extension or other mechanism **SHOULD** supply an alternate texture + * source, otherwise behavior is undefined. (optional) + * * @param source The source to set - * + * */ public void setSource(Integer source) { if (source == null) { this.source = source; - return; + return ; } this.source = source; } + /** + * The index of the image used by this texture. When undefined, an + * extension or other mechanism **SHOULD** supply an alternate texture + * source, otherwise behavior is undefined. (optional) + * + * @return The source + * + */ + public Integer getSource() { + return this.source; + } + } diff --git a/src/main/java/de/javagl/jgltf/impl/v2/TextureInfo.java b/src/main/java/de/javagl/jgltf/impl/v2/TextureInfo.java index e361716..8d4e6a1 100644 --- a/src/main/java/de/javagl/jgltf/impl/v2/TextureInfo.java +++ b/src/main/java/de/javagl/jgltf/impl/v2/TextureInfo.java @@ -1,6 +1,6 @@ /* * glTF JSON model - * + * * Do not modify this class. It is automatically generated * with JsonModelGen (https://github.com/javagl/JsonModelGen) * Copyright (c) 2016-2021 Marco Hutter - http://www.javagl.de @@ -9,97 +9,99 @@ package de.javagl.jgltf.impl.v2; + /** - * Reference to a texture. - *

    - * Auto-generated for textureInfo.schema.json - * + * Reference to a texture. + * + * Auto-generated for textureInfo.schema.json + * */ public class TextureInfo - extends GlTFProperty { + extends GlTFProperty +{ /** - * The index of the texture. (required) - * + * The index of the texture. (required) + * */ private Integer index; /** - * The set index of texture's TEXCOORD attribute used for texture - * coordinate mapping. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The set index of texture's TEXCOORD attribute used for texture + * coordinate mapping. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * */ private Integer texCoord; /** - * The index of the texture. (required) - * - * @return The index - * - */ - public Integer getIndex() { - return this.index; - } - - /** - * The index of the texture. (required) - * + * The index of the texture. (required) + * * @param index The index to set * @throws NullPointerException If the given value is null - * + * */ public void setIndex(Integer index) { if (index == null) { - throw new NullPointerException((("Invalid value for index: " + index) + ", may not be null")); + throw new NullPointerException((("Invalid value for index: "+ index)+", may not be null")); } this.index = index; } /** - * The set index of texture's TEXCOORD attribute used for texture - * coordinate mapping. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * - * @return The texCoord - * + * The index of the texture. (required) + * + * @return The index + * */ - public Integer getTexCoord() { - return this.texCoord; + public Integer getIndex() { + return this.index; } /** - * The set index of texture's TEXCOORD attribute used for texture - * coordinate mapping. (optional)
    - * Default: 0
    - * Minimum: 0 (inclusive) - * + * The set index of texture's TEXCOORD attribute used for texture + * coordinate mapping. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * * @param texCoord The texCoord to set * @throws IllegalArgumentException If the given value does not meet - * the given constraints - * + * the given constraints + * */ public void setTexCoord(Integer texCoord) { if (texCoord == null) { this.texCoord = texCoord; - return; + return ; } - if (texCoord < 0) { + if (texCoord< 0) { throw new IllegalArgumentException("texCoord < 0"); } this.texCoord = texCoord; } /** - * Returns the default value of the texCoord
    - * + * The set index of texture's TEXCOORD attribute used for texture + * coordinate mapping. (optional)
    + * Default: 0
    + * Minimum: 0 (inclusive) + * + * @return The texCoord + * + */ + public Integer getTexCoord() { + return this.texCoord; + } + + /** + * Returns the default value of the texCoord
    + * @see #getTexCoord + * * @return The default texCoord - * @see #getTexCoord - * + * */ public Integer defaultTexCoord() { - return 0; + return 0; } } diff --git a/src/main/java/de/javagl/jgltf/model/AbstractAccessorData.java b/src/main/java/de/javagl/jgltf/model/AbstractAccessorData.java index f225510..385ed38 100644 --- a/src/main/java/de/javagl/jgltf/model/AbstractAccessorData.java +++ b/src/main/java/de/javagl/jgltf/model/AbstractAccessorData.java @@ -32,12 +32,13 @@ /** * Package-private abstract base implementation of an {@link AccessorData} */ -abstract class AbstractAccessorData implements AccessorData { +abstract class AbstractAccessorData implements AccessorData +{ /** * The component type */ private final Class componentType; - + /** * The byte buffer of the buffer view that the accessor * refers to @@ -54,143 +55,168 @@ abstract class AbstractAccessorData implements AccessorData { * The number of elements */ private final int numElements; - + /** * The {@link ElementType} */ private final ElementType elementType; - + /** * The number of bytes per component */ private final int numBytesPerComponent; - + /** - * The stride, in number of bytes, between two consecutive elements + * The stride, in number of bytes, between two consecutive elements */ private final int byteStridePerElement; /** * Default constructor - * + * * @param accessorComponentType The accessor component type - * @param componentType The component type - * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param numBytesPerComponent The number of bytes per component - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * @throws NullPointerException If the bufferViewByteBuffer is - * null + * @param componentType The component type + * @param bufferViewByteBuffer The byte buffer of the buffer view + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param numBytesPerComponent The number of bytes per component + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * @throws NullPointerException If the bufferViewByteBuffer is + * null */ - AbstractAccessorData(int accessorComponentType, Class componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, - int numElements, ElementType elementType, - int numBytesPerComponent, Integer byteStride) { - Objects.requireNonNull(bufferViewByteBuffer, - "The bufferViewByteBuffer is null"); - + AbstractAccessorData(int accessorComponentType, Class componentType, + ByteBuffer bufferViewByteBuffer, int byteOffset, + int numElements, ElementType elementType, + int numBytesPerComponent, Integer byteStride) + { + Objects.requireNonNull(bufferViewByteBuffer, + "The bufferViewByteBuffer is null"); + this.componentType = componentType; this.bufferViewByteBuffer = bufferViewByteBuffer; this.byteOffset = byteOffset; this.numElements = numElements; this.elementType = elementType; this.numBytesPerComponent = numBytesPerComponent; - if (byteStride == null || byteStride == 0) { - this.byteStridePerElement = - elementType.getByteStride(accessorComponentType); - } else { + if (byteStride == null || byteStride == 0) + { + this.byteStridePerElement = + elementType.getByteStride(accessorComponentType); + } + else + { this.byteStridePerElement = byteStride; } } - + @Override - public final Class getComponentType() { + public final Class getComponentType() + { return componentType; } @Override - public final int getNumElements() { + public final int getNumElements() + { return numElements; } @Override - public final int getNumComponentsPerElement() { + public final int getNumComponentsPerElement() + { return elementType.getNumComponents(); } @Override - public final int getTotalNumComponents() { + public final int getTotalNumComponents() + { return numElements * getNumComponentsPerElement(); } - + /** * Returns the index of the byte in the byte buffer where the specified * component starts - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The byte index */ - protected final int getByteIndex(int elementIndex, int componentIndex) { + protected final int getByteIndex(int elementIndex, int componentIndex) + { // Compute the byte index, including possible padding for // matrix columns, as specified in 3.6.2.4. Data Alignment - int byteIndex = byteOffset - + elementIndex * byteStridePerElement; - if (this.componentType == byte.class) { - if (this.elementType == ElementType.MAT2) { + int byteIndex = byteOffset + + elementIndex * byteStridePerElement; + if (this.componentType == byte.class) + { + if (this.elementType == ElementType.MAT2) + { int columnIndex = componentIndex / 2; int rowIndex = componentIndex % 2; byteIndex += columnIndex * 4 + rowIndex; - } else if (this.elementType == ElementType.MAT3) { + } + else if (this.elementType == ElementType.MAT3) + { int columnIndex = componentIndex / 3; int rowIndex = componentIndex % 3; byteIndex += columnIndex * 4 + rowIndex; - } else { + } + else + { byteIndex += componentIndex * numBytesPerComponent; } - } else if (this.componentType == short.class) { - if (this.elementType == ElementType.MAT3) { + } + else if (this.componentType == short.class) + { + if (this.elementType == ElementType.MAT3) + { int columnIndex = componentIndex / 3; int rowIndex = componentIndex % 3; byteIndex += columnIndex * 8 + rowIndex * 2; - } else { + } + else + { byteIndex += componentIndex * numBytesPerComponent; } - } else { + } + else + { byteIndex += componentIndex * numBytesPerComponent; } return byteIndex; } - - + + /** * Returns the underlying byte buffer - * + * * @return The byte buffer */ - protected final ByteBuffer getBufferViewByteBuffer() { + protected final ByteBuffer getBufferViewByteBuffer() + { return bufferViewByteBuffer; } - + /** * Returns the byte stride per element - * + * * @return The byte stride */ - protected final int getByteStridePerElement() { + protected final int getByteStridePerElement() + { return byteStridePerElement; } - + /** * Returns the number of bytes per component - * + * * @return The number of bytes per component */ - protected final int getNumBytesPerComponent() { + protected final int getNumBytesPerComponent() + { return numBytesPerComponent; } diff --git a/src/main/java/de/javagl/jgltf/model/AccessorByteData.java b/src/main/java/de/javagl/jgltf/model/AccessorByteData.java index b4c66f8..0b6eac4 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorByteData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorByteData.java @@ -35,172 +35,184 @@ * A class for accessing the data that is described by an accessor. * It allows accessing the byte buffer of the buffer view of the * accessor, depending on the accessor parameters.
    - *
    + *
    * This data consists of several elements (for example, 3D byte vectors), - * which consist of several components (for example, the 3 byte values). + * which consist of several components (for example, the 3 byte values). */ -public final class AccessorByteData - extends AbstractAccessorData implements AccessorData { +public final class AccessorByteData + extends AbstractAccessorData implements AccessorData +{ /** * Whether the data should be interpreted as unsigned values */ private final boolean unsigned; - + /** - * Creates a new instance for accessing the data in the given + * Creates a new instance for accessing the data in the given * byte buffer, according to the rules described by the given * accessor parameters. - * - * @param componentType The component type + * @param componentType The component type * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * @throws NullPointerException If the bufferViewByteBuffer is - * null - * @throws IllegalArgumentException If the component type is not - * GL_BYTE or GL_UNSIGEND_BYTE + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * + * @throws NullPointerException If the bufferViewByteBuffer is + * null + * @throws IllegalArgumentException If the component type is not + * GL_BYTE or GL_UNSIGEND_BYTE * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity to provide the data for the accessor + * have a sufficient capacity to provide the data for the accessor */ public AccessorByteData(int componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, - ElementType elementType, Integer byteStride) { - super(componentType, byte.class, bufferViewByteBuffer, byteOffset, - numElements, elementType, Byte.BYTES, byteStride); + ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, + ElementType elementType, Integer byteStride) + { + super(componentType, byte.class, bufferViewByteBuffer, byteOffset, + numElements, elementType, Byte.BYTES, byteStride); AccessorDatas.validateByteType(componentType); this.unsigned = AccessorDatas.isUnsignedType(componentType); - int numBytesPerElement = - getNumComponentsPerElement() * getNumBytesPerComponent(); - AccessorDatas.validateCapacity(byteOffset, getNumElements(), - numBytesPerElement, getByteStridePerElement(), - bufferViewByteBuffer.capacity()); + int numBytesPerElement = + getNumComponentsPerElement() * getNumBytesPerComponent(); + AccessorDatas.validateCapacity(byteOffset, getNumElements(), + numBytesPerElement, getByteStridePerElement(), + bufferViewByteBuffer.capacity()); } - + /** * Returns whether the data should be interpreted as unsigned - * + * * @return Whether the data should be interpreted as unsigned */ - public boolean isUnsigned() { + public boolean isUnsigned() + { return unsigned; } - + /** * Returns the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public byte get(int elementIndex, int componentIndex) { + public byte get(int elementIndex, int componentIndex) + { int byteIndex = getByteIndex(elementIndex, componentIndex); return getBufferViewByteBuffer().get(byteIndex); } - + public float getFloat(int elementIndex, int componentIndex) { - byte value = get(elementIndex, componentIndex); + byte value = get(elementIndex, componentIndex); return unsigned ? Byte.toUnsignedInt(value) / (Byte.MAX_VALUE - Byte.MIN_VALUE) : Math.max(value / Byte.MAX_VALUE, -1.0F); } - + /** * Returns the value of the specified component - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public byte get(int globalComponentIndex) { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public byte get(int globalComponentIndex) + { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); return get(elementIndex, componentIndex); } /** * Set the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int elementIndex, int componentIndex, byte value) { + public void set(int elementIndex, int componentIndex, byte value) + { int byteIndex = getByteIndex(elementIndex, componentIndex); getBufferViewByteBuffer().put(byteIndex, value); } - + /** * Set the value of the specified component - * + * * @param globalComponentIndex The global component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int globalComponentIndex, byte value) { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public void set(int globalComponentIndex, byte value) + { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); set(elementIndex, componentIndex, value); } - - + + /** - * Returns the value of the specified component of the specified element, - * taking into account whether the data {@link #isUnsigned()}: If the data - * is unsigned, the returned byte value will be converted into an + * Returns the value of the specified component of the specified element, + * taking into account whether the data {@link #isUnsigned()}: If the data + * is unsigned, the returned byte value will be converted into an * unsigned integer value. - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int getInt(int elementIndex, int componentIndex) { + public int getInt(int elementIndex, int componentIndex) + { byte value = get(elementIndex, componentIndex); return unsigned ? Byte.toUnsignedInt(value) : value; } - + /** * Returns the value of the specified component, taking into account * whether the data {@link #isUnsigned()}: If the data is unsigned, * the returned byte value will be converted into an unsigned integer * value. - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int getInt(int globalComponentIndex) { + public int getInt(int globalComponentIndex) + { byte value = get(globalComponentIndex); return unsigned ? Byte.toUnsignedInt(value) : value; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public byte[] computeMin() { + public byte[] computeMin() + { byte result[] = new byte[getNumComponentsPerElement()]; Arrays.fill(result, Byte.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = (byte) Math.min(result[c], get(e, c)); } } @@ -208,36 +220,42 @@ public byte[] computeMin() { } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public byte[] computeMax() { + public byte[] computeMax() + { byte result[] = new byte[getNumComponentsPerElement()]; Arrays.fill(result, Byte.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = (byte) Math.max(result[c], get(e, c)); } } return result; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getInt(int, int)}. - * + * * @return The minimum values */ - public int[] computeMinInt() { + public int[] computeMinInt() + { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.min(result[c], getInt(e, c)); } } @@ -245,75 +263,88 @@ public int[] computeMinInt() { } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getInt(int, int)}. - * + * * @return The minimum values */ - public int[] computeMaxInt() { + public int[] computeMaxInt() + { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.max(result[c], getInt(e, c)); } } return result; } - + @Override - public ByteBuffer createByteBuffer() { + public ByteBuffer createByteBuffer() + { int totalNumComponents = getTotalNumComponents(); int totalBytes = totalNumComponents * getNumBytesPerComponent(); ByteBuffer result = ByteBuffer.allocateDirect(totalBytes) - .order(ByteOrder.nativeOrder()); - for (int i = 0; i < totalNumComponents; i++) { + .order(ByteOrder.nativeOrder()); + for (int i=0; i 0) { + for (int e = 0; e < getNumElements(); e++) + { + if (e > 0) + { sb.append(", "); - if (elementsPerRow > 0 && (e % elementsPerRow) == 0) { + if (elementsPerRow > 0 && (e % elementsPerRow) == 0) + { sb.append("\n "); } } - if (nc > 1) { + if (nc > 1) + { sb.append("("); } - for (int c = 0; c < nc; c++) { - if (c > 0) { + for (int c = 0; c < nc; c++) + { + if (c > 0) + { sb.append(", "); } int component = getInt(e, c); sb.append(String.format(locale, format, component)); } - if (nc > 1) { + if (nc > 1) + { sb.append(")"); } } sb.append("]"); return sb.toString(); } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/AccessorData.java b/src/main/java/de/javagl/jgltf/model/AccessorData.java index abcdfa9..2f3d4be 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorData.java @@ -30,33 +30,34 @@ /** * Interface for classes that provide typed access to raw accessor data. - * The exact type of the data (and thus, the implementing class) is + * The exact type of the data (and thus, the implementing class) is * defined by the {@link #getComponentType() component type}:
    *

      - *
    • For byte.class, the implementation is an + *
    • For byte.class, the implementation is an * {@link AccessorByteData}
    • - *
    • For short.class, the implementation is an + *
    • For short.class, the implementation is an * {@link AccessorShortData}
    • - *
    • For int.class, the implementation is an + *
    • For int.class, the implementation is an * {@link AccessorIntData}
    • - *
    • For float.class, the implementation is an + *
    • For float.class, the implementation is an * {@link AccessorFloatData}
    • *
    */ -public interface AccessorData { +public interface AccessorData +{ /** * Returns the type of the components that this class provides access to. * This will usually be a primitive type, like float.class * or short.class. - * + * * @return The component type */ Class getComponentType(); - + /** * Returns the number of elements in this data (for example, the number * of 3D vectors) - * + * * @return The number of elements */ int getNumElements(); @@ -64,7 +65,7 @@ public interface AccessorData { /** * Returns the number of components per element (for example, 3 if the * elements are 3D vectors) - * + * * @return The number of components per element */ int getNumComponentsPerElement(); @@ -72,7 +73,7 @@ public interface AccessorData { /** * Returns the total number of components (that is, the number of elements * multiplied with the number of components per element) - * + * * @return The total number of components */ int getTotalNumComponents(); @@ -81,12 +82,12 @@ public interface AccessorData { * Creates a new, direct byte buffer (with native byte order) that * contains the data for the accessor, in a compact form, * without any offset, and without any additional stride (that is, - * all elements will be tightly packed). - * + * all elements will be tightly packed). + * * @return The byte buffer */ ByteBuffer createByteBuffer(); - + float getFloat(int elementIndex, int componentIndex); } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/AccessorDatas.java b/src/main/java/de/javagl/jgltf/model/AccessorDatas.java index bae3fca..1d5f6ee 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorDatas.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorDatas.java @@ -34,31 +34,26 @@ * that allow a typed access to the data that is contained in the * buffer view that the accessor refers to.
    *
    - * Unless otherwise noted, none of the arguments to these methods may + * Unless otherwise noted, none of the arguments to these methods may * be null. */ -public class AccessorDatas { +public class AccessorDatas +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(AccessorDatas.class.getName()); - - - /** - * Private constructor to prevent instantiation - */ - private AccessorDatas() { - // Private constructor to prevent instantiation - } - + private static final Logger logger = + Logger.getLogger(AccessorDatas.class.getName()); + + /** * Create the {@link AccessorData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorData} */ - public static AccessorData create(AccessorModel accessorModel) { + public static AccessorData create(AccessorModel accessorModel) + { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); ByteBuffer bufferViewData = bufferViewModel.getBufferViewData(); return create(accessorModel, bufferViewData); @@ -67,502 +62,566 @@ public static AccessorData create(AccessorModel accessorModel) { /** * Create the {@link AccessorData} for the given {@link AccessorModel} * that refers to the data from the given buffer. - * + * * @param accessorModel The {@link AccessorModel} - * @param byteBuffer The byte buffer containing the data + * @param byteBuffer The byte buffer containing the data * @return The {@link AccessorData} */ public static AccessorData create( - AccessorModel accessorModel, ByteBuffer byteBuffer) { - if (accessorModel.getComponentDataType() == byte.class) { + AccessorModel accessorModel, ByteBuffer byteBuffer) + { + if (accessorModel.getComponentDataType() == byte.class) + { return createByte(accessorModel, byteBuffer); } - if (accessorModel.getComponentDataType() == short.class) { + if (accessorModel.getComponentDataType() == short.class) + { return createShort(accessorModel, byteBuffer); } - if (accessorModel.getComponentDataType() == int.class) { + if (accessorModel.getComponentDataType() == int.class) + { return createInt(accessorModel, byteBuffer); } - if (accessorModel.getComponentDataType() == float.class) { + if (accessorModel.getComponentDataType() == float.class) + { return createFloat(accessorModel, byteBuffer); } // Should never happen logger.severe("Invalid component data type: " - + accessorModel.getComponentDataType()); + + accessorModel.getComponentDataType()); return null; } - + /** * Create an {@link AccessorData} depending on the given component type. * This will return an {@link AccessorByteData}, {@link AccessorShortData}, * {@link AccessorIntData} or {@link AccessorFloatData} - * - * @param componentType The component type, as a GL constant (for example, - * GL_UNSIGNED_SHORT or GL_FLOAT) + * + * @param componentType The component type, as a GL constant (for example, + * GL_UNSIGNED_SHORT or GL_FLOAT) * @param bufferViewData The buffer view data that the accessor refers to - * @param byteOffset The byte offset for the accessor - * @param count The count (number of elements) for the accessor - * @param elementType The {@link ElementType} - * For example, if the accessor type is "VEC3", then this - * will be 3 - * @param byteStride The optional byte stride for the accessor data + * @param byteOffset The byte offset for the accessor + * @param count The count (number of elements) for the accessor + * @param elementType The {@link ElementType} + * For example, if the accessor type is "VEC3", then this + * will be 3 + * @param byteStride The optional byte stride for the accessor data * @return The {@link AccessorData} * @throws IllegalArgumentException If the given component type is - * not a valid GL constant + * not a valid GL constant */ public static AccessorData create( - int componentType, ByteBuffer bufferViewData, int byteOffset, - int count, ElementType elementType, Integer byteStride) { - if (isByteType(componentType)) { + int componentType, ByteBuffer bufferViewData, int byteOffset, + int count, ElementType elementType, Integer byteStride) + { + if (isByteType(componentType)) + { return new AccessorByteData( - componentType, bufferViewData, byteOffset, count, - elementType, byteStride); + componentType, bufferViewData, byteOffset, count, + elementType, byteStride); } - if (isShortType(componentType)) { + if (isShortType(componentType)) + { return new AccessorShortData( - componentType, bufferViewData, byteOffset, count, - elementType, byteStride); + componentType, bufferViewData, byteOffset, count, + elementType, byteStride); } - if (isIntType(componentType)) { + if (isIntType(componentType)) + { return new AccessorIntData( - componentType, bufferViewData, byteOffset, count, - elementType, byteStride); + componentType, bufferViewData, byteOffset, count, + elementType, byteStride); } - if (isFloatType(componentType)) { + if (isFloatType(componentType)) + { return new AccessorFloatData( - componentType, bufferViewData, byteOffset, count, - elementType, byteStride); + componentType, bufferViewData, byteOffset, count, + elementType, byteStride); } throw new IllegalArgumentException( - "Not a valid component type: " + componentType); + "Not a valid component type: " + componentType); } - + + + /** * Returns whether the given constant is GL_BYTE or - * GL_UNSIGNED_BYTE. - * + * GL_UNSIGNED_BYTE. + * * @param type The type constant * @return Whether the type is a byte type */ - public static boolean isByteType(int type) { - return - type == GltfConstants.GL_BYTE || - type == GltfConstants.GL_UNSIGNED_BYTE; + public static boolean isByteType(int type) + { + return + type == GltfConstants.GL_BYTE || + type == GltfConstants.GL_UNSIGNED_BYTE; } - + /** * Returns whether the given constant is GL_SHORT or - * GL_UNSIGNED_SHORT. - * + * GL_UNSIGNED_SHORT. + * * @param type The type constant * @return Whether the type is a short type */ - public static boolean isShortType(int type) { - return - type == GltfConstants.GL_SHORT || - type == GltfConstants.GL_UNSIGNED_SHORT; + public static boolean isShortType(int type) + { + return + type == GltfConstants.GL_SHORT || + type == GltfConstants.GL_UNSIGNED_SHORT; } /** * Returns whether the given constant is GL_INT or - * GL_UNSIGNED_INT. - * + * GL_UNSIGNED_INT. + * * @param type The type constant * @return Whether the type is an int type */ - public static boolean isIntType(int type) { - return - type == GltfConstants.GL_INT || - type == GltfConstants.GL_UNSIGNED_INT; + public static boolean isIntType(int type) + { + return + type == GltfConstants.GL_INT || + type == GltfConstants.GL_UNSIGNED_INT; } /** * Returns whether the given constant is GL_FLOAT. - * + * * @param type The type constant * @return Whether the type is a float type */ - public static boolean isFloatType(int type) { + public static boolean isFloatType(int type) + { return type == GltfConstants.GL_FLOAT; } /** * Returns whether the given constant is GL_UNSIGNED_BYTE, * GL_UNSIGNED_SHORT or GL_UNSIGNED_INT. - * + * * @param type The type constant * @return Whether the type is an unsigned type */ - static boolean isUnsignedType(int type) { - return - type == GltfConstants.GL_UNSIGNED_BYTE || - type == GltfConstants.GL_UNSIGNED_SHORT || - type == GltfConstants.GL_UNSIGNED_INT; + static boolean isUnsignedType(int type) + { + return + type == GltfConstants.GL_UNSIGNED_BYTE || + type == GltfConstants.GL_UNSIGNED_SHORT || + type == GltfConstants.GL_UNSIGNED_INT; } - + + /** - * Make sure that the given type is GL_BYTE or - * GL_UNSIGNED_BYTE, and throw an + * Make sure that the given type is GL_BYTE or + * GL_UNSIGNED_BYTE, and throw an * IllegalArgumentException if this is not the case. - * + * * @param type The type constant - * @throws IllegalArgumentException If the given type is not - * GL_BYTE or GL_UNSIGNED_BYTE + * @throws IllegalArgumentException If the given type is not + * GL_BYTE or GL_UNSIGNED_BYTE */ - static void validateByteType(int type) { - if (!isByteType(type)) { + static void validateByteType(int type) + { + if (!isByteType(type)) + { throw new IllegalArgumentException( - "The type is not GL_BYTE or GL_UNSIGNED_BYTE, but " + - GltfConstants.stringFor(type)); + "The type is not GL_BYTE or GL_UNSIGNED_BYTE, but " + + GltfConstants.stringFor(type)); } } /** - * Make sure that the given type is GL_SHORT or - * GL_UNSIGNED_SHORT, and throw an + * Make sure that the given type is GL_SHORT or + * GL_UNSIGNED_SHORT, and throw an * IllegalArgumentException if this is not the case. - * + * * @param type The type constant - * @throws IllegalArgumentException If the given type is not - * GL_SHORT or GL_UNSIGNED_BYTE + * @throws IllegalArgumentException If the given type is not + * GL_SHORT or GL_UNSIGNED_BYTE */ - static void validateShortType(int type) { - if (!isShortType(type)) { + static void validateShortType(int type) + { + if (!isShortType(type)) + { throw new IllegalArgumentException( - "The type is not GL_SHORT or GL_UNSIGNED_SHORT, but " + - GltfConstants.stringFor(type)); + "The type is not GL_SHORT or GL_UNSIGNED_SHORT, but " + + GltfConstants.stringFor(type)); } } - + /** - * Make sure that the given type is GL_INT or - * GL_UNSIGNED_INT, and throw an + * Make sure that the given type is GL_INT or + * GL_UNSIGNED_INT, and throw an * IllegalArgumentException if this is not the case. - * + * * @param type The type constant - * @throws IllegalArgumentException If the given type is not - * GL_INT or GL_UNSIGNED_INT + * @throws IllegalArgumentException If the given type is not + * GL_INT or GL_UNSIGNED_INT */ - static void validateIntType(int type) { - if (!isIntType(type)) { + static void validateIntType(int type) + { + if (!isIntType(type)) + { throw new IllegalArgumentException( - "The type is not GL_INT or GL_UNSIGNED_INT, but " + - GltfConstants.stringFor(type)); + "The type is not GL_INT or GL_UNSIGNED_INT, but " + + GltfConstants.stringFor(type)); } } /** - * Make sure that the given type is GL_FLOAT, and throw an + * Make sure that the given type is GL_FLOAT, and throw an * IllegalArgumentException if this is not the case. - * + * * @param type The type constant - * @throws IllegalArgumentException If the given type is not - * GL_FLOAT + * @throws IllegalArgumentException If the given type is not + * GL_FLOAT */ - static void validateFloatType(int type) { - if (!isFloatType(type)) { + static void validateFloatType(int type) + { + if (!isFloatType(type)) + { throw new IllegalArgumentException( - "The type is not GL_FLOAT, but " + - GltfConstants.stringFor(type)); + "The type is not GL_FLOAT, but " + + GltfConstants.stringFor(type)); } } - + + + /** * Creates an {@link AccessorByteData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorByteData} - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessor is not GL_BYTE or GL_UNSIGNED_BYTE + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessor is not GL_BYTE or GL_UNSIGNED_BYTE */ - public static AccessorByteData createByte(AccessorModel accessorModel) { + public static AccessorByteData createByte(AccessorModel accessorModel) + { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); return createByte(accessorModel, bufferViewModel.getBufferViewData()); } - + /** * Creates an {@link AccessorByteData} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewByteBuffer The byte buffer of the - * {@link BufferViewModel} referenced by the {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewByteBuffer The byte buffer of the + * {@link BufferViewModel} referenced by the {@link AccessorModel} * @return The {@link AccessorByteData} - * @throws NullPointerException If any argument is null - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_BYTE or - * GL_UNSIGNED_BYTE + * @throws NullPointerException If any argument is null + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_BYTE or + * GL_UNSIGNED_BYTE */ private static AccessorByteData createByte( - AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) { - return new AccessorByteData(accessorModel.getComponentType(), - bufferViewByteBuffer, - accessorModel.getByteOffset(), - accessorModel.getCount(), - accessorModel.getElementType(), - accessorModel.getByteStride()); + AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) + { + return new AccessorByteData(accessorModel.getComponentType(), + bufferViewByteBuffer, + accessorModel.getByteOffset(), + accessorModel.getCount(), + accessorModel.getElementType(), + accessorModel.getByteStride()); } - + /** * Creates an {@link AccessorShortData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorShortData} - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_SHORT or - * GL_UNSIGNED_SHORT + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_SHORT or + * GL_UNSIGNED_SHORT */ - public static AccessorShortData createShort(AccessorModel accessorModel) { + public static AccessorShortData createShort(AccessorModel accessorModel) + { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); return createShort(accessorModel, bufferViewModel.getBufferViewData()); } - + /** * Creates an {@link AccessorShortData} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewByteBuffer The byte buffer of the - * {@link BufferViewModel} referenced by the {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewByteBuffer The byte buffer of the + * {@link BufferViewModel} referenced by the {@link AccessorModel} * @return The {@link AccessorShortData} - * @throws NullPointerException If any argument is null - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_SHORT or - * GL_UNSIGNED_SHORT + * @throws NullPointerException If any argument is null + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_SHORT or + * GL_UNSIGNED_SHORT */ private static AccessorShortData createShort( - AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) { - return new AccessorShortData(accessorModel.getComponentType(), - bufferViewByteBuffer, - accessorModel.getByteOffset(), - accessorModel.getCount(), - accessorModel.getElementType(), - accessorModel.getByteStride()); + AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) + { + return new AccessorShortData(accessorModel.getComponentType(), + bufferViewByteBuffer, + accessorModel.getByteOffset(), + accessorModel.getCount(), + accessorModel.getElementType(), + accessorModel.getByteStride()); } + /** * Creates an {@link AccessorIntData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorIntData} - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_INT or GL_UNSIGNED_INT + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_INT or GL_UNSIGNED_INT */ - public static AccessorIntData createInt(AccessorModel accessorModel) { + public static AccessorIntData createInt(AccessorModel accessorModel) + { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); return createInt(accessorModel, bufferViewModel.getBufferViewData()); } - + /** * Creates an {@link AccessorIntData} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewByteBuffer The byte buffer of the - * {@link BufferViewModel} referenced by the {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewByteBuffer The byte buffer of the + * {@link BufferViewModel} referenced by the {@link AccessorModel} * @return The {@link AccessorIntData} - * @throws NullPointerException If any argument is null - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_INT or GL_UNSIGNED_INT + * @throws NullPointerException If any argument is null + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_INT or GL_UNSIGNED_INT */ private static AccessorIntData createInt( - AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) { - return new AccessorIntData(accessorModel.getComponentType(), - bufferViewByteBuffer, - accessorModel.getByteOffset(), - accessorModel.getCount(), - accessorModel.getElementType(), - accessorModel.getByteStride()); + AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) + { + return new AccessorIntData(accessorModel.getComponentType(), + bufferViewByteBuffer, + accessorModel.getByteOffset(), + accessorModel.getCount(), + accessorModel.getElementType(), + accessorModel.getByteStride()); } - + /** * Creates an {@link AccessorFloatData} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link AccessorFloatData} - * @throws IllegalArgumentException If the - * {@link AccessorModel#getComponentType() component type} of the given - * accessorModel is not GL_FLOAT + * @throws IllegalArgumentException If the + * {@link AccessorModel#getComponentType() component type} of the given + * accessorModel is not GL_FLOAT */ - public static AccessorFloatData createFloat(AccessorModel accessorModel) { + public static AccessorFloatData createFloat(AccessorModel accessorModel) + { BufferViewModel bufferViewModel = accessorModel.getBufferViewModel(); return createFloat(accessorModel, bufferViewModel.getBufferViewData()); } - + /** * Creates an {@link AccessorFloatData} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewByteBuffer The byte buffer of the - * {@link BufferViewModel} referenced by the {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewByteBuffer The byte buffer of the + * {@link BufferViewModel} referenced by the {@link AccessorModel} * @return The {@link AccessorFloatData} - * @throws NullPointerException If any argument is null - * @throws IllegalArgumentException If the + * @throws NullPointerException If any argument is null + * @throws IllegalArgumentException If the */ private static AccessorFloatData createFloat( - AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) { - return new AccessorFloatData(accessorModel.getComponentType(), - bufferViewByteBuffer, - accessorModel.getByteOffset(), - accessorModel.getCount(), - accessorModel.getElementType(), - accessorModel.getByteStride()); + AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer) + { + return new AccessorFloatData(accessorModel.getComponentType(), + bufferViewByteBuffer, + accessorModel.getByteOffset(), + accessorModel.getCount(), + accessorModel.getElementType(), + accessorModel.getByteStride()); } /** * Validate that the given {@link AccessorModel} parameters are valid for * accessing a buffer with the given capacity - * - * @param byteOffset The byte offset - * @param numElements The number of elements - * @param numBytesPerElement The number of bytes per element + * + * @param byteOffset The byte offset + * @param numElements The number of elements + * @param numBytesPerElement The number of bytes per element * @param byteStridePerElement The byte stride - * @param bufferCapacity The buffer capacity + * @param bufferCapacity The buffer capacity * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity + * have a sufficient capacity */ static void validateCapacity(int byteOffset, int numElements, - int numBytesPerElement, int byteStridePerElement, int bufferCapacity) { - int expectedCapacity = - (numElements - 1) * byteStridePerElement + numBytesPerElement; - if (expectedCapacity > bufferCapacity) { + int numBytesPerElement, int byteStridePerElement, int bufferCapacity) + { + int expectedCapacity = + (numElements - 1) * byteStridePerElement + numBytesPerElement; + if (expectedCapacity > bufferCapacity) + { throw new IllegalArgumentException( - "The accessorModel has an offset of " + byteOffset + " and " + - numElements + " elements with a byte stride of " + - byteStridePerElement + " and a size of " + numBytesPerElement + - ", requiring " + expectedCapacity + - " bytes, but the buffer view has only " + - bufferCapacity + " bytes"); + "The accessorModel has an offset of " + byteOffset + " and " + + numElements + " elements with a byte stride of " + + byteStridePerElement + " and a size of " + numBytesPerElement + + ", requiring " + expectedCapacity + + " bytes, but the buffer view has only " + + bufferCapacity + " bytes"); } } - + + /** - * Compute the the minimum component values of the given + * Compute the the minimum component values of the given * {@link AccessorData} - * + * * @param accessorData The {@link AccessorData} * @return The minimum values * @throws IllegalArgumentException If the given model has an unknown type */ - public static Number[] computeMin(AccessorData accessorData) { - if (accessorData instanceof AccessorByteData) { - AccessorByteData accessorByteData = - (AccessorByteData) accessorData; + public static Number[] computeMin(AccessorData accessorData) + { + if (accessorData instanceof AccessorByteData) + { + AccessorByteData accessorByteData = + (AccessorByteData) accessorData; return NumberArrays.asNumbers( - accessorByteData.computeMinInt()); + accessorByteData.computeMinInt()); } - if (accessorData instanceof AccessorShortData) { - AccessorShortData accessorShortData = - (AccessorShortData) accessorData; + if (accessorData instanceof AccessorShortData) + { + AccessorShortData accessorShortData = + (AccessorShortData) accessorData; return NumberArrays.asNumbers( - accessorShortData.computeMinInt()); + accessorShortData.computeMinInt()); } - if (accessorData instanceof AccessorIntData) { - AccessorIntData accessorIntData = - (AccessorIntData) accessorData; + if (accessorData instanceof AccessorIntData) + { + AccessorIntData accessorIntData = + (AccessorIntData) accessorData; return NumberArrays.asNumbers( - accessorIntData.computeMinLong()); + accessorIntData.computeMinLong()); } - if (accessorData instanceof AccessorFloatData) { - AccessorFloatData accessorFloatData = - (AccessorFloatData) accessorData; + if (accessorData instanceof AccessorFloatData) + { + AccessorFloatData accessorFloatData = + (AccessorFloatData) accessorData; return NumberArrays.asNumbers( - accessorFloatData.computeMin()); + accessorFloatData.computeMin()); } throw new IllegalArgumentException( - "Invalid data type: " + accessorData); + "Invalid data type: " + accessorData); } - + /** - * Compute the the maximum component values of the given + * Compute the the maximum component values of the given * {@link AccessorData} - * + * * @param accessorData The {@link AccessorData} * @return The maximum values * @throws IllegalArgumentException If the given model has an unknown type */ - public static Number[] computeMax(AccessorData accessorData) { - if (accessorData instanceof AccessorByteData) { - AccessorByteData accessorByteData = - (AccessorByteData) accessorData; + public static Number[] computeMax(AccessorData accessorData) + { + if (accessorData instanceof AccessorByteData) + { + AccessorByteData accessorByteData = + (AccessorByteData) accessorData; return NumberArrays.asNumbers( - accessorByteData.computeMaxInt()); + accessorByteData.computeMaxInt()); } - if (accessorData instanceof AccessorShortData) { - AccessorShortData accessorShortData = - (AccessorShortData) accessorData; + if (accessorData instanceof AccessorShortData) + { + AccessorShortData accessorShortData = + (AccessorShortData) accessorData; return NumberArrays.asNumbers( - accessorShortData.computeMaxInt()); + accessorShortData.computeMaxInt()); } - if (accessorData instanceof AccessorIntData) { - AccessorIntData accessorIntData = - (AccessorIntData) accessorData; + if (accessorData instanceof AccessorIntData) + { + AccessorIntData accessorIntData = + (AccessorIntData) accessorData; return NumberArrays.asNumbers( - accessorIntData.computeMaxLong()); + accessorIntData.computeMaxLong()); } - if (accessorData instanceof AccessorFloatData) { - AccessorFloatData accessorFloatData = - (AccessorFloatData) accessorData; + if (accessorData instanceof AccessorFloatData) + { + AccessorFloatData accessorFloatData = + (AccessorFloatData) accessorData; return NumberArrays.asNumbers( - accessorFloatData.computeMax()); + accessorFloatData.computeMax()); } throw new IllegalArgumentException( - "Invalid data type: " + accessorData); + "Invalid data type: " + accessorData); } - + /** * Creates a (possibly large!) string representation of the given - * {@link AccessorData}, by calling + * {@link AccessorData}, by calling * {@link AccessorByteData#createString(Locale, String, int)}, * {@link AccessorShortData#createString(Locale, String, int)}, * {@link AccessorIntData#createString(Locale, String, int)} or * {@link AccessorFloatData#createString(Locale, String, int)}, * depending on the type of the given data, with an unspecified * format string. - * - * @param accessorData The {@link AccessorData} + * + * @param accessorData The {@link AccessorData} * @param elementsPerRow The number of elements per row * @return The string */ public static String createString( - AccessorData accessorData, int elementsPerRow) { - if (accessorData instanceof AccessorByteData) { - AccessorByteData accessorByteData = - (AccessorByteData) accessorData; - String accessorDataString = - accessorByteData.createString( - Locale.ENGLISH, "%4d", elementsPerRow); + AccessorData accessorData, int elementsPerRow) + { + if (accessorData instanceof AccessorByteData) + { + AccessorByteData accessorByteData = + (AccessorByteData) accessorData; + String accessorDataString = + accessorByteData.createString( + Locale.ENGLISH, "%4d", elementsPerRow); return accessorDataString; } - if (accessorData instanceof AccessorShortData) { - AccessorShortData accessorShortData = - (AccessorShortData) accessorData; - String accessorDataString = - accessorShortData.createString( - Locale.ENGLISH, "%6d", elementsPerRow); + if (accessorData instanceof AccessorShortData) + { + AccessorShortData accessorShortData = + (AccessorShortData) accessorData; + String accessorDataString = + accessorShortData.createString( + Locale.ENGLISH, "%6d", elementsPerRow); return accessorDataString; } - if (accessorData instanceof AccessorIntData) { - AccessorIntData accessorIntData = - (AccessorIntData) accessorData; - String accessorDataString = - accessorIntData.createString( - Locale.ENGLISH, "%11d", elementsPerRow); + if (accessorData instanceof AccessorIntData) + { + AccessorIntData accessorIntData = + (AccessorIntData) accessorData; + String accessorDataString = + accessorIntData.createString( + Locale.ENGLISH, "%11d", elementsPerRow); return accessorDataString; } - if (accessorData instanceof AccessorFloatData) { - AccessorFloatData accessorFloatData = - (AccessorFloatData) accessorData; - String accessorDataString = - accessorFloatData.createString( - Locale.ENGLISH, "%10.5f", elementsPerRow); + if (accessorData instanceof AccessorFloatData) + { + AccessorFloatData accessorFloatData = + (AccessorFloatData) accessorData; + String accessorDataString = + accessorFloatData.createString( + Locale.ENGLISH, "%10.5f", elementsPerRow); return accessorDataString; } return "Unknown accessor data type: " + accessorData; } - + + + /** + * Private constructor to prevent instantiation + */ + private AccessorDatas() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/AccessorFloatData.java b/src/main/java/de/javagl/jgltf/model/AccessorFloatData.java index 2809a29..3ae8a0e 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorFloatData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorFloatData.java @@ -35,124 +35,133 @@ * A class for accessing the data that is described by an accessor. * It allows accessing the byte buffer of the buffer view of the * accessor, depending on the accessor parameters.
    - *
    + *
    * This data consists of several elements (for example, 3D float vectors), - * which consist of several components (for example, the 3 float values). + * which consist of several components (for example, the 3 float values). */ -public final class AccessorFloatData - extends AbstractAccessorData - implements AccessorData { +public final class AccessorFloatData + extends AbstractAccessorData + implements AccessorData +{ /** - * Creates a new instance for accessing the data in the given + * Creates a new instance for accessing the data in the given * byte buffer, according to the rules described by the given * accessor parameters. - * - * @param componentType The component type + * @param componentType The component type * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * @throws NullPointerException If the bufferViewByteBuffer is - * null - * @throws IllegalArgumentException If the component type is not - * GL_FLOAT + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * + * @throws NullPointerException If the bufferViewByteBuffer is + * null + * @throws IllegalArgumentException If the component type is not + * GL_FLOAT * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity to provide the data for the accessor + * have a sufficient capacity to provide the data for the accessor */ public AccessorFloatData(int componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, - ElementType elementType, Integer byteStride) { - super(componentType, float.class, bufferViewByteBuffer, byteOffset, - numElements, elementType, Float.BYTES, byteStride); + ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, + ElementType elementType, Integer byteStride) + { + super(componentType, float.class, bufferViewByteBuffer, byteOffset, + numElements, elementType, Float.BYTES, byteStride); AccessorDatas.validateFloatType(componentType); - int numBytesPerElement = - getNumComponentsPerElement() * getNumBytesPerComponent(); - AccessorDatas.validateCapacity(byteOffset, getNumElements(), - numBytesPerElement, getByteStridePerElement(), - bufferViewByteBuffer.capacity()); + int numBytesPerElement = + getNumComponentsPerElement() * getNumBytesPerComponent(); + AccessorDatas.validateCapacity(byteOffset, getNumElements(), + numBytesPerElement, getByteStridePerElement(), + bufferViewByteBuffer.capacity()); } - + /** * Returns the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public float get(int elementIndex, int componentIndex) { + public float get(int elementIndex, int componentIndex) + { int byteIndex = getByteIndex(elementIndex, componentIndex); return getBufferViewByteBuffer().getFloat(byteIndex); } - + public float getFloat(int elementIndex, int componentIndex) { - return get(elementIndex, componentIndex); + return get(elementIndex, componentIndex); } - + /** * Returns the value of the specified component - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public float get(int globalComponentIndex) { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public float get(int globalComponentIndex) + { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); return get(elementIndex, componentIndex); } - + /** * Set the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int elementIndex, int componentIndex, float value) { + public void set(int elementIndex, int componentIndex, float value) + { int byteIndex = getByteIndex(elementIndex, componentIndex); getBufferViewByteBuffer().putFloat(byteIndex, value); } - + /** * Set the value of the specified component - * + * * @param globalComponentIndex The global component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int globalComponentIndex, float value) { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public void set(int globalComponentIndex, float value) + { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); set(elementIndex, componentIndex, value); } - - + + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public float[] computeMin() { + public float[] computeMin() + { float result[] = new float[getNumComponentsPerElement()]; Arrays.fill(result, Float.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.min(result[c], get(e, c)); } } @@ -160,74 +169,87 @@ public float[] computeMin() { } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public float[] computeMax() { + public float[] computeMax() + { float result[] = new float[getNumComponentsPerElement()]; Arrays.fill(result, -Float.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.max(result[c], get(e, c)); } } return result; } - + @Override - public ByteBuffer createByteBuffer() { + public ByteBuffer createByteBuffer() + { int totalNumComponents = getTotalNumComponents(); int totalBytes = totalNumComponents * getNumBytesPerComponent(); ByteBuffer result = ByteBuffer.allocateDirect(totalBytes) - .order(ByteOrder.nativeOrder()); - for (int i = 0; i < totalNumComponents; i++) { + .order(ByteOrder.nativeOrder()); + for (int i=0; i 0) { + for (int e = 0; e < getNumElements(); e++) + { + if (e > 0) + { sb.append(", "); - if (elementsPerRow > 0 && (e % elementsPerRow) == 0) { + if (elementsPerRow > 0 && (e % elementsPerRow) == 0) + { sb.append("\n "); } } - if (nc > 1) { + if (nc > 1) + { sb.append("("); } - for (int c = 0; c < nc; c++) { - if (c > 0) { + for (int c = 0; c < nc; c++) + { + if (c > 0) + { sb.append(", "); } float component = get(e, c); sb.append(String.format(locale, format, component)); } - if (nc > 1) { + if (nc > 1) + { sb.append(")"); } } sb.append("]"); return sb.toString(); } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/AccessorIntData.java b/src/main/java/de/javagl/jgltf/model/AccessorIntData.java index e0bae60..d119317 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorIntData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorIntData.java @@ -35,173 +35,185 @@ * A class for accessing the data that is described by an accessor. * It allows accessing the byte buffer of the buffer view of the * accessor, depending on the accessor parameters.
    - *
    + *
    * This data consists of several elements (for example, 3D int vectors), - * which consist of several components (for example, the 3 int values). + * which consist of several components (for example, the 3 int values). */ -public final class AccessorIntData - extends AbstractAccessorData - implements AccessorData { +public final class AccessorIntData + extends AbstractAccessorData + implements AccessorData +{ /** * Whether the data should be interpreted as unsigned values */ private final boolean unsigned; - + /** - * Creates a new instance for accessing the data in the given + * Creates a new instance for accessing the data in the given * byte buffer, according to the rules described by the given * accessor parameters. - * - * @param componentType The component type + * @param componentType The component type * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * @throws NullPointerException If the bufferViewByteBuffer is - * null - * @throws IllegalArgumentException If the component type is not - * GL_INT or GL_UNSIGEND_INT + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * + * @throws NullPointerException If the bufferViewByteBuffer is + * null + * @throws IllegalArgumentException If the component type is not + * GL_INT or GL_UNSIGEND_INT * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity to provide the data for the accessor + * have a sufficient capacity to provide the data for the accessor */ public AccessorIntData(int componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, - ElementType elementType, Integer byteStride) { - super(componentType, int.class, bufferViewByteBuffer, byteOffset, - numElements, elementType, Integer.BYTES, byteStride); + ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, + ElementType elementType, Integer byteStride) + { + super(componentType, int.class, bufferViewByteBuffer, byteOffset, + numElements, elementType, Integer.BYTES, byteStride); AccessorDatas.validateIntType(componentType); this.unsigned = AccessorDatas.isUnsignedType(componentType); - int numBytesPerElement = - getNumComponentsPerElement() * getNumBytesPerComponent(); - AccessorDatas.validateCapacity(byteOffset, getNumElements(), - numBytesPerElement, getByteStridePerElement(), - bufferViewByteBuffer.capacity()); + int numBytesPerElement = + getNumComponentsPerElement() * getNumBytesPerComponent(); + AccessorDatas.validateCapacity(byteOffset, getNumElements(), + numBytesPerElement, getByteStridePerElement(), + bufferViewByteBuffer.capacity()); } - + /** * Returns whether the data should be interpreted as unsigned - * + * * @return Whether the data should be interpreted as unsigned */ - public boolean isUnsigned() { + public boolean isUnsigned() + { return unsigned; } - + /** * Returns the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int get(int elementIndex, int componentIndex) { + public int get(int elementIndex, int componentIndex) + { int byteIndex = getByteIndex(elementIndex, componentIndex); return getBufferViewByteBuffer().getInt(byteIndex); } - + public float getFloat(int elementIndex, int componentIndex) { - int value = get(elementIndex, componentIndex); - return unsigned ? Integer.toUnsignedLong(value) / (Integer.MAX_VALUE - Integer.MIN_VALUE) : Math.max(value / Integer.MAX_VALUE, -1.0F); + int value = get(elementIndex, componentIndex); + return unsigned ? Integer.toUnsignedLong(value) / (Integer.MAX_VALUE - Integer.MIN_VALUE) : Math.max(value / Integer.MAX_VALUE, -1.0F); } - + /** * Returns the value of the specified component - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int get(int globalComponentIndex) { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public int get(int globalComponentIndex) + { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); return get(elementIndex, componentIndex); } /** * Set the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int elementIndex, int componentIndex, int value) { + public void set(int elementIndex, int componentIndex, int value) + { int byteIndex = getByteIndex(elementIndex, componentIndex); getBufferViewByteBuffer().putInt(byteIndex, value); } - + /** * Set the value of the specified component - * + * * @param globalComponentIndex The global component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int globalComponentIndex, int value) { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public void set(int globalComponentIndex, int value) + { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); set(elementIndex, componentIndex, value); } - + /** - * Returns the value of the specified component of the specified element, - * taking into account whether the data {@link #isUnsigned()}: If the data - * is unsigned, the returned int value will be converted into an + * Returns the value of the specified component of the specified element, + * taking into account whether the data {@link #isUnsigned()}: If the data + * is unsigned, the returned int value will be converted into an * unsigned long value. - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public long getLong(int elementIndex, int componentIndex) { + public long getLong(int elementIndex, int componentIndex) + { int value = get(elementIndex, componentIndex); return unsigned ? Integer.toUnsignedLong(value) : value; } - + /** * Returns the value of the specified component, taking into account * whether the data {@link #isUnsigned()}: If the data is unsigned, * the returned int value will be converted into an unsigned integer * value. - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public long getLong(int globalComponentIndex) { + public long getLong(int globalComponentIndex) + { int value = get(globalComponentIndex); return unsigned ? Integer.toUnsignedLong(value) : value; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public int[] computeMin() { + public int[] computeMin() + { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.min(result[c], get(e, c)); } } @@ -209,36 +221,42 @@ public int[] computeMin() { } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public int[] computeMax() { + public int[] computeMax() + { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.max(result[c], get(e, c)); } } return result; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getLong(int, int)}. - * + * * @return The minimum values */ - public long[] computeMinLong() { + public long[] computeMinLong() + { long result[] = new long[getNumComponentsPerElement()]; Arrays.fill(result, Long.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.min(result[c], getLong(e, c)); } } @@ -246,75 +264,88 @@ public long[] computeMinLong() { } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getLong(int, int)}. - * + * * @return The minimum values */ - public long[] computeMaxLong() { + public long[] computeMaxLong() + { long result[] = new long[getNumComponentsPerElement()]; Arrays.fill(result, Long.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.max(result[c], getLong(e, c)); } } return result; } - + @Override - public ByteBuffer createByteBuffer() { + public ByteBuffer createByteBuffer() + { int totalNumComponents = getTotalNumComponents(); int totalBytes = totalNumComponents * getNumBytesPerComponent(); ByteBuffer result = ByteBuffer.allocateDirect(totalBytes) - .order(ByteOrder.nativeOrder()); - for (int i = 0; i < totalNumComponents; i++) { + .order(ByteOrder.nativeOrder()); + for (int i=0; i 0) { + for (int e = 0; e < getNumElements(); e++) + { + if (e > 0) + { sb.append(", "); - if (elementsPerRow > 0 && (e % elementsPerRow) == 0) { + if (elementsPerRow > 0 && (e % elementsPerRow) == 0) + { sb.append("\n "); } } - if (nc > 1) { + if (nc > 1) + { sb.append("("); } - for (int c = 0; c < nc; c++) { - if (c > 0) { + for (int c = 0; c < nc; c++) + { + if (c > 0) + { sb.append(", "); } long component = getLong(e, c); sb.append(String.format(locale, format, component)); } - if (nc > 1) { + if (nc > 1) + { sb.append(")"); } } sb.append("]"); return sb.toString(); } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/AccessorModel.java b/src/main/java/de/javagl/jgltf/model/AccessorModel.java index 45f56a0..c24e5c7 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorModel.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorModel.java @@ -29,147 +29,148 @@ /** * Interface for a data accessor */ -public interface AccessorModel extends NamedModelElement { +public interface AccessorModel extends NamedModelElement +{ /** * Returns the {@link BufferViewModel} for the data that this accessor * provides access to. Typed access to the data is possible by obtaining * the {@link AccessorData} using {@link #getAccessorData()}. - * + * * @return The {@link BufferViewModel} */ BufferViewModel getBufferViewModel(); - + /** * Returns the component type of this accessor, as a GL constant. For * example, GL_FLOAT or GL_UNSIGNED_SHORT - * + * * @return The component type */ int getComponentType(); - + /** * Returns the data type of the components of this accessor. For example, * float.class or short.class. - * + * * @return The component data type */ Class getComponentDataType(); - + /** * Returns whether this accessor contains normalized data - * + * * @return Whether this accessor contains normalized data */ boolean isNormalized(); - + /** * Returns the size of one component, in bytes - * + * * @return The component size, in bytes */ int getComponentSizeInBytes(); - + /** * Returns the size of one element, in bytes. - *

    + * * This does not include any padding that may have to be inserted * after the columns of certain matrix types (see section - * 3.6.2.4. "Data Alignment"). - *

    - * To obtain the padded size of the elements, - * {@link #getPaddedElementSizeInBytes()} can be used. - * + * 3.6.2.4. "Data Alignment"). + * + * To obtain the padded size of the elements, + * {@link #getPaddedElementSizeInBytes()} can be used. + * * @return The element size, in bytes */ int getElementSizeInBytes(); - + /** * Obtain the padded size of one element, in bytes. - *

    + * * This does include any padding that may have to be inserted * after the columns of certain matrix types (see section - * 3.6.2.4. "Data Alignment"). - *

    + * 3.6.2.4. "Data Alignment"). + * * For example, for a MAT2 with BYTE components, this will return 8, - * which is equivalent to calling + * which is equivalent to calling *

    
          * ElementType elementType = accessorModel.getElementType();
    -     * int componentType = accessorModel.getComponentType();
    +     * int componentType = accessorModel.getComponentType(); 
          * int sizeWithPadding = elementType.getByteStride(componentType);
          * 
    - *

    + * * See {@link ElementType#getByteStride(int)}. - * + * * @return The padded element size, in bytes */ int getPaddedElementSizeInBytes(); - + /** - * Returns the byte offset of this accessor referring to its + * Returns the byte offset of this accessor referring to its * {@link BufferViewModel} - * + * * @return The byte offset */ int getByteOffset(); - + /** * Returns the number of elements that this accessor provides access to - * + * * @return The number of elements */ int getCount(); - + /** * Returns the {@link ElementType} that this accessor provides access to - * + * * @return The {@link ElementType} */ ElementType getElementType(); - + /** * Returns the byte stride between the starts of two consecutive elements * of this accessor. - *

    + * * If this is 0, then the elements are tightly packed. This means that - * the byte stride is equal to the {@link #getElementSizeInBytes() element + * the byte stride is equal to the {@link #getElementSizeInBytes() element * size}. Note that for glTF 2.0, the byte stride for vertex attributes * must be a multiple 4. Callers must check whether the returned value * is 0 or not a multiple of 4 accordingly. - * + * * @return The byte stride */ int getByteStride(); - + /** * Returns the {@link AccessorData} for this accessor. The exact type - * of the returned {@link AccessorData} object will depend on the + * of the returned {@link AccessorData} object will depend on the * {@link #getComponentDataType() component data type}. It will be - * {@link AccessorByteData}, {@link AccessorShortData}, + * {@link AccessorByteData}, {@link AccessorShortData}, * {@link AccessorIntData} or {@link AccessorFloatData} for a component - * data type of byte.class, short.class, + * data type of byte.class, short.class, * int.class or float.class, respectively, - * and can be safely cast to the respective type. - * + * and can be safely cast to the respective type. + * * @return The {@link AccessorData} */ AccessorData getAccessorData(); - + /** - * Returns the minimum components of the {@link AccessorData}. The + * Returns the minimum components of the {@link AccessorData}. The * returned array will be a clone of the array that is stored internally, * and have a length that matches the {@link ElementType#getNumComponents() * number of components per element}. - * + * * @return The minimum components */ Number[] getMin(); - + /** - * Returns the maximum components of the {@link AccessorData}. The + * Returns the maximum components of the {@link AccessorData}. The * returned array will be a clone of the array that is stored internally, * and have a length that matches the {@link ElementType#getNumComponents() * number of components per element}. - * + * * @return The maximum components */ Number[] getMax(); diff --git a/src/main/java/de/javagl/jgltf/model/AccessorShortData.java b/src/main/java/de/javagl/jgltf/model/AccessorShortData.java index 64303d9..44a29af 100644 --- a/src/main/java/de/javagl/jgltf/model/AccessorShortData.java +++ b/src/main/java/de/javagl/jgltf/model/AccessorShortData.java @@ -35,174 +35,186 @@ * A class for accessing the data that is described by an accessor. * It allows accessing the byte buffer of the buffer view of the * accessor, depending on the accessor parameters.
    - *
    + *
    * This data consists of several elements (for example, 3D short vectors), - * which consist of several components (for example, the 3 short values). + * which consist of several components (for example, the 3 short values). */ -public final class AccessorShortData - extends AbstractAccessorData - implements AccessorData { +public final class AccessorShortData + extends AbstractAccessorData + implements AccessorData +{ /** * Whether the data should be interpreted as unsigned values */ private final boolean unsigned; - + /** - * Creates a new instance for accessing the data in the given + * Creates a new instance for accessing the data in the given * byte buffer, according to the rules described by the given * accessor parameters. - * - * @param componentType The component type + * @param componentType The component type * @param bufferViewByteBuffer The byte buffer of the buffer view - * @param byteOffset The byte offset in the buffer view - * @param numElements The number of elements - * @param elementType The {@link ElementType} - * @param byteStride The byte stride between two elements. If this - * is null or 0, then the stride will - * be the size of one element. - * @throws NullPointerException If the bufferViewByteBuffer is - * null - * @throws IllegalArgumentException If the component type is not - * GL_SHORT or GL_UNSIGEND_SHORT + * @param byteOffset The byte offset in the buffer view + * @param numElements The number of elements + * @param elementType The {@link ElementType} + * @param byteStride The byte stride between two elements. If this + * is null or 0, then the stride will + * be the size of one element. + * + * @throws NullPointerException If the bufferViewByteBuffer is + * null + * @throws IllegalArgumentException If the component type is not + * GL_SHORT or GL_UNSIGEND_SHORT * @throws IllegalArgumentException If the given byte buffer does not - * have a sufficient capacity to provide the data for the accessor + * have a sufficient capacity to provide the data for the accessor */ public AccessorShortData(int componentType, - ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, - ElementType elementType, Integer byteStride) { - super(componentType, short.class, bufferViewByteBuffer, byteOffset, - numElements, elementType, Short.BYTES, byteStride); + ByteBuffer bufferViewByteBuffer, int byteOffset, int numElements, + ElementType elementType, Integer byteStride) + { + super(componentType, short.class, bufferViewByteBuffer, byteOffset, + numElements, elementType, Short.BYTES, byteStride); AccessorDatas.validateShortType(componentType); this.unsigned = AccessorDatas.isUnsignedType(componentType); - int numBytesPerElement = - getNumComponentsPerElement() * getNumBytesPerComponent(); - AccessorDatas.validateCapacity(byteOffset, getNumElements(), - numBytesPerElement, getByteStridePerElement(), - bufferViewByteBuffer.capacity()); + int numBytesPerElement = + getNumComponentsPerElement() * getNumBytesPerComponent(); + AccessorDatas.validateCapacity(byteOffset, getNumElements(), + numBytesPerElement, getByteStridePerElement(), + bufferViewByteBuffer.capacity()); } - + /** * Returns whether the data should be interpreted as unsigned - * + * * @return Whether the data should be interpreted as unsigned */ - public boolean isUnsigned() { + public boolean isUnsigned() + { return unsigned; } - + /** * Returns the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public short get(int elementIndex, int componentIndex) { + public short get(int elementIndex, int componentIndex) + { int byteIndex = getByteIndex(elementIndex, componentIndex); return getBufferViewByteBuffer().getShort(byteIndex); } - + public float getFloat(int elementIndex, int componentIndex) { - short value = get(elementIndex, componentIndex); - return unsigned ? Short.toUnsignedInt(value) / (Short.MAX_VALUE - Short.MIN_VALUE) : Math.max(value / Short.MAX_VALUE, -1.0F); + short value = get(elementIndex, componentIndex); + return unsigned ? Short.toUnsignedInt(value) / (Short.MAX_VALUE - Short.MIN_VALUE) : Math.max(value / Short.MAX_VALUE, -1.0F); } - + /** * Returns the value of the specified component - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public short get(int globalComponentIndex) { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public short get(int globalComponentIndex) + { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); return get(elementIndex, componentIndex); } /** * Set the value of the specified component of the specified element - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int elementIndex, int componentIndex, short value) { + public void set(int elementIndex, int componentIndex, short value) + { int byteIndex = getByteIndex(elementIndex, componentIndex); getBufferViewByteBuffer().putShort(byteIndex, value); } - + /** * Set the value of the specified component - * + * * @param globalComponentIndex The global component index - * @param value The value + * @param value The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public void set(int globalComponentIndex, short value) { - int elementIndex = - globalComponentIndex / getNumComponentsPerElement(); - int componentIndex = - globalComponentIndex % getNumComponentsPerElement(); + public void set(int globalComponentIndex, short value) + { + int elementIndex = + globalComponentIndex / getNumComponentsPerElement(); + int componentIndex = + globalComponentIndex % getNumComponentsPerElement(); set(elementIndex, componentIndex, value); } - - + + /** - * Returns the value of the specified component of the specified element, - * taking into account whether the data {@link #isUnsigned()}: If the data - * is unsigned, the returned short value will be converted into an + * Returns the value of the specified component of the specified element, + * taking into account whether the data {@link #isUnsigned()}: If the data + * is unsigned, the returned short value will be converted into an * unsigned integer value. - * - * @param elementIndex The element index + * + * @param elementIndex The element index * @param componentIndex The component index * @return The value * @throws IndexOutOfBoundsException If the given indices cause the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int getInt(int elementIndex, int componentIndex) { + public int getInt(int elementIndex, int componentIndex) + { short value = get(elementIndex, componentIndex); return unsigned ? Short.toUnsignedInt(value) : value; } - + /** * Returns the value of the specified component, taking into account * whether the data {@link #isUnsigned()}: If the data is unsigned, * the returned short value will be converted into an unsigned integer * value. - * + * * @param globalComponentIndex The global component index * @return The value * @throws IndexOutOfBoundsException If the given index causes the - * underlying buffer to be accessed out of bounds + * underlying buffer to be accessed out of bounds */ - public int getInt(int globalComponentIndex) { + public int getInt(int globalComponentIndex) + { short value = get(globalComponentIndex); return unsigned ? Short.toUnsignedInt(value) : value; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public short[] computeMin() { + public short[] computeMin() + { short result[] = new short[getNumComponentsPerElement()]; Arrays.fill(result, Short.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = (short) Math.min(result[c], get(e, c)); } } @@ -210,36 +222,42 @@ public short[] computeMin() { } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. - * + * * @return The minimum values */ - public short[] computeMax() { + public short[] computeMax() + { short result[] = new short[getNumComponentsPerElement()]; Arrays.fill(result, Short.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = (short) Math.max(result[c], get(e, c)); } } return result; } - + /** - * Returns an array containing the minimum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the minimum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getInt(int, int)}. - * + * * @return The minimum values */ - public int[] computeMinInt() { + public int[] computeMinInt() + { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MAX_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.min(result[c], getInt(e, c)); } } @@ -247,75 +265,88 @@ public int[] computeMinInt() { } /** - * Returns an array containing the maximum component values of all elements - * of this accessor data. This will be an array whose length is the + * Returns an array containing the maximum component values of all elements + * of this accessor data. This will be an array whose length is the * {@link #getNumComponentsPerElement() number of components per element}. * These values are computed based on {@link #getInt(int, int)}. - * + * * @return The minimum values */ - public int[] computeMaxInt() { + public int[] computeMaxInt() + { int result[] = new int[getNumComponentsPerElement()]; Arrays.fill(result, Integer.MIN_VALUE); - for (int e = 0; e < getNumElements(); e++) { - for (int c = 0; c < getNumComponentsPerElement(); c++) { + for (int e = 0; e < getNumElements(); e++) + { + for (int c = 0; c < getNumComponentsPerElement(); c++) + { result[c] = Math.max(result[c], getInt(e, c)); } } return result; } - + @Override - public ByteBuffer createByteBuffer() { + public ByteBuffer createByteBuffer() + { int totalNumComponents = getTotalNumComponents(); int totalBytes = totalNumComponents * getNumBytesPerComponent(); ByteBuffer result = ByteBuffer.allocateDirect(totalBytes) - .order(ByteOrder.nativeOrder()); - for (int i = 0; i < totalNumComponents; i++) { + .order(ByteOrder.nativeOrder()); + for (int i=0; i 0) { + for (int e = 0; e < getNumElements(); e++) + { + if (e > 0) + { sb.append(", "); - if (elementsPerRow > 0 && (e % elementsPerRow) == 0) { + if (elementsPerRow > 0 && (e % elementsPerRow) == 0) + { sb.append("\n "); } } - if (nc > 1) { + if (nc > 1) + { sb.append("("); } - for (int c = 0; c < nc; c++) { - if (c > 0) { + for (int c = 0; c < nc; c++) + { + if (c > 0) + { sb.append(", "); } int component = getInt(e, c); sb.append(String.format(locale, format, component)); } - if (nc > 1) { + if (nc > 1) + { sb.append(")"); } } sb.append("]"); return sb.toString(); } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/Accessors.java b/src/main/java/de/javagl/jgltf/model/Accessors.java index f28f709..381eb6e 100644 --- a/src/main/java/de/javagl/jgltf/model/Accessors.java +++ b/src/main/java/de/javagl/jgltf/model/Accessors.java @@ -29,98 +29,82 @@ /** * Utility methods related to accessor properties.
    *
    - * Unless otherwise noted, none of the arguments to these methods may + * Unless otherwise noted, none of the arguments to these methods may * be null. */ -public class Accessors { +public class Accessors +{ /** - * Private constructor to prevent instantiation - */ - private Accessors() { - // Private constructor to prevent instantiation - } - - /** - * Returns the number of components that one element has for the given + * Returns the number of components that one element has for the given * accessor type. Valid parameters are *

    
          * "SCALAR" :  1
    -     * "VEC2"   :  2
    -     * "VEC3"   :  3
    -     * "VEC4"   :  4
    -     * "MAT2"   :  4
    -     * "MAT3"   :  9
    +     * "VEC2"   :  2 
    +     * "VEC3"   :  3 
    +     * "VEC4"   :  4 
    +     * "MAT2"   :  4 
    +     * "MAT3"   :  9 
          * "MAT4"   : 16
          * 
    - * - * @param accessorType The accessor type. + * + * @param accessorType The accessor type. * @return The number of components * @throws IllegalArgumentException If the given type is none of the - * valid parameters + * valid parameters */ - public static int getNumComponentsForAccessorType(String accessorType) { - switch (accessorType) { - case "SCALAR": - return 1; - case "VEC2": - return 2; - case "VEC3": - return 3; - case "VEC4": - return 4; - case "MAT2": - return 4; - case "MAT3": - return 9; - case "MAT4": - return 16; + public static int getNumComponentsForAccessorType(String accessorType) + { + switch (accessorType) + { + case "SCALAR": return 1; + case "VEC2": return 2; + case "VEC3": return 3; + case "VEC4": return 4; + case "MAT2": return 4; + case "MAT3": return 9; + case "MAT4": return 16; default: break; } throw new IllegalArgumentException( - "Invalid accessor type: " + accessorType); + "Invalid accessor type: "+accessorType); } /** - * Returns the number of bytes that one component with the given + * Returns the number of bytes that one component with the given * accessor component type consists of. * Valid parameters are *
    
          * GL_BYTE           : 1
    -     * GL_UNSIGNED_BYTE  : 1
    -     * GL_SHORT          : 2
    -     * GL_UNSIGNED_SHORT : 2
    -     * GL_INT            : 4
    -     * GL_UNSIGNED_INT   : 4
    +     * GL_UNSIGNED_BYTE  : 1 
    +     * GL_SHORT          : 2 
    +     * GL_UNSIGNED_SHORT : 2 
    +     * GL_INT            : 4 
    +     * GL_UNSIGNED_INT   : 4 
          * GL_FLOAT          : 4
          * 
    - * + * * @param componentType The component type * @return The number of bytes * @throws IllegalArgumentException If the given type is none of the - * valid parameters + * valid parameters */ - public static int getNumBytesForAccessorComponentType(int componentType) { - switch (componentType) { - case GltfConstants.GL_BYTE: - return 1; - case GltfConstants.GL_UNSIGNED_BYTE: - return 1; - case GltfConstants.GL_SHORT: - return 2; - case GltfConstants.GL_UNSIGNED_SHORT: - return 2; - case GltfConstants.GL_INT: - return 4; - case GltfConstants.GL_UNSIGNED_INT: - return 4; - case GltfConstants.GL_FLOAT: - return 4; + public static int getNumBytesForAccessorComponentType(int componentType) + { + switch (componentType) + { + case GltfConstants.GL_BYTE: return 1; + case GltfConstants.GL_UNSIGNED_BYTE: return 1; + case GltfConstants.GL_SHORT: return 2; + case GltfConstants.GL_UNSIGNED_SHORT: return 2; + case GltfConstants.GL_INT: return 4; + case GltfConstants.GL_UNSIGNED_INT: return 4; + case GltfConstants.GL_FLOAT: return 4; default: break; } throw new IllegalArgumentException( - "Invalid accessor component type: " + componentType); + "Invalid accessor component type: "+componentType); } /** @@ -129,40 +113,43 @@ public static int getNumBytesForAccessorComponentType(int componentType) { *
    
          * GL_BYTE           : byte.class
          * GL_UNSIGNED_BYTE  : byte.class
    -     * GL_SHORT          : short.class
    +     * GL_SHORT          : short.class 
          * GL_UNSIGNED_SHORT : short.class
    -     * GL_INT            : int.class
    +     * GL_INT            : int.class 
          * GL_UNSIGNED_INT   : int.class
          * GL_FLOAT          : float.class
          * 
    - * + * * @param componentType The component type * @return The data type * @throws IllegalArgumentException If the given type is none of the - * valid parameters + * valid parameters */ public static Class getDataTypeForAccessorComponentType( - int componentType) { - switch (componentType) { - case GltfConstants.GL_BYTE: - return byte.class; - case GltfConstants.GL_UNSIGNED_BYTE: - return byte.class; - case GltfConstants.GL_SHORT: - return short.class; - case GltfConstants.GL_UNSIGNED_SHORT: - return short.class; - case GltfConstants.GL_INT: - return int.class; - case GltfConstants.GL_UNSIGNED_INT: - return int.class; - case GltfConstants.GL_FLOAT: - return float.class; + int componentType) + { + switch (componentType) + { + case GltfConstants.GL_BYTE: return byte.class; + case GltfConstants.GL_UNSIGNED_BYTE: return byte.class; + case GltfConstants.GL_SHORT: return short.class; + case GltfConstants.GL_UNSIGNED_SHORT: return short.class; + case GltfConstants.GL_INT: return int.class; + case GltfConstants.GL_UNSIGNED_INT: return int.class; + case GltfConstants.GL_FLOAT: return float.class; default: break; } throw new IllegalArgumentException( - "Invalid accessor component type: " + componentType); + "Invalid accessor component type: "+componentType); } + /** + * Private constructor to prevent instantiation + */ + private Accessors() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/AnimationModel.java b/src/main/java/de/javagl/jgltf/model/AnimationModel.java index de2dd58..d237e71 100644 --- a/src/main/java/de/javagl/jgltf/model/AnimationModel.java +++ b/src/main/java/de/javagl/jgltf/model/AnimationModel.java @@ -31,87 +31,91 @@ /** * Interface for an animation */ -public interface AnimationModel extends NamedModelElement { - /** - * Returns an unmodifiable list containing the {@link Channel} instances - * of the animation - * - * @return The {@link Channel} instances - */ - List getChannels(); - +public interface AnimationModel extends NamedModelElement +{ /** * Enumeration of the different interpolation methods for an animation */ - public enum Interpolation { + public enum Interpolation + { /** * Stepwise interpolation */ STEP, - + /** * Linear interpolation */ LINEAR, - + /** * Cubic spline interpolation */ - CUBICSPLINE + CUBICSPLINE } - + /** * Interface for an animation channel */ - public interface Channel { + public interface Channel + { /** * Returns the {@link Sampler} for this channel - * + * * @return The {@link Sampler} */ Sampler getSampler(); - + /** * Returns the optional {@link NodeModel} to which the animated * property (path) belongs. - * + * * @return The {@link NodeModel} */ NodeModel getNodeModel(); - + /** * Returns the path describing the animated property - * + * * @return The path */ String getPath(); } - + /** * Interface for an animation sampler */ - public interface Sampler { + public interface Sampler + { /** * Returns the {@link AccessorModel} that contains the input (time * key frame) data - * + * * @return The input data */ AccessorModel getInput(); - + /** * Returns the {@link Interpolation} method - * + * * @return The {@link Interpolation} */ Interpolation getInterpolation(); - + /** * Returns the {@link AccessorModel} that contains the output (value * key frame) data - * + * * @return The output data */ AccessorModel getOutput(); } + + /** + * Returns an unmodifiable list containing the {@link Channel} instances + * of the animation + * + * @return The {@link Channel} instances + */ + List getChannels(); } diff --git a/src/main/java/de/javagl/jgltf/model/AssetModel.java b/src/main/java/de/javagl/jgltf/model/AssetModel.java index 4192a89..c3f58b7 100644 --- a/src/main/java/de/javagl/jgltf/model/AssetModel.java +++ b/src/main/java/de/javagl/jgltf/model/AssetModel.java @@ -27,26 +27,27 @@ package de.javagl.jgltf.model; /** - * Interface for an asset. - *

    + * Interface for an asset. + * * Note that this model does not include the version information that * will eventually be written as the gltf.asset.version. * This version information is intentionally hidden in the * model, and will depend on the version in which the model will * be written. */ -public interface AssetModel extends NamedModelElement { +public interface AssetModel extends NamedModelElement +{ /** * Returns the copyright message, suitable for display to credit * the content creator. - * + * * @return The copyright message */ String getCopyright(); - + /** * Returns the tool that generated this glTF model - * + * * @return The tool */ String getGenerator(); diff --git a/src/main/java/de/javagl/jgltf/model/BoundingBox.java b/src/main/java/de/javagl/jgltf/model/BoundingBox.java index 1b16ca4..3f273ae 100644 --- a/src/main/java/de/javagl/jgltf/model/BoundingBox.java +++ b/src/main/java/de/javagl/jgltf/model/BoundingBox.java @@ -31,41 +31,43 @@ /** * A very simple (package-private!) bounding box implementation */ -class BoundingBox { +class BoundingBox +{ /** * The minimum x coordinate */ private float minX; - + /** * The minimum y coordinate */ private float minY; - + /** * The minimum z coordinate */ private float minZ; - + /** * The maximum x coordinate */ private float maxX; - + /** * The maximum y coordinate */ private float maxY; - + /** * The maximum z coordinate */ private float maxZ; /** - * Creates a bounding box + * Creates a bounding box */ - BoundingBox() { + BoundingBox() + { minX = Float.MAX_VALUE; minY = Float.MAX_VALUE; minZ = Float.MAX_VALUE; @@ -73,15 +75,16 @@ class BoundingBox { maxY = -Float.MAX_VALUE; maxZ = -Float.MAX_VALUE; } - + /** * Combine this bounding box with the given point - * + * * @param x The x-coordinate * @param y The y-coordinate * @param z The z-coordinate */ - void combine(float x, float y, float z) { + void combine(float x, float y, float z) + { minX = Math.min(minX, x); minY = Math.min(minY, y); minZ = Math.min(minZ, z); @@ -92,10 +95,11 @@ void combine(float x, float y, float z) { /** * Combine this bounding box with the given one - * + * * @param other The other bounding box */ - void combine(BoundingBox other) { + void combine(BoundingBox other) + { Objects.requireNonNull(other, "The other bounding box may not be null"); minX = Math.min(minX, other.getMinX()); minY = Math.min(minY, other.getMinY()); @@ -110,7 +114,8 @@ void combine(BoundingBox other) { * * @return The x-coordinate of the center */ - float getCenterX() { + float getCenterX() + { return getMinX() + getSizeX() * 0.5f; } @@ -119,7 +124,8 @@ float getCenterX() { * * @return The y-coordinate of the center */ - float getCenterY() { + float getCenterY() + { return getMinY() + getSizeY() * 0.5f; } @@ -128,7 +134,8 @@ float getCenterY() { * * @return The z-coordinate of the center */ - float getCenterZ() { + float getCenterZ() + { return getMinZ() + getSizeZ() * 0.5f; } @@ -137,7 +144,8 @@ float getCenterZ() { * * @return The size in x-direction */ - float getSizeX() { + float getSizeX() + { return getMaxX() - getMinX(); } @@ -146,7 +154,8 @@ float getSizeX() { * * @return The size in y-direction */ - float getSizeY() { + float getSizeY() + { return getMaxY() - getMinY(); } @@ -155,7 +164,8 @@ float getSizeY() { * * @return The size in z-direction */ - float getSizeZ() { + float getSizeZ() + { return getMaxZ() - getMinZ(); } @@ -164,7 +174,8 @@ float getSizeZ() { * * @return The minimum x coordinate */ - float getMinX() { + float getMinX() + { return minX; } @@ -173,7 +184,8 @@ float getMinX() { * * @return The minimum y coordinate */ - float getMinY() { + float getMinY() + { return minY; } @@ -182,7 +194,8 @@ float getMinY() { * * @return The minimum z coordinate */ - float getMinZ() { + float getMinZ() + { return minZ; } @@ -191,7 +204,8 @@ float getMinZ() { * * @return The maximum x coordinate */ - float getMaxX() { + float getMaxX() + { return maxX; } @@ -200,7 +214,8 @@ float getMaxX() { * * @return The maximum y coordinate */ - float getMaxY() { + float getMaxY() + { return maxY; } @@ -209,14 +224,16 @@ float getMaxY() { * * @return The maximum z coordinate */ - float getMaxZ() { + float getMaxZ() + { return maxZ; } - + @Override - public String toString() { - return "[(" + - getMinX() + "," + getMinY() + "," + getMinZ() + ")-(" + - getMaxX() + "," + getMaxY() + "," + getMaxZ() + ")]"; + public String toString() + { + return "[(" + + getMinX() + "," + getMinY() + "," + getMinZ() + ")-(" + + getMaxX() + "," + getMaxY() + "," + getMaxZ() + ")]"; } } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/BoundingBoxComputer.java b/src/main/java/de/javagl/jgltf/model/BoundingBoxComputer.java index 9bb94f2..46184c7 100644 --- a/src/main/java/de/javagl/jgltf/model/BoundingBoxComputer.java +++ b/src/main/java/de/javagl/jgltf/model/BoundingBoxComputer.java @@ -33,101 +33,112 @@ /** * A (package-private!) utility class to compute bounding volumes */ -class BoundingBoxComputer { +class BoundingBoxComputer +{ /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(BoundingBoxComputer.class.getName()); - + Logger.getLogger(BoundingBoxComputer.class.getName()); + /** - * The {@link GltfModel} + * The {@link GltfModel} */ private final GltfModel gltfModel; - + /** * Create a new bounding box computer for the given {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} */ - BoundingBoxComputer(GltfModel gltfModel) { + BoundingBoxComputer(GltfModel gltfModel) + { this.gltfModel = gltfModel; } - + /** * Compute the bounding box of the {@link GltfModel} - * + * * @return The bounding box */ - BoundingBox compute() { + BoundingBox compute() + { BoundingBox boundingBox = new BoundingBox(); List sceneModels = gltfModel.getSceneModels(); - for (SceneModel sceneModel : sceneModels) { + for (SceneModel sceneModel : sceneModels) + { float rootTransform[] = MathUtils.createIdentity4x4(); computeSceneBoundingBox(sceneModel, rootTransform, boundingBox); } return boundingBox; } - + /** * Recursively compute the bounding box of the {@link MeshPrimitiveModel} - * objects of all {@link MeshModel} objects in the given {@link SceneModel} - * (including the respective global node transforms). + * objects of all {@link MeshModel} objects in the given {@link SceneModel} + * (including the respective global node transforms). * If the given result is null, then a new bounding box * will be created and returned. - * - * @param sceneModel The {@link SceneModel} - * @param transform The root transform, as a column major 4x4 matrix - * @param boundingBox The optional bounding box that will store the result + * + * @param sceneModel The {@link SceneModel} + * @param transform The root transform, as a column major 4x4 matrix + * @param boundingBox The optional bounding box that will store the result * @return The result */ private BoundingBox computeSceneBoundingBox( - SceneModel sceneModel, float transform[], BoundingBox boundingBox) { + SceneModel sceneModel, float transform[], BoundingBox boundingBox) + { BoundingBox localResult = boundingBox; - if (localResult == null) { + if (localResult == null) + { localResult = new BoundingBox(); } List nodeModels = sceneModel.getNodeModels(); - for (NodeModel nodeModel : nodeModels) { + for (NodeModel nodeModel : nodeModels) + { computeNodeBoundingBox(nodeModel, transform, localResult); } return localResult; } - - + + /** * Recursively compute the bounding box of the {@link MeshPrimitiveModel} - * objects of all {@link MeshModel} objects in the given {@link NodeModel} - * and its children (including the respective global node transforms). + * objects of all {@link MeshModel} objects in the given {@link NodeModel} + * and its children (including the respective global node transforms). * If the given result is null, then a new bounding box * will be created and returned. - * - * @param nodeModel The {@link NodeModel} + * + * @param nodeModel The {@link NodeModel} * @param parentTransform The transform, as a column major 4x4 matrix - * @param boundingBox The optional bounding box that will store the result + * @param boundingBox The optional bounding box that will store the result * @return The result */ private BoundingBox computeNodeBoundingBox( - NodeModel nodeModel, float parentTransform[], BoundingBox boundingBox) { + NodeModel nodeModel, float parentTransform[], BoundingBox boundingBox) + { BoundingBox result = boundingBox; - if (result == null) { + if (result == null) + { result = new BoundingBox(); } float[] localTransform = nodeModel.computeLocalTransform(null); float[] transform = new float[16]; MathUtils.mul4x4(parentTransform, localTransform, transform); - + List meshModels = nodeModel.getMeshModels(); - for (MeshModel meshModel : meshModels) { + for (MeshModel meshModel : meshModels) + { BoundingBox meshBoundingBox = - computeMeshBoundingBox( - meshModel, transform, result); + computeMeshBoundingBox( + meshModel, transform, result); result.combine(meshBoundingBox); } - + List children = nodeModel.getChildren(); - for (NodeModel child : children) { + for (NodeModel child : children) + { computeNodeBoundingBox(child, transform, result); } return result; @@ -138,97 +149,111 @@ private BoundingBox computeNodeBoundingBox( * the given transform. * If the given result is null, then a new bounding box * will be created and returned. - * - * @param meshModel The {@link MeshModel} - * @param transform The optional transform. If this is null, - * then the identity matrix will be assumed. - * @param boundingBox The optional bounding box that will store the result + * + * @param meshModel The {@link MeshModel} + * @param transform The optional transform. If this is null, + * then the identity matrix will be assumed. + * @param boundingBox The optional bounding box that will store the result * @return The result */ private BoundingBox computeMeshBoundingBox( - MeshModel meshModel, float transform[], BoundingBox boundingBox) { + MeshModel meshModel, float transform[], BoundingBox boundingBox) + { BoundingBox result = boundingBox; - if (result == null) { + if (result == null) + { result = new BoundingBox(); } - - List primitives = - meshModel.getMeshPrimitiveModels(); - for (MeshPrimitiveModel meshPrimitiveModel : primitives) { + + List primitives = + meshModel.getMeshPrimitiveModels(); + for (MeshPrimitiveModel meshPrimitiveModel : primitives) + { BoundingBox meshPrimitiveBoundingBox = - computeBoundingBox(meshPrimitiveModel, transform); - if (meshPrimitiveBoundingBox != null) { + computeBoundingBox(meshPrimitiveModel, transform); + if (meshPrimitiveBoundingBox != null) + { result.combine(meshPrimitiveBoundingBox); } } return result; } - + /** * Compute the bounding box of the given {@link MeshPrimitiveModel}, under * the given transform. - * + * * @param meshPrimitiveModel The {@link MeshPrimitiveModel} - * @param transform The optional transform. If this is null, - * then the identity matrix will be assumed. + * @param transform The optional transform. If this is null, + * then the identity matrix will be assumed. * @return The {@link BoundingBox}, or null if the given - * {@link MeshPrimitiveModel} does not refer to an {@link AccessorModel} + * {@link MeshPrimitiveModel} does not refer to an {@link AccessorModel} * with its "POSITION" attribute. If if refers to * an {@link AccessorModel} that does not contain 3D float elements, * then a warning will be printed and null will be - * returned. + * returned. */ private BoundingBox computeBoundingBox( - MeshPrimitiveModel meshPrimitiveModel, float transform[]) { - Map attributes = - meshPrimitiveModel.getAttributes(); + MeshPrimitiveModel meshPrimitiveModel, float transform[]) + { + Map attributes = + meshPrimitiveModel.getAttributes(); String positionsAttributeName = "POSITION"; AccessorModel accessorModel = attributes.get(positionsAttributeName); - if (accessorModel == null) { + if (accessorModel == null) + { return null; } - + ElementType accessorType = accessorModel.getElementType(); int numComponents = accessorType.getNumComponents(); - if (numComponents < 3) { - logger.warning("Mesh primitive " + positionsAttributeName + - " attribute refers to an accessor with type " + accessorType + - " - expected \"VEC3\" or \"VEC4\""); + if (numComponents < 3) + { + logger.warning("Mesh primitive " + positionsAttributeName + + " attribute refers to an accessor with type " + accessorType + + " - expected \"VEC3\" or \"VEC4\""); return null; } Class componentDataType = accessorModel.getComponentDataType(); - if (!componentDataType.equals(float.class)) { - logger.warning("Mesh primitive " + positionsAttributeName + - " attribute refers to an accessor with component type " + - GltfConstants.stringFor(accessorModel.getComponentType()) + - " - expected GL_FLOAT"); + if (!componentDataType.equals(float.class)) + { + logger.warning("Mesh primitive " + positionsAttributeName + + " attribute refers to an accessor with component type " + + GltfConstants.stringFor(accessorModel.getComponentType()) + + " - expected GL_FLOAT"); } - + AccessorData accessorData = accessorModel.getAccessorData(); - AccessorFloatData accessorFloatData = (AccessorFloatData) accessorData; - + AccessorFloatData accessorFloatData = (AccessorFloatData)accessorData; + float point[] = new float[3]; float transformedPoint[]; - if (transform != null) { + if (transform != null) + { transformedPoint = new float[3]; - } else { + } + else + { transformedPoint = point; } - + BoundingBox boundingBox = new BoundingBox(); - for (int e = 0; e < accessorData.getNumElements(); e++) { - for (int c = 0; c < 3; c++) { + for (int e = 0; e < accessorData.getNumElements(); e++) + { + for (int c = 0; c < 3; c++) + { point[c] = accessorFloatData.get(e, c); } - if (transform != null) { + if (transform != null) + { MathUtils.transformPoint3D(transform, point, transformedPoint); } boundingBox.combine( - transformedPoint[0], - transformedPoint[1], - transformedPoint[2]); + transformedPoint[0], + transformedPoint[1], + transformedPoint[2]); } return boundingBox; } - + } diff --git a/src/main/java/de/javagl/jgltf/model/BoundingBoxes.java b/src/main/java/de/javagl/jgltf/model/BoundingBoxes.java index 1a046aa..49c0988 100644 --- a/src/main/java/de/javagl/jgltf/model/BoundingBoxes.java +++ b/src/main/java/de/javagl/jgltf/model/BoundingBoxes.java @@ -34,37 +34,40 @@ * Note: This class is preliminary. It may be replaced with more * sophisticated bounding box computation methods in the future. */ -public class BoundingBoxes { - /** - * Private constructor to prevent instantiation - */ - private BoundingBoxes() { - // Private constructor to prevent instantiation - } - +public class BoundingBoxes +{ /** * Compute the bounding box of the given {@link GltfModel}. The result * will be an array [minX, minY, minZ, maxX, maxY, maxZ]. - * + * * @param gltfModel The {@link GltfModel} * @return The bounding box */ - public static float[] computeBoundingBoxMinMax(GltfModel gltfModel) { + public static float[] computeBoundingBoxMinMax(GltfModel gltfModel) + { Objects.requireNonNull(gltfModel, "The gltfModel may not be null"); - + BoundingBoxComputer boundingBoxComputer = - new BoundingBoxComputer(gltfModel); + new BoundingBoxComputer(gltfModel); BoundingBox boundingBox = boundingBoxComputer.compute(); - + float result[] = { - boundingBox.getMinX(), - boundingBox.getMinY(), - boundingBox.getMinZ(), - boundingBox.getMaxX(), - boundingBox.getMaxY(), - boundingBox.getMaxZ() + boundingBox.getMinX(), + boundingBox.getMinY(), + boundingBox.getMinZ(), + boundingBox.getMaxX(), + boundingBox.getMaxY(), + boundingBox.getMaxZ() }; return result; - + + } + + /** + * Private constructor to prevent instantiation + */ + private BoundingBoxes() + { + // Private constructor to prevent instantiation } } diff --git a/src/main/java/de/javagl/jgltf/model/BufferModel.java b/src/main/java/de/javagl/jgltf/model/BufferModel.java index 7e44614..e349d5c 100644 --- a/src/main/java/de/javagl/jgltf/model/BufferModel.java +++ b/src/main/java/de/javagl/jgltf/model/BufferModel.java @@ -31,29 +31,30 @@ /** * Interface for a buffer of a glTF asset */ -public interface BufferModel extends NamedModelElement { +public interface BufferModel extends NamedModelElement +{ /** * Returns the URI of the buffer data - * + * * @return The URI */ String getUri(); - + /** * Returns the length, in bytes, of the {@link #getBufferData() buffer data} - * + * * @return The buffer length, in bytes */ int getByteLength(); - + /** - * Returns the actual buffer data. This will return a slice of the buffer - * that is stored internally. Thus, changes to the contents of this buffer - * will affect this model, but modifications of the position and limit of + * Returns the actual buffer data. This will return a slice of the buffer + * that is stored internally. Thus, changes to the contents of this buffer + * will affect this model, but modifications of the position and limit of * the returned buffer will not affect this model.
    - * + * * @return The buffer data */ ByteBuffer getBufferData(); - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/BufferViewModel.java b/src/main/java/de/javagl/jgltf/model/BufferViewModel.java index 7107ff3..faeb983 100644 --- a/src/main/java/de/javagl/jgltf/model/BufferViewModel.java +++ b/src/main/java/de/javagl/jgltf/model/BufferViewModel.java @@ -29,54 +29,55 @@ import java.nio.ByteBuffer; /** - * Interface for a buffer view, which represents a slice of a + * Interface for a buffer view, which represents a slice of a * {@link BufferModel} */ -public interface BufferViewModel extends NamedModelElement { +public interface BufferViewModel extends NamedModelElement +{ /** * Return the actual data that this view stands for. This will be a new - * slice of the buffer of the data that is stored internally. Changes + * slice of the buffer of the data that is stored internally. Changes * in the position or limit of this buffer will not affect this model - * + * * @return The buffer view data */ ByteBuffer getBufferViewData(); /** * Returns the {@link BufferModel} that this view refers to - * + * * @return The {@link BufferModel} */ BufferModel getBufferModel(); - + /** * Returns the offset of this view referring to the buffer - * + * * @return The offset, in bytes */ int getByteOffset(); - + /** * Returns the length of this view, in bytes - * + * * @return The length, in bytes */ int getByteLength(); - + /** * Returns the stride between two consecutive elements of this buffer view, * in bytes. If this is null, then the elements are tightly * packed. - * + * * @return The stride, in bytes */ Integer getByteStride(); - + /** * Returns the (optional) target that this buffer should be bound to. - * If this is not null, then it will be the GL constant for - * GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER. - * + * If this is not null, then it will be the GL constant for + * GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER. + * * @return The target, or null */ Integer getTarget(); diff --git a/src/main/java/de/javagl/jgltf/model/CameraModel.java b/src/main/java/de/javagl/jgltf/model/CameraModel.java index 17e82b7..21b8a86 100644 --- a/src/main/java/de/javagl/jgltf/model/CameraModel.java +++ b/src/main/java/de/javagl/jgltf/model/CameraModel.java @@ -33,35 +33,36 @@ /** * An interface for a camera that is attached to a {@link NodeModel} */ -public interface CameraModel extends NamedModelElement { +public interface CameraModel extends NamedModelElement +{ /** * Returns the {@link CameraOrthographicModel}, or null if * this is a perspective camera - * + * * @return The {@link CameraOrthographicModel} */ CameraOrthographicModel getCameraOrthographicModel(); - + /** * Returns the {@link CameraPerspectiveModel}, or null if * this is an orthographic camera - * + * * @return The {@link CameraPerspectiveModel} */ CameraPerspectiveModel getCameraPerspectiveModel(); - + /** * Compute the projection matrix for this camera.
    *
    - * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * - * @param result The result array - * @param aspectRatio An optional aspect ratio that should be used. - * If this is null, then the aspect ratio of the - * camera will be used. + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * + * @param result The result array + * @param aspectRatio An optional aspect ratio that should be used. + * If this is null, then the aspect ratio of the + * camera will be used. * @return The result array */ float[] computeProjectionMatrix(float result[], Float aspectRatio); @@ -69,21 +70,21 @@ public interface CameraModel extends NamedModelElement { /** * Create the supplier of the projection matrix for this camera model.
    *
    - * The matrix will be provided as a float array with 16 elements, + * The matrix will be provided as a float array with 16 elements, * storing the matrix entries in column-major order.
    *
    - * Note: If the type of the camera that this {@link CameraModel} was - * created for is neither "perspective" nor + * Note: If the type of the camera that this {@link CameraModel} was + * created for is neither "perspective" nor * "orthographic", * then the supplier will print an error message and return * the identity matrix. - * + * * @param aspectRatioSupplier The optional supplier for the aspect - * ratio of the camera. If this is null, then the - * aspect ratio of the camera will be used. + * ratio of the camera. If this is null, then the + * aspect ratio of the camera will be used. * @return The supplier */ Supplier createProjectionMatrixSupplier( - DoubleSupplier aspectRatioSupplier); + DoubleSupplier aspectRatioSupplier); } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/CameraOrthographicModel.java b/src/main/java/de/javagl/jgltf/model/CameraOrthographicModel.java index ae5420d..5c37e37 100644 --- a/src/main/java/de/javagl/jgltf/model/CameraOrthographicModel.java +++ b/src/main/java/de/javagl/jgltf/model/CameraOrthographicModel.java @@ -29,33 +29,34 @@ /** * Interface for an orthographic camera */ -public interface CameraOrthographicModel { +public interface CameraOrthographicModel +{ /** * Returns the horizontal magnification - * + * * @return The magnification */ Float getXmag(); /** * Returns the vertical magnification - * + * * @return The magnification */ Float getYmag(); - + /** * Returns the distance of the far clipping plane - * + * * @return The distance */ Float getZfar(); - + /** * Returns the distance of the near clipping plane - * + * * @return The distance */ Float getZnear(); - + } diff --git a/src/main/java/de/javagl/jgltf/model/CameraPerspectiveModel.java b/src/main/java/de/javagl/jgltf/model/CameraPerspectiveModel.java index e9ebe08..7d0a41d 100644 --- a/src/main/java/de/javagl/jgltf/model/CameraPerspectiveModel.java +++ b/src/main/java/de/javagl/jgltf/model/CameraPerspectiveModel.java @@ -29,33 +29,34 @@ /** * Interface for an perspective camera */ -public interface CameraPerspectiveModel { +public interface CameraPerspectiveModel +{ /** * Returns the aspect ratio - * + * * @return The aspect ratio */ Float getAspectRatio(); - + /** * Returns the FOV, in y-direction, in radians - * + * * @return The FOV */ Float getYfov(); - + /** * Returns the distance of the far clipping plane - * + * * @return The distance */ Float getZfar(); - + /** * Returns the distance of the near clipping plane - * + * * @return The distance */ Float getZnear(); - + } diff --git a/src/main/java/de/javagl/jgltf/model/ElementType.java b/src/main/java/de/javagl/jgltf/model/ElementType.java index 873ba28..6c8112d 100644 --- a/src/main/java/de/javagl/jgltf/model/ElementType.java +++ b/src/main/java/de/javagl/jgltf/model/ElementType.java @@ -29,104 +29,73 @@ /** * Enumeration of the possible types of elements of an accessor */ -public enum ElementType { +public enum ElementType +{ /** * The scalar type */ SCALAR(1), - + /** * The 2D vector type */ VEC2(2), - + /** * The 3D vector type */ VEC3(3), - + /** * The 4D vector type */ VEC4(4), - + /** * The 2x2 matrix type */ MAT2(4), - + /** * The 3x3 matrix type */ MAT3(9), - + /** * The 4x4 matrix type */ MAT4(16); - + /** * The number of components that one element consists of */ private final int numComponents; - + /** * Creates a new instance with the given number of components - * + * * @param numComponents The number of components */ - ElementType(int numComponents) { + ElementType(int numComponents) + { this.numComponents = numComponents; } - - /** - * Returns whether the given string is a valid element type name, and may be - * passed to ElementType.valueOf without causing an exception. - * - * @param s The string - * @return Whether the given string is a valid element type - */ - public static boolean contains(String s) { - for (ElementType elementType : values()) { - if (elementType.name().equals(s)) { - return true; - } - } - return false; - } - - /** - * Returns the element type for the given string. If the string is - * null or does not describe a valid element type, - * then null is returned - * - * @param string The string - * @return The element type - */ - public static ElementType forString(String string) { - if (string == null) { - return null; - } - if (!contains(string)) { - return null; - } - return ElementType.valueOf(string); - } - + /** * Returns the number of components that one element consists of - * + * * @return The number of components */ - public int getNumComponents() { + public int getNumComponents() + { return numComponents; } - + /** * Obtains the byte stride that is implied for this element type with * the given component type, including any padding bytes that * may have to be inserted for matrix types. - *

    + * * According to the specification (section 3.6.2.4, Data Alignment), * padding bytes may have to be inserted after each column of matrix: *

      @@ -143,26 +112,72 @@ public int getNumComponents() { * have to be inserted after each column * *
    - * + * * @param componentType The component type * @return The byte stride */ - public int getByteStride(int componentType) { + public int getByteStride(int componentType) + { int n = Accessors.getNumBytesForAccessorComponentType(componentType); - if (n == 1) { - if (this == MAT2) { + if (n == 1) + { + if (this == MAT2) + { return 8; } - if (this == MAT3) { + if (this == MAT3) + { return 12; } } - if (n == 2) { - if (this == MAT3) { + if (n == 2) + { + if (this == MAT3) + { return 24; } } return numComponents * n; } - + + /** + * Returns whether the given string is a valid element type name, and may be + * passed to ElementType.valueOf without causing an exception. + * + * @param s The string + * @return Whether the given string is a valid element type + */ + public static boolean contains(String s) + { + for (ElementType elementType : values()) + { + if (elementType.name().equals(s)) + { + return true; + } + } + return false; + } + + /** + * Returns the element type for the given string. If the string is + * null or does not describe a valid element type, + * then null is returned + * + * @param string The string + * @return The element type + */ + public static ElementType forString(String string) + { + if (string == null) + { + return null; + } + if (!contains(string)) + { + return null; + } + return ElementType.valueOf(string); + } + } diff --git a/src/main/java/de/javagl/jgltf/model/ExtensionsModel.java b/src/main/java/de/javagl/jgltf/model/ExtensionsModel.java index e77d04c..263fb81 100644 --- a/src/main/java/de/javagl/jgltf/model/ExtensionsModel.java +++ b/src/main/java/de/javagl/jgltf/model/ExtensionsModel.java @@ -32,13 +32,14 @@ * An interface for the information about the extensions that are used in a * {@link GltfModel}. */ -public interface ExtensionsModel { +public interface ExtensionsModel +{ /** * Returns the list of extension names that are declared as the * extensionsUsed in the glTF asset. - *

    + * * The list should be assumed to be unmodifiable. - * + * * @return The list of used extensions */ List getExtensionsUsed(); @@ -46,9 +47,9 @@ public interface ExtensionsModel { /** * Returns the list of extension names that are declared as the * extensionsRequired in the glTF asset. - *

    + * * The list should be assumed to be unmodifiable. - * + * * @return The list of required extensions */ List getExtensionsRequired(); diff --git a/src/main/java/de/javagl/jgltf/model/GltfAnimations.java b/src/main/java/de/javagl/jgltf/model/GltfAnimations.java index a2a9a2c..415ac00 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfAnimations.java +++ b/src/main/java/de/javagl/jgltf/model/GltfAnimations.java @@ -26,6 +26,11 @@ */ package de.javagl.jgltf.model; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.logging.Logger; + import de.javagl.jgltf.model.AnimationModel.Channel; import de.javagl.jgltf.model.AnimationModel.Interpolation; import de.javagl.jgltf.model.AnimationModel.Sampler; @@ -35,334 +40,372 @@ import de.javagl.jgltf.model.animation.AnimationManager.AnimationPolicy; import de.javagl.jgltf.model.animation.InterpolatorType; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.logging.Logger; - /** * Utility methods to create {@link AnimationManager} instances that - * contain {@link Animation} instances that correspond to the - * {@link AnimationModel} instances of a glTF + * contain {@link Animation} instances that correspond to the + * {@link AnimationModel} instances of a glTF */ -@Deprecated -//Please use com.modularmods.mcgltf.animation.GltfAnimationCreator to compatible with CUBICSPLINE interpolation -public class GltfAnimations { +@Deprecated //Please use com.modularmods.mcgltf.animation.GltfAnimationCreator to compatible with CUBICSPLINE interpolation +public class GltfAnimations +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfAnimations.class.getName()); - + private static final Logger logger = + Logger.getLogger(GltfAnimations.class.getName()); + /** - * Private constructor to prevent instantiation - */ - private GltfAnimations() { - // Private constructor to prevent instantiation - } - - /** - * Create a new {@link AnimationManager} using the given + * Create a new {@link AnimationManager} using the given * {@link AnimationPolicy} - * + * * @param animationPolicy The {@link AnimationPolicy} * @return The {@link AnimationManager} */ public static AnimationManager createAnimationManager( - AnimationPolicy animationPolicy) { - AnimationManager animationManager = - new AnimationManager(animationPolicy); + AnimationPolicy animationPolicy) + { + AnimationManager animationManager = + new AnimationManager(animationPolicy); return animationManager; } - + /** - * Create all model {@link Animation} instances from the given + * Create all model {@link Animation} instances from the given * {@link AnimationModel} instances - * + * * @param animationModels The {@link AnimationModel} instances * @return The model animations */ public static List createModelAnimations( - Iterable animationModels) { - Objects.requireNonNull(animationModels, - "The animationModels may not be null"); + Iterable animationModels) + { + Objects.requireNonNull(animationModels, + "The animationModels may not be null"); List allModelAnimations = new ArrayList(); - for (AnimationModel animationModel : animationModels) { + for (AnimationModel animationModel : animationModels) + { List channels = animationModel.getChannels(); - List modelAnimations = - createModelAnimationsForChannels(channels); + List modelAnimations = + createModelAnimationsForChannels(channels); allModelAnimations.addAll(modelAnimations); } return allModelAnimations; } - + /** * Create one {@link Animation} for each {@link Channel}. - * If there is any error or inconsistency in the given data, then a + * If there is any error or inconsistency in the given data, then a * warning will be printed and the respective animation will be * skipped. - * + * * @param channels The {@link Channel} list * @return The list of model animations */ private static List createModelAnimationsForChannels( - Iterable channels) { + Iterable channels) + { List modelAnimations = new ArrayList(); - for (Channel channel : channels) { + for (Channel channel : channels) + { Animation modelAnimation = createModelAnimation(channel); - if (modelAnimation != null) { + if (modelAnimation != null) + { modelAnimations.add(modelAnimation); } } return modelAnimations; } - + + /** - * Create the {@link Animation} for the given + * Create the {@link Animation} for the given * {@link Channel}. If there is any error or inconsistency - * in the given data, then a warning will be printed and null + * in the given data, then a warning will be printed and null * will be returned. - * + * * @param channel The {@link Channel} * @return The {@link Animation}, or null. */ - private static Animation createModelAnimation(Channel channel) { + private static Animation createModelAnimation(Channel channel) + { Sampler sampler = channel.getSampler(); Interpolation interpolation = sampler.getInterpolation(); NodeModel nodeModel = channel.getNodeModel(); String path = channel.getPath(); - - AnimationListener animationListener = - createAnimationListener(nodeModel, path); - if (animationListener == null) { + + AnimationListener animationListener = + createAnimationListener(nodeModel, path); + if (animationListener == null) + { return null; } - InterpolatorType interpolatorType = - typeForInterpolation(interpolation, path); - + InterpolatorType interpolatorType = + typeForInterpolation(interpolation, path); + AccessorModel input = sampler.getInput(); AccessorData inputData = input.getAccessorData(); - if (!(inputData instanceof AccessorFloatData)) { + if (!(inputData instanceof AccessorFloatData)) + { logger.warning("Input data is not an AccessorFloatData, but " - + inputData.getClass()); + + inputData.getClass()); return null; } - AccessorFloatData inputFloatData = (AccessorFloatData) inputData; + AccessorFloatData inputFloatData = (AccessorFloatData)inputData; AccessorModel output = sampler.getOutput(); AccessorData outputData = output.getAccessorData(); - if (!(outputData instanceof AccessorFloatData)) { + if (!(outputData instanceof AccessorFloatData)) + { logger.warning("Output data is not an AccessorFloatData, but " - + outputData.getClass()); + + outputData.getClass()); return null; } - AccessorFloatData outputFloatData = (AccessorFloatData) outputData; - - Animation modelAnimation = - createAnimation(inputFloatData, outputFloatData, interpolatorType); + AccessorFloatData outputFloatData = (AccessorFloatData)outputData; + + Animation modelAnimation = + createAnimation(inputFloatData, outputFloatData, interpolatorType); modelAnimation.addAnimationListener(animationListener); return modelAnimation; } - + /** * Returns the {@link InterpolatorType} for the given {@link Interpolation} * and path - * + * * @param interpolation The {@link Interpolation} - * @param path The path + * @param path The path * @return The {@link InterpolatorType} */ private static InterpolatorType typeForInterpolation( - Interpolation interpolation, String path) { - switch (interpolation) { - case LINEAR: { - if (path.equals("rotation")) { + Interpolation interpolation, String path) + { + switch (interpolation) + { + case LINEAR: + { + if (path.equals("rotation")) + { return InterpolatorType.SLERP; } return InterpolatorType.LINEAR; } - case STEP: { + case STEP: + { return InterpolatorType.STEP; } - - case CUBICSPLINE: { + + case CUBICSPLINE: + { } default: logger.warning("This interpolation type is not supported yet"); break; } logger.warning( - "Interpolation type not supported: " + interpolation); + "Interpolation type not supported: " + interpolation); return InterpolatorType.LINEAR; } + + /** - * Creates a new {@link Animation} from + * Creates a new {@link Animation} from * the given input data - * - * @param timeData The (1D) {@link AccessorFloatData} containing the - * time key frames - * @param outputData The output data that contains the value key frames + * + * @param timeData The (1D) {@link AccessorFloatData} containing the + * time key frames + * @param outputData The output data that contains the value key frames * @param interpolatorType The {@link InterpolatorType} that should - * be used + * be used * @return The {@link Animation} */ static Animation createAnimation( - AccessorFloatData timeData, - AccessorFloatData outputData, - InterpolatorType interpolatorType) { + AccessorFloatData timeData, + AccessorFloatData outputData, + InterpolatorType interpolatorType) + { int numKeyElements = timeData.getNumElements(); float keys[] = new float[numKeyElements]; - for (int e = 0; e < numKeyElements; e++) { + for (int e=0; e"translation", "rotation", - * "scale" or "weights", then a warning + * path is not "translation", "rotation", + * "scale" or "weights", then a warning * will be printed and null will be returned. - * + * * @param nodeModel The {@link NodeModel} - * @param path The path + * @param path The path * @return The {@link AnimationListener} */ private static AnimationListener createAnimationListener( - NodeModel nodeModel, String path) { - switch (path) { + NodeModel nodeModel, String path) + { + switch (path) + { case "translation": return createTranslationAnimationListener(nodeModel); - + case "rotation": return createRotationAnimationListener(nodeModel); - + case "scale": return createScaleAnimationListener(nodeModel); - + case "weights": return createWeightsAnimationListener(nodeModel); - + default: break; } logger.warning("Animation channel target path must be " - + "\"translation\", \"rotation\", \"scale\" or \"weights\", " - + "but is " + path); + + "\"translation\", \"rotation\", \"scale\" or \"weights\", " + + "but is " + path); return null; } - + /** * Creates an {@link AnimationListener} that writes the animation data - * into the {@link NodeModel#getTranslation() translation} of the + * into the {@link NodeModel#getTranslation() translation} of the * {@link NodeModel}. - * + * * @param nodeModel The {@link NodeModel} * @return The {@link AnimationListener} */ private static AnimationListener createTranslationAnimationListener( - NodeModel nodeModel) { + NodeModel nodeModel) + { return (animation, timeS, values) -> { float translation[] = nodeModel.getTranslation(); - if (translation == null) { + if (translation == null) + { translation = values.clone(); nodeModel.setTranslation(translation); - } else { + } + else + { System.arraycopy(values, 0, translation, 0, values.length); } }; } - + /** * Creates an {@link AnimationListener} that writes the animation data - * into the {@link NodeModel#getRotation() rotation} of the + * into the {@link NodeModel#getRotation() rotation} of the * {@link NodeModel}. - * + * * @param nodeModel The {@link NodeModel} * @return The {@link AnimationListener} */ private static AnimationListener createRotationAnimationListener( - NodeModel nodeModel) { + NodeModel nodeModel) + { return (animation, timeS, values) -> { float rotation[] = nodeModel.getRotation(); - if (rotation == null) { + if (rotation == null) + { rotation = values.clone(); nodeModel.setRotation(rotation); - } else { + } + else + { System.arraycopy(values, 0, rotation, 0, values.length); } }; } - + /** * Creates an {@link AnimationListener} that writes the animation data - * into the {@link NodeModel#getScale() scale} of the + * into the {@link NodeModel#getScale() scale} of the * {@link NodeModel}. - * + * * @param nodeModel The {@link NodeModel} * @return The {@link AnimationListener} */ private static AnimationListener createScaleAnimationListener( - NodeModel nodeModel) { + NodeModel nodeModel) + { return (animation, timeS, values) -> { float scale[] = nodeModel.getScale(); - if (scale == null) { + if (scale == null) + { scale = values.clone(); nodeModel.setScale(scale); - } else { + } + else + { System.arraycopy(values, 0, scale, 0, values.length); } }; } - + /** * Creates an {@link AnimationListener} that writes the animation data - * into the {@link NodeModel#getWeights() weights} of the + * into the {@link NodeModel#getWeights() weights} of the * {@link NodeModel}. - * + * * @param nodeModel The {@link NodeModel} * @return The {@link AnimationListener} */ private static AnimationListener createWeightsAnimationListener( - NodeModel nodeModel) { + NodeModel nodeModel) + { return (animation, timeS, values) -> { float weights[] = nodeModel.getWeights(); - if (weights == null) { + if (weights == null) + { weights = values.clone(); nodeModel.setWeights(weights); - } else { + } + else + { System.arraycopy(values, 0, weights, 0, values.length); } }; } + + + /** + * Private constructor to prevent instantiation + */ + private GltfAnimations() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/GltfConstants.java b/src/main/java/de/javagl/jgltf/model/GltfConstants.java index 64134af..63d0c58 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfConstants.java +++ b/src/main/java/de/javagl/jgltf/model/GltfConstants.java @@ -30,33 +30,35 @@ /** * Some common OpenGL constants that are used in glTF */ -public class GltfConstants { +public class GltfConstants +{ /** * The GL_BGR constant (32992) */ public static final int GL_BGR = 32992; - + /** * The GL_RGB constant (6407) */ public static final int GL_RGB = 6407; - + /** * The GL_RGBA constant (6408) */ public static final int GL_RGBA = 6408; - + /** * The GL_BGRA constant (32993) */ public static final int GL_BGRA = 32993; - - + + + /** * The GL_BYTE constant (5120) */ public static final int GL_BYTE = 5120; - + /** * The GL_UNSIGNED_BYTE constant (5121) */ @@ -66,12 +68,12 @@ public class GltfConstants { * The GL_SHORT constant (5122) */ public static final int GL_SHORT = 5122; - + /** * The GL_UNSIGNED_SHORT constant (5123) */ public static final int GL_UNSIGNED_SHORT = 5123; - + /** * The GL_INT constant (5124) */ @@ -81,13 +83,14 @@ public class GltfConstants { * The GL_UNSIGNED_INT constant (5125) */ public static final int GL_UNSIGNED_INT = 5125; - + /** * The GL_FLOAT constant (5126) */ public static final int GL_FLOAT = 5126; + - + /** * The GL_FLOAT_VEC2 constant (35664) */ @@ -156,14 +159,14 @@ public class GltfConstants { /** * The GL_SAMPLER_2D constant (35678) */ - public static final int GL_SAMPLER_2D = 35678; - + public static final int GL_SAMPLER_2D = 35678; + /** * The GL_SAMPLER_CUBE constant (35680) */ public static final int GL_SAMPLER_CUBE = 35680; - - + + /** * The GL_POINTS constant (0) */ @@ -187,7 +190,7 @@ public class GltfConstants { /** * The GL_TRIANGLES constant (4) */ - public static final int GL_TRIANGLES = 4; + public static final int GL_TRIANGLES = 4; /** * The GL_TRIANGLE_STRIP constant (5) @@ -198,236 +201,239 @@ public class GltfConstants { * The GL_TRIANGLE_FAN constant (6) */ public static final int GL_TRIANGLE_FAN = 6; - - + + + /** * The GL_VERTEX_SHADER constant (35633) */ - public static final int GL_VERTEX_SHADER = 35633; - + public static final int GL_VERTEX_SHADER = 35633; + /** * The GL_VERTEX_SHADER constant (35632) */ - public static final int GL_FRAGMENT_SHADER = 35632; - - + public static final int GL_FRAGMENT_SHADER = 35632; + + + /** * The GL_TEXTURE_2D constant (3553) */ public static final int GL_TEXTURE_2D = 3553; - - + + + /** * The GL_ARRAY_BUFFER constant (34962) */ - public static final int GL_ARRAY_BUFFER = 34962; - + public static final int GL_ARRAY_BUFFER = 34962; + /** * The GL_ELEMENT_ARRAY_BUFFER constant (34963) */ public static final int GL_ELEMENT_ARRAY_BUFFER = 34963; - - + + // glEnable for technique.states - + /** * The GL_BLEND constant (3042) */ public static final int GL_BLEND = 3042; - + /** * The GL_CULL_FACE constant (2884) */ public static final int GL_CULL_FACE = 2884; - + /** * The GL_DEPTH_TEST constant (2929) */ public static final int GL_DEPTH_TEST = 2929; - + /** * The GL_POLYGON_OFFSET_FILL constant (32823) */ public static final int GL_POLYGON_OFFSET_FILL = 32823; - + /** * The GL_SAMPLE_ALPHA_TO_COVERAGE constant (32926) */ public static final int GL_SAMPLE_ALPHA_TO_COVERAGE = 32926; - + /** * The GL_SCISSOR_TEST constant (3089) */ public static final int GL_SCISSOR_TEST = 3089; // glBlendEquationSeparate - + /** * The GL_FUNC_ADD constant (32774) */ public static final int GL_FUNC_ADD = 32774; - + /** * The GL_FUNC_SUBTRACT constant (32778) */ public static final int GL_FUNC_SUBTRACT = 32778; - + /** * The GL_FUNC_REVERSE_SUBTRACT constant (32779) */ public static final int GL_FUNC_REVERSE_SUBTRACT = 32779; // glBlendFuncSeparate - + /** * The GL_ZERO constant (0) */ public static final int GL_ZERO = 0; - + /** * The GL_ONE constant (1) */ public static final int GL_ONE = 1; - + /** * The GL_SRC_COLOR constant (768) */ public static final int GL_SRC_COLOR = 768; - + /** * The GL_ONE_MINUS_SRC_COLOR constant (769) */ public static final int GL_ONE_MINUS_SRC_COLOR = 769; - + /** * The GL_DST_COLOR constant (774) */ public static final int GL_DST_COLOR = 774; - + /** * The GL_ONE_MINUS_DST_COLOR constant (775) */ public static final int GL_ONE_MINUS_DST_COLOR = 775; - + /** * The GL_SRC_ALPHA constant (770) */ public static final int GL_SRC_ALPHA = 770; - + /** * The GL_ONE_MINUS_SRC_ALPHA constant (771) */ public static final int GL_ONE_MINUS_SRC_ALPHA = 771; - + /** * The GL_DST_ALPHA constant (772) */ public static final int GL_DST_ALPHA = 772; - + /** * The GL_ONE_MINUS_DST_ALPHA constant (773) */ public static final int GL_ONE_MINUS_DST_ALPHA = 773; - + /** * The GL_CONSTANT_COLOR constant (32769) */ public static final int GL_CONSTANT_COLOR = 32769; - + /** * The GL_ONE_MINUS_CONSTANT_COLOR constant (32770) */ public static final int GL_ONE_MINUS_CONSTANT_COLOR = 32770; - + /** * The GL_CONSTANT_ALPHA constant (32771) */ public static final int GL_CONSTANT_ALPHA = 32771; - + /** * The GL_ONE_MINUS_CONSTANT_ALPHA constant (32772) */ public static final int GL_ONE_MINUS_CONSTANT_ALPHA = 32772; - + /** * The GL_SRC_ALPHA_SATURATE constant (776) */ public static final int GL_SRC_ALPHA_SATURATE = 776; // glCullFace - + /** * The GL_FRONT constant (1028) */ public static final int GL_FRONT = 1028; - + /** * The GL_BACK constant (1029) */ public static final int GL_BACK = 1029; - + /** * The GL_FRONT_AND_BACK constant (1032) */ public static final int GL_FRONT_AND_BACK = 1032; // glDepthFunc - + /** * The GL_NEVER constant (512) */ public static final int GL_NEVER = 512; - + /** * The GL_LESS constant (513) */ public static final int GL_LESS = 513; - + /** * The GL_LEQUAL constant (515) */ public static final int GL_LEQUAL = 515; - + /** * The GL_EQUAL constant (514) */ public static final int GL_EQUAL = 514; - + /** * The GL_GREATER constant (516) */ public static final int GL_GREATER = 516; - + /** * The GL_NOTEQUAL constant (517) */ public static final int GL_NOTEQUAL = 517; - + /** * The GL_GEQUAL constant (518) */ public static final int GL_GEQUAL = 518; - + /** * The GL_ALWAYS constant (519) */ public static final int GL_ALWAYS = 519; // glFrontFace - + /** * The GL_CW constant (2304) */ public static final int GL_CW = 2304; - + /** * The GL_CCW constant (2305) */ - public static final int GL_CCW = 2305; - - + public static final int GL_CCW = 2305; + + // glTexParameter - + /** * The GL_NEAREST constant (9728) */ @@ -459,7 +465,7 @@ public class GltfConstants { public static final int GL_LINEAR_MIPMAP_LINEAR = 9987; // glSamplerParameter - + /** * The GL_REPEAT constant (10497) */ @@ -480,213 +486,139 @@ public class GltfConstants { */ public static final int GL_CLAMP_TO_BORDER = 33069; - - /** - * Private constructor to prevent instantiation - */ - private GltfConstants() { - // Private constructor to prevent instantiation - } - + + /** * Returns the String representation of the given constant - * + * * @param constant The constant * @return The String for the constant */ - public static String stringFor(int constant) { - switch (constant) { - case GL_BGR: - return "GL_BGR"; - case GL_RGB: - return "GL_RGB"; - case GL_RGBA: - return "GL_RGBA"; - case GL_BGRA: - return "GL_BGRA"; - - case GL_BYTE: - return "GL_BYTE"; - case GL_UNSIGNED_BYTE: - return "GL_UNSIGNED_BYTE"; - case GL_SHORT: - return "GL_SHORT"; - case GL_UNSIGNED_SHORT: - return "GL_UNSIGNED_SHORT"; - case GL_INT: - return "GL_INT"; - case GL_UNSIGNED_INT: - return "GL_UNSIGNED_INT"; - case GL_FLOAT: - return "GL_FLOAT"; - - case GL_FLOAT_VEC2: - return "GL_FLOAT_VEC2"; - case GL_FLOAT_VEC3: - return "GL_FLOAT_VEC3"; - case GL_FLOAT_VEC4: - return "GL_FLOAT_VEC4"; - case GL_INT_VEC2: - return "GL_INT_VEC2"; - case GL_INT_VEC3: - return "GL_INT_VEC3"; - case GL_INT_VEC4: - return "GL_INT_VEC4"; - case GL_BOOL: - return "GL_BOOL"; - case GL_BOOL_VEC2: - return "GL_BOOL_VEC2"; - case GL_BOOL_VEC3: - return "GL_BOOL_VEC3"; - case GL_BOOL_VEC4: - return "GL_BOOL_VEC4"; - case GL_FLOAT_MAT2: - return "GL_FLOAT_MAT2"; - case GL_FLOAT_MAT3: - return "GL_FLOAT_MAT3"; - case GL_FLOAT_MAT4: - return "GL_FLOAT_MAT4"; - case GL_SAMPLER_2D: - return "GL_SAMPLER_2D"; - - case GL_POINTS: - return "GL_ZERO or GL_POINTS"; - case GL_LINES: - return "GL_ONE or GL_LINES"; - case GL_LINE_LOOP: - return "GL_LINE_LOOP"; - case GL_LINE_STRIP: - return "GL_LINE_STRIP"; - case GL_TRIANGLES: - return "GL_TRIANGLES"; - case GL_TRIANGLE_STRIP: - return "GL_TRIANGLE_STRIP"; - - case GL_VERTEX_SHADER: - return "GL_VERTEX_SHADER"; - case GL_FRAGMENT_SHADER: - return "GL_FRAGMENT_SHADER"; - - case GL_TEXTURE_2D: - return "GL_TEXTURE_2D"; - - case GL_ARRAY_BUFFER: - return "GL_ARRAY_BUFFER"; - case GL_ELEMENT_ARRAY_BUFFER: - return "GL_ELEMENT_ARRAY_BUFFER"; - + public static String stringFor(int constant) + { + switch (constant) + { + case GL_BGR : return "GL_BGR"; + case GL_RGB : return "GL_RGB"; + case GL_RGBA : return "GL_RGBA"; + case GL_BGRA : return "GL_BGRA"; + + case GL_BYTE : return "GL_BYTE"; + case GL_UNSIGNED_BYTE : return "GL_UNSIGNED_BYTE"; + case GL_SHORT : return "GL_SHORT"; + case GL_UNSIGNED_SHORT : return "GL_UNSIGNED_SHORT"; + case GL_INT : return "GL_INT"; + case GL_UNSIGNED_INT : return "GL_UNSIGNED_INT"; + case GL_FLOAT : return "GL_FLOAT"; + + case GL_FLOAT_VEC2 : return "GL_FLOAT_VEC2"; + case GL_FLOAT_VEC3 : return "GL_FLOAT_VEC3"; + case GL_FLOAT_VEC4 : return "GL_FLOAT_VEC4"; + case GL_INT_VEC2 : return "GL_INT_VEC2"; + case GL_INT_VEC3 : return "GL_INT_VEC3"; + case GL_INT_VEC4 : return "GL_INT_VEC4"; + case GL_BOOL : return "GL_BOOL"; + case GL_BOOL_VEC2 : return "GL_BOOL_VEC2"; + case GL_BOOL_VEC3 : return "GL_BOOL_VEC3"; + case GL_BOOL_VEC4 : return "GL_BOOL_VEC4"; + case GL_FLOAT_MAT2 : return "GL_FLOAT_MAT2"; + case GL_FLOAT_MAT3 : return "GL_FLOAT_MAT3"; + case GL_FLOAT_MAT4 : return "GL_FLOAT_MAT4"; + case GL_SAMPLER_2D : return "GL_SAMPLER_2D"; + + case GL_POINTS: return "GL_ZERO or GL_POINTS"; + case GL_LINES: return "GL_ONE or GL_LINES"; + case GL_LINE_LOOP: return "GL_LINE_LOOP"; + case GL_LINE_STRIP: return "GL_LINE_STRIP"; + case GL_TRIANGLES: return "GL_TRIANGLES"; + case GL_TRIANGLE_STRIP: return "GL_TRIANGLE_STRIP"; + + case GL_VERTEX_SHADER: return "GL_VERTEX_SHADER"; + case GL_FRAGMENT_SHADER: return "GL_FRAGMENT_SHADER"; + + case GL_TEXTURE_2D: return "GL_TEXTURE_2D"; + + case GL_ARRAY_BUFFER: return "GL_ARRAY_BUFFER"; + case GL_ELEMENT_ARRAY_BUFFER: return "GL_ELEMENT_ARRAY_BUFFER"; + // glEnable for technique.states - case GL_BLEND: - return "GL_BLEND"; - case GL_CULL_FACE: - return "GL_CULL_FACE"; - case GL_DEPTH_TEST: - return "GL_DEPTH_TEST"; - case GL_POLYGON_OFFSET_FILL: - return "GL_POLYGON_OFFSET_FILL"; - case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_BLEND: return "GL_BLEND"; + case GL_CULL_FACE: return "GL_CULL_FACE"; + case GL_DEPTH_TEST: return "GL_DEPTH_TEST"; + case GL_POLYGON_OFFSET_FILL: return "GL_POLYGON_OFFSET_FILL"; + case GL_SAMPLE_ALPHA_TO_COVERAGE: return "GL_SAMPLE_ALPHA_TO_COVERAGE"; - case GL_SCISSOR_TEST: - return "GL_SCISSOR_TEST"; + case GL_SCISSOR_TEST: return "GL_SCISSOR_TEST"; // glBlendEquationSeparate - case GL_FUNC_ADD: - return "GL_FUNC_ADD"; - case GL_FUNC_SUBTRACT: - return "GL_FUNC_SUBTRACT"; - case GL_FUNC_REVERSE_SUBTRACT: - return "GL_FUNC_REVERSE_SUBTRACT"; + case GL_FUNC_ADD: return "GL_FUNC_ADD"; + case GL_FUNC_SUBTRACT: return "GL_FUNC_SUBTRACT"; + case GL_FUNC_REVERSE_SUBTRACT: return "GL_FUNC_REVERSE_SUBTRACT"; // glBlendFuncSeparate //case GL_ZERO: return "GL_ZERO"; // see GL_POINTS //case GL_ONE: return "GL_ONE"; // see GL_LINES - case GL_SRC_COLOR: - return "GL_SRC_COLOR"; - case GL_ONE_MINUS_SRC_COLOR: - return "GL_ONE_MINUS_SRC_COLOR"; - case GL_DST_COLOR: - return "GL_DST_COLOR"; - case GL_ONE_MINUS_DST_COLOR: - return "GL_ONE_MINUS_DST_COLOR"; - case GL_SRC_ALPHA: - return "GL_SRC_ALPHA"; - case GL_ONE_MINUS_SRC_ALPHA: - return "GL_ONE_MINUS_SRC_ALPHA"; - case GL_DST_ALPHA: - return "GL_DST_ALPHA"; - case GL_ONE_MINUS_DST_ALPHA: - return "GL_ONE_MINUS_DST_ALPHA"; - case GL_CONSTANT_COLOR: - return "GL_CONSTANT_COLOR"; - case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_SRC_COLOR: return "GL_SRC_COLOR"; + case GL_ONE_MINUS_SRC_COLOR: return "GL_ONE_MINUS_SRC_COLOR"; + case GL_DST_COLOR: return "GL_DST_COLOR"; + case GL_ONE_MINUS_DST_COLOR: return "GL_ONE_MINUS_DST_COLOR"; + case GL_SRC_ALPHA: return "GL_SRC_ALPHA"; + case GL_ONE_MINUS_SRC_ALPHA: return "GL_ONE_MINUS_SRC_ALPHA"; + case GL_DST_ALPHA: return "GL_DST_ALPHA"; + case GL_ONE_MINUS_DST_ALPHA: return "GL_ONE_MINUS_DST_ALPHA"; + case GL_CONSTANT_COLOR: return "GL_CONSTANT_COLOR"; + case GL_ONE_MINUS_CONSTANT_COLOR: return "GL_ONE_MINUS_CONSTANT_COLOR"; - case GL_CONSTANT_ALPHA: - return "GL_CONSTANT_ALPHA"; - case GL_ONE_MINUS_CONSTANT_ALPHA: + case GL_CONSTANT_ALPHA: return "GL_CONSTANT_ALPHA"; + case GL_ONE_MINUS_CONSTANT_ALPHA: return "GL_ONE_MINUS_CONSTANT_ALPHA"; - case GL_SRC_ALPHA_SATURATE: - return "GL_SRC_ALPHA_SATURATE"; + case GL_SRC_ALPHA_SATURATE: return "GL_SRC_ALPHA_SATURATE"; // glCullFace - case GL_FRONT: - return "GL_FRONT"; - case GL_BACK: - return "GL_BACK"; - case GL_FRONT_AND_BACK: - return "GL_FRONT_AND_BACK"; + case GL_FRONT: return "GL_FRONT"; + case GL_BACK: return "GL_BACK"; + case GL_FRONT_AND_BACK: return "GL_FRONT_AND_BACK"; // glDepthFunc - case GL_NEVER: - return "GL_NEVER"; - case GL_LESS: - return "GL_LESS"; - case GL_LEQUAL: - return "GL_LEQUAL"; - case GL_EQUAL: - return "GL_EQUAL"; - case GL_GREATER: - return "GL_GREATER"; - case GL_NOTEQUAL: - return "GL_NOTEQUAL"; - case GL_GEQUAL: - return "GL_GEQUAL"; - case GL_ALWAYS: - return "GL_ALWAYS"; + case GL_NEVER: return "GL_NEVER"; + case GL_LESS: return "GL_LESS"; + case GL_LEQUAL: return "GL_LEQUAL"; + case GL_EQUAL: return "GL_EQUAL"; + case GL_GREATER: return "GL_GREATER"; + case GL_NOTEQUAL: return "GL_NOTEQUAL"; + case GL_GEQUAL: return "GL_GEQUAL"; + case GL_ALWAYS: return "GL_ALWAYS"; // glFrontFace - case GL_CW: - return "GL_CW"; - case GL_CCW: - return "GL_CCW"; - + case GL_CW: return "GL_CW"; + case GL_CCW: return "GL_CCW"; + // glTexParameter - case GL_NEAREST: - return "GL_NEAREST"; - case GL_LINEAR: - return "GL_LINEAR"; - case GL_NEAREST_MIPMAP_NEAREST: - return "GL_NEAREST_MIPMAP_NEAREST"; - case GL_LINEAR_MIPMAP_NEAREST: - return "GL_LINEAR_MIPMAP_NEAREST"; - case GL_NEAREST_MIPMAP_LINEAR: - return "GL_NEAREST_MIPMAP_LINEAR"; - case GL_LINEAR_MIPMAP_LINEAR: - return "GL_LINEAR_MIPMAP_LINEAR"; - + case GL_NEAREST : return "GL_NEAREST"; + case GL_LINEAR : return "GL_LINEAR"; + case GL_NEAREST_MIPMAP_NEAREST : return "GL_NEAREST_MIPMAP_NEAREST"; + case GL_LINEAR_MIPMAP_NEAREST : return "GL_LINEAR_MIPMAP_NEAREST"; + case GL_NEAREST_MIPMAP_LINEAR : return "GL_NEAREST_MIPMAP_LINEAR"; + case GL_LINEAR_MIPMAP_LINEAR : return "GL_LINEAR_MIPMAP_LINEAR"; + // glSamplerParameter - case GL_REPEAT: - return "GL_REPEAT"; - case GL_MIRRORED_REPEAT: - return "GL_MIRRORED_REPEAT"; - case GL_CLAMP_TO_EDGE: - return "GL_CLAMP_TO_EDGE"; - case GL_CLAMP_TO_BORDER: - return "GL_CLAMP_TO_BORDER"; - + case GL_REPEAT : return "GL_REPEAT"; + case GL_MIRRORED_REPEAT : return "GL_MIRRORED_REPEAT"; + case GL_CLAMP_TO_EDGE : return "GL_CLAMP_TO_EDGE"; + case GL_CLAMP_TO_BORDER : return "GL_CLAMP_TO_BORDER"; + default: - return "UNKNOWN_GL_CONSTANT[" + constant + "]"; + return "UNKNOWN_GL_CONSTANT["+constant+"]"; } } - - + + /** + * Private constructor to prevent instantiation + */ + private GltfConstants() + { + // Private constructor to prevent instantiation + } + + } diff --git a/src/main/java/de/javagl/jgltf/model/GltfException.java b/src/main/java/de/javagl/jgltf/model/GltfException.java index b87344a..a63f7f5 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfException.java +++ b/src/main/java/de/javagl/jgltf/model/GltfException.java @@ -29,7 +29,8 @@ /** * An exception that may be thrown to indicate an error inside a glTF asset. */ -public class GltfException extends RuntimeException { +public class GltfException extends RuntimeException +{ /** * Serial UID */ @@ -37,20 +38,22 @@ public class GltfException extends RuntimeException { /** * Creates a new exception with the given message - * - * @param message The message + * + * @param message The message */ - public GltfException(String message) { + public GltfException(String message) + { super(message); } /** * Creates a new exception with the given message and cause - * - * @param message The message - * @param cause The cause + * + * @param message The message + * @param cause The cause */ - public GltfException(String message, Throwable cause) { + public GltfException(String message, Throwable cause) + { super(message, cause); } } diff --git a/src/main/java/de/javagl/jgltf/model/GltfModel.java b/src/main/java/de/javagl/jgltf/model/GltfModel.java index dd07613..06fc1f2 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfModel.java +++ b/src/main/java/de/javagl/jgltf/model/GltfModel.java @@ -31,118 +31,119 @@ /** * Interface for a model that was created from a glTF asset */ -public interface GltfModel extends ModelElement { +public interface GltfModel extends ModelElement +{ /** - * Returns an unmodifiable view on the list of {@link AccessorModel} + * Returns an unmodifiable view on the list of {@link AccessorModel} * instances that have been created for the glTF. - * + * * @return The {@link AccessorModel} instances */ List getAccessorModels(); - + /** - * Returns an unmodifiable view on the list of {@link AnimationModel} + * Returns an unmodifiable view on the list of {@link AnimationModel} * instances that have been created for the glTF. - * + * * @return The {@link AnimationModel} instances */ List getAnimationModels(); /** - * Returns an unmodifiable view on the list of {@link BufferModel} + * Returns an unmodifiable view on the list of {@link BufferModel} * instances that have been created for the glTF. - * + * * @return The {@link BufferModel} instances */ List getBufferModels(); /** - * Returns an unmodifiable view on the list of {@link BufferViewModel} + * Returns an unmodifiable view on the list of {@link BufferViewModel} * instances that have been created for the glTF. - * + * * @return The {@link BufferViewModel} instances */ List getBufferViewModels(); - + /** - * Returns an unmodifiable view on the list of {@link CameraModel} + * Returns an unmodifiable view on the list of {@link CameraModel} * instances that have been created for the glTF. - * + * * @return The {@link CameraModel} instances */ List getCameraModels(); /** - * Returns an unmodifiable view on the list of {@link ImageModel} + * Returns an unmodifiable view on the list of {@link ImageModel} * instances that have been created for the glTF. - * + * * @return The {@link ImageModel} instances */ List getImageModels(); - + /** - * Returns an unmodifiable view on the list of {@link MaterialModel} + * Returns an unmodifiable view on the list of {@link MaterialModel} * instances that have been created for the glTF. - * + * * @return The {@link MaterialModel} instances */ List getMaterialModels(); /** - * Returns an unmodifiable view on the list of {@link MeshModel} + * Returns an unmodifiable view on the list of {@link MeshModel} * instances that have been created for the glTF. - * + * * @return The {@link MeshModel} instances */ List getMeshModels(); - + /** - * Returns an unmodifiable view on the list of {@link NodeModel} + * Returns an unmodifiable view on the list of {@link NodeModel} * instances that have been created for the glTF. - * + * * @return The {@link NodeModel} instances */ List getNodeModels(); /** - * Returns an unmodifiable view on the list of {@link SceneModel} + * Returns an unmodifiable view on the list of {@link SceneModel} * instances that have been created for the glTF. - * + * * @return The {@link SceneModel} instances */ List getSceneModels(); /** - * Returns an unmodifiable view on the list of {@link SkinModel} + * Returns an unmodifiable view on the list of {@link SkinModel} * instances that have been created for the glTF. - * + * * @return The {@link SkinModel} instances */ List getSkinModels(); /** - * Returns an unmodifiable view on the list of {@link TextureModel} + * Returns an unmodifiable view on the list of {@link TextureModel} * instances that have been created for the glTF. - * + * * @return The {@link TextureModel} instances */ List getTextureModels(); - + /** * Returns the {@link ExtensionsModel} that summarizes information * about the extensions that are used in the glTF. - * + * * @return The {@link ExtensionsModel} */ ExtensionsModel getExtensionsModel(); - + /** * Returns the {@link AssetModel} that contains information * about the asset that is represented with this model. - * + * * @return The {@link AssetModel} */ AssetModel getAssetModel(); - + } diff --git a/src/main/java/de/javagl/jgltf/model/GltfModels.java b/src/main/java/de/javagl/jgltf/model/GltfModels.java index 31daaac..25fa4e4 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfModels.java +++ b/src/main/java/de/javagl/jgltf/model/GltfModels.java @@ -35,32 +35,37 @@ /** * Methods to create {@link GltfModel} instances from a {@link GltfAsset} */ -public class GltfModels { - /** - * Private constructor to prevent instantiation - */ - private GltfModels() { - // Private constructor to prevent instantiation - } - +public class GltfModels +{ /** * Creates a {@link GltfModel} instance from the given {@link GltfAsset} - * + * * @param gltfAsset The {@link GltfAsset} * @return The {@link GltfModel} - * @throws IllegalArgumentException If the given asset has an - * unknown version + * @throws IllegalArgumentException If the given asset has an + * unknown version */ - public static GltfModel create(GltfAsset gltfAsset) { - if (gltfAsset instanceof GltfAssetV1) { - GltfAssetV1 gltfAssetV1 = (GltfAssetV1) gltfAsset; + public static GltfModel create(GltfAsset gltfAsset) + { + if (gltfAsset instanceof GltfAssetV1) + { + GltfAssetV1 gltfAssetV1 = (GltfAssetV1)gltfAsset; return new GltfModelV1(gltfAssetV1); } - if (gltfAsset instanceof GltfAssetV2) { - GltfAssetV2 gltfAssetV2 = (GltfAssetV2) gltfAsset; + if (gltfAsset instanceof GltfAssetV2) + { + GltfAssetV2 gltfAssetV2 = (GltfAssetV2)gltfAsset; return GltfModelCreatorV2.create(gltfAssetV2); } throw new IllegalArgumentException( - "The glTF asset has an unknown version: " + gltfAsset); + "The glTF asset has an unknown version: " + gltfAsset); + } + + /** + * Private constructor to prevent instantiation + */ + private GltfModels() + { + // Private constructor to prevent instantiation } } diff --git a/src/main/java/de/javagl/jgltf/model/GltfUtils.java b/src/main/java/de/javagl/jgltf/model/GltfUtils.java index 265d9d5..f24df3d 100644 --- a/src/main/java/de/javagl/jgltf/model/GltfUtils.java +++ b/src/main/java/de/javagl/jgltf/model/GltfUtils.java @@ -26,43 +26,48 @@ */ package de.javagl.jgltf.model; +import java.util.Objects; + import de.javagl.jgltf.impl.v1.Asset; import de.javagl.jgltf.impl.v1.GlTF; -import java.util.Objects; - /** * Utility methods related to {@link GlTF} instances */ -public class GltfUtils { - /** - * Private constructor to prevent instantiation - */ - private GltfUtils() { - // Private constructor to prevent instantiation - } - +public class GltfUtils +{ /** * Returns the version string that is reported by the {@link Asset} in * the given {@link GlTF}. If it does not have an {@link Asset}, or * the version string in the asset is null, then * this method will return the string "1.0.0". - * + * * @param gltf The {@link GlTF} * @return The version string */ - public static String getVersion(GlTF gltf) { + public static String getVersion(GlTF gltf) + { Objects.requireNonNull(gltf, "The gltf is null"); Asset asset = gltf.getAsset(); - if (asset == null) { + if (asset == null) + { return "1.0"; } String version = asset.getVersion(); - if (version == null) { + if (version == null) + { return "1.0"; } return version; } + + /** + * Private constructor to prevent instantiation + */ + private GltfUtils() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/ImageModel.java b/src/main/java/de/javagl/jgltf/model/ImageModel.java index b5bd8bc..9b06746 100644 --- a/src/main/java/de/javagl/jgltf/model/ImageModel.java +++ b/src/main/java/de/javagl/jgltf/model/ImageModel.java @@ -31,37 +31,38 @@ /** * Interface for an image in a glTF asset */ -public interface ImageModel extends NamedModelElement { +public interface ImageModel extends NamedModelElement +{ /** * Returns the URI of the image data (optional) - * + * * @return The URI */ String getUri(); - + /** - * Returns the MIME type of the image data that is contained in + * Returns the MIME type of the image data that is contained in * the buffer view - * + * * @return The MIME type */ String getMimeType(); - + /** * Returns the (optional) {@link BufferViewModel} that contains * the image data - * + * * @return The {@link BufferViewModel} */ BufferViewModel getBufferViewModel(); - + /** * Returns the actual image data. This will return a slice of the * buffer that is stored internally. Thus, changes to the contents - * of this buffer will affect this model, but modifications of the - * position and limit of the returned buffer will not affect this + * of this buffer will affect this model, but modifications of the + * position and limit of the returned buffer will not affect this * model.
    - * + * * @return The image data */ ByteBuffer getImageData(); diff --git a/src/main/java/de/javagl/jgltf/model/MaterialModel.java b/src/main/java/de/javagl/jgltf/model/MaterialModel.java index a5eb86d..fd6c690 100644 --- a/src/main/java/de/javagl/jgltf/model/MaterialModel.java +++ b/src/main/java/de/javagl/jgltf/model/MaterialModel.java @@ -29,6 +29,7 @@ /** * Interface for a material model */ -public interface MaterialModel extends NamedModelElement { +public interface MaterialModel extends NamedModelElement +{ // No common methods } diff --git a/src/main/java/de/javagl/jgltf/model/MathUtils.java b/src/main/java/de/javagl/jgltf/model/MathUtils.java index 03dbb9a..1e61d15 100644 --- a/src/main/java/de/javagl/jgltf/model/MathUtils.java +++ b/src/main/java/de/javagl/jgltf/model/MathUtils.java @@ -32,57 +32,53 @@ import java.util.logging.Logger; /** - * Mathematical utility methods. These methods are mainly related to - * computations on arrays that represent matrices.
    + * Mathematical utility methods. These methods are mainly related to + * computations on arrays that represent matrices.
    *
    - * Unless otherwise noted, the matrices are assumed to be in + * Unless otherwise noted, the matrices are assumed to be in * column-major order.
    *
    * Unless otherwise noted, none of the arguments to these * methods may be null.
    *
    - * Unless otherwise noted, each 4x4 matrix is assumed to have a length of - * at least 16, and each 3x3 matrix is assumed to have a length of + * Unless otherwise noted, each 4x4 matrix is assumed to have a length of + * at least 16, and each 3x3 matrix is assumed to have a length of * at least 9. Points in 3D are assumed to have a length of at least 3. - *

    + * * TODO This class should not be considered as part of the public API! */ -public class MathUtils { +public class MathUtils +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(MathUtils.class.getName()); - + private static final Logger logger = + Logger.getLogger(MathUtils.class.getName()); + /** * Epsilon for floating point computations */ private static final float FLOAT_EPSILON = 1e-8f; - - /** - * Private constructor to prevent instantiation - */ - private MathUtils() { - // Private constructor to prevent instantiation - } - + /** * Creates a 4x4 identity matrix - * + * * @return The matrix */ - public static float[] createIdentity4x4() { + public static float[] createIdentity4x4() + { float m[] = new float[16]; setIdentity4x4(m); return m; } - + /** * Set the given matrix to be the identity matrix. - * + * * @param m The matrix */ - public static void setIdentity4x4(float m[]) { + public static void setIdentity4x4(float m[]) + { Arrays.fill(m, 0.0f); m[0] = 1.0f; m[5] = 1.0f; @@ -91,60 +87,64 @@ public static void setIdentity4x4(float m[]) { } /** - * Set the given matrix to be the identity matrix. - * + * Set the given matrix to be the identity matrix. + * * @param m The matrix */ - static void setIdentity3x3(float m[]) { + static void setIdentity3x3(float m[]) + { Arrays.fill(m, 0.0f); m[0] = 1.0f; m[4] = 1.0f; m[8] = 1.0f; } - + /** - * Copy the contents of the source array to the given target array. - * The length of the shorter array will determine how many elements + * Copy the contents of the source array to the given target array. + * The length of the shorter array will determine how many elements * are copied. - * + * * @param source The source array * @param target The target array */ - static void set(float source[], float target[]) { - System.arraycopy(source, 0, target, 0, - Math.min(source.length, target.length)); + static void set(float source[], float target[]) + { + System.arraycopy(source, 0, target, 0, + Math.min(source.length, target.length)); } - + /** - * Obtains the upper 3x3 matrix (which describes the rotation- and - * scaling part of the transformation) of the given 4x4 source matrix, - * and writes it into the given target 3x3 matrix. - * + * Obtains the upper 3x3 matrix (which describes the rotation- and + * scaling part of the transformation) of the given 4x4 source matrix, + * and writes it into the given target 3x3 matrix. + * * @param sourceMatrix4x4 The source matrix * @param targetMatrix3x3 The target matrix */ public static void getRotationScale( - float sourceMatrix4x4[], float targetMatrix3x3[]) { - targetMatrix3x3[0] = sourceMatrix4x4[0]; - targetMatrix3x3[1] = sourceMatrix4x4[1]; - targetMatrix3x3[2] = sourceMatrix4x4[2]; - targetMatrix3x3[3] = sourceMatrix4x4[4]; - targetMatrix3x3[4] = sourceMatrix4x4[5]; - targetMatrix3x3[5] = sourceMatrix4x4[6]; - targetMatrix3x3[6] = sourceMatrix4x4[8]; - targetMatrix3x3[7] = sourceMatrix4x4[9]; + float sourceMatrix4x4[], float targetMatrix3x3[]) + { + targetMatrix3x3[0] = sourceMatrix4x4[ 0]; + targetMatrix3x3[1] = sourceMatrix4x4[ 1]; + targetMatrix3x3[2] = sourceMatrix4x4[ 2]; + targetMatrix3x3[3] = sourceMatrix4x4[ 4]; + targetMatrix3x3[4] = sourceMatrix4x4[ 5]; + targetMatrix3x3[5] = sourceMatrix4x4[ 6]; + targetMatrix3x3[6] = sourceMatrix4x4[ 8]; + targetMatrix3x3[7] = sourceMatrix4x4[ 9]; targetMatrix3x3[8] = sourceMatrix4x4[10]; - + } - + /** * Transpose the given matrix, and write the result into the given - * target matrix. - * + * target matrix. + * * @param m The input matrix * @param t The target matrix */ - static void transpose3x3(float m[], float t[]) { + static void transpose3x3(float m[], float t[]) + { float m0 = m[0]; float m1 = m[1]; float m2 = m[2]; @@ -164,41 +164,42 @@ static void transpose3x3(float m[], float t[]) { t[7] = m5; t[8] = m8; } - + /** * Transpose the given matrix, and write the result into the given - * target matrix. - * + * target matrix. + * * @param m The input matrix * @param t The target matrix */ - public static void transpose4x4(float m[], float t[]) { - float m0 = m[0]; - float m1 = m[1]; - float m2 = m[2]; - float m3 = m[3]; - float m4 = m[4]; - float m5 = m[5]; - float m6 = m[6]; - float m7 = m[7]; - float m8 = m[8]; - float m9 = m[9]; + public static void transpose4x4(float m[], float t[]) + { + float m0 = m[ 0]; + float m1 = m[ 1]; + float m2 = m[ 2]; + float m3 = m[ 3]; + float m4 = m[ 4]; + float m5 = m[ 5]; + float m6 = m[ 6]; + float m7 = m[ 7]; + float m8 = m[ 8]; + float m9 = m[ 9]; float mA = m[10]; float mB = m[11]; float mC = m[12]; float mD = m[13]; float mE = m[14]; float mF = m[15]; - t[0] = m0; - t[1] = m4; - t[2] = m8; - t[3] = mC; - t[4] = m1; - t[5] = m5; - t[6] = m9; - t[7] = mD; - t[8] = m2; - t[9] = m6; + t[ 0] = m0; + t[ 1] = m4; + t[ 2] = m8; + t[ 3] = mC; + t[ 4] = m1; + t[ 5] = m5; + t[ 6] = m9; + t[ 7] = mD; + t[ 8] = m2; + t[ 9] = m6; t[10] = mA; t[11] = mE; t[12] = m3; @@ -206,25 +207,26 @@ public static void transpose4x4(float m[], float t[]) { t[14] = mB; t[15] = mF; } - + /** * Fills the given result matrix with the product of the given matrices. - * + * * @param a The first matrix * @param b The second matrix * @param m The result matrix */ - public static void mul4x4(float a[], float b[], float m[]) { - float a00 = a[0]; - float a10 = a[1]; - float a20 = a[2]; - float a30 = a[3]; - float a01 = a[4]; - float a11 = a[5]; - float a21 = a[6]; - float a31 = a[7]; - float a02 = a[8]; - float a12 = a[9]; + public static void mul4x4(float a[], float b[], float m[]) + { + float a00 = a[ 0]; + float a10 = a[ 1]; + float a20 = a[ 2]; + float a30 = a[ 3]; + float a01 = a[ 4]; + float a11 = a[ 5]; + float a21 = a[ 6]; + float a31 = a[ 7]; + float a02 = a[ 8]; + float a12 = a[ 9]; float a22 = a[10]; float a32 = a[11]; float a03 = a[12]; @@ -232,16 +234,16 @@ public static void mul4x4(float a[], float b[], float m[]) { float a23 = a[14]; float a33 = a[15]; - float b00 = b[0]; - float b10 = b[1]; - float b20 = b[2]; - float b30 = b[3]; - float b01 = b[4]; - float b11 = b[5]; - float b21 = b[6]; - float b31 = b[7]; - float b02 = b[8]; - float b12 = b[9]; + float b00 = b[ 0]; + float b10 = b[ 1]; + float b20 = b[ 2]; + float b30 = b[ 3]; + float b01 = b[ 4]; + float b11 = b[ 5]; + float b21 = b[ 6]; + float b31 = b[ 7]; + float b02 = b[ 8]; + float b12 = b[ 9]; float b22 = b[10]; float b32 = b[11]; float b03 = b[12]; @@ -269,16 +271,16 @@ public static void mul4x4(float a[], float b[], float m[]) { float m32 = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32; float m33 = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33; - m[0] = m00; - m[1] = m10; - m[2] = m20; - m[3] = m30; - m[4] = m01; - m[5] = m11; - m[6] = m21; - m[7] = m31; - m[8] = m02; - m[9] = m12; + m[ 0] = m00; + m[ 1] = m10; + m[ 2] = m20; + m[ 3] = m30; + m[ 4] = m01; + m[ 5] = m11; + m[ 6] = m21; + m[ 7] = m31; + m[ 8] = m02; + m[ 9] = m12; m[10] = m22; m[11] = m32; m[12] = m03; @@ -286,33 +288,35 @@ public static void mul4x4(float a[], float b[], float m[]) { m[14] = m23; m[15] = m33; } + /** - * Fills the given matrix, with the values for the rotation that is - * described by the given quaternion. None of the arguments may be - * null. The quaternion must have at least length 4. - * + * Fills the given matrix, with the values for the rotation that is + * described by the given quaternion. None of the arguments may be + * null. The quaternion must have at least length 4. + * * @param q The quaternion * @param m The matrix */ - public static void quaternionToMatrix4x4(float q[], float m[]) { - float invLength = 1.0f / (float) Math.sqrt(dot(q, q)); + public static void quaternionToMatrix4x4(float q[], float m[]) + { + float invLength = 1.0f / (float)Math.sqrt(dot(q, q)); // Adapted from javax.vecmath.Matrix4f float qx = q[0] * invLength; float qy = q[1] * invLength; float qz = q[2] * invLength; float qw = q[3] * invLength; - m[0] = 1.0f - 2.0f * qy * qy - 2.0f * qz * qz; - m[1] = 2.0f * (qx * qy + qw * qz); - m[2] = 2.0f * (qx * qz - qw * qy); - m[3] = 0.0f; - m[4] = 2.0f * (qx * qy - qw * qz); - m[5] = 1.0f - 2.0f * qx * qx - 2.0f * qz * qz; - m[6] = 2.0f * (qy * qz + qw * qx); - m[7] = 0.0f; - m[8] = 2.0f * (qx * qz + qw * qy); - m[9] = 2.0f * (qy * qz - qw * qx); + m[ 0] = 1.0f - 2.0f * qy * qy - 2.0f * qz * qz; + m[ 1] = 2.0f * (qx * qy + qw * qz); + m[ 2] = 2.0f * (qx * qz - qw * qy); + m[ 3] = 0.0f; + m[ 4] = 2.0f * (qx * qy - qw * qz); + m[ 5] = 1.0f - 2.0f * qx * qx - 2.0f * qz * qz; + m[ 6] = 2.0f * (qy * qz + qw * qx); + m[ 7] = 0.0f; + m[ 8] = 2.0f * (qx * qz + qw * qy); + m[ 9] = 2.0f * (qy * qz - qw * qx); m[10] = 1.0f - 2.0f * qx * qx - 2.0f * qy * qy; m[11] = 0.0f; m[12] = 0.0f; @@ -320,29 +324,30 @@ public static void quaternionToMatrix4x4(float q[], float m[]) { m[14] = 0.0f; m[15] = 1.0f; } - + /** * Inverts the given matrix and writes the result into the given target - * matrix. If the given matrix is not invertible, then the target matrix - * will be set to identity. - * - * @param m The input matrix + * matrix. If the given matrix is not invertible, then the target matrix + * will be set to identity. + * + * @param m The input matrix * @param inv The inverse matrix */ - public static void invert4x4(float m[], float inv[]) { - // Adapted from The Mesa 3-D graphics library. + public static void invert4x4(float m[], float inv[]) + { + // Adapted from The Mesa 3-D graphics library. // Copyright (C) 1999-2007 Brian Paul All Rights Reserved. // Published under the MIT license (see the header of this file) - float m0 = m[0]; - float m1 = m[1]; - float m2 = m[2]; - float m3 = m[3]; - float m4 = m[4]; - float m5 = m[5]; - float m6 = m[6]; - float m7 = m[7]; - float m8 = m[8]; - float m9 = m[9]; + float m0 = m[ 0]; + float m1 = m[ 1]; + float m2 = m[ 2]; + float m3 = m[ 3]; + float m4 = m[ 4]; + float m5 = m[ 5]; + float m6 = m[ 6]; + float m7 = m[ 7]; + float m8 = m[ 8]; + float m9 = m[ 9]; float mA = m[10]; float mB = m[11]; float mC = m[12]; @@ -350,64 +355,68 @@ public static void invert4x4(float m[], float inv[]) { float mE = m[14]; float mF = m[15]; - inv[0] = m5 * mA * mF - m5 * mB * mE - m9 * m6 * mF + - m9 * m7 * mE + mD * m6 * mB - mD * m7 * mA; - inv[4] = -m4 * mA * mF + m4 * mB * mE + m8 * m6 * mF - - m8 * m7 * mE - mC * m6 * mB + mC * m7 * mA; - inv[8] = m4 * m9 * mF - m4 * mB * mD - m8 * m5 * mF + - m8 * m7 * mD + mC * m5 * mB - mC * m7 * m9; - inv[12] = -m4 * m9 * mE + m4 * mA * mD + m8 * m5 * mE - - m8 * m6 * mD - mC * m5 * mA + mC * m6 * m9; - inv[1] = -m1 * mA * mF + m1 * mB * mE + m9 * m2 * mF - - m9 * m3 * mE - mD * m2 * mB + mD * m3 * mA; - inv[5] = m0 * mA * mF - m0 * mB * mE - m8 * m2 * mF + - m8 * m3 * mE + mC * m2 * mB - mC * m3 * mA; - inv[9] = -m0 * m9 * mF + m0 * mB * mD + m8 * m1 * mF - - m8 * m3 * mD - mC * m1 * mB + mC * m3 * m9; - inv[13] = m0 * m9 * mE - m0 * mA * mD - m8 * m1 * mE + - m8 * m2 * mD + mC * m1 * mA - mC * m2 * m9; - inv[2] = m1 * m6 * mF - m1 * m7 * mE - m5 * m2 * mF + - m5 * m3 * mE + mD * m2 * m7 - mD * m3 * m6; - inv[6] = -m0 * m6 * mF + m0 * m7 * mE + m4 * m2 * mF - - m4 * m3 * mE - mC * m2 * m7 + mC * m3 * m6; - inv[10] = m0 * m5 * mF - m0 * m7 * mD - m4 * m1 * mF + - m4 * m3 * mD + mC * m1 * m7 - mC * m3 * m5; - inv[14] = -m0 * m5 * mE + m0 * m6 * mD + m4 * m1 * mE - - m4 * m2 * mD - mC * m1 * m6 + mC * m2 * m5; - inv[3] = -m1 * m6 * mB + m1 * m7 * mA + m5 * m2 * mB - - m5 * m3 * mA - m9 * m2 * m7 + m9 * m3 * m6; - inv[7] = m0 * m6 * mB - m0 * m7 * mA - m4 * m2 * mB + - m4 * m3 * mA + m8 * m2 * m7 - m8 * m3 * m6; - inv[11] = -m0 * m5 * mB + m0 * m7 * m9 + m4 * m1 * mB - - m4 * m3 * m9 - m8 * m1 * m7 + m8 * m3 * m5; - inv[15] = m0 * m5 * mA - m0 * m6 * m9 - m4 * m1 * mA + - m4 * m2 * m9 + m8 * m1 * m6 - m8 * m2 * m5; + inv[ 0] = m5 * mA * mF - m5 * mB * mE - m9 * m6 * mF + + m9 * m7 * mE + mD * m6 * mB - mD * m7 * mA; + inv[ 4] = -m4 * mA * mF + m4 * mB * mE + m8 * m6 * mF - + m8 * m7 * mE - mC * m6 * mB + mC * m7 * mA; + inv[ 8] = m4 * m9 * mF - m4 * mB * mD - m8 * m5 * mF + + m8 * m7 * mD + mC * m5 * mB - mC * m7 * m9; + inv[12] = -m4 * m9 * mE + m4 * mA * mD + m8 * m5 * mE - + m8 * m6 * mD - mC * m5 * mA + mC * m6 * m9; + inv[ 1] = -m1 * mA * mF + m1 * mB * mE + m9 * m2 * mF - + m9 * m3 * mE - mD * m2 * mB + mD * m3 * mA; + inv[ 5] = m0 * mA * mF - m0 * mB * mE - m8 * m2 * mF + + m8 * m3 * mE + mC * m2 * mB - mC * m3 * mA; + inv[ 9] = -m0 * m9 * mF + m0 * mB * mD + m8 * m1 * mF - + m8 * m3 * mD - mC * m1 * mB + mC * m3 * m9; + inv[13] = m0 * m9 * mE - m0 * mA * mD - m8 * m1 * mE + + m8 * m2 * mD + mC * m1 * mA - mC * m2 * m9; + inv[ 2] = m1 * m6 * mF - m1 * m7 * mE - m5 * m2 * mF + + m5 * m3 * mE + mD * m2 * m7 - mD * m3 * m6; + inv[ 6] = -m0 * m6 * mF + m0 * m7 * mE + m4 * m2 * mF - + m4 * m3 * mE - mC * m2 * m7 + mC * m3 * m6; + inv[10] = m0 * m5 * mF - m0 * m7 * mD - m4 * m1 * mF + + m4 * m3 * mD + mC * m1 * m7 - mC * m3 * m5; + inv[14] = -m0 * m5 * mE + m0 * m6 * mD + m4 * m1 * mE - + m4 * m2 * mD - mC * m1 * m6 + mC * m2 * m5; + inv[ 3] = -m1 * m6 * mB + m1 * m7 * mA + m5 * m2 * mB - + m5 * m3 * mA - m9 * m2 * m7 + m9 * m3 * m6; + inv[ 7] = m0 * m6 * mB - m0 * m7 * mA - m4 * m2 * mB + + m4 * m3 * mA + m8 * m2 * m7 - m8 * m3 * m6; + inv[11] = -m0 * m5 * mB + m0 * m7 * m9 + m4 * m1 * mB - + m4 * m3 * m9 - m8 * m1 * m7 + m8 * m3 * m5; + inv[15] = m0 * m5 * mA - m0 * m6 * m9 - m4 * m1 * mA + + m4 * m2 * m9 + m8 * m1 * m6 - m8 * m2 * m5; // (Ain't that pretty?) - + float det = m0 * inv[0] + m1 * inv[4] + m2 * inv[8] + m3 * inv[12]; - if (Math.abs(det) <= FLOAT_EPSILON) { - if (logger.isLoggable(Level.FINE)) { + if (Math.abs(det) <= FLOAT_EPSILON) + { + if (logger.isLoggable(Level.FINE)) + { logger.fine("Matrix is not invertible, determinant is " + det - + ", returning identity"); + + ", returning identity"); } setIdentity4x4(inv); return; } float invDet = 1.0f / det; - for (int i = 0; i < 16; i++) { + for (int i = 0; i < 16; i++) + { inv[i] *= invDet; } - } - + } + /** * Inverts the given matrix and writes the result into the given target - * matrix. If the given matrix is not invertible, then the target matrix - * will be set to identity. - * - * @param m The input matrix + * matrix. If the given matrix is not invertible, then the target matrix + * will be set to identity. + * + * @param m The input matrix * @param inv The inverse matrix */ - public static void invert3x3(float m[], float inv[]) { + public static void invert3x3(float m[], float inv[]) + { // Adapted from http://stackoverflow.com/a/18504573 float m0 = m[0]; float m1 = m[1]; @@ -419,12 +428,14 @@ public static void invert3x3(float m[], float inv[]) { float m7 = m[7]; float m8 = m[8]; float det = m0 * (m4 * m8 - m5 * m7) - - m3 * (m1 * m8 - m7 * m2) + - m6 * (m1 * m5 - m4 * m2); - if (Math.abs(det) <= FLOAT_EPSILON) { - if (logger.isLoggable(Level.FINE)) { + m3 * (m1 * m8 - m7 * m2) + + m6 * (m1 * m5 - m4 * m2); + if (Math.abs(det) <= FLOAT_EPSILON) + { + if (logger.isLoggable(Level.FINE)) + { logger.fine("Matrix is not invertible, determinant is " + det - + ", returning identity"); + + ", returning identity"); } setIdentity3x3(inv); return; @@ -438,41 +449,43 @@ public static void invert3x3(float m[], float inv[]) { inv[7] = (m1 * m6 - m0 * m7) * invDet; inv[2] = (m1 * m5 - m2 * m4) * invDet; inv[5] = (m2 * m3 - m0 * m5) * invDet; - inv[8] = (m0 * m4 - m1 * m3) * invDet; + inv[8] = (m0 * m4 - m1 * m3) * invDet; } - + /** * Writes the given matrix into the given result matrix, with the * given values added to the translation component - * - * @param m The input matrix - * @param x The x-translation - * @param y The y-translation - * @param z The z-translation + * + * @param m The input matrix + * @param x The x-translation + * @param y The y-translation + * @param z The z-translation * @param result The result matrix */ public static void translate( - float m[], float x, float y, float z, float result[]) { - set(m, result); + float m[], float x, float y, float z, float result[]) + { + set(m, result); result[12] += x; result[13] += y; result[14] += z; } - + /** - * Fill the given matrix to describe an infinite perspective projection - * with the given parameters. - * + * Fill the given matrix to describe an infinite perspective projection + * with the given parameters. + * * @param fovyDeg The Field-Of-View, in y-direction, in degrees - * @param aspect The aspect ratio - * @param zNear The z-value of the near clipping plane - * @param m The matrix to fill + * @param aspect The aspect ratio + * @param zNear The z-value of the near clipping plane + * @param m The matrix to fill */ public static void infinitePerspective4x4( - float fovyDeg, float aspect, float zNear, float m[]) { + float fovyDeg, float aspect, float zNear, float m[]) + { setIdentity4x4(m); - float fovyRad = (float) Math.toRadians(fovyDeg); - float t = (float) Math.tan(0.5 * fovyRad); + float fovyRad = (float)Math.toRadians(fovyDeg); + float t = (float)Math.tan(0.5 * fovyRad); m[0] = 1.0f / (aspect * t); m[5] = 1.0f / t; m[10] = -1.0f; @@ -480,22 +493,23 @@ public static void infinitePerspective4x4( m[14] = 2.0f * zNear; m[15] = 0.0f; } - + /** * Fill the given matrix to describe a perspective projection with the - * given parameters. - * + * given parameters. + * * @param fovyDeg The Field-Of-View, in y-direction, in degrees - * @param aspect The aspect ratio - * @param zNear The z-value of the near clipping plane - * @param zFar The z-value of the far clipping plane - * @param m The matrix to fill + * @param aspect The aspect ratio + * @param zNear The z-value of the near clipping plane + * @param zFar The z-value of the far clipping plane + * @param m The matrix to fill */ public static void perspective4x4( - float fovyDeg, float aspect, float zNear, float zFar, float m[]) { + float fovyDeg, float aspect, float zNear, float zFar, float m[]) + { setIdentity4x4(m); - float fovyRad = (float) Math.toRadians(fovyDeg); - float t = (float) Math.tan(0.5 * fovyRad); + float fovyRad = (float)Math.toRadians(fovyDeg); + float t = (float)Math.tan(0.5 * fovyRad); m[0] = 1.0f / (aspect * t); m[5] = 1.0f / t; m[10] = (zFar + zNear) / (zNear - zFar); @@ -503,37 +517,44 @@ public static void perspective4x4( m[14] = 2.0f * zFar * zNear / (zNear - zFar); m[15] = 0.0f; } - + + /** - * Computes the dot product of the given arrays. The arrays must have + * Computes the dot product of the given arrays. The arrays must have * equal length. - * + * * @param a The first array * @param b The second array * @return The dot product */ - private static float dot(float a[], float b[]) { + private static float dot(float a[], float b[]) + { float sum = 0; - for (int i = 0; i < a.length; i++) { + for (int i=0; inull. If it is not null, * then it must either have 3x3 elements or 4x4 elements. - * + * * @param array The array * @return The string representation */ - public static String createMatrixString(float array[]) { - if (array == null) { + public static String createMatrixString(float array[]) + { + if (array == null) + { return "null"; } - if (array.length == 9) { + if (array.length == 9) + { return createMatrixString(array, 3, 3); } - if (array.length == 16) { + if (array.length == 16) + { return createMatrixString(array, 4, 4); } - return "WARNING: Not a matrix: " + Arrays.toString(array); + return "WARNING: Not a matrix: "+Arrays.toString(array); } - + /** * Creates a string representation of the given matrix, which is given * in column-major order - * + * * @param array The array storing the matrix - * @param rows The number of rows - * @param cols The number of columns + * @param rows The number of rows + * @param cols The number of columns * @return The string representation */ - private static String createMatrixString(float array[], int rows, int cols) { + private static String createMatrixString(float array[], int rows, int cols) + { StringBuilder sb = new StringBuilder(); - for (int r = 0; r < rows; r++) { - for (int c = 0; c < cols; c++) { + for (int r=0; rnull. If it is not null, * then it must either have 3x3 elements or 4x4 elements.
    *
    - * The individual elements of the matrix will be formatted (in an + * The individual elements of the matrix will be formatted (in an * unspecified way) so that the matrix entries are aligned. - * + * * @param array The array * @return The string representation */ - public static String createFormattedMatrixString(float array[]) { - if (array == null) { + public static String createFormattedMatrixString(float array[]) + { + if (array == null) + { return "null"; } String format = "%10.5f "; - if (array.length == 9) { + if (array.length == 9) + { return createFormattedMatrixString(array, 3, 3, format); } - if (array.length == 16) { + if (array.length == 16) + { return createFormattedMatrixString(array, 4, 4, format); } - return "WARNING: Not a matrix: " + Arrays.toString(array); + return "WARNING: Not a matrix: "+Arrays.toString(array); } - + /** * Creates a string representation of the given matrix, which is given * in column-major order. The elements of the matrix will be formatted * with the given string. - * - * @param array The array storing the matrix - * @param rows The number of rows - * @param cols The number of columns + * + * @param array The array storing the matrix + * @param rows The number of rows + * @param cols The number of columns * @param format The format string * @return The string representation */ private static String createFormattedMatrixString( - float array[], int rows, int cols, String format) { + float array[], int rows, int cols, String format) + { StringBuilder sb = new StringBuilder(); - for (int r = 0; r < rows; r++) { - for (int c = 0; c < cols; c++) { + for (int r = 0; r < rows; r++) + { + for (int c = 0; c < cols; c++) + { sb.append(String.format( - Locale.ENGLISH, format, array[r + c * cols])); + Locale.ENGLISH, format, array[r + c * cols])); } sb.append("\n"); } return sb.toString(); } + /** - * Computes a0-a1, and stores the result in the given array. - *

    - * This assumes that the given arrays are non-null - * and have equal lengths. - * - * @param a0 The first array - * @param a1 The second array - * @param result The array that stores the result - */ - public static void subtract(float[] a0, float[] a1, float[] result) { - for (int i = 0; i < a0.length; i++) { - result[i] = a0[i] - a1[i]; - } - } - - /** - * Computes the cross product of a0 and a1, and stores the result in - * the given array. - *

    - * This assumes that the given arrays are non-null - * and have length 3. - * - * @param a0 The first array - * @param a1 The second array - * @param result The array that stores the result - */ - public static void cross(float a0[], float a1[], float result[]) { - result[0] = a0[1] * a1[2] - a0[2] * a1[1]; - result[1] = a0[2] * a1[0] - a0[0] * a1[2]; - result[2] = a0[0] * a1[1] - a0[1] * a1[0]; - } - - /** - * Compute the length of the given vector - * - * @param a The vector - * @return The length - */ - public static float computeLength(float a[]) { - float sum = 0; - for (int i = 0; i < a.length; i++) { - sum += a[i] * a[i]; - } - float r = (float) Math.sqrt(sum); - return r; - } - - /** - * Normalizes the given array, and stores the result in the given array. - *

    - * This assumes that the given arrays are non-null - * and have the same length. - * - * @param a The array - * @param result The array that stores the result - */ - public static void normalize(float a[], float result[]) { - float scaling = 1.0f / computeLength(a); - scale(a, scaling, result); - } - - /** - * Scales the given vector with the given factor, and stores the result - * in the given array. - *

    - * This assumes that the given arrays are non-null - * and have equal lengths. - * - * @param a The vector - * @param factor The scaling factor - * @param result The array that will store the result + * Private constructor to prevent instantiation */ - public static void scale(float a[], float factor, float result[]) { - for (int i = 0; i < a.length; i++) { - result[i] = a[i] * factor; - } + private MathUtils() + { + // Private constructor to prevent instantiation } + + + /** + * Computes a0-a1, and stores the result in the given array. + * + * This assumes that the given arrays are non-null + * and have equal lengths. + * + * @param a0 The first array + * @param a1 The second array + * @param result The array that stores the result + */ + public static void subtract(float[] a0, float[] a1, float[] result) + { + for (int i = 0; i < a0.length; i++) + { + result[i] = a0[i] - a1[i]; + } + } + + /** + * Computes the cross product of a0 and a1, and stores the result in + * the given array. + * + * This assumes that the given arrays are non-null + * and have length 3. + * + * @param a0 The first array + * @param a1 The second array + * @param result The array that stores the result + */ + public static void cross(float a0[], float a1[], float result[]) + { + result[0] = a0[1] * a1[2] - a0[2] * a1[1]; + result[1] = a0[2] * a1[0] - a0[0] * a1[2]; + result[2] = a0[0] * a1[1] - a0[1] * a1[0]; + } + + /** + * Compute the length of the given vector + * + * @param a The vector + * @return The length + */ + public static float computeLength(float a[]) + { + float sum = 0; + for (int i=0; inull + * and have the same length. + * + * @param a The array + * @param result The array that stores the result + */ + public static void normalize(float a[], float result[]) + { + float scaling = 1.0f / computeLength(a); + scale(a, scaling, result); + } + + /** + * Scales the given vector with the given factor, and stores the result + * in the given array. + * + * This assumes that the given arrays are non-null + * and have equal lengths. + * + * @param a The vector + * @param factor The scaling factor + * @param result The array that will store the result + */ + public static void scale(float a[], float factor, float result[]) + { + for (int i = 0; i < a.length; i++) + { + result[i] = a[i] * factor; + } + } } diff --git a/src/main/java/de/javagl/jgltf/model/MeshModel.java b/src/main/java/de/javagl/jgltf/model/MeshModel.java index d1b6c87..4f5c3b2 100644 --- a/src/main/java/de/javagl/jgltf/model/MeshModel.java +++ b/src/main/java/de/javagl/jgltf/model/MeshModel.java @@ -31,20 +31,21 @@ /** * Interface for a mesh that is part of a glTF asset */ -public interface MeshModel extends NamedModelElement { +public interface MeshModel extends NamedModelElement +{ /** * Returns an unmodifiable view on the {@link MeshPrimitiveModel} objects * that this mesh consists of - * + * * @return The {@link MeshPrimitiveModel} objects */ List getMeshPrimitiveModels(); - + /** - * Returns a reference to the default morph target weights, - * or null if no default morph target weights have + * Returns a reference to the default morph target weights, + * or null if no default morph target weights have * been defined - * + * * @return The morph target weights */ float[] getWeights(); diff --git a/src/main/java/de/javagl/jgltf/model/MeshPrimitiveModel.java b/src/main/java/de/javagl/jgltf/model/MeshPrimitiveModel.java index 476d855..74bcebd 100644 --- a/src/main/java/de/javagl/jgltf/model/MeshPrimitiveModel.java +++ b/src/main/java/de/javagl/jgltf/model/MeshPrimitiveModel.java @@ -32,44 +32,45 @@ /** * Interface for a primitive that is part of a mesh */ -public interface MeshPrimitiveModel extends ModelElement { +public interface MeshPrimitiveModel extends ModelElement +{ /** * Returns an unmodifiable view on the mapping from attribute names to * the {@link AccessorModel} instances for the attribute data - * + * * @return The attributes mapping */ Map getAttributes(); - + /** * Return an {@link AccessorModel} for the indices, or null * if this primitive describes non-indexed geometry - * - * @return The indices + * + * @return The indices */ AccessorModel getIndices(); - + /** * Returns the rendering mode, as a (GL) constant, standing for * GL_POINTS, GL_TRIANGLES etc. - * + * * @return The rendering mode */ int getMode(); - + /** * Returns the {@link MaterialModel} that should be used for rendering * this mesh primitive - * + * * @return The {@link MaterialModel} */ MaterialModel getMaterialModel(); - + /** * Returns an unmodifiable view on the list of morph targets. Each element * of this list will be an unmodifiable map. Each map maps the attribute * name to the {@link AccessorModel} that provides the morph target data. - * + * * @return The morph targets */ List> getTargets(); diff --git a/src/main/java/de/javagl/jgltf/model/ModelElement.java b/src/main/java/de/javagl/jgltf/model/ModelElement.java index 8924d1f..43c1a45 100644 --- a/src/main/java/de/javagl/jgltf/model/ModelElement.java +++ b/src/main/java/de/javagl/jgltf/model/ModelElement.java @@ -32,18 +32,19 @@ * Interface for all classes of the model package. This is corresponds to * the GlTFProperty of the original glTF asset. */ -public interface ModelElement { +public interface ModelElement +{ /** * Returns the extensions of this element. This is a mapping from * property names to the JSON objects. - * + * * @return The extensions */ Map getExtensions(); - + /** - * Returns the extras of this element. - * + * Returns the extras of this element. + * * @return The extras */ Object getExtras(); diff --git a/src/main/java/de/javagl/jgltf/model/NamedModelElement.java b/src/main/java/de/javagl/jgltf/model/NamedModelElement.java index 765e9b5..1870a6c 100644 --- a/src/main/java/de/javagl/jgltf/model/NamedModelElement.java +++ b/src/main/java/de/javagl/jgltf/model/NamedModelElement.java @@ -31,11 +31,12 @@ * This is the name that was given to the GlTFChildOfRootProperty * of the original glTF asset. */ -public interface NamedModelElement extends ModelElement { +public interface NamedModelElement extends ModelElement +{ /** * Returns the name of this element, or null if this element * does not have an associated name. - * + * * @return The optional name */ String getName(); diff --git a/src/main/java/de/javagl/jgltf/model/NodeModel.java b/src/main/java/de/javagl/jgltf/model/NodeModel.java index e4f2034..a8fc11b 100644 --- a/src/main/java/de/javagl/jgltf/model/NodeModel.java +++ b/src/main/java/de/javagl/jgltf/model/NodeModel.java @@ -32,26 +32,27 @@ /** * Interface for a node that is part of a scene hierarchy */ -public interface NodeModel extends NamedModelElement { +public interface NodeModel extends NamedModelElement +{ /** * Returns the parent of this node, or null if this is * a root node - * + * * @return The parent */ NodeModel getParent(); /** * Returns an unmodifiable view on the list of children of this node - * + * * @return The children */ List getChildren(); - + /** * Returns an unmodifiable view on the list of {@link MeshModel} instances * that are attached to this node. - * + * * @return The {@link MeshModel} list */ List getMeshModels(); @@ -59,124 +60,124 @@ public interface NodeModel extends NamedModelElement { /** * Returns the {@link SkinModel} for this node, or null if * this node is not associated with a skin - * + * * @return The {@link SkinModel} */ SkinModel getSkinModel(); - + /** * Returns the {@link CameraModel} for this node, or null if * this node is not associated with a camera - * + * * @return The {@link CameraModel} */ CameraModel getCameraModel(); - - /** - * Returns a reference to the array storing the matrix of this node. - * This is a 16-element array containing the matrix in column-major order, - * or null if no matrix was set. - * - * @return The matrix - */ - float[] getMatrix(); - + /** * Set the matrix of this node to be a reference to the given * array.
    *
    - * The matrix is assumed to be a 16-element array containing the matrix - * in column-major order. If the given matrix is null, then + * The matrix is assumed to be a 16-element array containing the matrix + * in column-major order. If the given matrix is null, then * the {@link #getTranslation() translation}, * {@link #getRotation() rotation}, and - * {@link #getScale() scale} properties will be used for determining the + * {@link #getScale() scale} properties will be used for determining the * local transform. - * + * * @param matrix The matrix * @throws IllegalArgumentException If the given array does not have - * a length of 16 + * a length of 16 */ void setMatrix(float matrix[]); - + /** - * Returns a reference to the array storing the translation of this - * node, or null if no translation was set. - * - * @return The translation + * Returns a reference to the array storing the matrix of this node. + * This is a 16-element array containing the matrix in column-major order, + * or null if no matrix was set. + * + * @return The matrix */ - float[] getTranslation(); + float[] getMatrix(); /** * Set the translation of this node to be a reference to the given - * array. - * + * array. + * * @param translation The translation * @throws IllegalArgumentException If the given array does not have - * a length of 3 + * a length of 3 */ void setTranslation(float translation[]); - + /** - * Returns a reference to the array storing the rotation of this - * node, or null if no rotation was set - * - * @return The rotation + * Returns a reference to the array storing the translation of this + * node, or null if no translation was set. + * + * @return The translation */ - float[] getRotation(); + float[] getTranslation(); /** * Set the rotation of this node to be a reference to the given * array. The array is assumed to be a quaternion, consisting of 4 * float elements. - * + * * @param rotation The rotation * @throws IllegalArgumentException If the given array does not have - * a length of 4 + * a length of 4 */ void setRotation(float rotation[]); - + /** - * Returns a reference to the array storing the scale of this - * node, or null if no scale was set - * - * @return The scale + * Returns a reference to the array storing the rotation of this + * node, or null if no rotation was set + * + * @return The rotation */ - float[] getScale(); + float[] getRotation(); /** * Set the scale of this node to be a reference to the given * array. - * + * * @param scale The scale * @throws IllegalArgumentException If the given array does not have - * a length of 3 + * a length of 3 */ void setScale(float scale[]); /** - * Returns a reference to the morph target weights, - * or null if no morph target weights have been defined - * - * @return The morph target weights + * Returns a reference to the array storing the scale of this + * node, or null if no scale was set + * + * @return The scale */ - float[] getWeights(); - + float[] getScale(); + /** * Set the morph target weights to be a reference to the given - * array. - * + * array. + * * @param weights The weights */ void setWeights(float weights[]); - + + /** + * Returns a reference to the morph target weights, + * or null if no morph target weights have been defined + * + * @return The morph target weights + */ + float[] getWeights(); + /** * Computes the local transform of this node.
    *
    - * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * * @param result The result array * @return The result array */ @@ -185,39 +186,39 @@ public interface NodeModel extends NamedModelElement { /** * Computes the global transform of this node.
    *
    - * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * * @param result The result array * @return The result array */ float[] computeGlobalTransform(float result[]); /** - * Creates a supplier for the global transform matrix of this node + * Creates a supplier for the global transform matrix of this node * model.
    - *
    - * The matrix will be provided as a float array with 16 elements, + *
    + * The matrix will be provided as a float array with 16 elements, * storing the matrix entries in column-major order.
    *
    * Note: The supplier MAY always return the same array instance. - * Callers MUST NOT store or modify the returned array. - * + * Callers MUST NOT store or modify the returned array. + * * @return The supplier */ Supplier createGlobalTransformSupplier(); /** * Creates a supplier for the local transform matrix of this node model.
    - *
    - * The matrix will be provided as a float array with 16 elements, + *
    + * The matrix will be provided as a float array with 16 elements, * storing the matrix entries in column-major order.
    *
    * Note: The supplier MAY always return the same array instance. - * Callers MUST NOT store or modify the returned array. - * + * Callers MUST NOT store or modify the returned array. + * * @return The supplier */ Supplier createLocalTransformSupplier(); diff --git a/src/main/java/de/javagl/jgltf/model/NumberArrays.java b/src/main/java/de/javagl/jgltf/model/NumberArrays.java index dd2da19..45ec126 100644 --- a/src/main/java/de/javagl/jgltf/model/NumberArrays.java +++ b/src/main/java/de/javagl/jgltf/model/NumberArrays.java @@ -29,53 +29,62 @@ /** * Methods to convert primitive arrays to arrays of Number objects */ -class NumberArrays { - /** - * Private constructor to prevent instantiation - */ - private NumberArrays() { - // Private constructor to prevent instantiation - } - +class NumberArrays +{ /** * Convert the given array into a Number array - * + * * @param array The array * @return The result */ - static Number[] asNumbers(int array[]) { + static Number[] asNumbers(int array[]) + { Number result[] = new Number[array.length]; - for (int i = 0; i < array.length; i++) { + for (int i = 0; i < array.length; i++) + { result[i] = array[i]; } return result; - } + } /** * Convert the given array into a Number array - * + * * @param array The array * @return The result */ - static Number[] asNumbers(long array[]) { + static Number[] asNumbers(long array[]) + { Number result[] = new Number[array.length]; - for (int i = 0; i < array.length; i++) { + for (int i = 0; i < array.length; i++) + { result[i] = array[i]; } return result; } - + /** * Convert the given array into a Number array - * + * * @param array The array * @return The result */ - static Number[] asNumbers(float array[]) { + static Number[] asNumbers(float array[]) + { Number result[] = new Number[array.length]; - for (int i = 0; i < array.length; i++) { + for (int i = 0; i < array.length; i++) + { result[i] = array[i]; } return result; } + + + /** + * Private constructor to prevent instantiation + */ + private NumberArrays() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/Optionals.java b/src/main/java/de/javagl/jgltf/model/Optionals.java index 72b3a43..d7a8d67 100644 --- a/src/main/java/de/javagl/jgltf/model/Optionals.java +++ b/src/main/java/de/javagl/jgltf/model/Optionals.java @@ -32,137 +32,160 @@ /** * Utility methods related to values that are optional. These values may - * be null, and the utility methods will provide default - * values in this case. + * be null, and the utility methods will provide default + * values in this case. */ -public class Optionals { - /** - * Private constructor to prevent instantiation - */ - private Optionals() { - // Private constructor to prevent instantiation - } - +public class Optionals +{ /** * Returns the given list, or an unmodifiable empty list if the * given list is null. - * - * @param The element type + * + * @param The element type + * * @param list The list * @return The result */ - public static List of(List list) { + public static List of(List list) + { return of(list, Collections.emptyList()); } - + /** * Returns the specified element from the given list, or null * if the list is null or the index is not valid. - * - * @param The element type - * @param list The list + * + * @param The element type + * + * @param list The list * @param index The index * @return The element */ - public static T get(List list, int index) { - if (list == null) { + public static T get(List list, int index) + { + if (list == null) + { return null; } - if (index < 0) { + if (index < 0) + { return null; } - if (index >= list.size()) { + if (index >= list.size()) + { return null; } return list.get(index); } - + /** * Returns the given map, or an unmodifiable empty map if the * given map is null. - * + * * @param The key type * @param The value type + * * @param map The map * @return The result */ - public static Map of(Map map) { - return of(map, Collections.emptyMap()); + public static Map of(Map map) + { + return of (map, Collections.emptyMap()); } - + /** * Returns the given value, or the default value if the given value * is null. - * - * @param The value type - * @param value The value + * + * @param The value type + * + * @param value The value * @param defaultValue The default value * @return The result */ - public static T of(T value, T defaultValue) { + public static T of(T value, T defaultValue) + { return value != null ? value : defaultValue; } - + /** * Returns the value that is associated with the given key in the * given map, or null if either the key or the map * is null. - * + * * @param The value type + * * @param key The key * @param map The map * @return The value */ - public static V get(Object key, Map map) { - if (key == null) { + public static V get(Object key, Map map) + { + if (key == null) + { return null; } - if (map == null) { + if (map == null) + { return null; } return map.get(key); } - + /** * Returns a clone of the given array, or null if the * given array is null - * + * * @param array The array * @return The result */ - public static float[] clone(float array[]) { - if (array == null) { + public static float[] clone(float array[]) + { + if (array == null) + { return null; } return array.clone(); } - + /** * Returns a clone of the given array, or null if the * given array is null - * + * * @param array The array * @return The result */ - public static int[] clone(int array[]) { - if (array == null) { + public static int[] clone(int array[]) + { + if (array == null) + { return null; } return array.clone(); } - + /** * Returns a clone of the given array, or null if the * given array is null - * + * * @param array The array * @return The result */ - public static boolean[] clone(boolean array[]) { - if (array == null) { + public static boolean[] clone(boolean array[]) + { + if (array == null) + { return null; } return array.clone(); } - + + /** + * Private constructor to prevent instantiation + */ + private Optionals() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/SceneModel.java b/src/main/java/de/javagl/jgltf/model/SceneModel.java index bfeaf55..ebf3cae 100644 --- a/src/main/java/de/javagl/jgltf/model/SceneModel.java +++ b/src/main/java/de/javagl/jgltf/model/SceneModel.java @@ -31,11 +31,12 @@ /** * Interface for a scene that was read from a glTF asset */ -public interface SceneModel extends NamedModelElement { +public interface SceneModel extends NamedModelElement +{ /** - * Returns an unmodifiable view on the the list of all root + * Returns an unmodifiable view on the the list of all root * {@link NodeModel} instances of the scene - * + * * @return The {@link NodeModel} instances */ List getNodeModels(); diff --git a/src/main/java/de/javagl/jgltf/model/SkinModel.java b/src/main/java/de/javagl/jgltf/model/SkinModel.java index f464673..e21138d 100644 --- a/src/main/java/de/javagl/jgltf/model/SkinModel.java +++ b/src/main/java/de/javagl/jgltf/model/SkinModel.java @@ -31,53 +31,54 @@ /** * Interface for a skin of a glTF asset */ -public interface SkinModel extends NamedModelElement { +public interface SkinModel extends NamedModelElement +{ /** * Provides the bind shape matrix of the skin.
    *
    - * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * * @param result The result array * @return The result array */ float[] getBindShapeMatrix(float result[]); - + /** * Returns an unmodifiable list containing the joint nodes of the skeleton - * + * * @return The joint nodes */ List getJoints(); - + /** * Returns the skeleton root node. If the return value is null, - * then joint transforms refer to the scene root. - * + * then joint transforms refer to the scene root. + * * @return The skeleton node */ NodeModel getSkeleton(); - + /** - * Returns the {@link AccessorModel} that provides the data for the + * Returns the {@link AccessorModel} that provides the data for the * inverse bind matrices, one for each {@link #getJoints() joint} - * + * * @return The inverse bind matrices accessor */ AccessorModel getInverseBindMatrices(); - + /** * Convenience function to obtain the inverse bind matrix for the joint * with the given index.
    *
    - * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * - * @param index The index of the joint + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * + * @param index The index of the joint * @param result The result array * @return The result array */ diff --git a/src/main/java/de/javagl/jgltf/model/Suppliers.java b/src/main/java/de/javagl/jgltf/model/Suppliers.java index 8219d61..779d987 100644 --- a/src/main/java/de/javagl/jgltf/model/Suppliers.java +++ b/src/main/java/de/javagl/jgltf/model/Suppliers.java @@ -32,34 +32,31 @@ /** * Utility methods to create Supplier instances */ -public class Suppliers { +public class Suppliers +{ /** - * Private constructor to prevent instantiation - */ - private Suppliers() { - // Private constructor to prevent instantiation - } - - /** - * Create a supplier of a 4x4 matrix that is computed by applying + * Create a supplier of a 4x4 matrix that is computed by applying * the given computer to the given object and a 16-element array.
    *
    - * If the given object is null, then the identity + * If the given object is null, then the identity * matrix will be supplied.
    *
    * Note: The supplier MAY always return the same array instance. * Callers MUST NOT store or modify the returned array. - * - * @param The object type - * @param object The object + * + * @param The object type + * + * @param object The object * @param computer The computer function * @return The supplier */ public static Supplier createTransformSupplier( - T object, BiConsumer computer) { + T object, BiConsumer computer) + { float transform[] = new float[16]; - if (object == null) { - return () -> + if (object == null) + { + return () -> { MathUtils.setIdentity4x4(transform); return transform; @@ -71,4 +68,13 @@ public static Supplier createTransformSupplier( return transform; }; } + + + /** + * Private constructor to prevent instantiation + */ + private Suppliers() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/TextureModel.java b/src/main/java/de/javagl/jgltf/model/TextureModel.java index 863dc6e..986d464 100644 --- a/src/main/java/de/javagl/jgltf/model/TextureModel.java +++ b/src/main/java/de/javagl/jgltf/model/TextureModel.java @@ -29,38 +29,39 @@ /** * Interface for a texture in a glTF asset */ -public interface TextureModel extends NamedModelElement { +public interface TextureModel extends NamedModelElement +{ /** * Return the magnification filter constant - * + * * @return The constant */ Integer getMagFilter(); /** * Return the minification filter constant - * + * * @return The constant */ Integer getMinFilter(); /** * Return the wrapping constant for S-direction - * + * * @return The constant */ Integer getWrapS(); /** * Return the wrapping constant for T-direction - * + * * @return The constant */ Integer getWrapT(); - + /** * Returns the {@link ImageModel} that backs this texture - * + * * @return The {@link ImageModel} */ ImageModel getImageModel(); diff --git a/src/main/java/de/javagl/jgltf/model/Utils.java b/src/main/java/de/javagl/jgltf/model/Utils.java index fa5f375..74a403b 100644 --- a/src/main/java/de/javagl/jgltf/model/Utils.java +++ b/src/main/java/de/javagl/jgltf/model/Utils.java @@ -29,28 +29,32 @@ /** * Utility methods. These should not be considered as part of the public API. */ -public class Utils { - /** - * Private constructor to prevent instantiation - */ - private Utils() { - // Private constructor to prevent instantiation - } - +public class Utils +{ /** * Validate that the given array is not null and has the * given length. If this is not the case, return a new array with the * specified length. - * - * @param array The array + * + * @param array The array * @param length The length * @return The array, or a new array with the desired length */ - public static float[] validate(float array[], int length) { - if (array != null && array.length == length) { + public static float[] validate(float array[], int length) + { + if (array != null && array.length == length) + { return array; } return new float[length]; } + /** + * Private constructor to prevent instantiation + */ + private Utils() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/animation/Animation.java b/src/main/java/de/javagl/jgltf/model/animation/Animation.java index 3782bdf..0382473 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/Animation.java +++ b/src/main/java/de/javagl/jgltf/model/animation/Animation.java @@ -32,137 +32,148 @@ /** * A class representing a generic animation. The animation consists of - * a mapping between time key frames and values, and allows - * {@link AnimationListener}s to be informed about the progress of the - * animation, including the current time and the (interpolated) values + * a mapping between time key frames and values, and allows + * {@link AnimationListener}s to be informed about the progress of the + * animation, including the current time and the (interpolated) values * for this time point. */ -public final class Animation { +public final class Animation +{ /** * The key frame times, in seconds */ private final float timesS[]; - + /** * The values. Each element of this array corresponds to one key * frame time */ private final float values[][]; - + /** * The interpolator for the values */ private final Interpolator interpolator; - + /** * A pre-allocated array of the output values that will be passed * to the listeners. The listeners are not allowed to store or * modify this array. */ private final float outputValues[]; - + /** * The {@link AnimationListener}s that are informed about the progress * of this animation */ private final List listeners; - + /** - * Creates a new animation with the given time key frames and the + * Creates a new animation with the given time key frames and the * corresponding values. - * - * @param timesS The time key frames, in seconds - * @param values The values. Each element of this array consists of the - * values for the corresponding key frame time. + * + * @param timesS The time key frames, in seconds + * @param values The values. Each element of this array consists of the + * values for the corresponding key frame time. * @param interpolatorType The {@link InterpolatorType} that will be - * used for interpolating the values - * @throws NullPointerException If either of the given parameters is - * null, or the given values array contains null - * elements + * used for interpolating the values + * @throws NullPointerException If either of the given parameters is + * null, or the given values array contains null + * elements * @throws IllegalArgumentException If any of the given arrays has a - * length of 0 + * length of 0 * @throws IllegalArgumentException If any of the given values arrays - * has a length that is different from the length of the times array. + * has a length that is different from the length of the times array. */ public Animation( - float timesS[], - float values[][], - InterpolatorType interpolatorType) { + float timesS[], + float values[][], + InterpolatorType interpolatorType) + { Objects.requireNonNull(timesS, "The times may not be null"); Objects.requireNonNull(values, "The values may not be null"); - if (timesS.length == 0) { + if (timesS.length == 0) + { throw new IllegalArgumentException( - "The keys may not have a length of 0"); + "The keys may not have a length of 0"); } - if (values.length != timesS.length) { + if (values.length != timesS.length) + { throw new IllegalArgumentException( - "The values must have a length of " + timesS.length + ", " + - "but have a length of " + values.length); + "The values must have a length of "+timesS.length+", " + + "but have a length of "+values.length); } this.timesS = timesS.clone(); this.values = new float[values.length][]; - for (int i = 0; i < values.length; i++) { + for (int i=0; i(); } - + /** * Returns the start time of this animation, in seconds - * + * * @return The start time */ - float getStartTimeS() { + float getStartTimeS() + { return timesS[0]; } - + /** * Returns the end time of this animation, in seconds - * + * * @return The end time */ - float getEndTimeS() { - return timesS[timesS.length - 1]; + float getEndTimeS() + { + return timesS[timesS.length-1]; } - + /** * Returns the duration of this animation, in seconds - * + * * @return The duration */ - float getDurationS() { + float getDurationS() + { return getEndTimeS() - getStartTimeS(); } - + /** * Add the given {@link AnimationListener} to be informed about any * progress in this animation - * + * * @param listener The listener to add */ - public void addAnimationListener(AnimationListener listener) { + public void addAnimationListener(AnimationListener listener) + { listeners.add(listener); } /** - * Remove the given {@link AnimationListener} - * + * Remove the given {@link AnimationListener} + * * @param listener The listener to remove */ - public void removeAnimationListener(AnimationListener listener) { + public void removeAnimationListener(AnimationListener listener) + { listeners.remove(listener); } - + /** * Package-private method to update this animation based on the given time, * and inform all registered listeners. - * + * * @param timeS The time, in seconds */ - void update(float timeS) { + void update(float timeS) + { int index0 = InterpolatorKeys.computeIndex(timeS, timesS); int index1 = Math.min(timesS.length - 1, index0 + 1); float alpha = InterpolatorKeys.computeAlpha(timeS, timesS, index0); @@ -171,13 +182,14 @@ void update(float timeS) { //System.out.println("index0 "+index0); //System.out.println("index1 "+index1); //System.out.println("alpha "+alpha); - + float a[] = values[index0]; float b[] = values[index1]; interpolator.interpolate(a, b, alpha, outputValues); - for (AnimationListener listener : listeners) { + for (AnimationListener listener : listeners) + { listener.animationUpdated(this, timeS, outputValues); } } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/animation/AnimationListener.java b/src/main/java/de/javagl/jgltf/model/animation/AnimationListener.java index fb65eaf..d6e9f5c 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/AnimationListener.java +++ b/src/main/java/de/javagl/jgltf/model/animation/AnimationListener.java @@ -30,18 +30,19 @@ * Interface for classes that want to be informed about the progress * of an {@link Animation} */ -public interface AnimationListener { +public interface AnimationListener +{ /** * Will be called when the given {@link Animation} was updated.
    *
    * Note: The given array of interpolated output values MAY * be reused for multiple calls. Implementors of this method MUST NOT * store or modify the given array. - * + * * @param source The source {@link Animation} - * @param timeS The time, in seconds + * @param timeS The time, in seconds * @param values The interpolated values for the given time */ void animationUpdated( - Animation source, float timeS, float values[]); + Animation source, float timeS, float values[]); } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/animation/AnimationManager.java b/src/main/java/de/javagl/jgltf/model/animation/AnimationManager.java index b6c710f..3d70c3c 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/AnimationManager.java +++ b/src/main/java/de/javagl/jgltf/model/animation/AnimationManager.java @@ -32,222 +32,256 @@ import java.util.concurrent.CopyOnWriteArrayList; /** - * A class that manages several {@link Animation} instances, and dispatches + * A class that manages several {@link Animation} instances, and dispatches * any updates in the (global) time to these animations. */ -public final class AnimationManager { +public final class AnimationManager +{ /** - * The {@link AnimationPolicy} - */ - private final AnimationPolicy animationPolicy; - /** - * The list of {@link Animation} instances maintained by this manager + * A policy describing how the animations should be executed */ - private final List animations; + public enum AnimationPolicy + { + /** + * Indicates that the animations should be executed only + * once, and then removed from the {@link AnimationManager} + */ + ONCE, + + /** + * Indicates that the animations should be executed in + * a ping-pong fashion + */ + PING_PONG, + + /** + * Indicates that the animations should be looped + */ + LOOP + } + /** - * The list of {@link AnimationManagerListener}s that want to be - * informed about changes in this manager + * The {@link AnimationPolicy} */ - private final List animationManagerListeners; + private final AnimationPolicy animationPolicy; + /** * The start time, in nanoseconds */ private long startNs; + /** * The current time, in nanoseconds */ private long currentNs; + + /** + * The list of {@link Animation} instances maintained by this manager + */ + private final List animations; + /** * The maximum {@link Animation#getEndTimeS()} of all animations */ private float maxEndTimeS; - + + /** + * The list of {@link AnimationManagerListener}s that want to be + * informed about changes in this manager + */ + private final List animationManagerListeners; + /** * Creates a new, empty animation manager - * + * * @param animationPolicy The {@link AnimationPolicy} */ - public AnimationManager(AnimationPolicy animationPolicy) { + public AnimationManager(AnimationPolicy animationPolicy) + { this.animationPolicy = animationPolicy; this.startNs = System.nanoTime(); this.currentNs = startNs; this.animations = new CopyOnWriteArrayList(); this.maxEndTimeS = 0.0f; - this.animationManagerListeners = - new CopyOnWriteArrayList(); + this.animationManagerListeners = + new CopyOnWriteArrayList(); } - + /** * Reset this manager to its initial state. This will also update * all {@link Animation}s with a time of 0.0. */ - public void reset() { + public void reset() + { startNs = System.nanoTime(); currentNs = System.nanoTime(); performStep(0); } - + /** * Returns the current animation time, in seconds - * + * * @return The animation time */ - float getCurrentTimeS() { + float getCurrentTimeS() + { long timeNs = currentNs - startNs; float timeS = timeNs * 1e-9f; return timeS; } - + /** * Add the given {@link Animation} to this manager. - * + * * @param animation The {@link Animation} to add */ - public void addAnimation(Animation animation) { + public void addAnimation(Animation animation) + { Objects.requireNonNull(animation, "The animation may not be null"); animations.add(animation); updateMaxEndTime(); } - + /** * Add all {@link Animation}s of the given sequence to this manager - * + * * @param animations The {@link Animation}s to add */ - public void addAnimations(Iterable animations) { - for (Animation animation : animations) { + public void addAnimations(Iterable animations) + { + for (Animation animation : animations) + { addAnimation(animation); } } - + + /** * Remove the given {@link Animation} from this manager - * + * * @param animation The {@link Animation} to remove */ - public void removeAnimation(Animation animation) { + public void removeAnimation(Animation animation) + { animations.remove(animation); updateMaxEndTime(); } - + /** * Remove all {@link Animation}s of the given sequence from this manager - * + * * @param animations The {@link Animation}s to remove */ - public void removeAnimations(Iterable animations) { - for (Animation animation : animations) { + public void removeAnimations(Iterable animations) + { + for (Animation animation : animations) + { removeAnimation(animation); } } - + /** * Returns an unmodifiable view on the animations that are stored * in this manager - * + * * @return The animations */ - public List getAnimations() { + public List getAnimations() + { return Collections.unmodifiableList(animations); } - + /** - * Update the {@link #maxEndTimeS}, the maximum end time of any + * Update the {@link #maxEndTimeS}, the maximum end time of any * {@link Animation} */ - private void updateMaxEndTime() { + private void updateMaxEndTime() + { maxEndTimeS = 0.0f; - for (Animation animation : animations) { + for (Animation animation : animations) + { maxEndTimeS = Math.max(maxEndTimeS, animation.getEndTimeS()); } } - + /** * Perform a time step, with the given size (in nanoseconds), and * update all {@link Animation}s - * + * * @param deltaNs The time step size, in nanoseconds */ - void performStep(long deltaNs) { + void performStep(long deltaNs) + { currentNs += deltaNs; float currentTimeS = getCurrentTimeS(); - if (animationPolicy == AnimationPolicy.ONCE && - currentTimeS > maxEndTimeS) { + if (animationPolicy == AnimationPolicy.ONCE && + currentTimeS > maxEndTimeS) + { animations.clear(); return; } - for (Animation animation : animations) { - if (animationPolicy == AnimationPolicy.LOOP) { + for (Animation animation : animations) + { + if (animationPolicy == AnimationPolicy.LOOP) + { float loopTimeS = currentTimeS % maxEndTimeS; animation.update(loopTimeS); - } else if (animationPolicy == AnimationPolicy.PING_PONG) { - int interval = (int) (currentTimeS / maxEndTimeS); + } + else if (animationPolicy == AnimationPolicy.PING_PONG) + { + int interval = (int)(currentTimeS / maxEndTimeS); float loopTimeS = currentTimeS % maxEndTimeS; float pingPongTimeS = loopTimeS; - if ((interval & 1) != 0) { - pingPongTimeS = maxEndTimeS - loopTimeS; + if ((interval & 1) != 0) + { + pingPongTimeS = maxEndTimeS - loopTimeS; } animation.update(pingPongTimeS); - } else { + } + else + { animation.update(currentTimeS); } } fireAnimationsUpdated(); } - + /** * Add the given {@link AnimationManagerListener} to be informed about * changes in this manager - * + * * @param listener The listener to add */ public void addAnimationManagerListener( - AnimationManagerListener listener) { + AnimationManagerListener listener) + { animationManagerListeners.add(listener); } - + /** * Remove the given {@link AnimationManagerListener} - * + * * @param listener The listener to remove */ public void removeAnimationManagerListener( - AnimationManagerListener listener) { + AnimationManagerListener listener) + { animationManagerListeners.remove(listener); } - + + /** * Inform all registered {@link AnimationManagerListener}s that * the animations have been updated */ - private void fireAnimationsUpdated() { - for (AnimationManagerListener listener : animationManagerListeners) { + private void fireAnimationsUpdated() + { + for (AnimationManagerListener listener : animationManagerListeners) + { listener.animationsUpdated(this); } } - - - /** - * A policy describing how the animations should be executed - */ - public enum AnimationPolicy { - /** - * Indicates that the animations should be executed only - * once, and then removed from the {@link AnimationManager} - */ - ONCE, - - /** - * Indicates that the animations should be executed in - * a ping-pong fashion - */ - PING_PONG, - - /** - * Indicates that the animations should be looped - */ - LOOP - } - - + + + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/animation/AnimationManagerListener.java b/src/main/java/de/javagl/jgltf/model/animation/AnimationManagerListener.java index 4839a1c..9fc527f 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/AnimationManagerListener.java +++ b/src/main/java/de/javagl/jgltf/model/animation/AnimationManagerListener.java @@ -30,11 +30,12 @@ * Interface for classes that want to be informed about changes * in an {@link AnimationManager} */ -public interface AnimationManagerListener { +public interface AnimationManagerListener +{ /** * Will be called when the {@link Animation}s in the given * {@link AnimationManager} have been updated - * + * * @param source The {@link AnimationManager} */ void animationsUpdated(AnimationManager source); diff --git a/src/main/java/de/javagl/jgltf/model/animation/AnimationRunner.java b/src/main/java/de/javagl/jgltf/model/animation/AnimationRunner.java index 8eaf0dc..0c0b96d 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/AnimationRunner.java +++ b/src/main/java/de/javagl/jgltf/model/animation/AnimationRunner.java @@ -31,41 +31,48 @@ /** * Simple utility class to run an {@link AnimationManager} in an own thread */ -public final class AnimationRunner { +public final class AnimationRunner +{ /** * The {@link AnimationManager} */ private final AnimationManager animationManager; - /** - * The step size, in milliseconds - */ - private final long stepSizeMs = 10; + /** * Whether this runner is currently running */ private boolean running = false; + /** * The animation thread */ private Thread animationThread; - + + /** + * The step size, in milliseconds + */ + private final long stepSizeMs = 10; + /** * Create a new runner for the given {@link AnimationManager} - * + * * @param animationManager The {@link AnimationManager} */ - public AnimationRunner(AnimationManager animationManager) { - Objects.requireNonNull(animationManager, - "The animationManager may not be null"); + public AnimationRunner(AnimationManager animationManager) + { + Objects.requireNonNull(animationManager, + "The animationManager may not be null"); this.animationManager = animationManager; } - + /** * Start this runner. If the runner is already {@link #isRunning()}, * then this has no effect. */ - public synchronized void start() { - if (isRunning()) { + public synchronized void start() + { + if (isRunning()) + { return; } animationThread = new Thread(this::runAnimations, "animationThread"); @@ -73,13 +80,15 @@ public synchronized void start() { animationThread.start(); running = true; } - + /** * Stop this runner. If the runner is not {@link #isRunning()}, * then this has no effect. */ - public synchronized void stop() { - if (!isRunning()) { + public synchronized void stop() + { + if (!isRunning()) + { return; } running = false; @@ -88,31 +97,37 @@ public synchronized void stop() { /** * Returns whether this runner is currently running - * - * @return Whether this runner is currently running + * + * @return Whether this runner is currently running */ - boolean isRunning() { + boolean isRunning() + { return running; } - + /** * Will be called in an own thread to perform time steps in the * {@link AnimationManager} */ - private void runAnimations() { + private void runAnimations() + { long previousNs = System.nanoTime(); - while (isRunning()) { + while (isRunning()) + { long currentNs = System.nanoTime(); long deltaNs = currentNs - previousNs; animationManager.performStep(deltaNs); previousNs = currentNs; - try { + try + { Thread.sleep(stepSizeMs); - } catch (InterruptedException e) { + } + catch (InterruptedException e) + { Thread.currentThread().interrupt(); return; } } } - + } diff --git a/src/main/java/de/javagl/jgltf/model/animation/Interpolator.java b/src/main/java/de/javagl/jgltf/model/animation/Interpolator.java index 1a4da8d..9c95d96 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/Interpolator.java +++ b/src/main/java/de/javagl/jgltf/model/animation/Interpolator.java @@ -27,23 +27,24 @@ package de.javagl.jgltf.model.animation; /** - * Package-private interface for classes that can interpolate between + * Package-private interface for classes that can interpolate between * (equal-length) arrays of float values */ -interface Interpolator { +interface Interpolator +{ /** - * Interpolate between a and b, based on + * Interpolate between a and b, based on * the given alpha value (that is usually in [0,1]), and place the * results in the given result array. None of the given arrays may * be null, and they must all have the same length. - * - * @param a The first array - * @param b The second array - * @param alpha The interpolation value + * + * @param a The first array + * @param b The second array + * @param alpha The interpolation value * @param result The array that will store the result - * @throws NullPointerException If any argument is null - * @throws IndexOutOfBoundsException May be thrown if the arrays do not - * have the same length + * @throws NullPointerException If any argument is null + * @throws IndexOutOfBoundsException May be thrown if the arrays do not + * have the same length */ void interpolate(float a[], float b[], float alpha, float result[]); } diff --git a/src/main/java/de/javagl/jgltf/model/animation/InterpolatorKeys.java b/src/main/java/de/javagl/jgltf/model/animation/InterpolatorKeys.java index 62228f2..0998434 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/InterpolatorKeys.java +++ b/src/main/java/de/javagl/jgltf/model/animation/InterpolatorKeys.java @@ -29,66 +29,73 @@ import java.util.Arrays; /** - * Methods to compute {@link Interpolator} keys from a given value and a + * Methods to compute {@link Interpolator} keys from a given value and a * (sorted) float array */ -class InterpolatorKeys { +class InterpolatorKeys +{ /** * Compute the index of the segment that the given key belongs to. * If the given key is smaller than the smallest or larger than - * the largest key, then 0 or keys.length-1 will be returned, + * the largest key, then 0 or keys.length-1 will be returned, * respectively. - * - * @param key The key + * + * @param key The key * @param keys The sorted keys * @return The index for the key */ - static int computeIndex(float key, float keys[]) { + static int computeIndex(float key, float keys[]) + { int index = Arrays.binarySearch(keys, key); - if (index >= 0) { + if (index >= 0) + { return index; } return Math.max(0, -index - 2); } - + /** * Compute the alpha value for the given key. This is a value in [0,1], * describing the relative location of the key in the segment with the * given index. - * - * @param key The key - * @param keys The sorted keys + * + * @param key The key + * @param keys The sorted keys * @param index The index of the key * @return The alpha value */ - static float computeAlpha(float key, float keys[], int index) { - if (key <= keys[0]) { + static float computeAlpha(float key, float keys[], int index) + { + if (key <= keys[0]) + { return 0.0f; } - if (key >= keys[keys.length - 1]) { + if (key >= keys[keys.length-1]) + { return 1.0f; } float local = key - keys[index]; - float delta = keys[index + 1] - keys[index]; + float delta = keys[index+1] - keys[index]; float alpha = local / delta; return alpha; - + } - + /** * A basic test - * * @param args Not used */ - public static void main(String[] args) { - float keys[] = {1, 8, 11}; - for (float d = -1; d <= 12; d += 0.1) { + public static void main(String[] args) + { + float keys[] = { 1, 8, 11 }; + for (float d = -1; d <= 12; d+=0.1) + { int index = computeIndex(d, keys); float alpha = computeAlpha(d, keys, index); - System.out.println("For " + d); - System.out.println(" index " + index); - System.out.println(" alpha " + alpha); + System.out.println("For "+d); + System.out.println(" index "+index); + System.out.println(" alpha "+alpha); } } - + } diff --git a/src/main/java/de/javagl/jgltf/model/animation/InterpolatorType.java b/src/main/java/de/javagl/jgltf/model/animation/InterpolatorType.java index b153c7d..65ad4d0 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/InterpolatorType.java +++ b/src/main/java/de/javagl/jgltf/model/animation/InterpolatorType.java @@ -3,19 +3,20 @@ /** * Enumeration of interpolator types */ -public enum InterpolatorType { +public enum InterpolatorType +{ /** * A linear interpolator */ LINEAR, - + /** - * A spherical linear interpolation (SLERP). The input values will - * be assumed to consist of 4 elements, which are interpreted as + * A spherical linear interpolation (SLERP). The input values will + * be assumed to consist of 4 elements, which are interpreted as * quaternions for the interpolation */ SLERP, - + /** * A stepwise interpolation */ diff --git a/src/main/java/de/javagl/jgltf/model/animation/Interpolators.java b/src/main/java/de/javagl/jgltf/model/animation/Interpolators.java index a828402..d6115ff 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/Interpolators.java +++ b/src/main/java/de/javagl/jgltf/model/animation/Interpolators.java @@ -29,28 +29,25 @@ /** * Methods to create {@link Interpolator} instances */ -class Interpolators { - /** - * Private constructor to prevent instantiation - */ - private Interpolators() { - // Private constructor to prevent instantiation - } - +class Interpolators +{ /** * Creates an {@link Interpolator} for the given {@link InterpolatorType}. - * If the given {@link InterpolatorType} is null, then + * If the given {@link InterpolatorType} is null, then * a {@link InterpolatorType#LINEAR linear} interpolator will be returned. - * + * * @param interpolatorType The {@link InterpolatorType} * @return The {@link Interpolator} */ - static Interpolator create(InterpolatorType interpolatorType) { - if (interpolatorType == null) { + static Interpolator create(InterpolatorType interpolatorType) + { + if (interpolatorType == null) + { return new LinearInterpolator(); } - switch (interpolatorType) { - case SLERP: + switch (interpolatorType) + { + case SLERP: return new SlerpQuaternionInterpolator(); case LINEAR: @@ -61,7 +58,15 @@ static Interpolator create(InterpolatorType interpolatorType) { default: throw new IllegalArgumentException( - "Invalid interpolator type: " + interpolatorType); + "Invalid interpolator type: "+interpolatorType); } } + + /** + * Private constructor to prevent instantiation + */ + private Interpolators() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/animation/LinearInterpolator.java b/src/main/java/de/javagl/jgltf/model/animation/LinearInterpolator.java index e1b7d49..39db643 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/LinearInterpolator.java +++ b/src/main/java/de/javagl/jgltf/model/animation/LinearInterpolator.java @@ -30,17 +30,20 @@ * Implementation of an {@link Interpolator} that interpolates linearly. * Hence the name. */ -class LinearInterpolator implements Interpolator { +class LinearInterpolator implements Interpolator +{ @Override public void interpolate( - float[] a, float[] b, float alpha, float[] result) { - for (int i = 0; i < a.length; i++) { + float[] a, float[] b, float alpha, float[] result) + { + for (int i=0; i epsilon) { - float omega = (float) Math.acos(dot); - float invSinOmega = 1.0f / (float) Math.sin(omega); - s0 = (float) Math.sin((1.0 - alpha) * omega) * invSinOmega; - s1 = (float) Math.sin(alpha * omega) * invSinOmega; - } else { + if ((1.0 - dot) > epsilon) + { + float omega = (float)Math.acos(dot); + float invSinOmega = 1.0f / (float)Math.sin(omega); + s0 = (float)Math.sin((1.0 - alpha) * omega) * invSinOmega; + s1 = (float)Math.sin(alpha * omega) * invSinOmega; + } + else + { s0 = 1.0f - alpha; s1 = alpha; } diff --git a/src/main/java/de/javagl/jgltf/model/animation/StepInterpolator.java b/src/main/java/de/javagl/jgltf/model/animation/StepInterpolator.java index c916c4c..17c7238 100644 --- a/src/main/java/de/javagl/jgltf/model/animation/StepInterpolator.java +++ b/src/main/java/de/javagl/jgltf/model/animation/StepInterpolator.java @@ -29,10 +29,12 @@ /** * Implementation of an {@link Interpolator} that interpolates stepwise. */ -class StepInterpolator implements Interpolator { +class StepInterpolator implements Interpolator +{ @Override public void interpolate( - float[] a, float[] b, float alpha, float[] result) { + float[] a, float[] b, float alpha, float[] result) + { System.arraycopy(a, 0, result, 0, a.length); } diff --git a/src/main/java/de/javagl/jgltf/model/extensions/GltfExtensions.java b/src/main/java/de/javagl/jgltf/model/extensions/GltfExtensions.java index cf2e8c3..07b0bcd 100644 --- a/src/main/java/de/javagl/jgltf/model/extensions/GltfExtensions.java +++ b/src/main/java/de/javagl/jgltf/model/extensions/GltfExtensions.java @@ -26,107 +26,123 @@ */ package de.javagl.jgltf.model.extensions; -import com.google.gson.Gson; - import java.util.Map; +import com.google.gson.Gson; + /** * Utility methods related to glTF extension objects. */ -public class GltfExtensions { - /** - * Private constructor to prevent instantiation - */ - private GltfExtensions() { - // Private constructor to prevent instantiation - } - +public class GltfExtensions +{ /** * Obtain the specified extension object from the given glTF property. - *

    + * * If the given glTF object does not have an extension with the * given name, or this object cannot be converted to the given * target type, then null is returned. - * - * @param The type of the extension object - * @param gltfProperty The glTF property + * + * @param The type of the extension object + * + * @param gltfProperty The glTF property * @param extensionName The extension name * @param extensionType The extension type * @return The extension object, or null * @throws IllegalArgumentException If the given glTF property is neither - * a de.javagl.jgltf.impl.v1.GlTFProperty nor a - * a de.javagl.jgltf.impl.v2.GlTFProperty + * a de.javagl.jgltf.impl.v1.GlTFProperty nor a + * a de.javagl.jgltf.impl.v2.GlTFProperty */ public static T obtain( - Object gltfProperty, String extensionName, Class extensionType) { - if (gltfProperty instanceof de.javagl.jgltf.impl.v1.GlTFProperty) { - de.javagl.jgltf.impl.v1.GlTFProperty gltfPropertyV1 = - (de.javagl.jgltf.impl.v1.GlTFProperty) gltfProperty; + Object gltfProperty, String extensionName, Class extensionType) + { + if (gltfProperty instanceof de.javagl.jgltf.impl.v1.GlTFProperty) + { + de.javagl.jgltf.impl.v1.GlTFProperty gltfPropertyV1 = + (de.javagl.jgltf.impl.v1.GlTFProperty) gltfProperty; Map extensions = gltfPropertyV1.getExtensions(); return obtainInternal(extensions, extensionName, extensionType); } - if (gltfProperty instanceof de.javagl.jgltf.impl.v2.GlTFProperty) { - de.javagl.jgltf.impl.v2.GlTFProperty gltfPropertyV2 = - (de.javagl.jgltf.impl.v2.GlTFProperty) gltfProperty; + if (gltfProperty instanceof de.javagl.jgltf.impl.v2.GlTFProperty) + { + de.javagl.jgltf.impl.v2.GlTFProperty gltfPropertyV2 = + (de.javagl.jgltf.impl.v2.GlTFProperty) gltfProperty; Map extensions = gltfPropertyV2.getExtensions(); return obtainInternal(extensions, extensionName, extensionType); } throw new IllegalArgumentException( - "Not a valid glTF property: " + gltfProperty); + "Not a valid glTF property: " + gltfProperty); } /** * Internal method to obtain the extension object from the given map - * - * @param The type of the extension object - * @param extensions The optional extensions map + * + * @param The type of the extension object + * @param extensions The optional extensions map * @param extensionName The extension name * @param extensionType The extension type * @return The extension object, or null if it cannot be * obtained */ private static T obtainInternal( - Map extensions, - String extensionName, Class extensionType) { - if (extensions == null) { + Map extensions, + String extensionName, Class extensionType) + { + if (extensions == null) + { return null; } Object object = extensions.get(extensionName); - if (object == null) { + if (object == null) + { return null; } return convertValueOptional(object, extensionType); } - + /** * Convert the given object to the given target type - * - * @param The target type + * + * @param The target type * @param object The object - * @param type The target type + * @param type The target type * @return The result * @throws IllegalArgumentException If the conversion failed */ private static T convertValue(Object object, Class type) - throws IllegalArgumentException { - Gson gson = new Gson(); + throws IllegalArgumentException + { + Gson gson = new Gson(); return gson.fromJson(gson.toJsonTree(object), type); } - + /** - * Convert the given object to the given target type, returning + * Convert the given object to the given target type, returning * null if the conversion failed - * - * @param The target type + * + * @param The target type * @param object The object - * @param type The target type + * @param type The target type * @return The result */ - private static T convertValueOptional(Object object, Class type) { - try { + private static T convertValueOptional(Object object, Class type) + { + try + { return convertValue(object, type); - } catch (IllegalArgumentException e) { + } + catch (IllegalArgumentException e) + { return null; } } + + + + /** + * Private constructor to prevent instantiation + */ + private GltfExtensions() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/extensions/package-info.java b/src/main/java/de/javagl/jgltf/model/extensions/package-info.java index 599bafb..a1b875c 100644 --- a/src/main/java/de/javagl/jgltf/model/extensions/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/extensions/package-info.java @@ -1,5 +1,5 @@ /** - * Classes related to glTF extension objects + * Classes related to glTF extension objects */ package de.javagl.jgltf.model.extensions; diff --git a/src/main/java/de/javagl/jgltf/model/gl/ProgramModel.java b/src/main/java/de/javagl/jgltf/model/gl/ProgramModel.java index addd74c..52d6307 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/ProgramModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/ProgramModel.java @@ -26,32 +26,33 @@ */ package de.javagl.jgltf.model.gl; -import de.javagl.jgltf.model.NamedModelElement; - import java.util.List; +import de.javagl.jgltf.model.NamedModelElement; + /** - * Interface for a program that consists of a vertex- and fragment + * Interface for a program that consists of a vertex- and fragment * {@link ShaderModel} */ -public interface ProgramModel extends NamedModelElement { +public interface ProgramModel extends NamedModelElement +{ /** * Return the {@link ShaderModel} for the vertex shader - * + * * @return The {@link ShaderModel} */ ShaderModel getVertexShaderModel(); - + /** * Return the {@link ShaderModel} for the fragment shader - * + * * @return The {@link ShaderModel} */ ShaderModel getFragmentShaderModel(); - + /** * Returns an unmodifiable list of the program attribute names - * + * * @return The attributes */ List getAttributes(); diff --git a/src/main/java/de/javagl/jgltf/model/gl/Semantic.java b/src/main/java/de/javagl/jgltf/model/gl/Semantic.java index cce8c0d..44a6c47 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/Semantic.java +++ b/src/main/java/de/javagl/jgltf/model/gl/Semantic.java @@ -27,80 +27,81 @@ package de.javagl.jgltf.model.gl; /** - * Enumeration of the {@link TechniqueParametersModel#getSemantic() technique + * Enumeration of the {@link TechniqueParametersModel#getSemantic() technique * parameters semantics} */ -public enum Semantic { +public enum Semantic +{ /** * The LOCAL semantic */ LOCAL, - + /** * The MODEL semantic */ MODEL, - + /** * The VIEW semantic */ VIEW, - + /** * The PROJECTION semantic */ PROJECTION, - + /** * The MODELVIEW semantic */ MODELVIEW, - + /** * The MODELVIEWPROJECTION semantic */ MODELVIEWPROJECTION, - + /** * The MODELINVERSE semantic */ MODELINVERSE, - + /** * The VIEWINVERSE semantic */ VIEWINVERSE, - + /** * The MODELVIEWINVERSE semantic */ MODELVIEWINVERSE, - + /** * The PROJECTIONINVERSE semantic */ PROJECTIONINVERSE, - + /** * The MODELVIEWPROJECTIONINVERSE semantic */ MODELVIEWPROJECTIONINVERSE, - + /** * The MODELINVERSETRANSPOSE semantic */ MODELINVERSETRANSPOSE, - + /** * The MODELVIEWINVERSETRANSPOSE semantic */ MODELVIEWINVERSETRANSPOSE, - + /** * The VIEWPORT semantic */ VIEWPORT, - + /** * The JOINTMATRIX semantic */ @@ -109,35 +110,41 @@ public enum Semantic { /** * Returns whether the given string is a valid semantic name, and may be * passed to Semantic.valueOf without causing an exception. - * + * * @param s The string * @return Whether the given string is a valid semantic */ - public static boolean contains(String s) { - for (Semantic semantic : values()) { - if (semantic.name().equals(s)) { + public static boolean contains(String s) + { + for (Semantic semantic : values()) + { + if (semantic.name().equals(s)) + { return true; } } return false; } - + /** - * Returns the semantic for the given string. If the string is + * Returns the semantic for the given string. If the string is * null or does not describe a valid semantic, * then null is returned - * + * * @param string The string * @return The semantic */ - public static Semantic forString(String string) { - if (string == null) { + public static Semantic forString(String string) + { + if (string == null) + { return null; } - if (!contains(string)) { + if (!contains(string)) + { return null; } return Semantic.valueOf(string); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/gl/ShaderModel.java b/src/main/java/de/javagl/jgltf/model/gl/ShaderModel.java index e1cd064..f482919 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/ShaderModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/ShaderModel.java @@ -26,17 +26,34 @@ */ package de.javagl.jgltf.model.gl; -import de.javagl.jgltf.model.NamedModelElement; - import java.nio.ByteBuffer; +import de.javagl.jgltf.model.NamedModelElement; + /** - * Interface for a shader + * Interface for a shader */ -public interface ShaderModel extends NamedModelElement { +public interface ShaderModel extends NamedModelElement +{ + /** + * Enumeration of different shader types + */ + public enum ShaderType + { + /** + * The vertex shader type + */ + VERTEX_SHADER, + + /** + * The fragment shader type + */ + FRAGMENT_SHADER + } + /** * Returns the URI of the shader data - * + * * @return The URI */ String getUri(); @@ -44,43 +61,28 @@ public interface ShaderModel extends NamedModelElement { /** * Returns the actual shader data. This will return a slice of the * buffer that is stored internally. Thus, changes to the contents - * of this buffer will affect this model, but modifications of the - * position and limit of the returned buffer will not affect this + * of this buffer will affect this model, but modifications of the + * position and limit of the returned buffer will not affect this * model.
    - * + * * @return The shader data */ ByteBuffer getShaderData(); - + /** * Returns the shader source code as a string. This is a convenience * function that simply returns the {@link #getShaderData() shader data} * as a string. - * + * * @return The shader source code */ String getShaderSource(); - + /** * Returns the {@link ShaderType} of this shader - * + * * @return The {@link ShaderType} */ ShaderType getShaderType(); - - /** - * Enumeration of different shader types - */ - public enum ShaderType { - /** - * The vertex shader type - */ - VERTEX_SHADER, - - /** - * The fragment shader type - */ - FRAGMENT_SHADER - } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/gl/TechniqueModel.java b/src/main/java/de/javagl/jgltf/model/gl/TechniqueModel.java index 1e562cc..d847ed1 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/TechniqueModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/TechniqueModel.java @@ -26,59 +26,60 @@ */ package de.javagl.jgltf.model.gl; -import de.javagl.jgltf.model.NamedModelElement; - import java.util.Map; +import de.javagl.jgltf.model.NamedModelElement; + /** - * Interface for a rendering technique. Such a technique may be part of a - * core glTF 1.0 asset, an extension of a glTF 2.0 asset, or a custom + * Interface for a rendering technique. Such a technique may be part of a + * core glTF 1.0 asset, an extension of a glTF 2.0 asset, or a custom * implementation that is used internally. */ -public interface TechniqueModel extends NamedModelElement { +public interface TechniqueModel extends NamedModelElement +{ /** * Returns the {@link ProgramModel} that is used for implementing this * technique - * + * * @return The {@link ProgramModel} */ ProgramModel getProgramModel(); /** - * Returns an unmodifiable map that maps parameter names to + * Returns an unmodifiable map that maps parameter names to * {@link TechniqueParametersModel} instances - * + * * @return The parameters */ Map getParameters(); - + /** - * Returns an unmodifiable map that maps attribute names to + * Returns an unmodifiable map that maps attribute names to * parameter names - * + * * @return The mapping from attribute names to parameter names */ Map getAttributes(); - + /** * Returns the {@link TechniqueParametersModel} for the attribute * with the given name, or null if no such parameter - * exists. This is a convenience function and equivalent to + * exists. This is a convenience function and equivalent to *

    
          * techniqueModel.getParameters().get(
          *     techniqueModel.getAttributes().get(attributeName));
          * 
    , * handling null-cases accordingly. - * + * * @param attributeName The attribute name * @return The {@link TechniqueParametersModel} */ TechniqueParametersModel getAttributeParameters(String attributeName); - + /** - * Returns an unmodifiable map that maps uniform names to + * Returns an unmodifiable map that maps uniform names to * parameter names - * + * * @return The uniforms */ Map getUniforms(); @@ -86,22 +87,22 @@ public interface TechniqueModel extends NamedModelElement { /** * Returns the {@link TechniqueParametersModel} for the uniform * with the given name, or null if no such parameter - * exists. This is a convenience function and equivalent to + * exists. This is a convenience function and equivalent to *
    
          * techniqueModel.getParameters().get(
          *     techniqueModel.getUniforms().get(uniformName));
          * 
    , * handling null-cases accordingly. - * + * * @param uniformName The uniform name * @return The {@link TechniqueParametersModel} */ TechniqueParametersModel getUniformParameters(String uniformName); - + /** * Returns the {@link TechniqueStatesModel}, or null if the * default technique states should be used. - * + * * @return The {@link TechniqueStatesModel} */ TechniqueStatesModel getTechniqueStatesModel(); diff --git a/src/main/java/de/javagl/jgltf/model/gl/TechniqueParametersModel.java b/src/main/java/de/javagl/jgltf/model/gl/TechniqueParametersModel.java index ae7fdbd..e495af7 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/TechniqueParametersModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/TechniqueParametersModel.java @@ -31,43 +31,44 @@ /** * An interface for describing {@link TechniqueModel} parameters */ -public interface TechniqueParametersModel { +public interface TechniqueParametersModel +{ /** * Returns the type of the parameter, as a GL constant. For example, * GL_INT or GL_FLOAT_VEC3 - * + * * @return The type */ int getType(); - + /** - * Returns the count - * + * Returns the count + * * @return The count */ int getCount(); - + /** * Returns the string describing the {@link Semantic} of this parameter. * This may be a string that starts with an underscore "_", * indicating a custom semantic - * + * * @return The {@link Semantic} string */ String getSemantic(); - + /** * Returns the value of this parameter - * + * * @return The value */ Object getValue(); - + /** * Returns the {@link NodeModel} of the node that this parameter - * refers to. This is, for example, used for computing the + * refers to. This is, for example, used for computing the * {@link Semantic#MODEL} matrix. - * + * * @return The {@link NodeModel} */ NodeModel getNodeModel(); diff --git a/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesFunctionsModel.java b/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesFunctionsModel.java index a7a71a7..a78a1cc 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesFunctionsModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesFunctionsModel.java @@ -29,87 +29,88 @@ /** * Interface for technique state function parameters.
    *
    - * Note: The method comments here are placeholders. For details, refer + * Note: The method comments here are placeholders. For details, refer * to the glTF 1.0 specification and an OpenGL documentation!
    *
    * Note: The methods in this interface may return references * to arrays that are stored internally. Callers should not store - * or modify the returned arrays! + * or modify the returned arrays! */ -public interface TechniqueStatesFunctionsModel { +public interface TechniqueStatesFunctionsModel +{ /** * Returns the blend color - * + * * @return The blend color */ float[] getBlendColor(); - + /** * Returns the blend equation - * + * * @return the blend equation */ int[] getBlendEquationSeparate(); - + /** * Returns the blend function - * + * * @return The blend function */ int[] getBlendFuncSeparate(); - + /** * Returns the color mask - * + * * @return The color mask */ boolean[] getColorMask(); - + /** * Returns the cull face - * + * * @return The cull face */ int[] getCullFace(); - + /** * Returns the depth func - * + * * @return The depth func */ int[] getDepthFunc(); - + /** * Returns the depth mask - * + * * @return The depth mask */ boolean[] getDepthMask(); - + /** * Returns the depth range - * + * * @return The depth range */ float[] getDepthRange(); - + /** * Returns the front face - * + * * @return The front face */ int[] getFrontFace(); - + /** * Returns the line width - * + * * @return The line width */ float[] getLineWidth(); - + /** * Returns the polygon offset - * + * * @return The polygon offset */ float[] getPolygonOffset(); diff --git a/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesModel.java b/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesModel.java index 304dbed..58e1afa 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/TechniqueStatesModel.java @@ -26,47 +26,50 @@ */ package de.javagl.jgltf.model.gl; -import de.javagl.jgltf.model.GltfConstants; - import java.util.Arrays; import java.util.List; +import de.javagl.jgltf.model.GltfConstants; + /** - * Interface for technique states. + * Interface for technique states. */ -public interface TechniqueStatesModel { - /** - * Returns a list containing all possible states that may be contained - * in a technique.states.enable list. - * - * @return All possible states - */ - public static List getAllStates() { - List allStates = Arrays.asList( - GltfConstants.GL_BLEND, - GltfConstants.GL_CULL_FACE, - GltfConstants.GL_DEPTH_TEST, - GltfConstants.GL_POLYGON_OFFSET_FILL, - GltfConstants.GL_SAMPLE_ALPHA_TO_COVERAGE, - GltfConstants.GL_SCISSOR_TEST - ); - return allStates; - } - +public interface TechniqueStatesModel +{ /** * Returns an unmodifiable list containing the enabled states, * or null if only the default states should be * enabled. - * + * * @return The enabled states */ List getEnable(); - + /** * Returns the {@link TechniqueStatesFunctionsModel}, or null * if the default technique states functions should be used. - * + * * @return The {@link TechniqueStatesFunctionsModel} */ TechniqueStatesFunctionsModel getTechniqueStatesFunctionsModel(); + + + /** + * Returns a list containing all possible states that may be contained + * in a technique.states.enable list. + * + * @return All possible states + */ + public static List getAllStates() + { + List allStates = Arrays.asList( + GltfConstants.GL_BLEND, + GltfConstants.GL_CULL_FACE, + GltfConstants.GL_DEPTH_TEST, + GltfConstants.GL_POLYGON_OFFSET_FILL, + GltfConstants.GL_SAMPLE_ALPHA_TO_COVERAGE, + GltfConstants.GL_SCISSOR_TEST + ); + return allStates; + } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultProgramModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultProgramModel.java index 74f6244..c813de6 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultProgramModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultProgramModel.java @@ -26,81 +26,91 @@ */ package de.javagl.jgltf.model.gl.impl; -import de.javagl.jgltf.model.gl.ProgramModel; -import de.javagl.jgltf.model.gl.ShaderModel; -import de.javagl.jgltf.model.impl.AbstractNamedModelElement; - import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; +import de.javagl.jgltf.model.gl.ProgramModel; +import de.javagl.jgltf.model.gl.ShaderModel; +import de.javagl.jgltf.model.impl.AbstractNamedModelElement; + /** * Implementation of a {@link ProgramModel} */ public class DefaultProgramModel extends AbstractNamedModelElement - implements ProgramModel { - /** - * The attributes - */ - private final List attributes; + implements ProgramModel +{ /** * The vertex shader model */ private ShaderModel vertexShaderModel; + /** * The fragment shader model */ private ShaderModel fragmentShaderModel; - + + /** + * The attributes + */ + private final List attributes; + /** * Default constructor */ - public DefaultProgramModel() { + public DefaultProgramModel() + { this.attributes = new ArrayList(); } - + /** * Add the given attribute name to this program - * + * * @param attribute The attribute */ - public void addAttribute(String attribute) { + public void addAttribute(String attribute) + { attributes.add(attribute); } - - @Override - public ShaderModel getVertexShaderModel() { - return vertexShaderModel; - } - + /** * Set the vertex {@link ShaderModel} - * + * * @param vertexShaderModel The vertex {@link ShaderModel} */ - public void setVertexShaderModel(ShaderModel vertexShaderModel) { + public void setVertexShaderModel(ShaderModel vertexShaderModel) + { this.vertexShaderModel = Objects.requireNonNull(vertexShaderModel, - "The vertexShaderModel may not be null"); + "The vertexShaderModel may not be null"); } @Override - public ShaderModel getFragmentShaderModel() { - return fragmentShaderModel; + public ShaderModel getVertexShaderModel() + { + return vertexShaderModel; } - + /** * Set the fragment {@link ShaderModel} - * + * * @param fragmentShaderModel The fragment {@link ShaderModel} */ - public void setFragmentShaderModel(ShaderModel fragmentShaderModel) { + public void setFragmentShaderModel(ShaderModel fragmentShaderModel) + { this.fragmentShaderModel = Objects.requireNonNull(fragmentShaderModel, - "The fragmentShaderModel may not be null"); + "The fragmentShaderModel may not be null"); } @Override - public List getAttributes() { + public ShaderModel getFragmentShaderModel() + { + return fragmentShaderModel; + } + + @Override + public List getAttributes() + { return Collections.unmodifiableList(attributes); } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultShaderModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultShaderModel.java index 72028dd..9c83acc 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultShaderModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultShaderModel.java @@ -26,68 +26,77 @@ */ package de.javagl.jgltf.model.gl.impl; +import java.nio.ByteBuffer; + import de.javagl.jgltf.model.gl.ShaderModel; import de.javagl.jgltf.model.impl.AbstractNamedModelElement; import de.javagl.jgltf.model.io.Buffers; -import java.nio.ByteBuffer; - /** * Implementation of a {@link ShaderModel} */ public class DefaultShaderModel extends AbstractNamedModelElement - implements ShaderModel { + implements ShaderModel +{ /** - * The URI + * The URI */ private final String uri; - /** - * The {@link ShaderType} - */ - private final ShaderType shaderType; + /** * The actual raw shader data */ private ByteBuffer shaderData; /** - * Default constructor - * - * @param uri The URI - * @param shaderType The - * {@link ShaderType} + * The {@link ShaderType} + */ + private final ShaderType shaderType; + + /** + * Default constructor + * + * @param uri The URI + * @param shaderType The + * {@link ShaderType} */ - public DefaultShaderModel(String uri, ShaderType shaderType) { + public DefaultShaderModel(String uri, ShaderType shaderType) + { this.uri = uri; this.shaderType = shaderType; } + + /** + * Set the data of this shader + * + * @param shaderData The shader data + */ + public void setShaderData(ByteBuffer shaderData) + { + this.shaderData = shaderData; + } @Override - public String getUri() { + public String getUri() + { return uri; } @Override - public ByteBuffer getShaderData() { + public ByteBuffer getShaderData() + { return Buffers.createSlice(shaderData); } - /** - * Set the data of this shader - * - * @param shaderData The shader data - */ - public void setShaderData(ByteBuffer shaderData) { - this.shaderData = shaderData; - } - @Override - public String getShaderSource() { + public String getShaderSource() + { return Buffers.readAsString(shaderData); } - + @Override - public ShaderType getShaderType() { + public ShaderType getShaderType() + { return shaderType; } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueModel.java index 1044fcc..c11e374 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueModel.java @@ -26,149 +26,167 @@ */ package de.javagl.jgltf.model.gl.impl; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; + import de.javagl.jgltf.model.gl.ProgramModel; import de.javagl.jgltf.model.gl.TechniqueModel; import de.javagl.jgltf.model.gl.TechniqueParametersModel; import de.javagl.jgltf.model.gl.TechniqueStatesModel; import de.javagl.jgltf.model.impl.AbstractNamedModelElement; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; - /** * Implementation of a {@link TechniqueModel} */ public class DefaultTechniqueModel extends AbstractNamedModelElement - implements TechniqueModel { + implements TechniqueModel +{ + /** + * The {@link ProgramModel} + */ + private ProgramModel programModel; + /** * The parameters */ private final Map parameters; + /** * The attributes */ private final Map attributes; + /** * The uniforms */ private final Map uniforms; - /** - * The {@link ProgramModel} - */ - private ProgramModel programModel; + /** * The {@link TechniqueStatesModel} */ private TechniqueStatesModel techniqueStatesModel; - + /** * Default constructor */ - public DefaultTechniqueModel() { + public DefaultTechniqueModel() + { this.parameters = new LinkedHashMap(); this.attributes = new LinkedHashMap(); this.uniforms = new LinkedHashMap(); } - - @Override - public ProgramModel getProgramModel() { - return programModel; - } - + /** * Set the {@link ProgramModel} - * + * * @param programModel The {@link ProgramModel} */ - public void setProgramModel(ProgramModel programModel) { + public void setProgramModel(ProgramModel programModel) + { this.programModel = programModel; } - + + @Override + public ProgramModel getProgramModel() + { + return programModel; + } + @Override - public Map getParameters() { + public Map getParameters() + { return Collections.unmodifiableMap(parameters); } - + /** * Add the given attribute to this technique - * + * * @param attributeName The attribute name * @param parameterName The parameter name */ - public void addAttribute(String attributeName, String parameterName) { + public void addAttribute(String attributeName, String parameterName) + { Objects.requireNonNull( - attributeName, "The attributeName may not be null"); + attributeName, "The attributeName may not be null"); Objects.requireNonNull( - parameterName, "The parameterName may not be null"); + parameterName, "The parameterName may not be null"); attributes.put(attributeName, parameterName); } - + /** * Add the given parameter to this technique - * - * @param parameterName The parameter name + * + * @param parameterName The parameter name * @param techniqueParametersModel The {@link TechniqueParametersModel} */ public void addParameter( - String parameterName, TechniqueParametersModel techniqueParametersModel) { + String parameterName, TechniqueParametersModel techniqueParametersModel) + { Objects.requireNonNull( - parameterName, "The parameterName may not be null"); - Objects.requireNonNull(techniqueParametersModel, - "The techniqueParametersModel may not be null"); + parameterName, "The parameterName may not be null"); + Objects.requireNonNull(techniqueParametersModel, + "The techniqueParametersModel may not be null"); parameters.put(parameterName, techniqueParametersModel); } @Override - public Map getAttributes() { + public Map getAttributes() + { return Collections.unmodifiableMap(attributes); } - + @Override - public TechniqueParametersModel getAttributeParameters(String attributeName) { + public TechniqueParametersModel getAttributeParameters(String attributeName) + { String parameterName = attributes.get(attributeName); return parameters.get(parameterName); } - + /** * Add the given uniform to this technique - * - * @param uniformName The uniform name + * + * @param uniformName The uniform name * @param parameterName The parameter name */ - public void addUniform(String uniformName, String parameterName) { + public void addUniform(String uniformName, String parameterName) + { Objects.requireNonNull( - uniformName, "The uniformName may not be null"); + uniformName, "The uniformName may not be null"); Objects.requireNonNull( - parameterName, "The parameterName may not be null"); + parameterName, "The parameterName may not be null"); uniforms.put(uniformName, parameterName); } - + @Override - public Map getUniforms() { + public Map getUniforms() + { return Collections.unmodifiableMap(uniforms); } @Override - public TechniqueParametersModel getUniformParameters(String uniformName) { + public TechniqueParametersModel getUniformParameters(String uniformName) + { String parameterName = uniforms.get(uniformName); return parameters.get(parameterName); } - - @Override - public TechniqueStatesModel getTechniqueStatesModel() { - return techniqueStatesModel; - } - + /** * Set the {@link TechniqueStatesModel} - * + * * @param techniqueStatesModel The {@link TechniqueStatesModel} */ public void setTechniqueStatesModel( - TechniqueStatesModel techniqueStatesModel) { + TechniqueStatesModel techniqueStatesModel) + { this.techniqueStatesModel = techniqueStatesModel; } + + @Override + public TechniqueStatesModel getTechniqueStatesModel() + { + return techniqueStatesModel; + } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueParametersModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueParametersModel.java index e8e9c3e..2ffa9c1 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueParametersModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueParametersModel.java @@ -33,44 +33,46 @@ /** * Implementation of a {@link TechniqueParametersModel} */ -public class DefaultTechniqueParametersModel implements TechniqueParametersModel { +public class DefaultTechniqueParametersModel implements TechniqueParametersModel +{ /** * The type */ private final int type; - + /** * The count */ private final int count; - + /** * The {@link Semantic} semantic */ private final String semantic; - + /** * The value */ private final Object value; - + /** * The {@link NodeModel} */ private final NodeModel nodeModel; - + /** * Default constructor - * - * @param type The type - * @param count The count - * @param semantic The {@link Semantic} - * @param value The value + * + * @param type The type + * @param count The count + * @param semantic The {@link Semantic} + * @param value The value * @param nodeModel The {@link NodeModel} */ public DefaultTechniqueParametersModel( - int type, int count, String semantic, - Object value, NodeModel nodeModel) { + int type, int count, String semantic, + Object value, NodeModel nodeModel) + { this.type = type; this.count = count; this.semantic = semantic; @@ -79,27 +81,32 @@ public DefaultTechniqueParametersModel( } @Override - public int getType() { + public int getType() + { return type; } - + @Override - public int getCount() { + public int getCount() + { return count; } @Override - public String getSemantic() { + public String getSemantic() + { return semantic; } @Override - public Object getValue() { + public Object getValue() + { return value; } - + @Override - public NodeModel getNodeModel() { + public NodeModel getNodeModel() + { return nodeModel; } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesFunctionsModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesFunctionsModel.java index 159a8db..5856c47 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesFunctionsModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesFunctionsModel.java @@ -31,12 +31,13 @@ /** * Default implementation of a {@link TechniqueStatesFunctionsModel}.
    *
    - * Note: The method comments here are placeholders. For details, refer + * Note: The method comments here are placeholders. For details, refer * to the glTF 1.0 specification and an OpenGL documentation!
    *
    */ public class DefaultTechniqueStatesFunctionsModel - implements TechniqueStatesFunctionsModel { + implements TechniqueStatesFunctionsModel +{ /** * The BlendColor */ @@ -95,12 +96,14 @@ public class DefaultTechniqueStatesFunctionsModel /** * Default constructor */ - public DefaultTechniqueStatesFunctionsModel() { + public DefaultTechniqueStatesFunctionsModel() + { // Default constructor } @Override - public float[] getBlendColor() { + public float[] getBlendColor() + { return blendColor; } @@ -109,12 +112,14 @@ public float[] getBlendColor() { * * @param blendColor The BlendColor */ - public void setBlendColor(float[] blendColor) { + public void setBlendColor(float[] blendColor) + { this.blendColor = blendColor; } @Override - public int[] getBlendEquationSeparate() { + public int[] getBlendEquationSeparate() + { return blendEquationSeparate; } @@ -123,12 +128,14 @@ public int[] getBlendEquationSeparate() { * * @param blendEquationSeparate The BlendEquationSeparate */ - public void setBlendEquationSeparate(int[] blendEquationSeparate) { + public void setBlendEquationSeparate(int[] blendEquationSeparate) + { this.blendEquationSeparate = blendEquationSeparate; } @Override - public int[] getBlendFuncSeparate() { + public int[] getBlendFuncSeparate() + { return blendFuncSeparate; } @@ -137,12 +144,14 @@ public int[] getBlendFuncSeparate() { * * @param blendFuncSeparate The BlendFuncSeparate */ - public void setBlendFuncSeparate(int[] blendFuncSeparate) { + public void setBlendFuncSeparate(int[] blendFuncSeparate) + { this.blendFuncSeparate = blendFuncSeparate; } @Override - public boolean[] getColorMask() { + public boolean[] getColorMask() + { return colorMask; } @@ -151,12 +160,14 @@ public boolean[] getColorMask() { * * @param colorMask The ColorMask */ - public void setColorMask(boolean[] colorMask) { + public void setColorMask(boolean[] colorMask) + { this.colorMask = colorMask; } @Override - public int[] getCullFace() { + public int[] getCullFace() + { return cullFace; } @@ -165,12 +176,14 @@ public int[] getCullFace() { * * @param cullFace The CullFace */ - public void setCullFace(int[] cullFace) { + public void setCullFace(int[] cullFace) + { this.cullFace = cullFace; } @Override - public int[] getDepthFunc() { + public int[] getDepthFunc() + { return depthFunc; } @@ -179,12 +192,14 @@ public int[] getDepthFunc() { * * @param depthFunc The DepthFunc */ - public void setDepthFunc(int[] depthFunc) { + public void setDepthFunc(int[] depthFunc) + { this.depthFunc = depthFunc; } @Override - public boolean[] getDepthMask() { + public boolean[] getDepthMask() + { return depthMask; } @@ -193,12 +208,14 @@ public boolean[] getDepthMask() { * * @param depthMask The DepthMask */ - public void setDepthMask(boolean[] depthMask) { + public void setDepthMask(boolean[] depthMask) + { this.depthMask = depthMask; } @Override - public float[] getDepthRange() { + public float[] getDepthRange() + { return depthRange; } @@ -207,12 +224,14 @@ public float[] getDepthRange() { * * @param depthRange The DepthRange */ - public void setDepthRange(float[] depthRange) { + public void setDepthRange(float[] depthRange) + { this.depthRange = depthRange; } @Override - public int[] getFrontFace() { + public int[] getFrontFace() + { return frontFace; } @@ -221,12 +240,14 @@ public int[] getFrontFace() { * * @param frontFace The FrontFace */ - public void setFrontFace(int[] frontFace) { + public void setFrontFace(int[] frontFace) + { this.frontFace = frontFace; } @Override - public float[] getLineWidth() { + public float[] getLineWidth() + { return lineWidth; } @@ -235,12 +256,14 @@ public float[] getLineWidth() { * * @param lineWidth The LineWidth */ - public void setLineWidth(float[] lineWidth) { + public void setLineWidth(float[] lineWidth) + { this.lineWidth = lineWidth; } @Override - public float[] getPolygonOffset() { + public float[] getPolygonOffset() + { return polygonOffset; } @@ -249,7 +272,8 @@ public float[] getPolygonOffset() { * * @param polygonOffset The PolygonOffset */ - public void setPolygonOffset(float[] polygonOffset) { + public void setPolygonOffset(float[] polygonOffset) + { this.polygonOffset = polygonOffset; } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesModel.java b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesModel.java index e359807..7a95745 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesModel.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/DefaultTechniqueStatesModel.java @@ -26,47 +26,52 @@ */ package de.javagl.jgltf.model.gl.impl; -import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; -import de.javagl.jgltf.model.gl.TechniqueStatesModel; - import java.util.ArrayList; import java.util.Collections; import java.util.List; +import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; +import de.javagl.jgltf.model.gl.TechniqueStatesModel; + /** * Implementation of a {@link TechniqueStatesModel} */ -public class DefaultTechniqueStatesModel implements TechniqueStatesModel { +public class DefaultTechniqueStatesModel implements TechniqueStatesModel +{ /** * The enabled states */ private final List enable; - + /** * The {@link TechniqueStatesFunctionsModel} */ private final TechniqueStatesFunctionsModel techniqueStatesFunctionsModel; - + /** * Default constructor - * - * @param enable The enabled states - * @param techniqueStatesFunctionsModel The {@link TechniqueStatesFunctionsModel} + * + * @param enable The enabled states + * @param techniqueStatesFunctionsModel + * The {@link TechniqueStatesFunctionsModel} */ - public DefaultTechniqueStatesModel(List enable, - TechniqueStatesFunctionsModel techniqueStatesFunctionsModel) { + public DefaultTechniqueStatesModel(List enable, + TechniqueStatesFunctionsModel techniqueStatesFunctionsModel) + { this.enable = Collections.unmodifiableList( - new ArrayList(enable)); + new ArrayList(enable)); this.techniqueStatesFunctionsModel = techniqueStatesFunctionsModel; } @Override - public List getEnable() { + public List getEnable() + { return enable; } @Override - public TechniqueStatesFunctionsModel getTechniqueStatesFunctionsModel() { + public TechniqueStatesFunctionsModel getTechniqueStatesFunctionsModel() + { return techniqueStatesFunctionsModel; } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/TechniqueStatesModels.java b/src/main/java/de/javagl/jgltf/model/gl/impl/TechniqueStatesModels.java index ecbf0c2..5c04fad 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/TechniqueStatesModels.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/TechniqueStatesModels.java @@ -26,65 +26,69 @@ */ package de.javagl.jgltf.model.gl.impl; +import java.util.Arrays; +import java.util.List; + import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; import de.javagl.jgltf.model.GltfConstants; import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; import de.javagl.jgltf.model.gl.TechniqueStatesModel; import de.javagl.jgltf.model.v1.gl.TechniqueStatesFunctionsModels; -import java.util.Arrays; -import java.util.List; - /** * Methods to create {@link TechniqueStatesModel} instances */ -public class TechniqueStatesModels { - /** - * Private constructor to prevent instantiation - */ - private TechniqueStatesModels() { - // Private constructor to prevent instantiation - } - +public class TechniqueStatesModels +{ /** * Create a default {@link TechniqueStatesModel} - * + * * @return The {@link TechniqueStatesModel} */ - public static TechniqueStatesModel createDefault() { - TechniqueStatesModel techniqueStatesModel = - new DefaultTechniqueStatesModel( - createDefaultTechniqueStatesEnable(), - createDefaultTechniqueStatesFunctions()); + public static TechniqueStatesModel createDefault() + { + TechniqueStatesModel techniqueStatesModel = + new DefaultTechniqueStatesModel( + createDefaultTechniqueStatesEnable(), + createDefaultTechniqueStatesFunctions()); return techniqueStatesModel; } - + /** * Create the default {@link TechniqueStatesFunctionsModel} - * * @return The {@link TechniqueStatesFunctionsModel} */ - public static TechniqueStatesFunctionsModel - createDefaultTechniqueStatesFunctions() { - TechniqueStatesFunctions functions = - de.javagl.jgltf.model.v1.gl.Techniques - .createDefaultTechniqueStatesFunctions(); + public static TechniqueStatesFunctionsModel + createDefaultTechniqueStatesFunctions() + { + TechniqueStatesFunctions functions = + de.javagl.jgltf.model.v1.gl.Techniques + .createDefaultTechniqueStatesFunctions(); TechniqueStatesFunctionsModel techniqueStatesFunctionsModel = - TechniqueStatesFunctionsModels.create(functions); + TechniqueStatesFunctionsModels.create(functions); return techniqueStatesFunctionsModel; } - + /** * Returns the default {@link TechniqueStatesModel#getEnable() enable} - * states - * + * states + * * @return The default enable states */ - public static List createDefaultTechniqueStatesEnable() { + public static List createDefaultTechniqueStatesEnable() + { List enable = Arrays.asList( - GltfConstants.GL_DEPTH_TEST, - GltfConstants.GL_CULL_FACE + GltfConstants.GL_DEPTH_TEST, + GltfConstants.GL_CULL_FACE ); return enable; } + + /** + * Private constructor to prevent instantiation + */ + private TechniqueStatesModels() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/gl/impl/package-info.java b/src/main/java/de/javagl/jgltf/model/gl/impl/package-info.java index bb2a352..7402989 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/impl/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/gl/impl/package-info.java @@ -1,6 +1,6 @@ /** * Implementations of the de.javagl.jgltf.model.gl classes.
    - *
    + *
    * These classes should not be considered to be part of the public API. */ package de.javagl.jgltf.model.gl.impl; diff --git a/src/main/java/de/javagl/jgltf/model/gl/package-info.java b/src/main/java/de/javagl/jgltf/model/gl/package-info.java index 3f5120f..e0ddcaf 100644 --- a/src/main/java/de/javagl/jgltf/model/gl/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/gl/package-info.java @@ -1,5 +1,5 @@ /** - * Classes for modeling OpenGL rendering techniques. + * Classes for modeling OpenGL rendering techniques. */ package de.javagl.jgltf.model.gl; diff --git a/src/main/java/de/javagl/jgltf/model/image/DefaultPixelData.java b/src/main/java/de/javagl/jgltf/model/image/DefaultPixelData.java index 752f6ec..80a1963 100644 --- a/src/main/java/de/javagl/jgltf/model/image/DefaultPixelData.java +++ b/src/main/java/de/javagl/jgltf/model/image/DefaultPixelData.java @@ -31,47 +31,52 @@ /** * Default implementation of a {@link PixelData} */ -final class DefaultPixelData implements PixelData { +final class DefaultPixelData implements PixelData +{ /** * The width */ private final int width; - + /** * The height */ private final int height; - + /** * The pixels, as RGBA values */ private final ByteBuffer pixelsRGBA; - + /** * Creates a new instance - * - * @param width The width - * @param height The height + * + * @param width The width + * @param height The height * @param pixelsRGBA The pixels, as RGBA values */ - DefaultPixelData(int width, int height, ByteBuffer pixelsRGBA) { + DefaultPixelData(int width, int height, ByteBuffer pixelsRGBA) + { this.width = width; this.height = height; this.pixelsRGBA = pixelsRGBA; } - + @Override - public int getWidth() { + public int getWidth() + { return width; } @Override - public int getHeight() { + public int getHeight() + { return height; } @Override - public ByteBuffer getPixelsRGBA() { + public ByteBuffer getPixelsRGBA() + { // The slice is BIG_ENDIAN by default return pixelsRGBA.slice(); } diff --git a/src/main/java/de/javagl/jgltf/model/image/ImageReaders.java b/src/main/java/de/javagl/jgltf/model/image/ImageReaders.java index 77dd47b..c2467c0 100644 --- a/src/main/java/de/javagl/jgltf/model/image/ImageReaders.java +++ b/src/main/java/de/javagl/jgltf/model/image/ImageReaders.java @@ -26,16 +26,17 @@ */ package de.javagl.jgltf.model.image; -import de.javagl.jgltf.model.io.Buffers; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.stream.ImageInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.util.Iterator; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; + +import de.javagl.jgltf.model.io.Buffers; + /** * Utility methods to find ImageReader instances for given * image data.
    @@ -43,39 +44,43 @@ * This class should not be considered as part of the public API. It may * change or be omitted in the future. */ -public class ImageReaders { - /** - * Private constructor to prevent instantiation - */ - private ImageReaders() { - // Private constructor to prevent instantiation - } - +public class ImageReaders +{ /** * Tries to find an ImageReader that is capable of reading * the given image data. The returned image reader will be initialized * by passing an ImageInputStream that is created from the given data - * to its setInput method. The caller is responsible for + * to its setInput method. The caller is responsible for * disposing the returned image reader. - * + * * @param imageData The image data * @return The image reader * @throws IOException If no matching image reader can be found */ @SuppressWarnings("resource") - public static ImageReader findImageReader(ByteBuffer imageData) - throws IOException { - InputStream inputStream = - Buffers.createByteBufferInputStream(imageData.slice()); - ImageInputStream imageInputStream = - ImageIO.createImageInputStream(inputStream); - Iterator imageReaders = - ImageIO.getImageReaders(imageInputStream); - if (imageReaders.hasNext()) { + public static ImageReader findImageReader(ByteBuffer imageData) + throws IOException + { + InputStream inputStream = + Buffers.createByteBufferInputStream(imageData.slice()); + ImageInputStream imageInputStream = + ImageIO.createImageInputStream(inputStream); + Iterator imageReaders = + ImageIO.getImageReaders(imageInputStream); + if (imageReaders.hasNext()) + { ImageReader imageReader = imageReaders.next(); imageReader.setInput(imageInputStream); return imageReader; } throw new IOException("Could not find ImageReader for image data"); } + + /** + * Private constructor to prevent instantiation + */ + private ImageReaders() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/image/ImageUtils.java b/src/main/java/de/javagl/jgltf/model/image/ImageUtils.java index cfa4cd2..c10eead 100644 --- a/src/main/java/de/javagl/jgltf/model/image/ImageUtils.java +++ b/src/main/java/de/javagl/jgltf/model/image/ImageUtils.java @@ -26,10 +26,7 @@ */ package de.javagl.jgltf.model.image; -import de.javagl.jgltf.model.io.Buffers; - -import javax.imageio.ImageIO; -import java.awt.*; +import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; @@ -41,42 +38,45 @@ import java.nio.IntBuffer; import java.util.logging.Logger; +import javax.imageio.ImageIO; + +import de.javagl.jgltf.model.io.Buffers; + /** * Utility methods related to images.
    *
    * This class should not be considered to be part of the public API. */ -public class ImageUtils { +public class ImageUtils +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(ImageUtils.class.getName()); - - /** - * Private constructor to prevent instantiation - */ - private ImageUtils() { - // Private constructor to prevent instantiation - } - + private static final Logger logger = + Logger.getLogger(ImageUtils.class.getName()); + /** * Returns the contents of the given buffer as a BufferedImage. * Returns null if the given buffer is null. * If the data can not be converted into a buffered image, then an error * message is printed and null is returned. - * + * * @param byteBuffer The byte buffer * @return The buffered image */ - static BufferedImage readAsBufferedImage(ByteBuffer byteBuffer) { - if (byteBuffer == null) { + static BufferedImage readAsBufferedImage(ByteBuffer byteBuffer) + { + if (byteBuffer == null) + { return null; } - try (InputStream inputStream = - Buffers.createByteBufferInputStream(byteBuffer.slice())) { + try (InputStream inputStream = + Buffers.createByteBufferInputStream(byteBuffer.slice())) + { return ImageIO.read(inputStream); - } catch (IOException e) { + } + catch (IOException e) + { logger.severe(e.toString()); return null; } @@ -87,29 +87,32 @@ static BufferedImage readAsBufferedImage(ByteBuffer byteBuffer) { * the given image.
    *
    * The given image might become unmanaged/untrackable by this operation. - * - * @param inputImage The input image + * + * @param inputImage The input image * @param flipVertically Whether the contents of the image should be - * flipped vertically. This is always a hassle. + * flipped vertically. This is always a hassle. * @return The byte buffer containing the ARGB pixel values */ static ByteBuffer getImagePixelsARGB( - BufferedImage inputImage, boolean flipVertically) { + BufferedImage inputImage, boolean flipVertically) + { BufferedImage image = inputImage; - if (flipVertically) { + if (flipVertically) + { image = flipVertically(image); } - if (image.getType() != BufferedImage.TYPE_INT_ARGB) { + if (image.getType() != BufferedImage.TYPE_INT_ARGB) + { image = convertToARGB(image); } IntBuffer imageBuffer = getBuffer(image); - + // Note: The byte order is BIG_ENDIAN by default. This order // is kept here, to keep the ARGB order, and not convert them // to BGRA implicitly. ByteBuffer outputByteBuffer = ByteBuffer - .allocateDirect(imageBuffer.remaining() * Integer.BYTES) - .order(ByteOrder.BIG_ENDIAN); + .allocateDirect(imageBuffer.remaining() * Integer.BYTES) + .order(ByteOrder.BIG_ENDIAN); IntBuffer output = outputByteBuffer.asIntBuffer(); output.put(imageBuffer.slice()); return outputByteBuffer; @@ -118,188 +121,211 @@ static ByteBuffer getImagePixelsARGB( /** * Interpret the given byte buffer as ARGB pixels, and convert it into * a direct byte buffer containing the corresponding RGBA pixels - * + * * @param pixels The input pixels * @return The output pixels */ - static ByteBuffer swizzleARGBtoRGBA(ByteBuffer pixels) { + static ByteBuffer swizzleARGBtoRGBA(ByteBuffer pixels) + { return swizzle(pixels, 16, 8, 0, 24); } /** * Interpret the given byte buffer as RGBA pixels, and convert it into * a direct byte buffer containing the corresponding ARGB pixels - * + * * @param pixels The input pixels * @return The output pixels */ - static ByteBuffer swizzleRGBAtoARGB(ByteBuffer pixels) { + static ByteBuffer swizzleRGBAtoARGB(ByteBuffer pixels) + { return swizzle(pixels, 0, 24, 16, 8); } - + /** * Interpret the given byte buffer as pixels, swizzle the bytes - * of these pixels according to the given shifts, and return a + * of these pixels according to the given shifts, and return a * a direct byte buffer containing the corresponding new pixels - * + * * @param pixels The input pixels - * @param s0 The right-shift for byte 0 - * @param s1 The right-shift for byte 1 - * @param s2 The right-shift for byte 2 - * @param s3 The right-shift for byte 3 + * @param s0 The right-shift for byte 0 + * @param s1 The right-shift for byte 1 + * @param s2 The right-shift for byte 2 + * @param s3 The right-shift for byte 3 * @return The output pixels */ private static ByteBuffer swizzle(ByteBuffer pixels, - int s0, int s1, int s2, int s3) { + int s0, int s1, int s2, int s3) + { IntBuffer iBuffer = pixels.asIntBuffer(); ByteBuffer oByteBuffer = ByteBuffer - .allocateDirect(iBuffer.capacity() * Integer.BYTES) - .order(pixels.order()); + .allocateDirect(iBuffer.capacity() * Integer.BYTES) + .order(pixels.order()); IntBuffer oBuffer = oByteBuffer.asIntBuffer(); - for (int i = 0; i < iBuffer.capacity(); i++) { + for (int i = 0; i < iBuffer.capacity(); i++) + { int input = iBuffer.get(i); int output = swizzle(input, s0, s1, s2, s3); oBuffer.put(i, output); } return oByteBuffer; } - + /** * Swizzle the bytes of the given input according to the given shifts - * - * @param input The input - * @param s0 The right-shift for byte 0 - * @param s1 The right-shift for byte 1 - * @param s2 The right-shift for byte 2 - * @param s3 The right-shift for byte 3 + * + * @param input The input + * @param s0 The right-shift for byte 0 + * @param s1 The right-shift for byte 1 + * @param s2 The right-shift for byte 2 + * @param s3 The right-shift for byte 3 * @return The output */ - private static int swizzle(int input, int s0, int s1, int s2, int s3) { - int b0 = (input >> s0) & 0xFF; - int b1 = (input >> s1) & 0xFF; - int b2 = (input >> s2) & 0xFF; + private static int swizzle(int input, int s0, int s1, int s2, int s3) + { + int b0 = (input >> s0) & 0xFF; + int b1 = (input >> s1) & 0xFF; + int b2 = (input >> s2) & 0xFF; int b3 = (input >> s3) & 0xFF; return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; } - + /** * Convert the given image into a buffered image with the type * TYPE_INT_ARGB. - * + * * @param image The input image * @return The converted image */ - private static BufferedImage convertToARGB(BufferedImage image) { + private static BufferedImage convertToARGB(BufferedImage image) + { BufferedImage newImage = new BufferedImage( - image.getWidth(), image.getHeight(), - BufferedImage.TYPE_INT_ARGB); + image.getWidth(), image.getHeight(), + BufferedImage.TYPE_INT_ARGB); Graphics2D g = newImage.createGraphics(); g.drawImage(image, 0, 0, null); g.dispose(); return newImage; } - + /** - * Create a vertically flipped version of the given image. - * + * Create a vertically flipped version of the given image. + * * @param image The input image * @return The flipped image */ - private static BufferedImage flipVertically(BufferedImage image) { + private static BufferedImage flipVertically(BufferedImage image) + { int w = image.getWidth(); int h = image.getHeight(); BufferedImage newImage = new BufferedImage( - w, h, BufferedImage.TYPE_INT_ARGB); + w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g = newImage.createGraphics(); g.drawImage(image, 0, h, w, -h, null); g.dispose(); return newImage; } - + /** * Returns the data buffer of the given image as an IntBuffer. The given * image will become unmanaged/untrackable by this call. - * + * * @param image The image * @return The data from the image as an IntBuffer * @throws IllegalArgumentException If the given image is not - * backed by a DataBufferInt + * backed by a DataBufferInt */ - private static IntBuffer getBuffer(BufferedImage image) { + private static IntBuffer getBuffer(BufferedImage image) + { DataBuffer dataBuffer = image.getRaster().getDataBuffer(); - if (!(dataBuffer instanceof DataBufferInt)) { + if (!(dataBuffer instanceof DataBufferInt)) + { throw new IllegalArgumentException( - "Invalid buffer type in image, " + - "only TYPE_INT_* is allowed"); + "Invalid buffer type in image, " + + "only TYPE_INT_* is allowed"); } - DataBufferInt dataBufferInt = (DataBufferInt) dataBuffer; + DataBufferInt dataBufferInt = (DataBufferInt)dataBuffer; int data[] = dataBufferInt.getData(); IntBuffer intBuffer = IntBuffer.wrap(data); return intBuffer; } - + /** * Create a buffered image from the given {@link PixelData} - * + * * @param pixelData The {@link PixelData} * @return The buffered image */ - public static BufferedImage createBufferedImage(PixelData pixelData) { + public static BufferedImage createBufferedImage(PixelData pixelData) + { int w = pixelData.getWidth(); int h = pixelData.getHeight(); BufferedImage image = new BufferedImage( - w, h, BufferedImage.TYPE_INT_ARGB); + w, h, BufferedImage.TYPE_INT_ARGB); IntBuffer imageBuffer = getBuffer(image); ByteBuffer pixels = pixelData.getPixelsRGBA(); ByteBuffer argbBytes = swizzleRGBAtoARGB(pixels); imageBuffer.put(argbBytes.asIntBuffer()); return image; } - + /** * Creates the byte buffer containing the image data for the given * pixel data, with the given MIME type.
    *
    - * The MIME type must be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
    + * The MIME type must be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
    *
    * If the image data cannot be written, then an error message is * printed and null is returned. - * + * * @param pixelData The {@link PixelData} - * @param mimeType The MIME type + * @param mimeType The MIME type * @return The byte buffer * @throws IllegalArgumentException If the MIME type is not one of the - * types listed above + * types listed above */ public static ByteBuffer createImageDataBuffer( - PixelData pixelData, String mimeType) { + PixelData pixelData, String mimeType) + { String formatName = null; - if ("image/gif".equals(mimeType)) { + if ("image/gif".equals(mimeType)) + { formatName = "gif"; - } else if ("image/jpeg".equals(mimeType)) { + } + else if ("image/jpeg".equals(mimeType)) + { formatName = "jpg"; - } else if ("image/png".equals(mimeType)) { + } + else if ("image/png".equals(mimeType)) + { formatName = "png"; - } else { + } + else + { throw new IllegalArgumentException( - "The MIME type string must be \"image/gif\", " - + "\"image/jpeg\" or \"image/png\", but is " + mimeType); + "The MIME type string must be \"image/gif\", " + + "\"image/jpeg\" or \"image/png\", but is " + mimeType); } BufferedImage image = ImageUtils.createBufferedImage(pixelData); - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) + { ImageIO.write(image, formatName, baos); return Buffers.create(baos.toByteArray()); - } catch (IOException e) { + } + catch (IOException e) + { logger.severe(e.toString()); return null; } } - + + // Only a basic test for the swizzling @SuppressWarnings("javadoc") - public static void main(String[] args) { + public static void main(String[] args) + { int input = 0x11223344; ByteBuffer b0 = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN); b0.asIntBuffer().put(input); @@ -307,10 +333,18 @@ public static void main(String[] args) { int rgba = b1.asIntBuffer().get(); ByteBuffer b2 = swizzleRGBAtoARGB(b1); int argb = b2.asIntBuffer().get(); - + System.out.println("Input: " + Integer.toHexString(input)); System.out.println("RGBA : " + Integer.toHexString(rgba)); System.out.println("ARGB : " + Integer.toHexString(argb)); } + /** + * Private constructor to prevent instantiation + */ + private ImageUtils() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/image/PixelData.java b/src/main/java/de/javagl/jgltf/model/image/PixelData.java index 581e15e..dc2e91b 100644 --- a/src/main/java/de/javagl/jgltf/model/image/PixelData.java +++ b/src/main/java/de/javagl/jgltf/model/image/PixelData.java @@ -33,25 +33,26 @@ *
    * This class should not be considered to be part of the public API. */ -public interface PixelData { +public interface PixelData +{ /** * Returns the width of the image - * + * * @return The width */ int getWidth(); /** * Returns the height of the image - * + * * @return The height */ int getHeight(); /** - * Returns a new slice of the direct byte buffer containing the pixel + * Returns a new slice of the direct byte buffer containing the pixel * data, as RGBA values - * + * * @return The pixels */ ByteBuffer getPixelsRGBA(); diff --git a/src/main/java/de/javagl/jgltf/model/image/PixelDatas.java b/src/main/java/de/javagl/jgltf/model/image/PixelDatas.java index 7f11dcf..d754b68 100644 --- a/src/main/java/de/javagl/jgltf/model/image/PixelDatas.java +++ b/src/main/java/de/javagl/jgltf/model/image/PixelDatas.java @@ -37,57 +37,54 @@ *
    * This class should not be considered to be part of the public API. */ -public class PixelDatas { +public class PixelDatas +{ /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(PixelDatas.class.getName()); - - /** - * Private constructor to prevent instantiation - */ - private PixelDatas() { - // Private constructor to prevent instantiation - } - + Logger.getLogger(PixelDatas.class.getName()); + /** * Create a {@link PixelData} from the given image data. The image data * may for example the the raw data of a JPG or PNG or GIF file. The * exact set of supported file formats is not specified. If the given * data can not be read, then a warning is printed and null * is returned. - * + * * @param imageData The image data * @return The {@link PixelData} */ - public static PixelData create(ByteBuffer imageData) { + public static PixelData create(ByteBuffer imageData) + { BufferedImage textureImage = ImageUtils.readAsBufferedImage(imageData); - if (textureImage == null) { + if (textureImage == null) + { logger.warning("Could not read image from image data"); return null; } - - ByteBuffer pixelDataARGB = - ImageUtils.getImagePixelsARGB(textureImage, false); + + ByteBuffer pixelDataARGB = + ImageUtils.getImagePixelsARGB(textureImage, false); ByteBuffer pixelDataRGBA = - ImageUtils.swizzleARGBtoRGBA(pixelDataARGB); + ImageUtils.swizzleARGBtoRGBA(pixelDataARGB); int width = textureImage.getWidth(); int height = textureImage.getHeight(); return new DefaultPixelData(width, height, pixelDataRGBA); } - + /** - * Create an unspecified {@link PixelData} object that may be used as + * Create an unspecified {@link PixelData} object that may be used as * a placeholder for image data that could not be read - * + * * @return The {@link PixelData} object */ - public static PixelData createErrorPixelData() { + public static PixelData createErrorPixelData() + { // Right now, this is a 2x2 checkerboard of red and white pixels ByteBuffer pixelDataRGBA = ByteBuffer.allocateDirect(4 * Integer.SIZE); - IntBuffer intPixelDataRGBA = - pixelDataRGBA.order(ByteOrder.BIG_ENDIAN).asIntBuffer(); + IntBuffer intPixelDataRGBA = + pixelDataRGBA.order(ByteOrder.BIG_ENDIAN).asIntBuffer(); intPixelDataRGBA.put(0, 0xFF0000FF); intPixelDataRGBA.put(1, 0xFFFFFFFF); intPixelDataRGBA.put(2, 0xFF0000FF); @@ -96,4 +93,13 @@ public static PixelData createErrorPixelData() { int height = 2; return new DefaultPixelData(width, height, pixelDataRGBA); } + + + /** + * Private constructor to prevent instantiation + */ + private PixelDatas() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/AbstractModelElement.java b/src/main/java/de/javagl/jgltf/model/impl/AbstractModelElement.java index ae96a25..8e915aa 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/AbstractModelElement.java +++ b/src/main/java/de/javagl/jgltf/model/impl/AbstractModelElement.java @@ -26,38 +26,51 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.ModelElement; - import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; +import de.javagl.jgltf.model.ModelElement; + /** * Abstract base implementation of the {@link ModelElement} interface. */ -public class AbstractModelElement implements ModelElement { +public class AbstractModelElement implements ModelElement +{ /** * The extensions */ private Map extensions; - + /** * The extras */ private Object extras; - + + /** + * Set the extensions to be a reference to the given map. + * + * @param extensions The extensions + */ + public void setExtensions(Map extensions) + { + this.extensions = extensions; + } + /** * Add the given extension to this object. - *

    + * * This will add the given key-value pair to the extensions map, * creating it if it was null. - * - * @param name The name of the extension + * + * @param name The name of the extension * @param extension The extension object */ - public void addExtension(String name, Object extension) { + public void addExtension(String name, Object extension) + { Objects.requireNonNull(name, "The name may not be null"); - if (this.extensions == null) { + if (this.extensions == null) + { this.extensions = new LinkedHashMap(); } this.extensions.put(name, extension); @@ -65,46 +78,44 @@ public void addExtension(String name, Object extension) { /** * Remove the specified extension from this object. - *

    + * * If the extension map is empty after this call, then it will be * set to null. - * + * * @param name The name of the extension */ - public void removeExtension(String name) { - if (this.extensions != null) { + public void removeExtension(String name) + { + if (this.extensions != null) + { this.extensions.remove(name); - if (this.extensions.isEmpty()) { + if (this.extensions.isEmpty()) + { this.extensions = null; } } } - - @Override - public Map getExtensions() { - return extensions; - } - - /** - * Set the extensions to be a reference to the given map. - * - * @param extensions The extensions - */ - public void setExtensions(Map extensions) { - this.extensions = extensions; - } - - @Override - public Object getExtras() { - return extras; - } + /** * Set the extras - * + * * @param extras The extras */ - public void setExtras(Object extras) { + public void setExtras(Object extras) + { this.extras = extras; } + + @Override + public Map getExtensions() + { + return extensions; + } + + @Override + public Object getExtras() + { + return extras; + } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/AbstractNamedModelElement.java b/src/main/java/de/javagl/jgltf/model/impl/AbstractNamedModelElement.java index 7acf52c..e8ffe93 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/AbstractNamedModelElement.java +++ b/src/main/java/de/javagl/jgltf/model/impl/AbstractNamedModelElement.java @@ -31,25 +31,28 @@ /** * Abstract base implementation of the {@link NamedModelElement} interface. */ -public class AbstractNamedModelElement extends AbstractModelElement - implements NamedModelElement { +public class AbstractNamedModelElement extends AbstractModelElement + implements NamedModelElement +{ /** * The name */ private String name; - + @Override - public String getName() { + public String getName() + { return name; } - + /** - * Set the name of this model element, or null if this + * Set the name of this model element, or null if this * model element does not have a name. - * + * * @param name The optional name */ - public void setName(String name) { + public void setName(String name) + { this.name = name; } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/Cameras.java b/src/main/java/de/javagl/jgltf/model/impl/Cameras.java index 2e091a0..debf755 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/Cameras.java +++ b/src/main/java/de/javagl/jgltf/model/impl/Cameras.java @@ -26,72 +26,80 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.*; - import java.util.logging.Logger; +import de.javagl.jgltf.model.CameraModel; +import de.javagl.jgltf.model.CameraOrthographicModel; +import de.javagl.jgltf.model.CameraPerspectiveModel; +import de.javagl.jgltf.model.MathUtils; +import de.javagl.jgltf.model.Utils; + /** * Utility methods related to cameras */ -class Cameras { +class Cameras +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(Cameras.class.getName()); - - /** - * Private constructor to prevent instantiation - */ - private Cameras() { - // Private constructor to prevent instantiation - } - + private static final Logger logger = + Logger.getLogger(Cameras.class.getName()); + /** - * Compute the projection matrix for the given {@link CameraModel}. If the - * camera is neither perspective orthographic, then an error message will + * Compute the projection matrix for the given {@link CameraModel}. If the + * camera is neither perspective orthographic, then an error message will * be printed, and the result will be the identity matrix.
    *
    - * The result will be written to the given array, as a 4x4 matrix in + * The result will be written to the given array, as a 4x4 matrix in * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * * @param cameraModel The {@link CameraModel} - * @param aspectRatio An optional aspect ratio to use. If this is - * null, then the aspect ratio of the camera will be used. - * @param result The array storing the result + * @param aspectRatio An optional aspect ratio to use. If this is + * null, then the aspect ratio of the camera will be used. + * @param result The array storing the result * @return The result array */ static float[] computeProjectionMatrix( - CameraModel cameraModel, Float aspectRatio, float result[]) { + CameraModel cameraModel, Float aspectRatio, float result[]) + { float localResult[] = Utils.validate(result, 16); + + CameraPerspectiveModel cameraPerspective = + cameraModel.getCameraPerspectiveModel(); - CameraPerspectiveModel cameraPerspective = - cameraModel.getCameraPerspectiveModel(); - - CameraOrthographicModel cameraOrthographic = - cameraModel.getCameraOrthographicModel(); - - if (cameraPerspective != null) { + CameraOrthographicModel cameraOrthographic = + cameraModel.getCameraOrthographicModel(); + + if (cameraPerspective != null) + { float fovRad = cameraPerspective.getYfov(); - float fovDeg = (float) Math.toDegrees(fovRad); + float fovDeg = (float)Math.toDegrees(fovRad); float localAspectRatio = 1.0f; - if (aspectRatio != null) { + if (aspectRatio != null) + { localAspectRatio = aspectRatio; - } else if (cameraPerspective.getAspectRatio() != null) { + } + else if (cameraPerspective.getAspectRatio() != null) + { localAspectRatio = cameraPerspective.getAspectRatio(); } float zNear = cameraPerspective.getZnear(); Float zFar = cameraPerspective.getZfar(); - if (zFar == null) { + if (zFar == null) + { MathUtils.infinitePerspective4x4( - fovDeg, localAspectRatio, zNear, localResult); - } else { + fovDeg, localAspectRatio, zNear, localResult); + } + else + { MathUtils.perspective4x4( - fovDeg, localAspectRatio, zNear, zFar, localResult); + fovDeg, localAspectRatio, zNear, zFar, localResult); } - } else if (cameraOrthographic != null) { + } + else if (cameraOrthographic != null) + { float xMag = cameraOrthographic.getXmag(); float yMag = cameraOrthographic.getYmag(); float zNear = cameraOrthographic.getZnear(); @@ -101,10 +109,20 @@ static float[] computeProjectionMatrix( localResult[5] = 1.0f / yMag; localResult[10] = 2.0f / (zNear - zFar); localResult[14] = (zFar + zNear) / (zNear - zFar); - } else { + } + else + { logger.severe("Invalid camera type: " + cameraModel); MathUtils.setIdentity4x4(localResult); } return localResult; } + + /** + * Private constructor to prevent instantiation + */ + private Cameras() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultAccessorModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultAccessorModel.java index 1381898..947460f 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultAccessorModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultAccessorModel.java @@ -26,195 +26,230 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.*; +import de.javagl.jgltf.model.AccessorData; +import de.javagl.jgltf.model.AccessorDatas; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.Accessors; +import de.javagl.jgltf.model.BufferViewModel; +import de.javagl.jgltf.model.ElementType; /** * Implementation of an {@link AccessorModel} */ public final class DefaultAccessorModel extends AbstractNamedModelElement - implements AccessorModel { + implements AccessorModel +{ /** * The component type, as a GL constant */ private final int componentType; - /** - * The {@link ElementType} of this accessor - */ - private final ElementType elementType; - /** - * The number of elements - */ - private final int count; + /** * Whether the accessor is normalized */ private boolean normalized; + /** * The offset in bytes, referring to the buffer view */ private int byteOffset; + /** * The {@link BufferViewModel} for this model */ private BufferViewModel bufferViewModel; + + /** + * The {@link ElementType} of this accessor + */ + private final ElementType elementType; + + /** + * The number of elements + */ + private final int count; + /** * The stride between the start of one element and the next */ private int byteStride; - + /** * The {@link AccessorData} */ private AccessorData accessorData; - + /** * The minimum components */ private Number[] max; - + /** * The maximum components */ private Number[] min; - + /** * Creates a new instance - * + * * @param componentType The component type GL constant - * @param count The number of elements - * @param elementType The element type + * @param count The number of elements + * @param elementType The element type */ public DefaultAccessorModel( - int componentType, - int count, - ElementType elementType) { + int componentType, + int count, + ElementType elementType) + { this.componentType = componentType; this.count = count; this.elementType = elementType; this.byteStride = elementType.getByteStride(componentType); } - - @Override - public BufferViewModel getBufferViewModel() { - return bufferViewModel; - } - + /** * Set the {@link BufferViewModel} for this model - * + * * @param bufferViewModel The {@link BufferViewModel} */ - public void setBufferViewModel(BufferViewModel bufferViewModel) { + public void setBufferViewModel(BufferViewModel bufferViewModel) + { this.bufferViewModel = bufferViewModel; } + + /** + * Set the byte offset, referring to the {@link BufferViewModel} + * + * @param byteOffset The byte offset + */ + public void setByteOffset(int byteOffset) + { + this.byteOffset = byteOffset; + } + + /** + * Set the byte stride, indicating the number of bytes between the start + * of one element and the start of the next element. + * + * @param byteStride The byte stride + */ + public void setByteStride(int byteStride) + { + this.byteStride = byteStride; + } @Override - public int getComponentType() { + public BufferViewModel getBufferViewModel() + { + return bufferViewModel; + } + + @Override + public int getComponentType() + { return componentType; } - + @Override - public Class getComponentDataType() { + public Class getComponentDataType() + { return Accessors.getDataTypeForAccessorComponentType( - getComponentType()); + getComponentType()); } - + @Override - public boolean isNormalized() { + public boolean isNormalized() + { return normalized; } - + /** * Set whether the underlying data is normalized - * - * @param normalized Whether the underlying data is normalized + * + * @param normalized Whether the underlying data is normalized */ - public void setNormalized(boolean normalized) { + public void setNormalized(boolean normalized) + { this.normalized = normalized; } - + @Override - public int getComponentSizeInBytes() { + public int getComponentSizeInBytes() + { return Accessors.getNumBytesForAccessorComponentType(componentType); } - + @Override - public int getElementSizeInBytes() { + public int getElementSizeInBytes() + { return elementType.getNumComponents() * getComponentSizeInBytes(); } - + @Override - public int getPaddedElementSizeInBytes() { + public int getPaddedElementSizeInBytes() + { return elementType.getByteStride(componentType); } - + @Override - public int getByteOffset() { + public int getByteOffset() + { return byteOffset; } - - /** - * Set the byte offset, referring to the {@link BufferViewModel} - * - * @param byteOffset The byte offset - */ - public void setByteOffset(int byteOffset) { - this.byteOffset = byteOffset; - } - + @Override - public int getCount() { + public int getCount() + { return count; } - + @Override - public ElementType getElementType() { + public ElementType getElementType() + { return elementType; } - + @Override - public int getByteStride() { + public int getByteStride() + { return byteStride; } - - /** - * Set the byte stride, indicating the number of bytes between the start - * of one element and the start of the next element. - * - * @param byteStride The byte stride - */ - public void setByteStride(int byteStride) { - this.byteStride = byteStride; - } - - @Override - public AccessorData getAccessorData() { - return accessorData; - } - + /** * Set the {@link AccessorData} for this accessor - * + * * @param accessorData The {@link AccessorData} */ - public void setAccessorData(AccessorData accessorData) { + public void setAccessorData(AccessorData accessorData) + { this.accessorData = accessorData; } - + @Override - public Number[] getMin() { - if (min == null) { + public AccessorData getAccessorData() + { + return accessorData; + } + + + @Override + public Number[] getMin() + { + if (min == null) + { min = AccessorDatas.computeMin(getAccessorData()); } return min.clone(); } - + @Override - public Number[] getMax() { - if (max == null) { + public Number[] getMax() + { + if (max == null) + { max = AccessorDatas.computeMax(getAccessorData()); } return max.clone(); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultAnimationModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultAnimationModel.java index 52a48f9..d6c565c 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultAnimationModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultAnimationModel.java @@ -26,157 +26,171 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.AccessorModel; -import de.javagl.jgltf.model.AnimationModel; -import de.javagl.jgltf.model.NodeModel; - import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.AnimationModel; +import de.javagl.jgltf.model.NodeModel; + /** * Implementation of an {@link AnimationModel} */ public class DefaultAnimationModel extends AbstractNamedModelElement - implements AnimationModel { - /** - * The {@link Channel} instances - * of this animation - */ - private final List channels; - - /** - * Creates a new instance - */ - public DefaultAnimationModel() { - this.channels = new ArrayList(); - } - - /** - * Add the given {@link Channel} - * - * @param channel The {@link Channel} - */ - public void addChannel(Channel channel) { - Objects.requireNonNull(channel, "The channel may not be null"); - this.channels.add(channel); - } - - @Override - public List getChannels() { - return Collections.unmodifiableList(channels); - } - + implements AnimationModel +{ /** - * Default implementation of a + * Default implementation of a * {@link Sampler} */ - public static class DefaultSampler implements Sampler { + public static class DefaultSampler implements Sampler + { /** * The input data */ private final AccessorModel input; - + /** * The interpolation method */ private final Interpolation interpolation; - + /** * The output data */ private final AccessorModel output; - + /** * Default constructor - * - * @param input The input + * + * @param input The input * @param interpolation The interpolation - * @param output The output + * @param output The output */ public DefaultSampler( - AccessorModel input, - Interpolation interpolation, - AccessorModel output) { + AccessorModel input, + Interpolation interpolation, + AccessorModel output) + { this.input = Objects.requireNonNull( - input, "The input may not be null"); + input, "The input may not be null"); this.interpolation = Objects.requireNonNull( - interpolation, "The interpolation may not be null"); + interpolation, "The interpolation may not be null"); this.output = Objects.requireNonNull( - output, "The output may not be null"); + output, "The output may not be null"); } - + @Override - public AccessorModel getInput() { + public AccessorModel getInput() + { return input; } @Override - public Interpolation getInterpolation() { + public Interpolation getInterpolation() + { return interpolation; } @Override - public AccessorModel getOutput() { + public AccessorModel getOutput() + { return output; } } - + /** - * Default implementation of a + * Default implementation of a * {@link Channel} */ - public static class DefaultChannel implements Channel { + public static class DefaultChannel implements Channel + { /** * The sampler */ private final Sampler sampler; - + /** * The node model */ private final NodeModel nodeModel; - + /** * The path */ private final String path; - + /** * Default constructor - * - * @param sampler The sampler + * + * @param sampler The sampler * @param nodeModel The node model - * @param path The path + * @param path The path */ public DefaultChannel( - Sampler sampler, - NodeModel nodeModel, - String path) { + Sampler sampler, + NodeModel nodeModel, + String path) + { this.sampler = Objects.requireNonNull( - sampler, "The sampler may not be null"); + sampler, "The sampler may not be null"); this.nodeModel = nodeModel; this.path = Objects.requireNonNull( - path, "The path may not be null"); - + path, "The path may not be null"); + } - + @Override - public Sampler getSampler() { + public Sampler getSampler() + { return sampler; } @Override - public NodeModel getNodeModel() { + public NodeModel getNodeModel() + { return nodeModel; } @Override - public String getPath() { + public String getPath() + { return path; } - + } - + + /** + * The {@link Channel} instances + * of this animation + */ + private final List channels; + + /** + * Creates a new instance + */ + public DefaultAnimationModel() + { + this.channels = new ArrayList(); + } + + /** + * Add the given {@link Channel} + * + * @param channel The {@link Channel} + */ + public void addChannel(Channel channel) + { + Objects.requireNonNull(channel, "The channel may not be null"); + this.channels.add(channel); + } + + @Override + public List getChannels() + { + return Collections.unmodifiableList(channels); + } + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultAssetModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultAssetModel.java index 8bf40c8..eccf894 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultAssetModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultAssetModel.java @@ -32,7 +32,8 @@ * Default implementation of an {@link AssetModel} */ public class DefaultAssetModel extends AbstractNamedModelElement - implements AssetModel { + implements AssetModel +{ /** * The copyright */ @@ -43,31 +44,35 @@ public class DefaultAssetModel extends AbstractNamedModelElement */ private String generator; - @Override - public String getCopyright() { - return copyright; - } - /** * Set the copyright - * + * * @param copyright The copyright */ - public void setCopyright(String copyright) { + public void setCopyright(String copyright) + { this.copyright = copyright; } @Override - public String getGenerator() { - return generator; + public String getCopyright() + { + return copyright; } /** * Set the generator - * + * * @param generator The generator */ - public void setGenerator(String generator) { + public void setGenerator(String generator) + { this.generator = generator; } + + @Override + public String getGenerator() + { + return generator; + } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferModel.java index 087bfd1..62f63e4 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferModel.java @@ -26,64 +26,71 @@ */ package de.javagl.jgltf.model.impl; +import java.nio.ByteBuffer; + import de.javagl.jgltf.model.BufferModel; import de.javagl.jgltf.model.io.Buffers; -import java.nio.ByteBuffer; - /** * Implementation of a {@link BufferModel} */ public final class DefaultBufferModel extends AbstractNamedModelElement - implements BufferModel { + implements BufferModel +{ /** * The URI of the buffer data */ private String uri; - + /** * The actual data of the buffer */ private ByteBuffer bufferData; - + /** * Creates a new instance */ - public DefaultBufferModel() { + public DefaultBufferModel() + { // Default constructor } - - @Override - public String getUri() { - return uri; - } - + /** * Set the URI for the buffer data - * + * * @param uri The URI of the buffer data */ - public void setUri(String uri) { + public void setUri(String uri) + { this.uri = uri; } - @Override - public int getByteLength() { - return bufferData.capacity(); - } - - @Override - public ByteBuffer getBufferData() { - return Buffers.createSlice(bufferData); - } - /** * Set the data of this buffer - * + * * @param bufferData The buffer data */ - public void setBufferData(ByteBuffer bufferData) { + public void setBufferData(ByteBuffer bufferData) + { this.bufferData = bufferData; } + + @Override + public String getUri() + { + return uri; + } + @Override + public int getByteLength() + { + return bufferData.capacity(); + } + + @Override + public ByteBuffer getBufferData() + { + return Buffers.createSlice(bufferData); + } + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferViewModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferViewModel.java index 2405fe8..4eccc9b 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferViewModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultBufferViewModel.java @@ -26,146 +26,166 @@ */ package de.javagl.jgltf.model.impl; +import java.nio.ByteBuffer; +import java.util.function.Consumer; + import de.javagl.jgltf.model.BufferModel; import de.javagl.jgltf.model.BufferViewModel; import de.javagl.jgltf.model.io.Buffers; -import java.nio.ByteBuffer; -import java.util.function.Consumer; - /** * Implementation of a {@link BufferViewModel} */ public final class DefaultBufferViewModel extends AbstractNamedModelElement - implements BufferViewModel { - /** - * The optional target - */ - private final Integer target; + implements BufferViewModel +{ /** * The {@link BufferModel} for this model */ private BufferModel bufferModel; + /** * The byte offset */ private int byteOffset; + /** * The byte length */ private int byteLength; + /** * The byte stride */ private Integer byteStride; + + /** + * The optional target + */ + private final Integer target; + /** * An optional callback that will be used to perform the - * substitution of sparse accessor data in the + * substitution of sparse accessor data in the * {@link #getBufferViewData() buffer view data} - * when it is obtained for the first time. + * when it is obtained for the first time. */ private Consumer sparseSubstitutionCallback; - + /** * Whether the sparse substitution was already applied */ private boolean sparseSubstitutionApplied; - + /** * Creates a new instance - * + * * @param target The optional target */ - public DefaultBufferViewModel(Integer target) { + public DefaultBufferViewModel(Integer target) + { this.byteOffset = 0; this.byteLength = 0; this.target = target; } - + /** - * Set the callback that will perform the substitution of sparse accessor - * data in the {@link #getBufferViewData() buffer view data} when it is + * Set the callback that will perform the substitution of sparse accessor + * data in the {@link #getBufferViewData() buffer view data} when it is * obtained for the first time. - * + * * @param sparseSubstitutionCallback The callback */ public void setSparseSubstitutionCallback( - Consumer sparseSubstitutionCallback) { + Consumer sparseSubstitutionCallback) + { this.sparseSubstitutionCallback = sparseSubstitutionCallback; } - - @Override - public ByteBuffer getBufferViewData() { - ByteBuffer bufferData = bufferModel.getBufferData(); - ByteBuffer bufferViewData = - Buffers.createSlice(bufferData, getByteOffset(), getByteLength()); - if (sparseSubstitutionCallback != null && !sparseSubstitutionApplied) { - sparseSubstitutionCallback.accept(bufferViewData); - sparseSubstitutionApplied = true; - } - return bufferViewData; - } - - @Override - public BufferModel getBufferModel() { - return bufferModel; - } - + /** * Set the {@link BufferModel} for this model - * + * * @param bufferModel The {@link BufferModel} */ - public void setBufferModel(BufferModel bufferModel) { + public void setBufferModel(BufferModel bufferModel) + { this.bufferModel = bufferModel; } - - @Override - public int getByteOffset() { - return byteOffset; - } - + /** * Set the byte offset of this view referring to its {@link BufferModel} - * + * * @param byteOffset The byte offset */ - public void setByteOffset(int byteOffset) { + public void setByteOffset(int byteOffset) + { this.byteOffset = byteOffset; } - @Override - public int getByteLength() { - return byteLength; - } - /** * Set the byte length of this buffer view - * + * * @param byteLength The byte length */ - public void setByteLength(int byteLength) { + public void setByteLength(int byteLength) + { this.byteLength = byteLength; } - @Override - public Integer getByteStride() { - return byteStride; - } - /** - * Set the optional byte stride. This byte stride must be + * Set the optional byte stride. This byte stride must be * non-null if more than one accessor refers * to this buffer view. - * + * * @param byteStride The byte stride */ - public void setByteStride(Integer byteStride) { + public void setByteStride(Integer byteStride) + { this.byteStride = byteStride; } + + + @Override + public ByteBuffer getBufferViewData() + { + ByteBuffer bufferData = bufferModel.getBufferData(); + ByteBuffer bufferViewData = + Buffers.createSlice(bufferData, getByteOffset(), getByteLength()); + if (sparseSubstitutionCallback != null && !sparseSubstitutionApplied) + { + sparseSubstitutionCallback.accept(bufferViewData); + sparseSubstitutionApplied = true; + } + return bufferViewData; + } + + @Override + public BufferModel getBufferModel() + { + return bufferModel; + } + + @Override + public int getByteOffset() + { + return byteOffset; + } + + @Override + public int getByteLength() + { + return byteLength; + } + + @Override + public Integer getByteStride() + { + return byteStride; + } @Override - public Integer getTarget() { + public Integer getTarget() + { return target; } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraModel.java index fb446ce..b4f21d5 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraModel.java @@ -26,83 +26,92 @@ */ package de.javagl.jgltf.model.impl; +import java.util.function.DoubleSupplier; +import java.util.function.Supplier; + import de.javagl.jgltf.model.CameraModel; import de.javagl.jgltf.model.CameraOrthographicModel; import de.javagl.jgltf.model.CameraPerspectiveModel; import de.javagl.jgltf.model.Suppliers; -import java.util.function.DoubleSupplier; -import java.util.function.Supplier; - /** - * Implementation of a {@link CameraModel} + * Implementation of a {@link CameraModel} */ public final class DefaultCameraModel extends AbstractNamedModelElement - implements CameraModel { + implements CameraModel +{ /** * The {@link CameraOrthographicModel} */ private CameraOrthographicModel cameraOrthographicModel; - + /** * The {@link CameraPerspectiveModel} */ private CameraPerspectiveModel cameraPerspectiveModel; - + /** * Creates a new instance */ - public DefaultCameraModel() { + public DefaultCameraModel() + { // Default constructor } - - @Override - public CameraOrthographicModel getCameraOrthographicModel() { - return cameraOrthographicModel; - } - + /** * Set the {@link CameraOrthographicModel} - * + * * @param cameraOrthographicModel The {@link CameraOrthographicModel} */ public void setCameraOrthographicModel( - CameraOrthographicModel cameraOrthographicModel) { + CameraOrthographicModel cameraOrthographicModel) + { this.cameraOrthographicModel = cameraOrthographicModel; } - + @Override - public CameraPerspectiveModel getCameraPerspectiveModel() { - return cameraPerspectiveModel; + public CameraOrthographicModel getCameraOrthographicModel() + { + return cameraOrthographicModel; } - + /** * Set the {@link CameraPerspectiveModel} - * + * * @param cameraPerspectiveModel The {@link CameraPerspectiveModel} */ public void setCameraPerspectiveModel( - CameraPerspectiveModel cameraPerspectiveModel) { + CameraPerspectiveModel cameraPerspectiveModel) + { this.cameraPerspectiveModel = cameraPerspectiveModel; } + + @Override + public CameraPerspectiveModel getCameraPerspectiveModel() + { + return cameraPerspectiveModel; + } @Override - public float[] computeProjectionMatrix(float result[], Float aspectRatio) { + public float[] computeProjectionMatrix(float result[], Float aspectRatio) + { return Cameras.computeProjectionMatrix(this, aspectRatio, result); } - + @Override public Supplier createProjectionMatrixSupplier( - DoubleSupplier aspectRatioSupplier) { - return Suppliers.createTransformSupplier(this, (c, t) -> + DoubleSupplier aspectRatioSupplier) + { + return Suppliers.createTransformSupplier(this, (c, t) -> { Float aspectRatio = null; - if (aspectRatioSupplier != null) { - aspectRatio = (float) aspectRatioSupplier.getAsDouble(); + if (aspectRatioSupplier != null) + { + aspectRatio = (float)aspectRatioSupplier.getAsDouble(); } computeProjectionMatrix(t, aspectRatio); }); } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraOrthographicModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraOrthographicModel.java index c52b1d2..0f6ced7 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraOrthographicModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraOrthographicModel.java @@ -31,7 +31,8 @@ /** * Default implementation of a {@link CameraOrthographicModel} */ -public class DefaultCameraOrthographicModel implements CameraOrthographicModel { +public class DefaultCameraOrthographicModel implements CameraOrthographicModel +{ /** * The magnification in x-direction */ @@ -52,61 +53,69 @@ public class DefaultCameraOrthographicModel implements CameraOrthographicModel { */ private Float znear; - @Override - public Float getXmag() { - return xmag; - } - /** * Set the magnification in x-direction - * + * * @param xmag The magnification */ - public void setXmag(Float xmag) { + public void setXmag(Float xmag) + { this.xmag = xmag; } - @Override - public Float getYmag() { - return ymag; - } - /** * Set the magnification in y-direction - * + * * @param ymag The magnification */ - public void setYmag(Float ymag) { + public void setYmag(Float ymag) + { this.ymag = ymag; } - @Override - public Float getZfar() { - return zfar; - } - /** * Set the far clipping plane distance - * + * * @param zfar The distance */ - public void setZfar(Float zfar) { + public void setZfar(Float zfar) + { this.zfar = zfar; } - @Override - public Float getZnear() { - return znear; - } - /** * Set the near clipping plane distance - * + * * @param znear The distance */ - public void setZnear(Float znear) { + public void setZnear(Float znear) + { this.znear = znear; } + + @Override + public Float getXmag() + { + return xmag; + } + + @Override + public Float getYmag() + { + return ymag; + } + + @Override + public Float getZfar() + { + return zfar; + } + + @Override + public Float getZnear() + { + return znear; + } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraPerspectiveModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraPerspectiveModel.java index 0b190b9..6fdd0bc 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraPerspectiveModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultCameraPerspectiveModel.java @@ -31,7 +31,8 @@ /** * Default implementation of a {@link CameraPerspectiveModel} */ -public class DefaultCameraPerspectiveModel implements CameraPerspectiveModel { +public class DefaultCameraPerspectiveModel implements CameraPerspectiveModel +{ /** * The aspect ratio */ @@ -52,61 +53,69 @@ public class DefaultCameraPerspectiveModel implements CameraPerspectiveModel { */ private Float znear; - @Override - public Float getAspectRatio() { - return aspectRatio; - } - /** * Set the aspect ratio - * + * * @param aspectRatio The aspect ratio */ - public void setAspectRatio(Float aspectRatio) { + public void setAspectRatio(Float aspectRatio) + { this.aspectRatio = aspectRatio; } - @Override - public Float getYfov() { - return yfov; - } - /** * Set the FOV - * + * * @param yfov The FOV */ - public void setYfov(Float yfov) { + public void setYfov(Float yfov) + { this.yfov = yfov; } - @Override - public Float getZfar() { - return zfar; - } - /** * Set the far clipping plane distance - * + * * @param zfar The distance */ - public void setZfar(Float zfar) { + public void setZfar(Float zfar) + { this.zfar = zfar; } - @Override - public Float getZnear() { - return znear; - } - /** * Set the near clipping plane distance - * + * * @param znear The distance */ - public void setZnear(Float znear) { + public void setZnear(Float znear) + { this.znear = znear; } + + @Override + public Float getAspectRatio() + { + return aspectRatio; + } + + @Override + public Float getYfov() + { + return yfov; + } + + @Override + public Float getZfar() + { + return zfar; + } + + @Override + public Float getZnear() + { + return znear; + } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultExtensionsModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultExtensionsModel.java index ef4e172..9823d9f 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultExtensionsModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultExtensionsModel.java @@ -26,13 +26,18 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.ExtensionsModel; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; -import java.util.*; +import de.javagl.jgltf.model.ExtensionsModel; /** * Default implementation of an {@link ExtensionsModel}. - *

    + * * This implementation ensures a certain degree of consistency for * the extension information: *

      @@ -47,10 +52,11 @@ * *
    * (Of course, adding a "used" extension will not add it as a "required" one, - * and removing a "required" extension will not remove it as - * a "used" extension) + * and removing a "required" extension will not remove it as + * a "used" extension) */ -public class DefaultExtensionsModel implements ExtensionsModel { +public class DefaultExtensionsModel implements ExtensionsModel +{ /** * The used extensions */ @@ -64,38 +70,43 @@ public class DefaultExtensionsModel implements ExtensionsModel { /** * Default constructor */ - public DefaultExtensionsModel() { + public DefaultExtensionsModel() + { this.extensionsUsed = new LinkedHashSet(); this.extensionsRequired = new LinkedHashSet(); } /** * Add the given extension name to the "used" extensions. - * + * * @param extension The extension name. */ - public void addExtensionUsed(String extension) { + public void addExtensionUsed(String extension) + { this.extensionsUsed.add(extension); } /** * Remove the given extension name from the "used" extensions and * from the list of "required" extensions. - * + * * @param extension The extension name. */ - public void removeExtensionUsed(String extension) { + public void removeExtensionUsed(String extension) + { this.extensionsUsed.remove(extension); removeExtensionRequired(extension); } /** * Add the given extension names to the "used" extensions. - * + * * @param extensions The extension names */ - public void addExtensionsUsed(Collection extensions) { - if (extensions != null) { + public void addExtensionsUsed(Collection extensions) + { + if (extensions != null) + { this.extensionsUsed.addAll(extensions); } } @@ -103,49 +114,55 @@ public void addExtensionsUsed(Collection extensions) { /** * Clear the list of "used" extensions and the list of "required" extensions */ - public void clearExtensionUsed() { + public void clearExtensionUsed() + { this.extensionsUsed.clear(); clearExtensionRequired(); } @Override - public List getExtensionsUsed() { + public List getExtensionsUsed() + { return Collections.unmodifiableList( - new ArrayList(extensionsUsed)); + new ArrayList(extensionsUsed)); } - + /** * Add the given extension name to the "required" extensions and to * the "used" extensions. - * + * * @param extension The extension name. */ - public void addExtensionRequired(String extension) { + public void addExtensionRequired(String extension) + { this.extensionsRequired.add(extension); addExtensionUsed(extension); } /** * Remove the given extension name from the "required" extensions. - *

    + * * (Note that this will not remove the given extension name * from the "used" extensions!) - * + * * @param extension The extension name. */ - public void removeExtensionRequired(String extension) { + public void removeExtensionRequired(String extension) + { this.extensionsRequired.remove(extension); } /** * Add the given extension names to the "required" extensions and to * the "used" extensions. - * + * * @param extensions The extension names */ - public void addExtensionsRequired(Collection extensions) { - if (extensions != null) { + public void addExtensionsRequired(Collection extensions) + { + if (extensions != null) + { this.extensionsRequired.addAll(extensions); addExtensionsUsed(extensions); } @@ -154,14 +171,16 @@ public void addExtensionsRequired(Collection extensions) { /** * Clear the list of "required" extensions. */ - public void clearExtensionRequired() { + public void clearExtensionRequired() + { this.extensionsRequired.clear(); } - + @Override - public List getExtensionsRequired() { + public List getExtensionsRequired() + { return Collections.unmodifiableList( - new ArrayList(extensionsRequired)); + new ArrayList(extensionsRequired)); } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultGltfModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultGltfModel.java index 4f236e3..9ddd532 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultGltfModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultGltfModel.java @@ -26,17 +26,32 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.*; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.AnimationModel; +import de.javagl.jgltf.model.AssetModel; +import de.javagl.jgltf.model.BufferModel; +import de.javagl.jgltf.model.BufferViewModel; +import de.javagl.jgltf.model.CameraModel; +import de.javagl.jgltf.model.ExtensionsModel; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.ImageModel; +import de.javagl.jgltf.model.MaterialModel; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.SceneModel; +import de.javagl.jgltf.model.SkinModel; +import de.javagl.jgltf.model.TextureModel; + /** * Default implementation of a {@link GltfModel}.
    */ -public class DefaultGltfModel extends AbstractModelElement implements GltfModel { +public class DefaultGltfModel extends AbstractModelElement implements GltfModel +{ /** * The {@link AccessorModel} instances */ @@ -46,7 +61,7 @@ public class DefaultGltfModel extends AbstractModelElement implements GltfModel * The {@link AnimationModel} instances */ private final List animationModels; - + /** * The {@link BufferModel} instances */ @@ -56,7 +71,7 @@ public class DefaultGltfModel extends AbstractModelElement implements GltfModel * The {@link BufferViewModel} instances */ private final List bufferViewModels; - + /** * The {@link CameraModel} instances */ @@ -71,7 +86,7 @@ public class DefaultGltfModel extends AbstractModelElement implements GltfModel * The {@link MaterialModel} instances */ private final List materialModels; - + /** * The {@link MeshModel} instances */ @@ -96,21 +111,22 @@ public class DefaultGltfModel extends AbstractModelElement implements GltfModel * The {@link TextureModel} instances */ private final List textureModels; - + /** * The {@link ExtensionsModel} */ private final DefaultExtensionsModel extensionsModel; - + /** * The {@link AssetModel} */ private final DefaultAssetModel assetModel; /** - * Creates a new model + * Creates a new model */ - public DefaultGltfModel() { + public DefaultGltfModel() + { this.accessorModels = new ArrayList(); this.animationModels = new ArrayList(); this.bufferModels = new ArrayList(); @@ -126,33 +142,37 @@ public DefaultGltfModel() { this.extensionsModel = new DefaultExtensionsModel(); this.assetModel = new DefaultAssetModel(); } - + /** * Add the given {@link AccessorModel} to this model - * + * * @param accessorModel The object to add */ - public void addAccessorModel(DefaultAccessorModel accessorModel) { + public void addAccessorModel(DefaultAccessorModel accessorModel) + { accessorModels.add(accessorModel); } /** * Remove the given {@link AccessorModel} from this model - * + * * @param accessorModel The object to remove */ - public void removeAccessorModel(DefaultAccessorModel accessorModel) { + public void removeAccessorModel(DefaultAccessorModel accessorModel) + { accessorModels.remove(accessorModel); } /** * Add the given {@link AccessorModel} instances to this model - * + * * @param accessorModels The objects to add */ public void addAccessorModels( - Collection accessorModels) { - for (DefaultAccessorModel accessorModel : accessorModels) { + Collection accessorModels) + { + for (DefaultAccessorModel accessorModel : accessorModels) + { addAccessorModel(accessorModel); } } @@ -163,28 +183,32 @@ public void addAccessorModels( * @param index The index * @return The {@link AccessorModel} */ - public DefaultAccessorModel getAccessorModel(int index) { + public DefaultAccessorModel getAccessorModel(int index) + { return accessorModels.get(index); } /** * Remove all {@link AccessorModel} instances */ - public void clearAccessorModels() { + public void clearAccessorModels() + { accessorModels.clear(); } @Override - public List getAccessorModels() { + public List getAccessorModels() + { return Collections.unmodifiableList(accessorModels); } - + /** * Add the given {@link AnimationModel} to this model * * @param animationModel The instance to add */ - public void addAnimationModel(DefaultAnimationModel animationModel) { + public void addAnimationModel(DefaultAnimationModel animationModel) + { animationModels.add(animationModel); } @@ -193,7 +217,8 @@ public void addAnimationModel(DefaultAnimationModel animationModel) { * * @param animationModel The instance to remove */ - public void removeAnimationModel(DefaultAnimationModel animationModel) { + public void removeAnimationModel(DefaultAnimationModel animationModel) + { animationModels.remove(animationModel); } @@ -203,8 +228,10 @@ public void removeAnimationModel(DefaultAnimationModel animationModel) { * @param animationModels The instances to add */ public void addAnimationModels( - Collection animationModels) { - for (DefaultAnimationModel animationModel : animationModels) { + Collection animationModels) + { + for (DefaultAnimationModel animationModel : animationModels) + { addAnimationModel(animationModel); } } @@ -215,48 +242,55 @@ public void addAnimationModels( * @param index The index * @return The {@link AnimationModel} */ - public DefaultAnimationModel getAnimationModel(int index) { + public DefaultAnimationModel getAnimationModel(int index) + { return animationModels.get(index); } /** * Remove all {@link AnimationModel} instances */ - public void clearAnimationModels() { + public void clearAnimationModels() + { animationModels.clear(); } @Override - public List getAnimationModels() { + public List getAnimationModels() + { return Collections.unmodifiableList(animationModels); } - + /** * Add the given {@link BufferModel} to this model - * + * * @param bufferModel The instance to add */ - public void addBufferModel(DefaultBufferModel bufferModel) { + public void addBufferModel(DefaultBufferModel bufferModel) + { bufferModels.add(bufferModel); } /** * Remove the given {@link BufferModel} from this model - * + * * @param bufferModel The instance to remove */ - public void removeBufferModel(DefaultBufferModel bufferModel) { + public void removeBufferModel(DefaultBufferModel bufferModel) + { bufferModels.remove(bufferModel); } /** * Add the given {@link BufferModel} instances to this model - * + * * @param bufferModels The instances to add */ public void addBufferModels( - Collection bufferModels) { - for (DefaultBufferModel bufferModel : bufferModels) { + Collection bufferModels) + { + for (DefaultBufferModel bufferModel : bufferModels) + { addBufferModel(bufferModel); } } @@ -267,48 +301,55 @@ public void addBufferModels( * @param index The index * @return The {@link BufferModel} */ - public DefaultBufferModel getBufferModel(int index) { + public DefaultBufferModel getBufferModel(int index) + { return bufferModels.get(index); } /** * Remove all {@link BufferModel} instances */ - public void clearBufferModels() { + public void clearBufferModels() + { bufferModels.clear(); } @Override - public List getBufferModels() { + public List getBufferModels() + { return Collections.unmodifiableList(bufferModels); } - + /** * Add the given {@link BufferViewModel} to this model - * + * * @param bufferViewModel The instance to add */ - public void addBufferViewModel(DefaultBufferViewModel bufferViewModel) { + public void addBufferViewModel(DefaultBufferViewModel bufferViewModel) + { bufferViewModels.add(bufferViewModel); } /** * Remove the given {@link BufferViewModel} from this model - * + * * @param bufferViewModel The instance to remove */ - public void removeBufferViewModel(DefaultBufferViewModel bufferViewModel) { + public void removeBufferViewModel(DefaultBufferViewModel bufferViewModel) + { bufferViewModels.remove(bufferViewModel); } /** * Add the given {@link BufferViewModel} instances to this model - * + * * @param bufferViewModels The instances to add */ public void addBufferViewModels( - Collection bufferViewModels) { - for (DefaultBufferViewModel bufferViewModel : bufferViewModels) { + Collection bufferViewModels) + { + for (DefaultBufferViewModel bufferViewModel : bufferViewModels) + { addBufferViewModel(bufferViewModel); } } @@ -319,48 +360,55 @@ public void addBufferViewModels( * @param index The index * @return The {@link BufferViewModel} */ - public DefaultBufferViewModel getBufferViewModel(int index) { + public DefaultBufferViewModel getBufferViewModel(int index) + { return bufferViewModels.get(index); } /** * Remove all {@link BufferViewModel} instances */ - public void clearBufferViewModels() { + public void clearBufferViewModels() + { bufferViewModels.clear(); } @Override - public List getBufferViewModels() { + public List getBufferViewModels() + { return Collections.unmodifiableList(bufferViewModels); } - + /** * Add the given {@link CameraModel} to this model - * + * * @param cameraModel The instance to add */ - public void addCameraModel(DefaultCameraModel cameraModel) { + public void addCameraModel(DefaultCameraModel cameraModel) + { cameraModels.add(cameraModel); } /** * Remove the given {@link CameraModel} from this model - * + * * @param cameraModel The instance to remove */ - public void removeCameraModel(DefaultCameraModel cameraModel) { + public void removeCameraModel(DefaultCameraModel cameraModel) + { cameraModels.remove(cameraModel); } /** * Add the given {@link CameraModel} instances to this model - * + * * @param cameraModels The instances to add */ public void addCameraModels( - Collection cameraModels) { - for (DefaultCameraModel cameraModel : cameraModels) { + Collection cameraModels) + { + for (DefaultCameraModel cameraModel : cameraModels) + { addCameraModel(cameraModel); } } @@ -371,48 +419,55 @@ public void addCameraModels( * @param index The index * @return The {@link CameraModel} */ - public DefaultCameraModel getCameraModel(int index) { + public DefaultCameraModel getCameraModel(int index) + { return cameraModels.get(index); } /** * Remove all {@link CameraModel} instances */ - public void clearCameraModels() { + public void clearCameraModels() + { cameraModels.clear(); } @Override - public List getCameraModels() { + public List getCameraModels() + { return Collections.unmodifiableList(cameraModels); } - + /** * Add the given {@link ImageModel} to this model - * + * * @param imageModel The instance to add */ - public void addImageModel(DefaultImageModel imageModel) { + public void addImageModel(DefaultImageModel imageModel) + { imageModels.add(imageModel); } /** * Remove the given {@link ImageModel} from this model - * + * * @param imageModel The instance to remove */ - public void removeImageModel(DefaultImageModel imageModel) { + public void removeImageModel(DefaultImageModel imageModel) + { imageModels.remove(imageModel); } /** * Add the given {@link ImageModel} instances to this model - * + * * @param imageModels The instances to add */ public void addImageModels( - Collection imageModels) { - for (DefaultImageModel imageModel : imageModels) { + Collection imageModels) + { + for (DefaultImageModel imageModel : imageModels) + { addImageModel(imageModel); } } @@ -423,48 +478,55 @@ public void addImageModels( * @param index The index * @return The {@link ImageModel} */ - public DefaultImageModel getImageModel(int index) { + public DefaultImageModel getImageModel(int index) + { return imageModels.get(index); } /** * Remove all {@link ImageModel} instances */ - public void clearImageModels() { + public void clearImageModels() + { imageModels.clear(); } @Override - public List getImageModels() { + public List getImageModels() + { return Collections.unmodifiableList(imageModels); } - + /** * Add the given {@link MaterialModel} to this model - * + * * @param materialModel The instance to add */ - public void addMaterialModel(MaterialModel materialModel) { + public void addMaterialModel(MaterialModel materialModel) + { materialModels.add(materialModel); } /** * Remove the given {@link MaterialModel} from this model - * + * * @param materialModel The instance to remove */ - public void removeMaterialModel(MaterialModel materialModel) { + public void removeMaterialModel(MaterialModel materialModel) + { materialModels.remove(materialModel); } /** * Add the given {@link MaterialModel} instances to this model - * + * * @param materialModels The instances to add */ public void addMaterialModels( - Collection materialModels) { - for (MaterialModel materialModel : materialModels) { + Collection materialModels) + { + for (MaterialModel materialModel : materialModels) + { addMaterialModel(materialModel); } } @@ -475,48 +537,55 @@ public void addMaterialModels( * @param index The index * @return The {@link MaterialModel} */ - public MaterialModel getMaterialModel(int index) { + public MaterialModel getMaterialModel(int index) + { return materialModels.get(index); } /** * Remove all {@link MaterialModel} instances */ - public void clearMaterialModels() { + public void clearMaterialModels() + { materialModels.clear(); } @Override - public List getMaterialModels() { + public List getMaterialModels() + { return Collections.unmodifiableList(materialModels); } /** * Add the given {@link MeshModel} to this model - * + * * @param meshModel The instance to add */ - public void addMeshModel(DefaultMeshModel meshModel) { + public void addMeshModel(DefaultMeshModel meshModel) + { meshModels.add(meshModel); } /** * Remove the given {@link MeshModel} from this model - * + * * @param meshModel The instance to remove */ - public void removeMeshModel(DefaultMeshModel meshModel) { + public void removeMeshModel(DefaultMeshModel meshModel) + { meshModels.remove(meshModel); } /** * Add the given {@link MeshModel} instances to this model - * + * * @param meshModels The instances to add */ public void addMeshModels( - Collection meshModels) { - for (DefaultMeshModel meshModel : meshModels) { + Collection meshModels) + { + for (DefaultMeshModel meshModel : meshModels) + { addMeshModel(meshModel); } } @@ -527,48 +596,55 @@ public void addMeshModels( * @param index The index * @return The {@link MeshModel} */ - public DefaultMeshModel getMeshModel(int index) { + public DefaultMeshModel getMeshModel(int index) + { return meshModels.get(index); } /** * Remove all {@link MeshModel} instances */ - public void clearMeshModels() { + public void clearMeshModels() + { meshModels.clear(); } @Override - public List getMeshModels() { + public List getMeshModels() + { return Collections.unmodifiableList(meshModels); } - + /** * Add the given {@link NodeModel} to this model - * + * * @param nodeModel The instance to add */ - public void addNodeModel(DefaultNodeModel nodeModel) { + public void addNodeModel(DefaultNodeModel nodeModel) + { nodeModels.add(nodeModel); } /** * Remove the given {@link NodeModel} from this model - * + * * @param nodeModel The instance to remove */ - public void removeNodeModel(DefaultNodeModel nodeModel) { + public void removeNodeModel(DefaultNodeModel nodeModel) + { nodeModels.remove(nodeModel); } /** * Add the given {@link NodeModel} instances to this model - * + * * @param nodeModels The instances to add */ public void addNodeModels( - Collection nodeModels) { - for (DefaultNodeModel nodeModel : nodeModels) { + Collection nodeModels) + { + for (DefaultNodeModel nodeModel : nodeModels) + { addNodeModel(nodeModel); } } @@ -579,48 +655,55 @@ public void addNodeModels( * @param index The index * @return The {@link NodeModel} */ - public DefaultNodeModel getNodeModel(int index) { + public DefaultNodeModel getNodeModel(int index) + { return nodeModels.get(index); } /** * Remove all {@link NodeModel} instances */ - public void clearNodeModels() { + public void clearNodeModels() + { nodeModels.clear(); } @Override - public List getNodeModels() { + public List getNodeModels() + { return Collections.unmodifiableList(nodeModels); } - + /** * Add the given {@link SceneModel} to this model - * + * * @param sceneModel The instance to add */ - public void addSceneModel(DefaultSceneModel sceneModel) { + public void addSceneModel(DefaultSceneModel sceneModel) + { sceneModels.add(sceneModel); } /** * Remove the given {@link SceneModel} from this model - * + * * @param sceneModel The instance to remove */ - public void removeSceneModel(DefaultSceneModel sceneModel) { + public void removeSceneModel(DefaultSceneModel sceneModel) + { sceneModels.remove(sceneModel); } /** * Add the given {@link SceneModel} instances to this model - * + * * @param sceneModels The instances to add */ public void addSceneModels( - Collection sceneModels) { - for (DefaultSceneModel sceneModel : sceneModels) { + Collection sceneModels) + { + for (DefaultSceneModel sceneModel : sceneModels) + { addSceneModel(sceneModel); } } @@ -631,48 +714,55 @@ public void addSceneModels( * @param index The index * @return The {@link SceneModel} */ - public DefaultSceneModel getSceneModel(int index) { + public DefaultSceneModel getSceneModel(int index) + { return sceneModels.get(index); } /** * Remove all {@link SceneModel} instances */ - public void clearSceneModels() { + public void clearSceneModels() + { sceneModels.clear(); } @Override - public List getSceneModels() { + public List getSceneModels() + { return Collections.unmodifiableList(sceneModels); } /** * Add the given {@link SkinModel} to this model - * + * * @param skinModel The instance to add */ - public void addSkinModel(DefaultSkinModel skinModel) { + public void addSkinModel(DefaultSkinModel skinModel) + { skinModels.add(skinModel); } /** * Remove the given {@link SkinModel} from this model - * + * * @param skinModel The instance to remove */ - public void removeSkinModel(DefaultSkinModel skinModel) { + public void removeSkinModel(DefaultSkinModel skinModel) + { skinModels.remove(skinModel); } /** * Add the given {@link SkinModel} instances to this model - * + * * @param skinModels The instances to add */ public void addSkinModels( - Collection skinModels) { - for (DefaultSkinModel skinModel : skinModels) { + Collection skinModels) + { + for (DefaultSkinModel skinModel : skinModels) + { addSkinModel(skinModel); } } @@ -683,48 +773,55 @@ public void addSkinModels( * @param index The index * @return The {@link SkinModel} */ - public DefaultSkinModel getSkinModel(int index) { + public DefaultSkinModel getSkinModel(int index) + { return skinModels.get(index); } /** * Remove all {@link SkinModel} instances */ - public void clearSkinModels() { + public void clearSkinModels() + { skinModels.clear(); } @Override - public List getSkinModels() { + public List getSkinModels() + { return Collections.unmodifiableList(skinModels); } - + /** * Add the given {@link TextureModel} to this model - * + * * @param textureModel The instance to add */ - public void addTextureModel(DefaultTextureModel textureModel) { + public void addTextureModel(DefaultTextureModel textureModel) + { textureModels.add(textureModel); } /** * Remove the given {@link TextureModel} from this model - * + * * @param textureModel The instance to remove */ - public void removeTextureModel(DefaultTextureModel textureModel) { + public void removeTextureModel(DefaultTextureModel textureModel) + { textureModels.remove(textureModel); } /** * Add the given {@link TextureModel} instances to this model - * + * * @param textureModels The instances to add */ public void addTextureModels( - Collection textureModels) { - for (DefaultTextureModel textureModel : textureModels) { + Collection textureModels) + { + for (DefaultTextureModel textureModel : textureModels) + { addTextureModel(textureModel); } } @@ -735,29 +832,34 @@ public void addTextureModels( * @param index The index * @return The {@link TextureModel} */ - public DefaultTextureModel getTextureModel(int index) { + public DefaultTextureModel getTextureModel(int index) + { return textureModels.get(index); } /** * Remove all {@link TextureModel} instances */ - public void clearTextureModels() { + public void clearTextureModels() + { textureModels.clear(); } @Override - public List getTextureModels() { + public List getTextureModels() + { return Collections.unmodifiableList(textureModels); } - + @Override - public DefaultExtensionsModel getExtensionsModel() { + public DefaultExtensionsModel getExtensionsModel() + { return extensionsModel; } - + @Override - public DefaultAssetModel getAssetModel() { + public DefaultAssetModel getAssetModel() + { return assetModel; } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultImageModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultImageModel.java index 57d1b46..310005e 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultImageModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultImageModel.java @@ -26,102 +26,113 @@ */ package de.javagl.jgltf.model.impl; +import java.nio.ByteBuffer; + import de.javagl.jgltf.model.BufferViewModel; import de.javagl.jgltf.model.ImageModel; import de.javagl.jgltf.model.io.Buffers; -import java.nio.ByteBuffer; - /** * Implementation of a {@link ImageModel} */ public class DefaultImageModel extends AbstractNamedModelElement - implements ImageModel { + implements ImageModel +{ /** * The URI of the image */ private String uri; - + /** * The MIME type of the image data in the buffer view model */ private String mimeType; - + /** * The {@link BufferViewModel} */ private BufferViewModel bufferViewModel; - + /** * The image data */ private ByteBuffer imageData; - + /** * Creates a new instance */ - public DefaultImageModel() { + public DefaultImageModel() + { // Default constructor } - - @Override - public String getUri() { - return uri; - } - + /** * Set the URI - * + * * @param uri The URI */ - public void setUri(String uri) { + public void setUri(String uri) + { this.uri = uri; } - - @Override - public String getMimeType() { - return mimeType; - } - + /** * Set the MIME type - * + * * @param mimeType The MIME type */ - public void setMimeType(String mimeType) { + public void setMimeType(String mimeType) + { this.mimeType = mimeType; } - @Override - public BufferViewModel getBufferViewModel() { - return bufferViewModel; - } - /** - * Set the {@link BufferViewModel} - * + * Set the {@link BufferViewModel} + * * @param bufferViewModel The {@link BufferViewModel} */ - public void setBufferViewModel(BufferViewModel bufferViewModel) { + public void setBufferViewModel(BufferViewModel bufferViewModel) + { this.bufferViewModel = bufferViewModel; } - - @Override - public ByteBuffer getImageData() { - if (imageData == null) { - return bufferViewModel.getBufferViewData(); - } - return Buffers.createSlice(imageData); - } - + /** * Set the image data - * + * * @param imageData The image data */ - public void setImageData(ByteBuffer imageData) { + public void setImageData(ByteBuffer imageData) + { this.imageData = imageData; } + + @Override + public String getUri() + { + return uri; + } + + @Override + public String getMimeType() + { + return mimeType; + } + + @Override + public BufferViewModel getBufferViewModel() + { + return bufferViewModel; + } + + @Override + public ByteBuffer getImageData() + { + if (imageData == null) + { + return bufferViewModel.getBufferViewData(); + } + return Buffers.createSlice(imageData); + } - + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshModel.java index fb06594..0b4d725 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshModel.java @@ -26,62 +26,68 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.MeshModel; -import de.javagl.jgltf.model.MeshPrimitiveModel; - import java.util.ArrayList; import java.util.Collections; import java.util.List; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; + /** * Implementation of a {@link MeshModel} */ public class DefaultMeshModel extends AbstractNamedModelElement - implements MeshModel { + implements MeshModel +{ /** - * The {@link MeshPrimitiveModel} instances + * The {@link MeshPrimitiveModel} instances */ private final List meshPrimitiveModels; - + /** * The morph target weights */ private float weights[]; - + /** * Creates a new instance */ - public DefaultMeshModel() { + public DefaultMeshModel() + { this.meshPrimitiveModels = new ArrayList(); } /** * Add the given {@link MeshPrimitiveModel} - * + * * @param meshPrimitiveModel The {@link MeshPrimitiveModel} */ - public void addMeshPrimitiveModel(MeshPrimitiveModel meshPrimitiveModel) { + public void addMeshPrimitiveModel(MeshPrimitiveModel meshPrimitiveModel) + { this.meshPrimitiveModels.add(meshPrimitiveModel); } - + + /** + * Set the default morph target weights to be a reference to the + * given array. + * + * @param weights The weights + */ + public void setWeights(float[] weights) + { + this.weights = weights; + } + @Override - public List getMeshPrimitiveModels() { + public List getMeshPrimitiveModels() + { return Collections.unmodifiableList(meshPrimitiveModels); } - + @Override - public float[] getWeights() { + public float[] getWeights() + { return weights; } - /** - * Set the default morph target weights to be a reference to the - * given array. - * - * @param weights The weights - */ - public void setWeights(float[] weights) { - this.weights = weights; - } - } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshPrimitiveModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshPrimitiveModel.java index 256757b..16bfe82 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshPrimitiveModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultMeshPrimitiveModel.java @@ -26,115 +26,136 @@ */ package de.javagl.jgltf.model.impl; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + import de.javagl.jgltf.model.AccessorModel; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.MeshPrimitiveModel; -import java.util.*; - /** * Implementation of a {@link MeshPrimitiveModel} */ -public final class DefaultMeshPrimitiveModel extends AbstractModelElement - implements MeshPrimitiveModel { +public final class DefaultMeshPrimitiveModel extends AbstractModelElement + implements MeshPrimitiveModel +{ /** * The attributes of this mesh primitive model */ private final Map attributes; - /** - * The rendering mode - */ - private final int mode; - /** - * The morph targets - */ - private final List> targets; + /** * The {@link AccessorModel} for the indices data */ private AccessorModel indices; + /** * The {@link MaterialModel} that should be used for rendering */ private MaterialModel materialModel; - + + /** + * The rendering mode + */ + private final int mode; + + /** + * The morph targets + */ + private final List> targets; + /** * Creates a new instance - * + * * @param mode The rendering mode */ - public DefaultMeshPrimitiveModel(int mode) { + public DefaultMeshPrimitiveModel(int mode) + { this.mode = mode; this.attributes = new LinkedHashMap(); - this.targets = new ArrayList>(); + this.targets = new ArrayList>(); } - - + + /** * Put the given {@link AccessorModel} into the attributes, under the * given name - * - * @param name The name + * + * @param name The name * @param accessorModel The {@link AccessorModel} * @return The old value that was stored under the given name */ - public AccessorModel putAttribute(String name, AccessorModel accessorModel) { + public AccessorModel putAttribute(String name, AccessorModel accessorModel) + { Objects.requireNonNull( - accessorModel, "The accessorModel may not be null"); + accessorModel, "The accessorModel may not be null"); return attributes.put(name, accessorModel); } - + + /** + * Set the {@link AccessorModel} for the indices + * + * @param indices The indices + */ + public void setIndices(AccessorModel indices) + { + this.indices = indices; + } + + /** + * Set the {@link MaterialModel} + * + * @param materialModel The {@link MaterialModel} + */ + public void setMaterialModel(MaterialModel materialModel) + { + this.materialModel = Objects.requireNonNull( + materialModel, "The materialModel may not be null"); + } + /** * Add the given morph target. A reference to the given map will be stored. - * + * * @param target The target */ - public void addTarget(Map target) { + public void addTarget(Map target) + { Objects.requireNonNull(target, "The target may not be null"); this.targets.add(target); } + @Override - public Map getAttributes() { + public Map getAttributes() + { return Collections.unmodifiableMap(attributes); } @Override - public AccessorModel getIndices() { + public AccessorModel getIndices() + { return indices; } - /** - * Set the {@link AccessorModel} for the indices - * - * @param indices The indices - */ - public void setIndices(AccessorModel indices) { - this.indices = indices; - } - @Override - public int getMode() { + public int getMode() + { return mode; } @Override - public MaterialModel getMaterialModel() { + public MaterialModel getMaterialModel() + { return materialModel; } - - /** - * Set the {@link MaterialModel} - * - * @param materialModel The {@link MaterialModel} - */ - public void setMaterialModel(MaterialModel materialModel) { - this.materialModel = Objects.requireNonNull( - materialModel, "The materialModel may not be null"); - } - + @Override - public List> getTargets() { + public List> getTargets() + { return Collections.unmodifiableList(targets); } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultNodeModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultNodeModel.java index 9b1b45d..25ed9cb 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultNodeModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultNodeModel.java @@ -26,47 +26,58 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.*; - import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.function.Supplier; +import de.javagl.jgltf.model.CameraModel; +import de.javagl.jgltf.model.MathUtils; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.SkinModel; +import de.javagl.jgltf.model.Suppliers; +import de.javagl.jgltf.model.Utils; + /** - * Implementation of a {@link NodeModel} + * Implementation of a {@link NodeModel} */ public class DefaultNodeModel extends AbstractNamedModelElement - implements NodeModel { + implements NodeModel +{ /** * A thread-local, temporary 16-element matrix */ private static final ThreadLocal TEMP_MATRIX_4x4_IN_LOCAL = - ThreadLocal.withInitial(() -> new float[16]); - + ThreadLocal.withInitial(() -> new float[16]); + /** * A thread-local, temporary 16-element matrix */ private static final ThreadLocal TEMP_MATRIX_4x4_IN_GLOBAL = - ThreadLocal.withInitial(() -> new float[16]); + ThreadLocal.withInitial(() -> new float[16]); + + /** + * The parent of this node. This is null for the root node. + */ + private NodeModel parent; + /** * The children of this node */ private final List children; + /** * The {@link MeshModel} objects that are attached to this node */ private final List meshModels; - /** - * The parent of this node. This is null for the root node. - */ - private NodeModel parent; + /** * The {@link SkinModel} */ private SkinModel skinModel; - + /** * The {@link CameraModel} */ @@ -76,17 +87,17 @@ public class DefaultNodeModel extends AbstractNamedModelElement * The local transform matrix */ private float matrix[]; - + /** * The translation */ private float translation[]; - + /** * The rotation */ private float rotation[]; - + /** * The scale */ @@ -96,23 +107,25 @@ public class DefaultNodeModel extends AbstractNamedModelElement * The weights */ private float weights[]; - + /** - * Creates a new instance + * Creates a new instance */ - public DefaultNodeModel() { + public DefaultNodeModel() + { this.children = new ArrayList(); this.meshModels = new ArrayList(); } - + /** * Copy constructor that creates a shallow copy with references * to the elements of the given model, except for the children and * {@link MeshModel} instances (which will be empty in the copy). - * + * * @param other The other {@link NodeModel} */ - public DefaultNodeModel(NodeModel other) { + public DefaultNodeModel(NodeModel other) + { this.cameraModel = other.getCameraModel(); this.children = new ArrayList(); this.matrix = other.getMatrix(); @@ -124,251 +137,286 @@ public DefaultNodeModel(NodeModel other) { this.translation = other.getTranslation(); this.weights = other.getWeights(); } - - /** - * Compute the local transform of the given node. The transform - * is either taken from the {@link #getMatrix()} (if it is not - * null), or computed from the {@link #getTranslation()}, - * {@link #getRotation()} and {@link #getScale()}, if they - * are not null, respectively.
    - *
    - * The result will be written to the given array, as a 4x4 matrix in - * column major order. If the given array is null or does - * not have a length of 16, then a new array with length 16 will be - * created and returned. - * - * @param nodeModel The node. May not be null. - * @param result The result array - * @return The result array - */ - public static float[] computeLocalTransform( - NodeModel nodeModel, float result[]) { - float localResult[] = Utils.validate(result, 16); - if (nodeModel.getMatrix() != null) { - float m[] = nodeModel.getMatrix(); - System.arraycopy(m, 0, localResult, 0, m.length); - return localResult; - } - - MathUtils.setIdentity4x4(localResult); - if (nodeModel.getTranslation() != null) { - float t[] = nodeModel.getTranslation(); - localResult[12] = t[0]; - localResult[13] = t[1]; - localResult[14] = t[2]; - } - if (nodeModel.getRotation() != null) { - float q[] = nodeModel.getRotation(); - float m[] = TEMP_MATRIX_4x4_IN_LOCAL.get(); - MathUtils.quaternionToMatrix4x4(q, m); - MathUtils.mul4x4(localResult, m, localResult); - } - if (nodeModel.getScale() != null) { - float s[] = nodeModel.getScale(); - float m[] = TEMP_MATRIX_4x4_IN_LOCAL.get(); - MathUtils.setIdentity4x4(m); - m[0] = s[0]; - m[5] = s[1]; - m[10] = s[2]; - m[15] = 1.0f; - MathUtils.mul4x4(localResult, m, localResult); - } - return localResult; - } - + /** - * Compute the global transform for the given {@link NodeModel}, - * and store it in the given result. If the given result is - * null or does not have a length of 16, then - * a new array will be created and returned. - * - * @param nodeModel The {@link NodeModel} - * @param result The result - * @return The result - */ - private static float[] computeGlobalTransform( - NodeModel nodeModel, float result[]) { - float localResult[] = Utils.validate(result, 16); - float tempLocalTransform[] = TEMP_MATRIX_4x4_IN_GLOBAL.get(); - NodeModel currentNode = nodeModel; - MathUtils.setIdentity4x4(localResult); - while (currentNode != null) { - currentNode.computeLocalTransform(tempLocalTransform); - MathUtils.mul4x4( - tempLocalTransform, localResult, localResult); - currentNode = currentNode.getParent(); - } - return localResult; - } - - /** - * Check whether the given array has the expected length, and return - * the given array. If the given source array is null, then - * null will be returned. If the given source array does not - * have the expected length, then an IllegalArgumentException - * will be thrown. - * - * @param array The array - * @param expectedLength The expected length - * @return The array - * @throws IllegalArgumentException If the given array does not have - * the expected length + * Set the parent of this node + * + * @param parent The parent node */ - private static float[] check(float array[], int expectedLength) { - if (array == null) { - return null; - } - if (array.length != expectedLength) { - throw new IllegalArgumentException("Expected " + expectedLength - + " array elements, but found " + array.length); - } - return array; + public void setParent(DefaultNodeModel parent) + { + this.parent = parent; } - + /** * Add the given child node - * + * * @param child The child node */ - public void addChild(DefaultNodeModel child) { + public void addChild(DefaultNodeModel child) + { Objects.requireNonNull(child, "The child may not be null"); children.add(child); child.setParent(this); } - + /** - * Add the given {@link MeshModel} - * + * Add the given {@link MeshModel} + * * @param meshModel The {@link MeshModel} */ - public void addMeshModel(MeshModel meshModel) { + public void addMeshModel(MeshModel meshModel) + { Objects.requireNonNull(meshModel, "The meshModel may not be null"); meshModels.add(meshModel); } - - @Override - public NodeModel getParent() { - return parent; + + /** + * Set the {@link SkinModel} + * + * @param skinModel The {@link SkinModel} + */ + public void setSkinModel(SkinModel skinModel) + { + this.skinModel = skinModel; } - + /** - * Set the parent of this node - * - * @param parent The parent node + * Set the {@link CameraModel} + * + * @param cameraModel The {@link CameraModel} */ - public void setParent(DefaultNodeModel parent) { - this.parent = parent; + public void setCameraModel(CameraModel cameraModel) + { + this.cameraModel = cameraModel; } - + + @Override + public NodeModel getParent() + { + return parent; + } + @Override - public List getChildren() { + public List getChildren() + { return Collections.unmodifiableList(children); } - + @Override - public List getMeshModels() { + public List getMeshModels() + { return Collections.unmodifiableList(meshModels); } - + @Override - public SkinModel getSkinModel() { + public SkinModel getSkinModel() + { return skinModel; } - - /** - * Set the {@link SkinModel} - * - * @param skinModel The {@link SkinModel} - */ - public void setSkinModel(SkinModel skinModel) { - this.skinModel = skinModel; - } - + @Override - public CameraModel getCameraModel() { + public CameraModel getCameraModel() + { return cameraModel; } - - /** - * Set the {@link CameraModel} - * - * @param cameraModel The {@link CameraModel} - */ - public void setCameraModel(CameraModel cameraModel) { - this.cameraModel = cameraModel; + + @Override + public void setMatrix(float[] matrix) + { + this.matrix = check(matrix, 16); } - + @Override - public float[] getMatrix() { + public float[] getMatrix() + { return matrix; } @Override - public void setMatrix(float[] matrix) { - this.matrix = check(matrix, 16); + public void setTranslation(float[] translation) + { + this.translation = check(translation, 3); } @Override - public float[] getTranslation() { + public float[] getTranslation() + { return translation; } @Override - public void setTranslation(float[] translation) { - this.translation = check(translation, 3); + public void setRotation(float[] rotation) + { + this.rotation = check(rotation, 4); } @Override - public float[] getRotation() { + public float[] getRotation() + { return rotation; } @Override - public void setRotation(float[] rotation) { - this.rotation = check(rotation, 4); + public void setScale(float[] scale) + { + this.scale = check(scale, 3); } @Override - public float[] getScale() { + public float[] getScale() + { return scale; } @Override - public void setScale(float[] scale) { - this.scale = check(scale, 3); + public void setWeights(float[] weights) + { + this.weights = weights; } @Override - public float[] getWeights() { + public float[] getWeights() + { return weights; } - + + @Override - public void setWeights(float[] weights) { - this.weights = weights; - } - - @Override - public float[] computeLocalTransform(float result[]) { + public float[] computeLocalTransform(float result[]) + { return computeLocalTransform(this, result); } @Override - public float[] computeGlobalTransform(float result[]) { + public float[] computeGlobalTransform(float result[]) + { return computeGlobalTransform(this, result); } - + @Override - public Supplier createGlobalTransformSupplier() { - return Suppliers.createTransformSupplier(this, - NodeModel::computeGlobalTransform); + public Supplier createGlobalTransformSupplier() + { + return Suppliers.createTransformSupplier(this, + NodeModel::computeGlobalTransform); } - + @Override - public Supplier createLocalTransformSupplier() { - return Suppliers.createTransformSupplier(this, - NodeModel::computeLocalTransform); + public Supplier createLocalTransformSupplier() + { + return Suppliers.createTransformSupplier(this, + NodeModel::computeLocalTransform); } - + /** + * Compute the local transform of the given node. The transform + * is either taken from the {@link #getMatrix()} (if it is not + * null), or computed from the {@link #getTranslation()}, + * {@link #getRotation()} and {@link #getScale()}, if they + * are not null, respectively.
    + *
    + * The result will be written to the given array, as a 4x4 matrix in + * column major order. If the given array is null or does + * not have a length of 16, then a new array with length 16 will be + * created and returned. + * + * @param nodeModel The node. May not be null. + * @param result The result array + * @return The result array + */ + public static float[] computeLocalTransform( + NodeModel nodeModel, float result[]) + { + float localResult[] = Utils.validate(result, 16); + if (nodeModel.getMatrix() != null) + { + float m[] = nodeModel.getMatrix(); + System.arraycopy(m, 0, localResult, 0, m.length); + return localResult; + } + + MathUtils.setIdentity4x4(localResult); + if (nodeModel.getTranslation() != null) + { + float t[] = nodeModel.getTranslation(); + localResult[12] = t[0]; + localResult[13] = t[1]; + localResult[14] = t[2]; + } + if (nodeModel.getRotation() != null) + { + float q[] = nodeModel.getRotation(); + float m[] = TEMP_MATRIX_4x4_IN_LOCAL.get(); + MathUtils.quaternionToMatrix4x4(q, m); + MathUtils.mul4x4(localResult, m, localResult); + } + if (nodeModel.getScale() != null) + { + float s[] = nodeModel.getScale(); + float m[] = TEMP_MATRIX_4x4_IN_LOCAL.get(); + MathUtils.setIdentity4x4(m); + m[ 0] = s[0]; + m[ 5] = s[1]; + m[10] = s[2]; + m[15] = 1.0f; + MathUtils.mul4x4(localResult, m, localResult); + } + return localResult; + } + + /** + * Compute the global transform for the given {@link NodeModel}, + * and store it in the given result. If the given result is + * null or does not have a length of 16, then + * a new array will be created and returned. + * + * @param nodeModel The {@link NodeModel} + * @param result The result + * @return The result + */ + private static float[] computeGlobalTransform( + NodeModel nodeModel, float result[]) + { + float localResult[] = Utils.validate(result, 16); + float tempLocalTransform[] = TEMP_MATRIX_4x4_IN_GLOBAL.get(); + NodeModel currentNode = nodeModel; + MathUtils.setIdentity4x4(localResult); + while (currentNode != null) + { + currentNode.computeLocalTransform(tempLocalTransform); + MathUtils.mul4x4( + tempLocalTransform, localResult, localResult); + currentNode = currentNode.getParent(); + } + return localResult; + } + + /** + * Check whether the given array has the expected length, and return + * the given array. If the given source array is null, then + * null will be returned. If the given source array does not + * have the expected length, then an IllegalArgumentException + * will be thrown. + * + * @param array The array + * @param expectedLength The expected length + * @return The array + * @throws IllegalArgumentException If the given array does not have + * the expected length + */ + private static float[] check(float array[], int expectedLength) + { + if (array == null) + { + return null; + } + if (array.length != expectedLength) + { + throw new IllegalArgumentException("Expected " + expectedLength + + " array elements, but found " + array.length); + } + return array; + } + + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultSceneModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultSceneModel.java index 4f09c7f..5e1f582 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultSceneModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultSceneModel.java @@ -26,41 +26,45 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.SceneModel; - import java.util.ArrayList; import java.util.Collections; import java.util.List; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.SceneModel; + /** - * Implementation of a {@link SceneModel} + * Implementation of a {@link SceneModel} */ public class DefaultSceneModel extends AbstractNamedModelElement - implements SceneModel { + implements SceneModel +{ /** * The list of root nodes */ private final List nodeModels; - + /** * Creates a new instance */ - public DefaultSceneModel() { + public DefaultSceneModel() + { this.nodeModels = new ArrayList(); } - + /** * Add the given (root) {@link NodeModel} to this scene - * + * * @param node The {@link NodeModel} */ - public void addNode(NodeModel node) { - nodeModels.add(node); + public void addNode(NodeModel node) + { + nodeModels.add(node); } - + @Override - public List getNodeModels() { + public List getNodeModels() + { return Collections.unmodifiableList(nodeModels); } diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultSkinModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultSkinModel.java index dcdba05..14fc98a 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultSkinModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultSkinModel.java @@ -26,116 +26,141 @@ */ package de.javagl.jgltf.model.impl; -import de.javagl.jgltf.model.*; - import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; +import de.javagl.jgltf.model.AccessorDatas; +import de.javagl.jgltf.model.AccessorFloatData; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.MathUtils; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.SkinModel; +import de.javagl.jgltf.model.Utils; + /** * Implementation of a {@link SkinModel} */ public final class DefaultSkinModel extends AbstractNamedModelElement - implements SkinModel { - /** - * The joint nodes - */ - private final List joints; + implements SkinModel +{ /** * The bind shape matrix */ private float bindShapeMatrix[]; + + /** + * The joint nodes + */ + private final List joints; + /** * The skeleton node */ private NodeModel skeleton; - + /** * The inverse bind matrices */ private AccessorModel inverseBindMatrices; - + /** * Creates a new instance */ - public DefaultSkinModel() { + public DefaultSkinModel() + { this.bindShapeMatrix = MathUtils.createIdentity4x4(); this.joints = new ArrayList(); } - + /** * Set the bind shape matrix - * + * * @param bindShapeMatrix The bind shape matrix. A copy of this array - * will be stored. If it is null, a new array will be - * created, which represents the identity matrix. + * will be stored. If it is null, a new array will be + * created, which represents the identity matrix. */ - public void setBindShapeMatrix(float[] bindShapeMatrix) { - if (bindShapeMatrix == null) { + public void setBindShapeMatrix(float[] bindShapeMatrix) + { + if (bindShapeMatrix == null) + { this.bindShapeMatrix = MathUtils.createIdentity4x4(); - } else { + } + else + { this.bindShapeMatrix = bindShapeMatrix.clone(); } } - + /** - * Add the given joint - * + * Add the given joint + * * @param joint The joint */ - public void addJoint(NodeModel joint) { + public void addJoint(NodeModel joint) + { Objects.requireNonNull(joint, "The joint may not be null"); joints.add(joint); } + + /** + * Set the skeleton root node + * + * @param skeleton The skeleton root node + */ + public void setSkeleton(NodeModel skeleton) + { + this.skeleton = skeleton; + } + + /** + * Set the inverse bind matrices + * + * @param inverseBindMatrices The inverse bind matrices + */ + public void setInverseBindMatrices(AccessorModel inverseBindMatrices) + { + this.inverseBindMatrices = Objects.requireNonNull( + inverseBindMatrices, "The inverseBindMatrices may not be null"); + } + @Override - public float[] getBindShapeMatrix(float[] result) { + public float[] getBindShapeMatrix(float[] result) + { float localResult[] = Utils.validate(result, 16); System.arraycopy(bindShapeMatrix, 0, localResult, 0, 16); return localResult; } + @Override - public List getJoints() { + public List getJoints() + { return Collections.unmodifiableList(joints); } @Override - public NodeModel getSkeleton() { + public NodeModel getSkeleton() + { return skeleton; } - /** - * Set the skeleton root node - * - * @param skeleton The skeleton root node - */ - public void setSkeleton(NodeModel skeleton) { - this.skeleton = skeleton; - } - @Override - public AccessorModel getInverseBindMatrices() { + public AccessorModel getInverseBindMatrices() + { return inverseBindMatrices; } - /** - * Set the inverse bind matrices - * - * @param inverseBindMatrices The inverse bind matrices - */ - public void setInverseBindMatrices(AccessorModel inverseBindMatrices) { - this.inverseBindMatrices = Objects.requireNonNull( - inverseBindMatrices, "The inverseBindMatrices may not be null"); - } - @Override - public float[] getInverseBindMatrix(int index, float[] result) { + public float[] getInverseBindMatrix(int index, float[] result) + { float localResult[] = Utils.validate(result, 16); - AccessorFloatData inverseBindMatricesData = - AccessorDatas.createFloat(inverseBindMatrices); - for (int j = 0; j < 16; j++) { + AccessorFloatData inverseBindMatricesData = + AccessorDatas.createFloat(inverseBindMatrices); + for (int j = 0; j < 16; j++) + { localResult[j] = inverseBindMatricesData.get(index, j); } return localResult; diff --git a/src/main/java/de/javagl/jgltf/model/impl/DefaultTextureModel.java b/src/main/java/de/javagl/jgltf/model/impl/DefaultTextureModel.java index f7aeb2b..4fc29de 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/DefaultTextureModel.java +++ b/src/main/java/de/javagl/jgltf/model/impl/DefaultTextureModel.java @@ -33,7 +33,8 @@ * Implementation of a {@link TextureModel} */ public class DefaultTextureModel extends AbstractNamedModelElement - implements TextureModel { + implements TextureModel +{ /** * The magnification filter constant */ @@ -43,96 +44,107 @@ public class DefaultTextureModel extends AbstractNamedModelElement * The minification filter constant */ private Integer minFilter; - + /** * The wrapping constant for the S-direction */ private Integer wrapS; - + /** * The wrapping constant for the T-direction */ private Integer wrapT; - + /** * The {@link ImageModel} */ private ImageModel imageModel; - + /** * Creates a new instance */ - public DefaultTextureModel() { + public DefaultTextureModel() + { // Default constructor } - + + /** + * Set the {@link ImageModel} that backs this texture + * + * @param imageModel The {@link ImageModel} + */ + public void setImageModel(ImageModel imageModel) + { + this.imageModel = imageModel; + } + @Override - public Integer getMagFilter() { + public Integer getMagFilter() + { return magFilter; } - + /** * Set the magnification filter - * + * * @param magFilter The filter */ - public void setMagFilter(Integer magFilter) { + public void setMagFilter(Integer magFilter) + { this.magFilter = magFilter; } @Override - public Integer getMinFilter() { + public Integer getMinFilter() + { return minFilter; } - + /** * Set the minification filter - * + * * @param minFilter The filter */ - public void setMinFilter(Integer minFilter) { + public void setMinFilter(Integer minFilter) + { this.minFilter = minFilter; } @Override - public Integer getWrapS() { + public Integer getWrapS() + { return wrapS; } - + /** * Set the wrapping behavior in S-direction - * + * * @param wrapS The wrapping mode */ - public void setWrapS(Integer wrapS) { + public void setWrapS(Integer wrapS) + { this.wrapS = wrapS; } @Override - public Integer getWrapT() { + public Integer getWrapT() + { return wrapT; } /** * Set the wrapping behavior in T-direction - * + * * @param wrapT The wrapping mode */ - public void setWrapT(Integer wrapT) { + public void setWrapT(Integer wrapT) + { this.wrapT = wrapT; } - + @Override - public ImageModel getImageModel() { + public ImageModel getImageModel() + { return imageModel; } - - /** - * Set the {@link ImageModel} that backs this texture - * - * @param imageModel The {@link ImageModel} - */ - public void setImageModel(ImageModel imageModel) { - this.imageModel = imageModel; - } } diff --git a/src/main/java/de/javagl/jgltf/model/impl/UriStrings.java b/src/main/java/de/javagl/jgltf/model/impl/UriStrings.java index ca4510a..b5a5605 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/UriStrings.java +++ b/src/main/java/de/javagl/jgltf/model/impl/UriStrings.java @@ -26,69 +26,69 @@ */ package de.javagl.jgltf.model.impl; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.logging.Logger; + import de.javagl.jgltf.model.ImageModel; import de.javagl.jgltf.model.gl.ShaderModel; import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; import de.javagl.jgltf.model.io.MimeTypes; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.logging.Logger; - /** * Utility methods to generate URI strings for buffers, images and shaders.
    *
    * This class is only intended for internal use! */ -public class UriStrings { +public class UriStrings +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(UriStrings.class.getName()); - + private static final Logger logger = + Logger.getLogger(UriStrings.class.getName()); + /** - * Private constructor to prevent instantiation - */ - private UriStrings() { - // Private constructor to prevent instantiation - } - - /** - * Create an unspecified, new URI string that is not yet used as + * Create an unspecified, new URI string that is not yet used as * a URI string. - * + * * @param existingUriStrings The existing URI strings * @return The new URI string */ public static String createBufferUriString( - Collection existingUriStrings) { + Collection existingUriStrings) + { int counter = 0; - while (true) { + while (true) + { String uri = "buffer" + counter + "." + "bin"; - if (!existingUriStrings.contains(uri)) { + if (!existingUriStrings.contains(uri)) + { return uri; } counter++; } } - + /** - * Create an unspecified, new URI string that is not yet used as + * Create an unspecified, new URI string that is not yet used as * a URI string - * - * @param imageModel The {@link ImageModel} to create the string for + * + * @param imageModel The {@link ImageModel} to create the string for * @param existingUriStrings The existing URI strings * @return The new URI string */ public static String createImageUriString(ImageModel imageModel, - Collection existingUriStrings) { - String extensionWithoutDot = - determineImageFileNameExtension(imageModel); + Collection existingUriStrings) + { + String extensionWithoutDot = + determineImageFileNameExtension(imageModel); int counter = 0; - while (true) { + while (true) + { String uri = "image" + counter + "." + extensionWithoutDot; - if (!existingUriStrings.contains(uri)) { + if (!existingUriStrings.contains(uri)) + { return uri; } counter++; @@ -96,70 +96,87 @@ public static String createImageUriString(ImageModel imageModel, } /** - * Determine the extension for an image file name (without the + * Determine the extension for an image file name (without the * "." dot), for the given {@link ImageModel} - * + * * @param imageModel The {@link ImageModel} * @return The file extension */ private static String determineImageFileNameExtension( - ImageModel imageModel) { + ImageModel imageModel) + { // Try to figure out the MIME type String mimeTypeString = imageModel.getMimeType(); - if (mimeTypeString == null) { + if (mimeTypeString == null) + { ByteBuffer imageData = imageModel.getImageData(); - mimeTypeString = - MimeTypes.guessImageMimeTypeStringUnchecked(imageData); + mimeTypeString = + MimeTypes.guessImageMimeTypeStringUnchecked(imageData); } - + // Try to figure out the extension based on the MIME type - if (mimeTypeString != null) { - String extensionWithoutDot = - MimeTypes.imageFileNameExtensionForMimeTypeString( - mimeTypeString); - if (extensionWithoutDot != null) { + if (mimeTypeString != null) + { + String extensionWithoutDot = + MimeTypes.imageFileNameExtensionForMimeTypeString( + mimeTypeString); + if (extensionWithoutDot != null) + { return extensionWithoutDot; } } logger.warning("Could not determine file extension for image URI"); return ""; } - + /** - * Create an unspecified, new URI string that is not yet used as + * Create an unspecified, new URI string that is not yet used as * a URI string - * - * @param shaderModel The {@link ShaderModel} to create the string for + * + * @param shaderModel The {@link ShaderModel} to create the string for * @param existingUriStrings The existing URI strings * @return The new URI string */ public static String createShaderUriString(ShaderModel shaderModel, - Collection existingUriStrings) { - String extensionWithoutDot = - determineShaderFileNameExtension(shaderModel); + Collection existingUriStrings) + { + String extensionWithoutDot = + determineShaderFileNameExtension(shaderModel); int counter = 0; - while (true) { + while (true) + { String uri = "shader" + counter + "." + extensionWithoutDot; - if (!existingUriStrings.contains(uri)) { + if (!existingUriStrings.contains(uri)) + { return uri; } counter++; } } - + /** - * Determine the extension for a shader file name, (without the + * Determine the extension for a shader file name, (without the * "." dot), for the given {@link ShaderModel} - * + * * @param shaderModel The {@link ShaderModel} * @return The file extension */ private static String determineShaderFileNameExtension( - ShaderModel shaderModel) { - if (shaderModel.getShaderType() == ShaderType.VERTEX_SHADER) { + ShaderModel shaderModel) + { + if (shaderModel.getShaderType() == ShaderType.VERTEX_SHADER) + { return "vert"; } return "frag"; } + /** + * Private constructor to prevent instantiation + */ + private UriStrings() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/impl/package-info.java b/src/main/java/de/javagl/jgltf/model/impl/package-info.java index 8c6df71..93ac6bc 100644 --- a/src/main/java/de/javagl/jgltf/model/impl/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/impl/package-info.java @@ -1,6 +1,6 @@ /** * Default implementations of the glTF model interfaces.
    - *
    + *
    * These classes should not be considered to be part of the public API. */ package de.javagl.jgltf.model.impl; diff --git a/src/main/java/de/javagl/jgltf/model/io/Buffers.java b/src/main/java/de/javagl/jgltf/model/io/Buffers.java index cc8261c..175ce18 100644 --- a/src/main/java/de/javagl/jgltf/model/io/Buffers.java +++ b/src/main/java/de/javagl/jgltf/model/io/Buffers.java @@ -27,31 +27,31 @@ package de.javagl.jgltf.model.io; import java.io.InputStream; -import java.nio.*; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; import java.util.Collection; /** * Utility methods related to buffers */ -public class Buffers { - /** - * Private constructor to prevent instantiation - */ - private Buffers() { - // Private constructor to prevent instantiation - } - +public class Buffers +{ /** * Returns the contents of the given byte buffer as a string, using - * the platform's default charset, or null if the given + * the platform's default charset, or null if the given * buffer is null. The position and limit of the given * buffer will be unaffected by this call. - * + * * @param byteBuffer The byte buffer * @return The data as a string */ - public static String readAsString(ByteBuffer byteBuffer) { - if (byteBuffer == null) { + public static String readAsString(ByteBuffer byteBuffer) + { + if (byteBuffer == null) + { return null; } byte array[] = new byte[byteBuffer.capacity()]; @@ -64,149 +64,167 @@ public static String readAsString(ByteBuffer byteBuffer) { * and limit. The returned slice will have the same byte order as the * given buffer. If the given buffer is null, then * null will be returned. - * + * * @param byteBuffer The byte buffer * @return The slice */ - public static ByteBuffer createSlice(ByteBuffer byteBuffer) { - if (byteBuffer == null) { + public static ByteBuffer createSlice(ByteBuffer byteBuffer) + { + if (byteBuffer == null) + { return null; } return byteBuffer.slice().order(byteBuffer.order()); } - + /** * Create a slice of the given byte buffer, in the specified range. * The returned buffer will have the same byte order as the given * buffer. If the given buffer is null, then * null will be returned. - * + * * @param byteBuffer The byte buffer - * @param position The position where the slice should start - * @param length The length of the slice + * @param position The position where the slice should start + * @param length The length of the slice * @return The slice * @throws IllegalArgumentException If the range that is specified - * by the position and length are not valid for the given buffer + * by the position and length are not valid for the given buffer */ public static ByteBuffer createSlice( - ByteBuffer byteBuffer, int position, int length) { - if (byteBuffer == null) { + ByteBuffer byteBuffer, int position, int length) + { + if (byteBuffer == null) + { return null; } int oldPosition = byteBuffer.position(); int oldLimit = byteBuffer.limit(); - try { + try + { int newLimit = position + length; - if (newLimit > byteBuffer.capacity()) { + if (newLimit > byteBuffer.capacity()) + { throw new IllegalArgumentException( - "The new limit is " + newLimit + ", but the capacity is " - + byteBuffer.capacity()); + "The new limit is " + newLimit + ", but the capacity is " + + byteBuffer.capacity()); } byteBuffer.limit(newLimit); byteBuffer.position(position); ByteBuffer slice = byteBuffer.slice(); slice.order(byteBuffer.order()); return slice; - } finally { + } + finally + { byteBuffer.limit(oldLimit); byteBuffer.position(oldPosition); } } - + /** * Creates a new, direct byte buffer that contains the given data, * with little-endian byte order - * + * * @param data The data * @return The byte buffer */ - public static ByteBuffer create(byte data[]) { + public static ByteBuffer create(byte data[]) + { return create(data, 0, data.length); } - + /** * Creates a new, direct byte buffer that contains the specified range * of the given data, with little-endian byte order - * - * @param data The data + * + * @param data The data * @param offset The offset in the data array * @param length The length of the range * @return The byte buffer */ - public static ByteBuffer create(byte data[], int offset, int length) { + public static ByteBuffer create(byte data[], int offset, int length) + { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(length); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); byteBuffer.put(data, offset, length); byteBuffer.position(0); return byteBuffer; } - + /** * Create a new direct byte buffer with the given size, and little-endian * byte order. - * + * * @param size The size of the buffer * @return The byte buffer * @throws IllegalArgumentException If the given size is negative */ - public static ByteBuffer create(int size) { + public static ByteBuffer create(int size) + { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(size); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); return byteBuffer; } - + /** * Create an input stream from the given byte buffer, starting at its * current position, up to its current limit. Reading the returned - * stream will advance the position of the buffer. If this is not + * stream will advance the position of the buffer. If this is not * desired, a slice of the buffer may be passed to this method. - * + * * @param byteBuffer The buffer * @return The input stream */ - public static InputStream createByteBufferInputStream(ByteBuffer byteBuffer) { + public static InputStream createByteBufferInputStream(ByteBuffer byteBuffer) + { return new ByteBufferInputStream(byteBuffer); } - + + /** * Create a direct byte buffer with native byte order whose contents is * a concatenation of the given byte buffers. If the given collection * is null or empty, then a 0-byte buffer will be created. * The given collection may not contain null elements. - * + * * @param byteBuffers The input byte buffers * @return The concatenated byte buffer */ public static ByteBuffer concat( - Collection byteBuffers) { - if (byteBuffers == null || byteBuffers.isEmpty()) { + Collection byteBuffers) + { + if (byteBuffers == null || byteBuffers.isEmpty()) + { return ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder()); } int resultCapacity = byteBuffers.stream() - .mapToInt(ByteBuffer::capacity) - .reduce(0, (a, b) -> a + b); + .mapToInt(ByteBuffer::capacity) + .reduce(0, (a, b) -> a + b); ByteBuffer newByteBuffer = ByteBuffer - .allocateDirect(resultCapacity) - .order(ByteOrder.nativeOrder()); - for (ByteBuffer byteBuffer : byteBuffers) { + .allocateDirect(resultCapacity) + .order(ByteOrder.nativeOrder()); + for (ByteBuffer byteBuffer : byteBuffers) + { newByteBuffer.put(byteBuffer.slice()); } newByteBuffer.position(0); return newByteBuffer; } - + + /** * Create a new direct byte buffer with native byte order that has the * same contents as the given float buffer. - * + * * @param buffer The input buffer * @return The new byte buffer */ - public static ByteBuffer createByteBufferFrom(FloatBuffer buffer) { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity() * Float.BYTES); - FloatBuffer floatBuffer = - byteBuffer.order(ByteOrder.nativeOrder()).asFloatBuffer(); + public static ByteBuffer createByteBufferFrom(FloatBuffer buffer) + { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity() * Float.BYTES); + FloatBuffer floatBuffer = + byteBuffer.order(ByteOrder.nativeOrder()).asFloatBuffer(); floatBuffer.put(buffer.slice()); return byteBuffer; } @@ -214,15 +232,16 @@ public static ByteBuffer createByteBufferFrom(FloatBuffer buffer) { /** * Create a new direct byte buffer with native byte order that has the * same contents as the given int buffer. - * + * * @param buffer The input buffer * @return The new byte buffer */ - public static ByteBuffer createByteBufferFrom(IntBuffer buffer) { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity() * Integer.BYTES); - IntBuffer intBuffer = - byteBuffer.order(ByteOrder.nativeOrder()).asIntBuffer(); + public static ByteBuffer createByteBufferFrom(IntBuffer buffer) + { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity() * Integer.BYTES); + IntBuffer intBuffer = + byteBuffer.order(ByteOrder.nativeOrder()).asIntBuffer(); intBuffer.put(buffer.slice()); return byteBuffer; } @@ -230,98 +249,118 @@ public static ByteBuffer createByteBufferFrom(IntBuffer buffer) { /** * Create a new direct byte buffer with native byte order that has the * same contents as the given short buffer. - * + * * @param buffer The input buffer * @return The new byte buffer */ - public static ByteBuffer createByteBufferFrom(ShortBuffer buffer) { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity() * Short.BYTES); - ShortBuffer shortBuffer = - byteBuffer.order(ByteOrder.nativeOrder()).asShortBuffer(); + public static ByteBuffer createByteBufferFrom(ShortBuffer buffer) + { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity() * Short.BYTES); + ShortBuffer shortBuffer = + byteBuffer.order(ByteOrder.nativeOrder()).asShortBuffer(); shortBuffer.put(buffer.slice()); return byteBuffer; } - + /** * Convert the given input buffer into a direct byte buffer with native * byte order, by casting all elements to byte. - * + * * @param buffer The input buffer * @return The byte buffer */ - public static ByteBuffer castToByteBuffer(IntBuffer buffer) { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity()) - .order(ByteOrder.nativeOrder()); - for (int i = 0; i < buffer.capacity(); i++) { + public static ByteBuffer castToByteBuffer(IntBuffer buffer) + { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity()) + .order(ByteOrder.nativeOrder()); + for (int i = 0; i < buffer.capacity(); i++) + { byteBuffer.put(i, (byte) buffer.get(i)); } return byteBuffer; - } - + } + /** * Convert the given input buffer into a direct byte buffer with native * byte order that contains the elements of the given input buffer, * casted to short. - * + * * @param buffer The input buffer * @return The short buffer */ - public static ByteBuffer castToShortByteBuffer(IntBuffer buffer) { - ByteBuffer byteBuffer = - ByteBuffer.allocateDirect(buffer.capacity() * Short.BYTES); - ShortBuffer shortBuffer = - byteBuffer.order(ByteOrder.nativeOrder()).asShortBuffer(); - for (int i = 0; i < buffer.capacity(); i++) { + public static ByteBuffer castToShortByteBuffer(IntBuffer buffer) + { + ByteBuffer byteBuffer = + ByteBuffer.allocateDirect(buffer.capacity() * Short.BYTES); + ShortBuffer shortBuffer = + byteBuffer.order(ByteOrder.nativeOrder()).asShortBuffer(); + for (int i = 0; i < buffer.capacity(); i++) + { shortBuffer.put(i, (short) buffer.get(i)); } return byteBuffer; } + /** - * Creates a copy of the given buffer, as a direct buffer with the + * Creates a copy of the given buffer, as a direct buffer with the * same byte order, and the given capacity. If the given capacity - * is smaller than that of the given buffer, the copy will be - * truncated. If it is larger, the additional bytes will be + * is smaller than that of the given buffer, the copy will be + * truncated. If it is larger, the additional bytes will be * initialized to zero. - * - * @param buffer The input buffer + * + * @param buffer The input buffer * @param newCapacity The new capacity * @return The copy */ - public static ByteBuffer copyOf(ByteBuffer buffer, int newCapacity) { + public static ByteBuffer copyOf(ByteBuffer buffer, int newCapacity) + { ByteBuffer copy = ByteBuffer.allocateDirect(newCapacity); copy.order(buffer.order()); - if (newCapacity < buffer.capacity()) { + if (newCapacity < buffer.capacity()) + { copy.slice().put(createSlice(buffer, 0, newCapacity)); - } else { + } + else + { copy.slice().put(createSlice(buffer)); } return copy; } - + /** - * Perform a copy of the specified buffer range, analogously to + * Perform a copy of the specified buffer range, analogously to * System#arraycopy. - * - * @param src The source buffer + * + * @param src The source buffer * @param srcPos The source position - * @param dst The destination buffer + * @param dst The destination buffer * @param dstPos The destination position * @param length The length * @throws IndexOutOfBoundsException If the indices are invalid. */ public static void bufferCopy( - ByteBuffer src, int srcPos, - ByteBuffer dst, int dstPos, - int length) { + ByteBuffer src, int srcPos, + ByteBuffer dst, int dstPos, + int length) + { // This could be optimized for large lengths, by using bulk operations // on slices of the buffers - for (int i = 0; i < length; i++) { + for (int i = 0; i < length; i++) + { byte b = src.get(srcPos + i); dst.put(dstPos + i, b); } } + + /** + * Private constructor to prevent instantiation + */ + private Buffers() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/io/ByteBufferInputStream.java b/src/main/java/de/javagl/jgltf/model/io/ByteBufferInputStream.java index 4a2c246..3931d36 100644 --- a/src/main/java/de/javagl/jgltf/model/io/ByteBufferInputStream.java +++ b/src/main/java/de/javagl/jgltf/model/io/ByteBufferInputStream.java @@ -34,36 +34,42 @@ /** * Implementation of an input stream that reads from a byte buffer */ -class ByteBufferInputStream extends InputStream { +class ByteBufferInputStream extends InputStream +{ /** * The byte buffer from which this stream is reading */ private final ByteBuffer byteBuffer; - + /** * Creates a new instance that read from the given byte buffer. * Reading from the stream will increase the position of the * given buffer. If this is not desired, a slice of the actual - * buffer may be passed to this constructor. - * + * buffer may be passed to this constructor. + * * @param byteBuffer The byte buffer from which this stream is reading */ - ByteBufferInputStream(ByteBuffer byteBuffer) { + ByteBufferInputStream(ByteBuffer byteBuffer) + { this.byteBuffer = Objects.requireNonNull(byteBuffer, - "The byteBuffer may not be null"); + "The byteBuffer may not be null"); } - + @Override - public int read() throws IOException { - if (!byteBuffer.hasRemaining()) { + public int read() throws IOException + { + if (!byteBuffer.hasRemaining()) + { return -1; } return byteBuffer.get() & 0xFF; } @Override - public int read(byte[] bytes, int off, int len) throws IOException { - if (!byteBuffer.hasRemaining()) { + public int read(byte[] bytes, int off, int len) throws IOException + { + if (!byteBuffer.hasRemaining()) + { return -1; } int readLength = Math.min(len, byteBuffer.remaining()); diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfAsset.java b/src/main/java/de/javagl/jgltf/model/io/GltfAsset.java index 0ac0504..3f694cb 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfAsset.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfAsset.java @@ -31,37 +31,38 @@ import java.util.Map; /** - * Interface for a low-level representation of a glTF asset, consisting of - * the (version-specific) JSON part, optional binary data, and references + * Interface for a low-level representation of a glTF asset, consisting of + * the (version-specific) JSON part, optional binary data, and references * to external data. */ -public interface GltfAsset { +public interface GltfAsset +{ /** - * Returns the version-specific glTF object. This may be a + * Returns the version-specific glTF object. This may be a * {@link de.javagl.jgltf.impl.v1.GlTF version 1.0 glTF} or * or a {@link de.javagl.jgltf.impl.v2.GlTF version 2.0 glTF} - * + * * @return The glTF */ Object getGltf(); - + /** * Returns the binary data of this asset, or null if this * asset does not have associated binary data.
    *
    - * The returned buffer will be a slice of the data that is stored + * The returned buffer will be a slice of the data that is stored * internally. So changes of the contents of the buffer will affect * this asset, but changes of the limit or position of the buffer * will not affect this asset. - * + * * @return the optional binary data */ ByteBuffer getBinaryData(); - + /** * Return a list of all {@link GltfReference} objects that refer to * external resources for this asset - * + * * @return The {@link GltfReference} objects */ List getReferences(); @@ -71,25 +72,25 @@ public interface GltfAsset { * with the given (relative!) URI, or null if there is * no such data.
    *
    - * The returned buffer will be a slice of the data that is stored + * The returned buffer will be a slice of the data that is stored * internally. So changes of the contents of the buffer will affect * this asset, but changes of the limit or position of the buffer * will not affect this asset. - * + * * @param uriString The URI string * @return The byte buffer */ ByteBuffer getReferenceData(String uriString); - + /** * Returns an unmodifiable view on the mapping from relative URI strings * to the byte buffers containing the data of the external resources.
    - *
    - * Callers may not modify the values of this map. That is, the + *
    + * Callers may not modify the values of this map. That is, the * positions or limits of the returned buffers may not be modified! - * + * * @return The reference data mapping */ Map getReferenceDatas(); - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfAssetReader.java b/src/main/java/de/javagl/jgltf/model/io/GltfAssetReader.java index c8df8a3..e07476e 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfAssetReader.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfAssetReader.java @@ -26,17 +26,17 @@ */ package de.javagl.jgltf.model.io; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.GltfModels; -import de.javagl.jgltf.model.io.v1.GltfAssetV1; -import de.javagl.jgltf.model.io.v2.GltfAssetV2; - import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.nio.ByteBuffer; import java.nio.file.Path; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.GltfModels; +import de.javagl.jgltf.model.io.v1.GltfAssetV1; +import de.javagl.jgltf.model.io.v2.GltfAssetV2; + /** * A class for reading a glTF asset in a version-agnostic form.
    *
    @@ -45,9 +45,9 @@ * of the given URI, and loaded automatically. The respective data may * then be obtained with {@link GltfAsset#getReferenceData(String)}.
    *
    - * The {@link #readWithoutReferences(URI)} and + * The {@link #readWithoutReferences(URI)} and * {@link #readWithoutReferences(InputStream)} methods allow reading an - * asset from a URI or an input stream, without resolving external + * asset from a URI or an input stream, without resolving external * references. This is mainly intended for binary- or embedded glTF assets * that do not have external references, or for cases where the external * references should be resolved manually.
    @@ -55,27 +55,31 @@ * Such a {@link GltfAsset} may then be processed further, for example, * by creating a {@link GltfModel} using {@link GltfModels#create(GltfAsset)}. */ -public final class GltfAssetReader { +public final class GltfAssetReader +{ /** * Creates a new instance */ - public GltfAssetReader() { + public GltfAssetReader() + { // Default constructor } - + /** * Read the {@link GltfAsset} from the given URI - * + * * @param uri The URI * @return The {@link GltfAsset} * @throws IOException If an IO error occurs */ - public GltfAsset read(URI uri) throws IOException { - try (InputStream inputStream = uri.toURL().openStream()) { + public GltfAsset read(URI uri) throws IOException + { + try (InputStream inputStream = uri.toURL().openStream()) + { GltfAsset gltfAsset = readWithoutReferences(inputStream); URI baseUri = IO.getParent(uri); GltfReferenceResolver.resolveAll( - gltfAsset.getReferences(), baseUri); + gltfAsset.getReferences(), baseUri); return gltfAsset; } } @@ -87,12 +91,14 @@ public GltfAsset read(URI uri) throws IOException { * @return The {@link GltfAsset} * @throws IOException If an IO error occurs */ - public GltfAsset read(Path path) throws IOException { - try (InputStream inputStream = path.toUri().toURL().openStream()) { + public GltfAsset read(Path path) throws IOException + { + try (InputStream inputStream = path.toUri().toURL().openStream()) + { GltfAsset gltfAsset = readWithoutReferences(inputStream); Path basePath = IO.getParent(path); GltfReferenceResolver.resolveAll( - gltfAsset.getReferences(), basePath); + gltfAsset.getReferences(), basePath); return gltfAsset; } } @@ -105,19 +111,21 @@ public GltfAsset read(Path path) throws IOException { *
    * This is mainly intended for binary- or embedded glTF assets that do not * have external references. - * + * * @param uri The URI * @return The {@link GltfAsset} * @throws IOException If an IO error occurs */ - public GltfAsset readWithoutReferences(URI uri) throws IOException { - try (InputStream inputStream = uri.toURL().openStream()) { + public GltfAsset readWithoutReferences(URI uri) throws IOException + { + try (InputStream inputStream = uri.toURL().openStream()) + { return readWithoutReferences(inputStream); } } - + /** - * Read the glTF asset from the given input stream. The caller is + * Read the glTF asset from the given input stream. The caller is * responsible for closing the given stream.
    *
    * In contrast to the {@link #read(URI)} method, this method will @@ -126,47 +134,55 @@ public GltfAsset readWithoutReferences(URI uri) throws IOException { * This is mainly intended for binary- or embedded glTF assets that do not * have external references, or for cases where the external * references should be resolved manually. - * + * * @param inputStream The input stream * @return The {@link GltfAsset} * @throws IOException If an IO error occurred */ - public GltfAsset readWithoutReferences(InputStream inputStream) - throws IOException { + public GltfAsset readWithoutReferences(InputStream inputStream) + throws IOException + { RawGltfData rawGltfData = RawGltfDataReader.read(inputStream); return read(rawGltfData); } /** * Read the {@link GltfAsset} from the given {@link RawGltfData} - * + * * @param rawGltfData The {@link RawGltfData} * @return The {@link GltfAsset} * @throws IOException If the data cannot be read */ - GltfAsset read(RawGltfData rawGltfData) throws IOException { - GltfReader gltfReader = new GltfReader(); + GltfAsset read(RawGltfData rawGltfData) throws IOException + { + GltfReader gltfReader = new GltfReader(); ByteBuffer jsonData = rawGltfData.getJsonData(); try (InputStream jsonInputStream = - Buffers.createByteBufferInputStream(jsonData)) { + Buffers.createByteBufferInputStream(jsonData)) + { gltfReader.read(jsonInputStream); int majorVersion = gltfReader.getMajorVersion(); - if (majorVersion == 1) { - de.javagl.jgltf.impl.v1.GlTF gltfV1 = - gltfReader.getAsGltfV1(); - return new GltfAssetV1(gltfV1, - rawGltfData.getBinaryData()); - } else if (majorVersion == 2) { - de.javagl.jgltf.impl.v2.GlTF gltfV2 = - gltfReader.getAsGltfV2(); - return new GltfAssetV2(gltfV2, - rawGltfData.getBinaryData()); - } else { + if (majorVersion == 1) + { + de.javagl.jgltf.impl.v1.GlTF gltfV1 = + gltfReader.getAsGltfV1(); + return new GltfAssetV1(gltfV1, + rawGltfData.getBinaryData()); + } + else if (majorVersion == 2) + { + de.javagl.jgltf.impl.v2.GlTF gltfV2 = + gltfReader.getAsGltfV2(); + return new GltfAssetV2(gltfV2, + rawGltfData.getBinaryData()); + } + else + { throw new IOException( - "Unsupported major version: " + majorVersion); + "Unsupported major version: " + majorVersion); } } } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfAssetWriter.java b/src/main/java/de/javagl/jgltf/model/io/GltfAssetWriter.java index af5798f..1af68d9 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfAssetWriter.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfAssetWriter.java @@ -26,11 +26,6 @@ */ package de.javagl.jgltf.model.io; -import de.javagl.jgltf.model.io.v1.GltfAssetV1; -import de.javagl.jgltf.model.io.v1.GltfAssetWriterV1; -import de.javagl.jgltf.model.io.v2.GltfAssetV2; -import de.javagl.jgltf.model.io.v2.GltfAssetWriterV2; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -40,168 +35,193 @@ import java.nio.channels.WritableByteChannel; import java.util.Map.Entry; +import de.javagl.jgltf.model.io.v1.GltfAssetV1; +import de.javagl.jgltf.model.io.v1.GltfAssetWriterV1; +import de.javagl.jgltf.model.io.v2.GltfAssetV2; +import de.javagl.jgltf.model.io.v2.GltfAssetWriterV2; + /** * A class for writing a {@link GltfAsset} */ -public class GltfAssetWriter { +public class GltfAssetWriter +{ /** * Default constructor */ - public GltfAssetWriter() { + public GltfAssetWriter() + { // Default constructor } /** - * Write the the given {@link GltfAsset} to a file with the given name. + * Write the the given {@link GltfAsset} to a file with the given name. * The {@link GltfAsset#getBinaryData() binary data} will be ignored. - * The {@link GltfAsset#getReferenceDatas() reference data elements} - * will be written to files that are determined by resolving the + * The {@link GltfAsset#getReferenceDatas() reference data elements} + * will be written to files that are determined by resolving the * (relative) URLs of the references against the parent of the specified - * file. - * + * file. + * * @param gltfAsset The {@link GltfAsset} - * @param fileName The file name for the JSON file + * @param fileName The file name for the JSON file * @throws IOException If an IO error occurred */ - public void write(GltfAsset gltfAsset, String fileName) - throws IOException { + public void write(GltfAsset gltfAsset, String fileName) + throws IOException + { write(gltfAsset, new File(fileName)); } - + /** - * Write the the given {@link GltfAsset} to the given file. + * Write the the given {@link GltfAsset} to the given file. * The {@link GltfAsset#getBinaryData() binary data} will be ignored. - * The {@link GltfAsset#getReferenceDatas() reference data elements} - * will be written to files that are determined by resolving the + * The {@link GltfAsset#getReferenceDatas() reference data elements} + * will be written to files that are determined by resolving the * (relative) URLs of the references against the parent of the specified - * file. - * + * file. + * * @param gltfAsset The {@link GltfAsset} - * @param file The file for the JSON part + * @param file The file for the JSON part * @throws IOException If an IO error occurred */ - public void write(GltfAsset gltfAsset, File file) - throws IOException { - try (OutputStream outputStream = new FileOutputStream(file)) { + public void write(GltfAsset gltfAsset, File file) + throws IOException + { + try (OutputStream outputStream = new FileOutputStream(file)) + { writeJson(gltfAsset, outputStream); } - for (Entry entry : - gltfAsset.getReferenceDatas().entrySet()) { + for (Entry entry : + gltfAsset.getReferenceDatas().entrySet()) + { String relativeUrlString = entry.getKey(); ByteBuffer data = entry.getValue(); - - String referenceFileName = - file.toPath().getParent().resolve(relativeUrlString).toString(); + + String referenceFileName = + file.toPath().getParent().resolve(relativeUrlString).toString(); try (@SuppressWarnings("resource") - WritableByteChannel writableByteChannel = - Channels.newChannel(new FileOutputStream(referenceFileName))) { + WritableByteChannel writableByteChannel = + Channels.newChannel(new FileOutputStream(referenceFileName))) + { writableByteChannel.write(data.slice()); } } } - + /** - * Write the JSON part of the given {@link GltfAsset} to a file with + * Write the JSON part of the given {@link GltfAsset} to a file with * the given name. The {@link GltfAsset#getBinaryData() binary data} * and {@link GltfAsset#getReferenceDatas() reference data elements} * will be ignored. - * + * * @param gltfAsset The {@link GltfAsset} - * @param fileName The file name for the JSON file + * @param fileName The file name for the JSON file * @throws IOException If an IO error occurred */ - public void writeJson(GltfAsset gltfAsset, String fileName) - throws IOException { + public void writeJson(GltfAsset gltfAsset, String fileName) + throws IOException + { writeJson(gltfAsset, new File(fileName)); } - + /** - * Write the JSON part of the given {@link GltfAsset} to a file with + * Write the JSON part of the given {@link GltfAsset} to a file with * the given name. The {@link GltfAsset#getBinaryData() binary data} * and {@link GltfAsset#getReferenceDatas() reference data elements} * will be ignored. - * + * * @param gltfAsset The {@link GltfAsset} - * @param file The file for the JSON part + * @param file The file for the JSON part * @throws IOException If an IO error occurred */ - public void writeJson(GltfAsset gltfAsset, File file) - throws IOException { - try (OutputStream outputStream = new FileOutputStream(file)) { + public void writeJson(GltfAsset gltfAsset, File file) + throws IOException + { + try (OutputStream outputStream = new FileOutputStream(file)) + { writeJson(gltfAsset, outputStream); } } - + /** * Write the JSON part of the given {@link GltfAsset} to the given * output stream. The {@link GltfAsset#getBinaryData() binary data} * and {@link GltfAsset#getReferenceDatas() reference data elements} * will be ignored. The caller is responsible for closing the given * stream. - * - * @param gltfAsset The {@link GltfAsset} + * + * @param gltfAsset The {@link GltfAsset} * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void writeJson(GltfAsset gltfAsset, OutputStream outputStream) - throws IOException { + public void writeJson(GltfAsset gltfAsset, OutputStream outputStream) + throws IOException + { Object gltf = gltfAsset.getGltf(); GltfWriter gltfWriter = new GltfWriter(); gltfWriter.write(gltf, outputStream); } - + /** - * Write the given {@link GltfAsset} as a binary glTF asset to file with + * Write the given {@link GltfAsset} as a binary glTF asset to file with * the given name. - * + * * @param gltfAsset The {@link GltfAsset} - * @param fileName The file name for the JSON file + * @param fileName The file name for the JSON file * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAsset gltfAsset, String fileName) - throws IOException { + public void writeBinary(GltfAsset gltfAsset, String fileName) + throws IOException + { writeBinary(gltfAsset, new File(fileName)); } - + /** * Write the given {@link GltfAsset} as a binary glTF asset to the given * file - * + * * @param gltfAsset The {@link GltfAsset} - * @param file The file + * @param file The file * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAsset gltfAsset, File file) - throws IOException { - try (OutputStream outputStream = new FileOutputStream(file)) { + public void writeBinary(GltfAsset gltfAsset, File file) + throws IOException + { + try (OutputStream outputStream = new FileOutputStream(file)) + { writeBinary(gltfAsset, outputStream); } } - + /** - * Write the given {@link GltfAsset} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * Write the given {@link GltfAsset} as a binary glTF asset to the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfAsset The {@link GltfAsset} + * + * @param gltfAsset The {@link GltfAsset} * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAsset gltfAsset, OutputStream outputStream) - throws IOException { - if (gltfAsset instanceof GltfAssetV1) { - GltfAssetV1 gltfAssetV1 = (GltfAssetV1) gltfAsset; + public void writeBinary(GltfAsset gltfAsset, OutputStream outputStream) + throws IOException + { + if (gltfAsset instanceof GltfAssetV1) + { + GltfAssetV1 gltfAssetV1 = (GltfAssetV1)gltfAsset; GltfAssetWriterV1 gltfAssetWriterV1 = new GltfAssetWriterV1(); gltfAssetWriterV1.writeBinary(gltfAssetV1, outputStream); - } else if (gltfAsset instanceof GltfAssetV2) { - GltfAssetV2 gltfAssetV2 = (GltfAssetV2) gltfAsset; + } + else if (gltfAsset instanceof GltfAssetV2) + { + GltfAssetV2 gltfAssetV2 = (GltfAssetV2)gltfAsset; GltfAssetWriterV2 gltfAssetWriterV2 = new GltfAssetWriterV2(); gltfAssetWriterV2.writeBinary(gltfAssetV2, outputStream); - } else { + } + else + { throw new IOException( - "The gltfAsset has an unknown version: " + gltfAsset); + "The gltfAsset has an unknown version: " + gltfAsset); } } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfAssets.java b/src/main/java/de/javagl/jgltf/model/io/GltfAssets.java index fe40aed..4e30b8d 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfAssets.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfAssets.java @@ -32,126 +32,144 @@ /** * Utility methods related to {@link GltfAsset} instances.
    *
    - * The methods in this class may be used to check the "nature" of a - * {@link GltfAsset}. A default asset may contain references with - * URIs that refer to a file. An embedded asset may contain + * The methods in this class may be used to check the "nature" of a + * {@link GltfAsset}. A default asset may contain references with + * URIs that refer to a file. An embedded asset may contain * references with URIs that are data URIs. A binary asset may * contain a binary data blob. Mixed forms of assets are possible: * It is possible to create an asset where one URI refers to a file, * and another URI is a data URI. The methods in this class allow - * checking whether an asset is "purely" of one specific type. + * checking whether an asset is "purely" of one specific type. *
    * This class should not be considered as part of the public API. It may * change or be omitted in the future. */ -public class GltfAssets { - /** - * Private constructor to prevent instantiation - */ - private GltfAssets() { - // Private constructor to prevent instantiation - } - +public class GltfAssets +{ /** * Returns whether the given {@link GltfAsset} is a default - * asset. This means that it does not contain a (non-empty) + * asset. This means that it does not contain a (non-empty) * {@link GltfAsset#getBinaryData() binary data} blob, and it * does not contain references with (embedded) data URIs. - * + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset is a default asset */ - public static boolean isDefault(GltfAsset gltfAsset) { + public static boolean isDefault(GltfAsset gltfAsset) + { ByteBuffer binaryData = gltfAsset.getBinaryData(); - if (binaryData != null && binaryData.capacity() > 0) { + if (binaryData != null && binaryData.capacity() > 0) + { return false; } - if (containsDataUriReferences(gltfAsset)) { + if (containsDataUriReferences(gltfAsset)) + { return false; } return true; } - + /** * Returns whether the given {@link GltfAsset} is an embedded - * asset. This means that it does not contain a (non-empty) + * asset. This means that it does not contain a (non-empty) * {@link GltfAsset#getBinaryData() binary data} blob, and it * does not contain references that refer to files. - * + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset is an embedded asset */ - public static boolean isEmbedded(GltfAsset gltfAsset) { + public static boolean isEmbedded(GltfAsset gltfAsset) + { ByteBuffer binaryData = gltfAsset.getBinaryData(); - if (binaryData != null && binaryData.capacity() > 0) { + if (binaryData != null && binaryData.capacity() > 0) + { return false; } - if (containsFileUriReferences(gltfAsset)) { + if (containsFileUriReferences(gltfAsset)) + { return false; } return true; } - + /** * Returns whether the given {@link GltfAsset} is binary - * asset. This means that it does does not contain references + * asset. This means that it does does not contain references * that refer to files or have (embedded) data URIs. (Note that - * this method returns true in this case even if + * this method returns true in this case even if * the asset does not have a {@link GltfAsset#getBinaryData() binary data} - * blob) - * + * blob) + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset is a binary asset */ - public static boolean isBinary(GltfAsset gltfAsset) { - if (containsFileUriReferences(gltfAsset)) { + public static boolean isBinary(GltfAsset gltfAsset) + { + if (containsFileUriReferences(gltfAsset)) + { return false; } - if (containsDataUriReferences(gltfAsset)) { + if (containsDataUriReferences(gltfAsset)) + { return false; } return true; } - + /** - * Returns whether the given {@link GltfAsset} contains any + * Returns whether the given {@link GltfAsset} contains any * {@link GltfReference} that has a URI that is not a data URI.
    *
    - * If the asset does not contain any references, then + * If the asset does not contain any references, then * false is returned.
    - * + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset contains (non-data) URI references */ - private static boolean containsFileUriReferences(GltfAsset gltfAsset) { + private static boolean containsFileUriReferences(GltfAsset gltfAsset) + { List references = gltfAsset.getReferences(); - for (GltfReference reference : references) { + for (GltfReference reference : references) + { String uriString = reference.getUri(); - if (!IO.isDataUriString(uriString)) { + if (!IO.isDataUriString(uriString)) + { return true; } } return false; } - + /** - * Returns whether the given {@link GltfAsset} contains any + * Returns whether the given {@link GltfAsset} contains any * {@link GltfReference} that has a URI that is a data URI.
    *
    - * If the asset does not contain any references, then + * If the asset does not contain any references, then * false is returned.
    - * + * * @param gltfAsset The {@link GltfAsset} * @return Whether the asset contains data URI references */ - private static boolean containsDataUriReferences(GltfAsset gltfAsset) { + private static boolean containsDataUriReferences(GltfAsset gltfAsset) + { List references = gltfAsset.getReferences(); - for (GltfReference reference : references) { + for (GltfReference reference : references) + { String uriString = reference.getUri(); - if (!IO.isDataUriString(uriString)) { + if (!IO.isDataUriString(uriString)) + { return true; } } return false; } + + + /** + * Private constructor to prevent instantiation + */ + private GltfAssets() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfModelReader.java b/src/main/java/de/javagl/jgltf/model/io/GltfModelReader.java index 76c6e48..cf98047 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfModelReader.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfModelReader.java @@ -26,56 +26,39 @@ */ package de.javagl.jgltf.model.io; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.Path; + import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.io.v1.GltfAssetV1; import de.javagl.jgltf.model.io.v2.GltfAssetV2; import de.javagl.jgltf.model.v1.GltfModelV1; import de.javagl.jgltf.model.v2.GltfModelCreatorV2; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.nio.file.Path; - /** * A class for reading a {@link GltfModel} from a URI. */ -public final class GltfModelReader { +public final class GltfModelReader +{ /** * Default constructor */ - public GltfModelReader() { + public GltfModelReader() + { // Default constructor } - - /** - * Creates a {@link GltfModel} instance from the given {@link GltfAsset} - * - * @param gltfAsset The {@link GltfAsset} - * @return The {@link GltfModel} - * @throws IOException If the given asset has an unknown version - */ - private static GltfModel createModel(GltfAsset gltfAsset) throws IOException { - if (gltfAsset instanceof GltfAssetV1) { - GltfAssetV1 gltfAssetV1 = (GltfAssetV1) gltfAsset; - return new GltfModelV1(gltfAssetV1); - } - if (gltfAsset instanceof GltfAssetV2) { - GltfAssetV2 gltfAssetV2 = (GltfAssetV2) gltfAsset; - return GltfModelCreatorV2.create(gltfAssetV2); - } - throw new IOException( - "The glTF asset has an unknown version: " + gltfAsset); - } - + /** * Read the {@link GltfModel} from the given URI - * + * * @param uri The URI * @return The {@link GltfModel} * @throws IOException If an IO error occurs */ - public GltfModel read(URI uri) throws IOException { + public GltfModel read(URI uri) throws IOException + { GltfAssetReader gltfAssetReader = new GltfAssetReader(); GltfAsset gltfAsset = gltfAssetReader.read(uri); return createModel(gltfAsset); @@ -88,49 +71,76 @@ public GltfModel read(URI uri) throws IOException { * @return The {@link GltfModel} * @throws IOException If an IO error occurs */ - public GltfModel read(Path path) throws IOException { + public GltfModel read(Path path) throws IOException + { GltfAssetReader gltfAssetReader = new GltfAssetReader(); GltfAsset gltfAsset = gltfAssetReader.read(path); return createModel(gltfAsset); } /** - * Read the {@link GltfModel} from the given URI. In contrast to the - * {@link #read(URI)} method, this method will not resolve any + * Read the {@link GltfModel} from the given URI. In contrast to the + * {@link #read(URI)} method, this method will not resolve any * references that are contained in the {@link GltfModel}.
    *
    * This is mainly intended for binary- or embedded glTF assets that do not * have external references. - * + * * @param uri The URI * @return The {@link GltfModel} * @throws IOException If an IO error occurs */ - public GltfModel readWithoutReferences(URI uri) throws IOException { - try (InputStream inputStream = uri.toURL().openStream()) { + public GltfModel readWithoutReferences(URI uri) throws IOException + { + try (InputStream inputStream = uri.toURL().openStream()) + { GltfModel gltfModel = readWithoutReferences(inputStream); return gltfModel; } } - + /** * Read the {@link GltfModel} from the given input stream. In contrast - * to the {@link #read(URI)} method, this method will not resolve any + * to the {@link #read(URI)} method, this method will not resolve any * references that are contained in the {@link GltfAsset}.
    *
    * This is mainly intended for binary- or embedded glTF assets that do not * have external references. - * + * * @param inputStream The input stream to read from * @return The {@link GltfModel} * @throws IOException If an IO error occurs */ - public GltfModel readWithoutReferences(InputStream inputStream) - throws IOException { + public GltfModel readWithoutReferences(InputStream inputStream) + throws IOException + { GltfAssetReader gltfAssetReader = new GltfAssetReader(); - GltfAsset gltfAsset = - gltfAssetReader.readWithoutReferences(inputStream); + GltfAsset gltfAsset = + gltfAssetReader.readWithoutReferences(inputStream); return createModel(gltfAsset); } - + + /** + * Creates a {@link GltfModel} instance from the given {@link GltfAsset} + * + * @param gltfAsset The {@link GltfAsset} + * @return The {@link GltfModel} + * @throws IOException If the given asset has an unknown version + */ + private static GltfModel createModel(GltfAsset gltfAsset) throws IOException + { + if (gltfAsset instanceof GltfAssetV1) + { + GltfAssetV1 gltfAssetV1 = (GltfAssetV1)gltfAsset; + return new GltfModelV1(gltfAssetV1); + } + if (gltfAsset instanceof GltfAssetV2) + { + GltfAssetV2 gltfAssetV2 = (GltfAssetV2)gltfAsset; + return GltfModelCreatorV2.create(gltfAssetV2); + } + throw new IOException( + "The glTF asset has an unknown version: " + gltfAsset); + } + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfModelWriter.java b/src/main/java/de/javagl/jgltf/model/io/GltfModelWriter.java index 374e36d..4c44855 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfModelWriter.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfModelWriter.java @@ -26,145 +26,158 @@ */ package de.javagl.jgltf.model.io; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.io.v1.GltfModelWriterV1; -import de.javagl.jgltf.model.io.v2.GltfModelWriterV2; -import de.javagl.jgltf.model.v1.GltfModelV1; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.io.v1.GltfModelWriterV1; +import de.javagl.jgltf.model.io.v2.GltfModelWriterV2; +import de.javagl.jgltf.model.v1.GltfModelV1; + /** * A class for writing a {@link GltfModel}. The model can be written as - * a default glTF, consisting of a JSON file and the files that are + * a default glTF, consisting of a JSON file and the files that are * referred to via URIs, or as a binary file, or an embedded file where * all external references are replaced by data URIs. */ -public class GltfModelWriter { +public class GltfModelWriter +{ /** * Default constructor */ - public GltfModelWriter() { + public GltfModelWriter() + { // Default constructor } /** - * Write the given {@link GltfModel} to a file with the given name. - * External references of buffers or images that are given via the - * respective URI string will be resolved against the parent directory - * of the file, and the corresponding data will be written into the - * corresponding files. - * + * Write the given {@link GltfModel} to a file with the given name. + * External references of buffers or images that are given via the + * respective URI string will be resolved against the parent directory + * of the file, and the corresponding data will be written into the + * corresponding files. + * * @param gltfModel The {@link GltfModel} - * @param fileName The file name + * @param fileName The file name * @throws IOException If an IO error occurs */ - public void write(GltfModel gltfModel, String fileName) - throws IOException { + public void write(GltfModel gltfModel, String fileName) + throws IOException + { write(gltfModel, new File(fileName)); } - + /** * Write the given {@link GltfModel} to the given file. External - * references of buffers or images that are given via the respective - * URI string will be resolved against the parent directory of the - * given file, and the corresponding data will be written into the - * corresponding files. - * + * references of buffers or images that are given via the respective + * URI string will be resolved against the parent directory of the + * given file, and the corresponding data will be written into the + * corresponding files. + * * @param gltfModel The {@link GltfModel} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void write(GltfModel gltfModel, File file) - throws IOException { - if (gltfModel instanceof GltfModelV1) { - GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; - GltfModelWriterV1 gltfModelWriterV1 = - new GltfModelWriterV1(); + public void write(GltfModel gltfModel, File file) + throws IOException + { + if (gltfModel instanceof GltfModelV1) + { + GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; + GltfModelWriterV1 gltfModelWriterV1 = + new GltfModelWriterV1(); gltfModelWriterV1.write(gltfModelV1, file); return; } - GltfModelWriterV2 gltfModelWriterV2 = - new GltfModelWriterV2(); + GltfModelWriterV2 gltfModelWriterV2 = + new GltfModelWriterV2(); gltfModelWriterV2.write(gltfModel, file); } - + /** * Write the given {@link GltfModel} as a binary glTF asset to the * given file - * + * * @param gltfModel The {@link GltfModel} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModel gltfModel, File file) - throws IOException { - try (OutputStream outputStream = new FileOutputStream(file)) { + public void writeBinary(GltfModel gltfModel, File file) + throws IOException + { + try (OutputStream outputStream = new FileOutputStream(file)) + { writeBinary(gltfModel, outputStream); } } - + /** * Write the given {@link GltfModel} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModel gltfModel, OutputStream outputStream) - throws IOException { - if (gltfModel instanceof GltfModelV1) { - GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; - GltfModelWriterV1 gltfModelWriterV1 = - new GltfModelWriterV1(); + public void writeBinary(GltfModel gltfModel, OutputStream outputStream) + throws IOException + { + if (gltfModel instanceof GltfModelV1) + { + GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; + GltfModelWriterV1 gltfModelWriterV1 = + new GltfModelWriterV1(); gltfModelWriterV1.writeBinary(gltfModelV1, outputStream); return; } - GltfModelWriterV2 gltfModelWriterV2 = - new GltfModelWriterV2(); + GltfModelWriterV2 gltfModelWriterV2 = + new GltfModelWriterV2(); gltfModelWriterV2.writeBinary(gltfModel, outputStream); } - + /** * Write the given {@link GltfModel} as an embedded glTF asset to the * given file - * + * * @param gltfModel The {@link GltfModel} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void writeEmbedded(GltfModel gltfModel, File file) - throws IOException { - try (OutputStream outputStream = new FileOutputStream(file)) { + public void writeEmbedded(GltfModel gltfModel, File file) + throws IOException + { + try (OutputStream outputStream = new FileOutputStream(file)) + { writeEmbedded(gltfModel, outputStream); } } - + /** * Write the given {@link GltfModel} as an embedded glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeEmbedded(GltfModel gltfModel, OutputStream outputStream) - throws IOException { - if (gltfModel instanceof GltfModelV1) { - GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; - GltfModelWriterV1 gltfModelWriterV1 = - new GltfModelWriterV1(); + public void writeEmbedded(GltfModel gltfModel, OutputStream outputStream) + throws IOException + { + if (gltfModel instanceof GltfModelV1) + { + GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; + GltfModelWriterV1 gltfModelWriterV1 = + new GltfModelWriterV1(); gltfModelWriterV1.writeEmbedded(gltfModelV1, outputStream); return; } - GltfModelWriterV2 gltfModelWriterV2 = - new GltfModelWriterV2(); + GltfModelWriterV2 gltfModelWriterV2 = + new GltfModelWriterV2(); gltfModelWriterV2.writeEmbedded(gltfModel, outputStream); } } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfReader.java b/src/main/java/de/javagl/jgltf/model/io/GltfReader.java index 4a89d32..b92f545 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfReader.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfReader.java @@ -26,131 +26,145 @@ */ package de.javagl.jgltf.model.io; -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; - import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.logging.Logger; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + /** * A class for reading the JSON for a glTF asset in a version-agnostic form. - * It a allows determining the version of the glTF and returning it as + * It a allows determining the version of the glTF and returning it as * a properly typed object - that is, as a {@link de.javagl.jgltf.impl.v1.GlTF} * or a {@link de.javagl.jgltf.impl.v2.GlTF}.
    */ -final class GltfReader { +final class GltfReader +{ /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(GltfReader.class.getName()); + Logger.getLogger(GltfReader.class.getName()); /** * The root node that was read during the last call to {@link #read} */ private JsonElement rootNode; - - /** - * Tries to obtain the rootNode.asset.version string. If - * either node is null, then "1.0" will be - * returned. - * - * @param rootNode The root node - * @return The version - */ - private static String getVersion(JsonElement rootNode) { - JsonElement assetNode = rootNode.getAsJsonObject().get("asset"); - if (assetNode == null) { - return "1.0"; - } - JsonElement versionNode = assetNode.getAsJsonObject().get("version"); - if (versionNode == null) { - return "1.0"; - } - if (!versionNode.isJsonPrimitive()) { - logger.warning("No valid 'version' property in 'asset'. " + - "Assuming version 1.0"); - return "1.0"; - } - return versionNode.getAsString(); - } - + /** - * Read the JSON data from the given input stream. The caller is + * Read the JSON data from the given input stream. The caller is * responsible for closing the given stream. After this method * has been called, the version of the glTF may be obtained with * {@link #getVersion()}, and the actual asset may be obtained * with {@link #getAsGltfV1()} or {@link #getAsGltfV2()}. - * + * * @param inputStream The input stream * @throws IOException If an IO error occurred */ - void read(InputStream inputStream) throws IOException { - InputStreamReader reader = new InputStreamReader(inputStream); - rootNode = JsonParser.parseReader(reader); - reader.close(); + void read(InputStream inputStream) throws IOException + { + InputStreamReader reader = new InputStreamReader(inputStream); + rootNode = JsonParser.parseReader(reader); + reader.close(); } - + /** * Returns the version of the glTF, or null * if no glTF was read yet - * + * * @return The version string */ - String getVersion() { - if (rootNode == null) { + String getVersion() + { + if (rootNode == null) + { return null; } return getVersion(rootNode); } - + /** * Returns the major version of the glTF, or 0 of no glTF was read yet. - * + * * @return The major version number */ - int getMajorVersion() { - if (rootNode == null) { + int getMajorVersion() + { + if (rootNode == null) + { return 0; } int version[] = VersionUtils.computeMajorMinorPatch(getVersion()); return version[0]; } - + /** - * Obtain the glTF as a {@link de.javagl.jgltf.impl.v1.GlTF}, + * Obtain the glTF as a {@link de.javagl.jgltf.impl.v1.GlTF}, * or null if no glTF was read yet. - * + * * @return The glTF. * @throws IllegalArgumentException If the glTF that was read is not - * a valid glTF 1.0 + * a valid glTF 1.0 */ - de.javagl.jgltf.impl.v1.GlTF getAsGltfV1() { - if (rootNode == null) { + de.javagl.jgltf.impl.v1.GlTF getAsGltfV1() + { + if (rootNode == null) + { return null; } - return new Gson().fromJson(rootNode, - de.javagl.jgltf.impl.v1.GlTF.class); + return new Gson().fromJson(rootNode, + de.javagl.jgltf.impl.v1.GlTF.class); } - + /** - * Obtain the glTF as a {@link de.javagl.jgltf.impl.v2.GlTF}, + * Obtain the glTF as a {@link de.javagl.jgltf.impl.v2.GlTF}, * or null if no glTF was read yet. - * + * * @return The glTF. * @throws IllegalArgumentException If the glTF that was read is not - * a valid glTF 2.0 + * a valid glTF 2.0 */ - de.javagl.jgltf.impl.v2.GlTF getAsGltfV2() { - if (rootNode == null) { + de.javagl.jgltf.impl.v2.GlTF getAsGltfV2() + { + if (rootNode == null) + { return null; } - return new Gson().fromJson(rootNode, - de.javagl.jgltf.impl.v2.GlTF.class); + return new Gson().fromJson(rootNode, + de.javagl.jgltf.impl.v2.GlTF.class); } - - + + /** + * Tries to obtain the rootNode.asset.version string. If + * either node is null, then "1.0" will be + * returned. + * + * @param rootNode The root node + * @return The version + */ + private static String getVersion(JsonElement rootNode) + { + JsonElement assetNode = rootNode.getAsJsonObject().get("asset"); + if (assetNode == null) + { + return "1.0"; + } + JsonElement versionNode = assetNode.getAsJsonObject().get("version"); + if (versionNode == null) + { + return "1.0"; + } + if (!versionNode.isJsonPrimitive()) + { + logger.warning("No valid 'version' property in 'asset'. " + + "Assuming version 1.0"); + return "1.0"; + } + return versionNode.getAsString(); + } + + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfReference.java b/src/main/java/de/javagl/jgltf/model/io/GltfReference.java index 7eabd97..be72717 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfReference.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfReference.java @@ -33,65 +33,70 @@ /** * A reference to an external resource that belongs to a {@link GltfAsset}. */ -public final class GltfReference { +public final class GltfReference +{ /** * The name of the external resource */ private final String name; - + /** * The (relative) URI of the reference */ private final String uri; - + /** * The target that is supposed to receive the binary data that was * read from the external resource */ private final Consumer target; - + /** * Default constructor - * - * @param name The name of the external resource - * @param uri The (relative) URI of the reference + * + * @param name The name of the external resource + * @param uri The (relative) URI of the reference * @param target The target that is supposed to receive the binary - * data that was read from the external resource + * data that was read from the external resource */ - public GltfReference(String name, String uri, Consumer target) { + public GltfReference(String name, String uri, Consumer target) + { this.name = Objects.requireNonNull( - name, "The name may not be null"); + name, "The name may not be null"); this.uri = Objects.requireNonNull( - uri, "The uri may not be null"); + uri, "The uri may not be null"); this.target = Objects.requireNonNull( - target, "The target may not be null"); + target, "The target may not be null"); } - + /** * Returns the name of the external resource - * + * * @return The name */ - public String getName() { + public String getName() + { return name; } - + /** * Returns the (relative) URI of the reference - * + * * @return The URI */ - public String getUri() { + public String getUri() + { return uri; } - + /** * Returns the target that is supposed to receive the binary * data that was read from the external resource - * + * * @return The target */ - public Consumer getTarget() { + public Consumer getTarget() + { return target; } } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfReferenceResolver.java b/src/main/java/de/javagl/jgltf/model/io/GltfReferenceResolver.java index a7697e2..56e596b 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfReferenceResolver.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfReferenceResolver.java @@ -38,34 +38,29 @@ * A class for resolving the external data of {@link GltfReference} objects * that are obtained from a {@link GltfAsset} */ -public class GltfReferenceResolver { +public class GltfReferenceResolver +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfReferenceResolver.class.getName()); + private static final Logger logger = + Logger.getLogger(GltfReferenceResolver.class.getName()); /** - * Private constructor to prevent instantiation - */ - private GltfReferenceResolver() { - // Private constructor to prevent instantiation - } - - /** - * Calls {@link #resolve(GltfReference, Function)} with each + * Calls {@link #resolve(GltfReference, Function)} with each * {@link GltfReference} of the given list, resolving the * URIs of the references against the given base URI - * + * * @param references The {@link GltfReference} objects - * @param baseUri The base URI that references will be resolved against + * @param baseUri The base URI that references will be resolved against */ public static void resolveAll( - Iterable references, URI baseUri) { + Iterable references, URI baseUri) + { Objects.requireNonNull(references, "The references may not be null"); Objects.requireNonNull(baseUri, "The baseUri may not be null"); - Function uriResolver = - UriResolvers.createBaseUriResolver(baseUri); + Function uriResolver = + UriResolvers.createBaseUriResolver(baseUri); resolveAll(references, uriResolver); } @@ -75,59 +70,72 @@ public static void resolveAll( * Paths of the references against the given base Path * * @param references The {@link GltfReference} objects - * @param basePath The base Path that references will be resolved against + * @param basePath The base Path that references will be resolved against */ public static void resolveAll( - Iterable references, Path basePath) { + Iterable references, Path basePath) + { Objects.requireNonNull(references, "The references may not be null"); Objects.requireNonNull(basePath, "The basePath may not be null"); Function uriResolver = - UriResolvers.createBasePathResolver(basePath); + UriResolvers.createBasePathResolver(basePath); resolveAll(references, uriResolver); } /** - * Calls {@link #resolve(GltfReference, Function)} with each + * Calls {@link #resolve(GltfReference, Function)} with each * {@link GltfReference} of the given list - * - * @param references The {@link GltfReference} objects + * + * @param references The {@link GltfReference} objects * @param uriResolver The function for resolving a URI string - * into a byte buffer + * into a byte buffer */ public static void resolveAll( - Iterable references, - Function uriResolver) { + Iterable references, + Function uriResolver) + { Objects.requireNonNull(references, "The references may not be null"); Objects.requireNonNull(uriResolver, "The uriResolver may not be null"); - for (GltfReference reference : references) { + for (GltfReference reference : references) + { resolve(reference, uriResolver); } } - + /** - * Pass the {@link GltfReference#getUri() URI} of the given - * {@link GltfReference} to the given resolver function, - * and and pass the resulting byte buffer to the + * Pass the {@link GltfReference#getUri() URI} of the given + * {@link GltfReference} to the given resolver function, + * and and pass the resulting byte buffer to the * {@link GltfReference#getTarget() target} of the reference. If * a URI cannot be resolved, a warning will be printed. - * - * @param reference The {@link GltfReference} + * + * @param reference The {@link GltfReference} * @param uriResolver The function for resolving a URI string - * into an byte buffer + * into an byte buffer */ - public static void resolve(GltfReference reference, - Function uriResolver) { + public static void resolve(GltfReference reference, + Function uriResolver) + { Objects.requireNonNull(reference, "The reference may not be null"); Objects.requireNonNull(uriResolver, "The uriResolver may not be null"); String uri = reference.getUri(); ByteBuffer byteBuffer = uriResolver.apply(uri); - if (byteBuffer == null) { + if (byteBuffer == null) + { logger.warning("Could not resolve URI " + uri); } Consumer target = reference.getTarget(); target.accept(byteBuffer); } - + + /** + * Private constructor to prevent instantiation + */ + private GltfReferenceResolver() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/io/GltfWriter.java b/src/main/java/de/javagl/jgltf/model/io/GltfWriter.java index 87ed1f9..5befb1c 100644 --- a/src/main/java/de/javagl/jgltf/model/io/GltfWriter.java +++ b/src/main/java/de/javagl/jgltf/model/io/GltfWriter.java @@ -26,66 +26,72 @@ */ package de.javagl.jgltf.model.io; -import com.google.gson.GsonBuilder; - import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; +import com.google.gson.GsonBuilder; + /** * A class for writing a glTF as JSON */ -public final class GltfWriter { +public final class GltfWriter +{ /** * Whether the JSON output should be indented */ private boolean indenting; - + /** * Creates a new glTF writer. By default, the output written by this class * will be indented. */ - public GltfWriter() { + public GltfWriter() + { this.indenting = true; } - - /** - * Returns whether the JSON output will be indented - * - * @return Whether the JSON output will be indented - */ - public boolean isIndenting() { - return indenting; - } - + /** * Set whether the JSON output should be indented - * + * * @param indenting whether the JSON output should be indented */ - public void setIndenting(boolean indenting) { + public void setIndenting(boolean indenting) + { this.indenting = indenting; } - + + /** + * Returns whether the JSON output will be indented + * + * @return Whether the JSON output will be indented + */ + public boolean isIndenting() + { + return indenting; + } + /** * Write the given glTF to the given output stream. The caller * is responsible for closing the stream. - * - * @param gltf The glTF + * + * @param gltf The glTF * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void write(Object gltf, OutputStream outputStream) - throws IOException { - GsonBuilder gsonBuilder = new GsonBuilder(); - if (indenting) { - gsonBuilder.setPrettyPrinting(); + public void write(Object gltf, OutputStream outputStream) + throws IOException + { + GsonBuilder gsonBuilder = new GsonBuilder(); + if (indenting) + { + gsonBuilder.setPrettyPrinting(); } OutputStreamWriter writer = new OutputStreamWriter(outputStream); gsonBuilder.create().toJson(gsonBuilder, writer); writer.close(); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/IO.java b/src/main/java/de/javagl/jgltf/model/io/IO.java index 7cb5a07..8571952 100644 --- a/src/main/java/de/javagl/jgltf/model/io/IO.java +++ b/src/main/java/de/javagl/jgltf/model/io/IO.java @@ -26,8 +26,17 @@ */ package de.javagl.jgltf.model.io; -import java.io.*; -import java.net.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; @@ -35,73 +44,79 @@ /** * IO utility methods */ -public class IO { - /** - * Private constructor to prevent instantiation - */ - private IO() { - // Private constructor to prevent instantiation - } - +public class IO +{ /** * Convert the given URI string into an absolute URI, resolving it * against the given base URI if necessary - * - * @param baseUri The base URI + * + * @param baseUri The base URI * @param uriString The URI string * @return The absolute URI * @throws IOException If the URI string is not valid */ - public static URI makeAbsolute(URI baseUri, String uriString) - throws IOException { - try { + public static URI makeAbsolute(URI baseUri, String uriString) + throws IOException + { + try + { String escapedUriString = uriString.replaceAll(" ", "%20"); URI uri = new URI(escapedUriString); - if (uri.isAbsolute()) { + if (uri.isAbsolute()) + { return uri; } return baseUri.resolve(escapedUriString); - } catch (URISyntaxException e) { + } + catch (URISyntaxException e) + { throw new IOException("Invalid URI string: " + uriString, e); } } - + /** * Convert the given URI string into an absolute path, resolving it * against the given base path if necessary * - * @param basePath The base path + * @param basePath The base path * @param uriString The URI string * @return The absolute path * @throws IOException If the URI string is not valid */ public static Path makeAbsolute(Path basePath, String uriString) - throws IOException { - try { + throws IOException + { + try + { String escapedUriString = uriString.replaceAll(" ", "%20"); URI uri = new URI(escapedUriString); - if (uri.isAbsolute()) { + if (uri.isAbsolute()) + { return Paths.get(uri).toAbsolutePath(); } return basePath.resolve(escapedUriString).toAbsolutePath(); - } catch (URISyntaxException e) { + } + catch (URISyntaxException e) + { throw new IOException("Invalid URI string: " + uriString, e); } } /** - * Returns the URI describing the parent of the given URI. If the - * given URI describes a file, this will return the URI of the + * Returns the URI describing the parent of the given URI. If the + * given URI describes a file, this will return the URI of the * directory. If the given URI describes a directory, this will * return the URI of the parent directory - * + * * @param uri The URI * @return The parent URI */ - public static URI getParent(URI uri) { - if (uri.getPath().endsWith("/")) { - return uri.resolve(".."); + public static URI getParent(URI uri) + { + if (uri.getPath().endsWith("/")) + { + return uri.resolve(".."); } return uri.resolve("."); } @@ -115,88 +130,103 @@ public static URI getParent(URI uri) { * @param path The path * @return The parent path */ - public static Path getParent(Path path) { + public static Path getParent(Path path) + { return path.getParent(); } /** - * Returns whether the given URI is a data URI. - * + * Returns whether the given URI is a data URI. + * * @param uri The URI * @return Whether the string is a data URI */ - public static boolean isDataUri(URI uri) { + public static boolean isDataUri(URI uri) + { return "data".equalsIgnoreCase(uri.getScheme()); } - + /** * Returns whether the given string is a data URI. If the given string - * is null, then false will be returned. - * + * is null, then false will be returned. + * * @param uriString The URI string * @return Whether the string is a data URI */ - public static boolean isDataUriString(String uriString) { - if (uriString == null) { + public static boolean isDataUriString(String uriString) + { + if (uriString == null) + { return false; } - try { + try + { URI uri = new URI(uriString); return isDataUri(uri); - } catch (URISyntaxException e) { + } + catch (URISyntaxException e) + { return false; } } - + /** - * Tries to extract the "file name" that is referred to with the + * Tries to extract the "file name" that is referred to with the * given URI. This is the part behind the last "/" slash - * that appears in the string representation of the given URI. If no - * file name can be extracted, then the string representation of the + * that appears in the string representation of the given URI. If no + * file name can be extracted, then the string representation of the * URI is returned. - * + * * @param uri The URI * @return The file name */ - public static String extractFileName(URI uri) { + public static String extractFileName(URI uri) + { String s = uri.toString(); int lastSlashIndex = s.lastIndexOf('/'); - if (lastSlashIndex != -1) { + if (lastSlashIndex != -1) + { return s.substring(lastSlashIndex + 1); } return s; } - + /** * Returns whether the resource that is described with the given URI * exists. If an IO exception occurs during this check, this method - * will simply return false. - * + * will simply return false. + * * @param uri The URI * @return Whether the resource exists */ - public static boolean existsUnchecked(URI uri) { - try { + public static boolean existsUnchecked(URI uri) + { + try + { return exists(uri); - } catch (IOException e) { + } + catch (IOException e) + { return false; } } - + /** * Returns whether the resource that is described with the given URI * exists - * + * * @param uri The URI * @return Whether the resource exists * @throws IOException If an IO error occurs. This usually implies that - * the return value would be false... + * the return value would be false... */ - private static boolean exists(URI uri) throws IOException { + private static boolean exists(URI uri) throws IOException + { URL url = uri.toURL(); URLConnection connection = url.openConnection(); - if (connection instanceof HttpURLConnection) { - HttpURLConnection httpConnection = (HttpURLConnection) connection; + if (connection instanceof HttpURLConnection) + { + HttpURLConnection httpConnection = (HttpURLConnection)connection; httpConnection.setRequestMethod("HEAD"); int responseCode = httpConnection.getResponseCode(); return responseCode == HttpURLConnection.HTTP_OK; @@ -204,39 +234,49 @@ private static boolean exists(URI uri) throws IOException { String path = uri.getPath(); return new File(path).exists(); } - + + /** * Try to obtain the content length from the given URI. Returns -1 * if the content length can not be determined. - * + * * @param uri The URI * @return The content length */ - public static long getContentLength(URI uri) { - try { + public static long getContentLength(URI uri) + { + try + { URLConnection connection = uri.toURL().openConnection(); return connection.getContentLengthLong(); - } catch (IOException e) { + } + catch (IOException e) + { return -1; } } - + /** * Creates an input stream from the given URI, which may either be * an actual (absolute) URI, or a data URI with base64 encoded data - * + * * @param uri The URI * @return The input stream * @throws IOException If the stream can not be opened */ - public static InputStream createInputStream(URI uri) throws IOException { - if ("data".equalsIgnoreCase(uri.getScheme())) { + public static InputStream createInputStream(URI uri) throws IOException + { + if ("data".equalsIgnoreCase(uri.getScheme())) + { byte data[] = readDataUri(uri.toString()); return new ByteArrayInputStream(data); } - try { + try + { return uri.toURL().openStream(); - } catch (MalformedURLException e) { + } + catch (MalformedURLException e) + { throw new IOException(e); } } @@ -249,14 +289,19 @@ public static InputStream createInputStream(URI uri) throws IOException { * @return The input stream * @throws IOException If the stream can not be opened */ - public static InputStream createInputStream(Path path) throws IOException { - if ("data".equalsIgnoreCase(path.toUri().getScheme())) { + public static InputStream createInputStream(Path path) throws IOException + { + if ("data".equalsIgnoreCase(path.toUri().getScheme())) + { byte data[] = readDataUri(path.toUri().toString()); return new ByteArrayInputStream(data); } - try { + try + { return path.toUri().toURL().openStream(); - } catch (MalformedURLException e) { + } + catch (MalformedURLException e) + { throw new IOException(e); } } @@ -264,127 +309,152 @@ public static InputStream createInputStream(Path path) throws IOException { /** * Read the data from the given URI as a byte array. The data may either * be an actual URI, or a data URI with base64 encoded data. - * + * * @param uri The URI * @return The byte array * @throws IOException If an IO error occurs */ - public static byte[] read(URI uri) - throws IOException { - try (InputStream inputStream = createInputStream(uri)) { + public static byte[] read(URI uri) + throws IOException + { + try (InputStream inputStream = createInputStream(uri)) + { byte data[] = readStream(inputStream); return data; } } + /** * Read the base 64 encoded data from the given data URI string. * The data is assumed to start after the base64, part - * of the URI string, which must have the form + * of the URI string, which must have the form * data:...;base64,... - * + * * @param uriString The URI string * @return The data * @throws IllegalArgumentException If the given string is not a valid - * Base64 encoded data URI string + * Base64 encoded data URI string */ - public static byte[] readDataUri(String uriString) { + public static byte[] readDataUri(String uriString) + { String encoding = "base64,"; int encodingIndex = uriString.indexOf(encoding); - if (encodingIndex < 0) { + if (encodingIndex < 0) + { throw new IllegalArgumentException( - "The given URI string is not a base64 encoded " - + "data URI string: " + uriString); + "The given URI string is not a base64 encoded " + + "data URI string: " + uriString); } int contentStartIndex = encodingIndex + encoding.length(); byte data[] = Base64.getDecoder().decode( - uriString.substring(contentStartIndex)); + uriString.substring(contentStartIndex)); return data; } - + /** * Reads the data from the given inputStream and returns it as * a byte array. The caller is responsible for closing the stream. - * + * * @param inputStream The input stream to read * @return The data from the inputStream * @throws IOException If an IO error occurs, or if the thread that - * executes this method is interrupted. + * executes this method is interrupted. */ - public static byte[] readStream(InputStream inputStream) throws IOException { + public static byte[] readStream(InputStream inputStream) throws IOException + { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte buffer[] = new byte[16384]; - while (true) { + while (true) + { int read = inputStream.read(buffer); - if (read == -1) { + if (read == -1) + { break; } baos.write(buffer, 0, read); - if (Thread.currentThread().isInterrupted()) { + if (Thread.currentThread().isInterrupted()) + { throw new IOException("Interrupted while reading stream", - new InterruptedException()); + new InterruptedException()); } } baos.flush(); return baos.toByteArray(); } - + /** - * Read the specified number of bytes from the given input stream, + * Read the specified number of bytes from the given input stream, * writing them into the given array at the given offset - * - * @param inputStream The input stream - * @param data The array to write the data to - * @param offset The offset inside the target array - * @param numBytesToRead The number of bytes to read - * @throws IOException If an IO error occurs, or the end of the input - * stream was encountered before the requested number of bytes have - * been read + * + * @param inputStream The input stream + * @param data The array to write the data to + * @param offset The offset inside the target array + * @param numBytesToRead The number of bytes to read + * @throws IOException If an IO error occurs, or the end of the input + * stream was encountered before the requested number of bytes have + * been read * @throws IllegalArgumentException If the given offset is negative, or - * the sum of the given offset and the number of bytes to read is larger - * than the length of the given array + * the sum of the given offset and the number of bytes to read is larger + * than the length of the given array */ - static void read(InputStream inputStream, byte data[], int offset, - int numBytesToRead) throws IOException { - if (offset < 0) { + static void read(InputStream inputStream, byte data[], int offset, + int numBytesToRead) throws IOException + { + if (offset < 0) + { throw new IllegalArgumentException( - "Array offset is negative: " + offset); + "Array offset is negative: " + offset); } - if (offset + numBytesToRead > data.length) { + if (offset + numBytesToRead > data.length) + { throw new IllegalArgumentException( - "Cannot write " + numBytesToRead - + " bytes into an array of length " + data.length - + " with an offset of " + offset); + "Cannot write " + numBytesToRead + + " bytes into an array of length " + data.length + + " with an offset of " + offset); } int totalNumBytesRead = 0; - while (true) { + while (true) + { int read = inputStream.read( - data, offset + totalNumBytesRead, - numBytesToRead - totalNumBytesRead); - if (read == -1) { + data, offset + totalNumBytesRead, + numBytesToRead - totalNumBytesRead); + if (read == -1) + { throw new IOException( - "Could not read " + numBytesToRead + " bytes"); + "Could not read " + numBytesToRead + " bytes"); } totalNumBytesRead += read; - if (totalNumBytesRead == numBytesToRead) { + if (totalNumBytesRead == numBytesToRead) + { break; } } } - + /** * Read from the given input stream, writing into the given array, * until the array is filled. - * + * * @param inputStream The input stream - * @param data The array to write the data to + * @param data The array to write the data to * @throws IOException If an IO error occurs, or the end of the input - * stream was encountered before the requested number of bytes have - * been read + * stream was encountered before the requested number of bytes have + * been read */ - public static void read(InputStream inputStream, byte data[]) - throws IOException { + public static void read(InputStream inputStream, byte data[]) + throws IOException + { read(inputStream, data, 0, data.length); } - + + + /** + * Private constructor to prevent instantiation + */ + private IO() + { + // Private constructor to prevent instantiation + } + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/io/MimeTypes.java b/src/main/java/de/javagl/jgltf/model/io/MimeTypes.java index 95eae3b..80858cc 100644 --- a/src/main/java/de/javagl/jgltf/model/io/MimeTypes.java +++ b/src/main/java/de/javagl/jgltf/model/io/MimeTypes.java @@ -26,165 +26,183 @@ */ package de.javagl.jgltf.model.io; -import de.javagl.jgltf.model.image.ImageReaders; - -import javax.imageio.ImageReader; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.util.logging.Logger; +import javax.imageio.ImageReader; + +import de.javagl.jgltf.model.image.ImageReaders; + /** * Utility methods to related to the MIME type from data URLs or image data */ -public class MimeTypes { +public class MimeTypes +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(MimeTypes.class.getName()); - - /** - * Private constructor to prevent instantiation - */ - private MimeTypes() { - // Private constructor to prevent instantiation - } - + private static final Logger logger = + Logger.getLogger(MimeTypes.class.getName()); + /** - * Tries to detect the format of the image data from the given URI, and + * Tries to detect the format of the image data from the given URI, and * return the corresponding MIME type string.
    *
    - * This may, for example, be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
    + * This may, for example, be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
    *
    - * + * * @param uriString The image data * @return The image format string, or null if it can not * be detected. */ - private static String guessImageMimeTypeString(String uriString) { - try { + private static String guessImageMimeTypeString(String uriString) + { + try + { URI uri = new URI(uriString); - if ("data".equalsIgnoreCase(uri.getScheme())) { + if ("data".equalsIgnoreCase(uri.getScheme())) + { String raw = uri.getRawSchemeSpecificPart().toLowerCase(); String type = getStringBetween(raw, "image/", ";base64"); return "image/" + type.toLowerCase(); } - } catch (URISyntaxException e) { + } + catch (URISyntaxException e) + { return null; } int lastDotIndex = uriString.lastIndexOf('.'); - if (lastDotIndex == -1) { + if (lastDotIndex == -1) + { return null; } String end = uriString.substring(lastDotIndex + 1).toLowerCase(); - if (end.equalsIgnoreCase("jpg") || end.equalsIgnoreCase("jpeg")) { + if (end.equalsIgnoreCase("jpg") || end.equalsIgnoreCase("jpeg")) + { return "image/jpeg"; } return "image/" + end.toLowerCase(); } - + /** * Returns the part of the input string between the given "before" and * "after" part, or null if either of the given parts are - * not contained in the input string, or the "after" part appears + * not contained in the input string, or the "after" part appears * before the "before" part. - * - * @param input The input string + * + * @param input The input string * @param before The "before" part - * @param after The "after" part + * @param after The "after" part * @return The string between "before" and "after" */ private static String getStringBetween( - String input, String before, String after) { + String input, String before, String after) + { int beforeIndex = input.indexOf(before); - if (beforeIndex < 0) { + if (beforeIndex < 0) + { return null; } int afterIndex = input.indexOf(after); - if (afterIndex < beforeIndex) { + if (afterIndex < beforeIndex) + { return null; } return input.substring(beforeIndex + before.length(), afterIndex); } - + + /** * Tries to detect the format of the given image data, and return the * corresponding MIME type string.
    *
    - * This may, for example, be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
    + * This may, for example, be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
    *
    - * + * * @param imageData The image data * @return The image format string * @throws IOException If the image format can not be detected */ - private static String guessImageMimeTypeString(ByteBuffer imageData) - throws IOException { + private static String guessImageMimeTypeString(ByteBuffer imageData) + throws IOException + { ImageReader imageReader = null; - try { + try + { imageReader = ImageReaders.findImageReader(imageData); return "image/" + imageReader.getFormatName().toLowerCase(); - } finally { - if (imageReader != null) { + } + finally + { + if (imageReader != null) + { imageReader.dispose(); } } } - + /** * Tries to detect the format of the given image data, and return the * corresponding MIME type string.
    *
    - * This may, for example, be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
    - *
    - * + * This may, for example, be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
    + *
    * @param imageData The image data * @return The image format string */ - public static String guessImageMimeTypeStringUnchecked(ByteBuffer imageData) { - try { + public static String guessImageMimeTypeStringUnchecked(ByteBuffer imageData) + { + try + { return guessImageMimeTypeString(imageData); - } catch (IOException e) { + } + catch (IOException e) + { return null; } } - + /** - * Tries to detect the format of the given image URI and its data and - * return the corresponding MIME type string.
    + * Tries to detect the format of the given image URI and its data and + * return the corresponding MIME type string.
    *
    - * This may, for example, be "image/png" or - * "image/gif" or "image/jpeg" (not - * "image/jpg"!).
    + * This may, for example, be "image/png" or + * "image/gif" or "image/jpeg" (not + * "image/jpg"!).
    *
    - * This method will do an (unspecified) best-effort approach to detect + * This method will do an (unspecified) best-effort approach to detect * the mime type, either from the image or from the image data (which - * are both optional). If the type can not be determined, then - * null will be returned. - * + * are both optional). If the type can not be determined, then + * null will be returned. + * * @param uriString The URI string * @param imageData The image data * @return The image format string, or null if it can not * be detected. */ public static String guessImageMimeTypeString( - String uriString, ByteBuffer imageData) { - if (uriString != null) { - String imageMimeTypeString = - MimeTypes.guessImageMimeTypeString(uriString); - if (imageMimeTypeString != null) { + String uriString, ByteBuffer imageData) + { + if (uriString != null) + { + String imageMimeTypeString = + MimeTypes.guessImageMimeTypeString(uriString); + if (imageMimeTypeString != null) + { return imageMimeTypeString; } } - if (imageData != null) { + if (imageData != null) + { return guessImageMimeTypeStringUnchecked(imageData); } return null; @@ -201,22 +219,35 @@ public static String guessImageMimeTypeString( *

* For other inputs, a warning will be printed, and null will * be returned. - * + * * @param mimeTypeString The MIME type string * @return The file extension */ public static String imageFileNameExtensionForMimeTypeString( - String mimeTypeString) { - if ("image/jpeg".equals(mimeTypeString)) { + String mimeTypeString) + { + if ("image/jpeg".equals(mimeTypeString)) + { return "jpg"; } - if ("image/png".equals(mimeTypeString)) { + if ("image/png".equals(mimeTypeString)) + { return "png"; } - if ("image/gif".equals(mimeTypeString)) { + if ("image/gif".equals(mimeTypeString)) + { return "gif"; } logger.warning("Invalid MIME type string: " + mimeTypeString); return null; } + + + /** + * Private constructor to prevent instantiation + */ + private MimeTypes() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/io/ProgressInputStream.java b/src/main/java/de/javagl/jgltf/model/io/ProgressInputStream.java index 9554961..fd9d996 100644 --- a/src/main/java/de/javagl/jgltf/model/io/ProgressInputStream.java +++ b/src/main/java/de/javagl/jgltf/model/io/ProgressInputStream.java @@ -39,20 +39,21 @@ * An input stream that informs property change listeners and consumers * about the number of bytes that are read. */ -public final class ProgressInputStream extends FilterInputStream { +public final class ProgressInputStream extends FilterInputStream +{ // Originally based on http://stackoverflow.com/a/1339589, heavily modified /** * The property change support */ private final PropertyChangeSupport propertyChangeSupport; - + /** - * The consumers that will be informed about the total number of + * The consumers that will be informed about the total number of * bytes that have been read */ private final List totalNumBytesReadConsumers; - + /** * The total number of bytes that have been read */ @@ -61,120 +62,137 @@ public final class ProgressInputStream extends FilterInputStream { /** * Creates a new progress input stream that reads from the given input * stream - * + * * @param inputStream The input stream */ - public ProgressInputStream(InputStream inputStream) { + public ProgressInputStream(InputStream inputStream) + { super(inputStream); this.propertyChangeSupport = new PropertyChangeSupport(this); - this.totalNumBytesReadConsumers = - new CopyOnWriteArrayList(); + this.totalNumBytesReadConsumers = + new CopyOnWriteArrayList(); } - + /** * Returns the total number of bytes that already have been read * from the stream - * + * * @return The number of bytes read */ - long getTotalNumBytesRead() { + long getTotalNumBytesRead() + { return totalNumBytesRead; } /** * Add the given listener to be informed when the number of bytes * that have been read from this stream changes - * + * * @param listener The listener to add */ - void addPropertyChangeListener(PropertyChangeListener listener) { + void addPropertyChangeListener(PropertyChangeListener listener) + { propertyChangeSupport.addPropertyChangeListener(listener); } /** * Remove the given listener from this stream - * + * * @param listener The listener to remove */ - void removePropertyChangeListener(PropertyChangeListener listener) { + void removePropertyChangeListener(PropertyChangeListener listener) + { propertyChangeSupport.removePropertyChangeListener(listener); } - + /** - * Add the given consumer to be informed about the total number of + * Add the given consumer to be informed about the total number of * bytes that have been read - * + * * @param consumer The consumer */ - public void addTotalNumBytesReadConsumer(LongConsumer consumer) { + public void addTotalNumBytesReadConsumer(LongConsumer consumer) + { totalNumBytesReadConsumers.add(consumer); } /** * Remove the given consumer - * + * * @param consumer The consumer */ - public void removeTotalNumBytesReadConsumer(LongConsumer consumer) { + public void removeTotalNumBytesReadConsumer(LongConsumer consumer) + { totalNumBytesReadConsumers.remove(consumer); } @Override - public int read() throws IOException { + public int read() throws IOException + { int b = super.read(); - if (b != -1) { + if (b != -1) + { updateProgress(1); } return b; } @Override - public int read(byte[] b) throws IOException { + public int read(byte[] b) throws IOException + { return read(b, 0, b.length); } @Override - public int read(byte[] b, int off, int len) throws IOException { + public int read(byte[] b, int off, int len) throws IOException + { int read = super.read(b, off, len); - if (read == -1) { + if (read == -1) + { return -1; } return (int) updateProgress(read); } @Override - public long skip(long n) throws IOException { + public long skip(long n) throws IOException + { return updateProgress(super.skip(n)); } @Override - public void mark(int readlimit) { + public void mark(int readlimit) + { throw new UnsupportedOperationException(); } @Override - public void reset() throws IOException { + public void reset() throws IOException + { throw new UnsupportedOperationException(); } @Override - public boolean markSupported() { + public boolean markSupported() + { return false; } /** * Update the progress of this stream, based on the given number of * bytes that have been read, and inform all registered listeners - * - * @param numBytesRead The number of bytes that have been read + * + * @param numBytesRead The number of bytes that have been read * @return The number of bytes read */ - private long updateProgress(long numBytesRead) { - if (numBytesRead > 0) { + private long updateProgress(long numBytesRead) + { + if (numBytesRead > 0) + { long oldTotalNumBytesRead = this.totalNumBytesRead; this.totalNumBytesRead += numBytesRead; propertyChangeSupport.firePropertyChange("totalNumBytesRead", - oldTotalNumBytesRead, this.totalNumBytesRead); + oldTotalNumBytesRead, this.totalNumBytesRead); fireTotalNumBytesRead(); } return numBytesRead; @@ -184,8 +202,10 @@ private long updateProgress(long numBytesRead) { * Forward the information about the total number of bytes that have * been read to the consumers */ - private void fireTotalNumBytesRead() { - for (LongConsumer consumer : totalNumBytesReadConsumers) { + private void fireTotalNumBytesRead() + { + for (LongConsumer consumer : totalNumBytesReadConsumers) + { consumer.accept(totalNumBytesRead); } } diff --git a/src/main/java/de/javagl/jgltf/model/io/RawGltfData.java b/src/main/java/de/javagl/jgltf/model/io/RawGltfData.java index bbb09c1..b9a6a94 100644 --- a/src/main/java/de/javagl/jgltf/model/io/RawGltfData.java +++ b/src/main/java/de/javagl/jgltf/model/io/RawGltfData.java @@ -32,75 +32,80 @@ /** * The raw data of a glTF asset, consisting of the raw JSON data and the binary - * data. This data is still independent of the actual glTF version, and covers + * data. This data is still independent of the actual glTF version, and covers * both standard (JSON) and binary glTF.
*
* Instances of this class are returned by the {@link RawGltfDataReader}. - * Clients will usually not use this class directly. + * Clients will usually not use this class directly. */ -public final class RawGltfData { +public final class RawGltfData +{ /** * The JSON data */ private final ByteBuffer jsonData; - + /** * The optional binary data */ private final ByteBuffer binaryData; - + /** * Default constructor. References to the buffers will be stored. * So they should have their position and limit set accordingly, * and may not be modified after being passed to this constructor. - * - * @param jsonData The JSON data + * + * @param jsonData The JSON data * @param binaryData The optional binary data */ - public RawGltfData(ByteBuffer jsonData, ByteBuffer binaryData) { + public RawGltfData(ByteBuffer jsonData, ByteBuffer binaryData) + { this.jsonData = Objects.requireNonNull( - jsonData, "The jsonData may not be null"); + jsonData, "The jsonData may not be null"); this.binaryData = binaryData; } - + /** * Returns the JSON string from this data - * + * * @return The JSON string */ - public String getJsonString() { + public String getJsonString() + { byte jsonDataArray[] = new byte[jsonData.capacity()]; jsonData.slice().get(jsonDataArray); String jsonString = new String(jsonDataArray, Charset.forName("UTF-8")); return jsonString; } - + /** * Returns the JSON data.
*
- * The returned buffer will be a slice of the data that is stored + * The returned buffer will be a slice of the data that is stored * internally. This means that changes of the data will affect this * instance, but changes of the position or limit of the returned - * buffer will not affect this instance. - * + * buffer will not affect this instance. + * * @return The JSON data */ - public ByteBuffer getJsonData() { + public ByteBuffer getJsonData() + { return Buffers.createSlice(jsonData); } - + /** * Returns the binary data. This may be null if the asset * was created from a JSON string only.
*
- * The returned buffer will be a slice of the data that is stored + * The returned buffer will be a slice of the data that is stored * internally. This means that changes of the data will affect this * instance, but changes of the position or limit of the returned * buffer will not affect this instance. - * + * * @return The binary data */ - public ByteBuffer getBinaryData() { + public ByteBuffer getBinaryData() + { return Buffers.createSlice(binaryData); } } diff --git a/src/main/java/de/javagl/jgltf/model/io/RawGltfDataReader.java b/src/main/java/de/javagl/jgltf/model/io/RawGltfDataReader.java index b032706..46bd327 100644 --- a/src/main/java/de/javagl/jgltf/model/io/RawGltfDataReader.java +++ b/src/main/java/de/javagl/jgltf/model/io/RawGltfDataReader.java @@ -26,15 +26,15 @@ */ package de.javagl.jgltf.model.io; -import de.javagl.jgltf.model.io.v1.RawBinaryGltfDataReaderV1; -import de.javagl.jgltf.model.io.v2.RawBinaryGltfDataReaderV2; - import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; +import de.javagl.jgltf.model.io.v1.RawBinaryGltfDataReaderV1; +import de.javagl.jgltf.model.io.v2.RawBinaryGltfDataReaderV2; + /** * A class for reading the raw data of a glTF asset from an input stream. * The given stream may provide any form of glTF data: @@ -50,61 +50,68 @@ *
* Clients will usually not use this class directly. */ -public class RawGltfDataReader { +public class RawGltfDataReader +{ /** * The magic binary glTF header. * This is an integer corresponding to the ASCII string "glTF" */ private static final int MAGIC_BINARY_GLTF_HEADER = 0x46546C67; - + /** * The version number indicating glTF 1.0 */ private static final int BINARY_GLTF_VERSION_1 = 1; - + /** * The version number indicating glTF 2.0 */ private static final int BINARY_GLTF_VERSION_2 = 2; - /** - * Private constructor to prevent instantiation - */ - private RawGltfDataReader() { - // Private constructor to prevent instantiation - } - /** * Read the raw glTF data from the given input stream. The caller is * responsible for closing the given stream. - * + * * @param inputStream The input stream * @return The {@link RawGltfData} * @throws IOException If an IO error occurs */ - public static RawGltfData read(InputStream inputStream) throws IOException { + public static RawGltfData read(InputStream inputStream) throws IOException + { byte rawData[] = IO.readStream(inputStream); - if (rawData.length >= 8) { - ByteBuffer data = - ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN); + if (rawData.length >= 8) + { + ByteBuffer data = + ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN); IntBuffer intData = data.asIntBuffer(); int magic = intData.get(0); - if (magic == MAGIC_BINARY_GLTF_HEADER) { + if (magic == MAGIC_BINARY_GLTF_HEADER) + { int version = intData.get(1); - if (version == BINARY_GLTF_VERSION_1) { + if (version == BINARY_GLTF_VERSION_1) + { return RawBinaryGltfDataReaderV1.readBinaryGltf(data); } - if (version == BINARY_GLTF_VERSION_2) { + if (version == BINARY_GLTF_VERSION_2) + { return RawBinaryGltfDataReaderV2.readBinaryGltf(data); } throw new IOException( - "Unknown binary glTF version: " + version); + "Unknown binary glTF version: " + version); } } ByteBuffer jsonData = Buffers.create(rawData); return new RawGltfData(jsonData, null); } - + + /** + * Private constructor to prevent instantiation + */ + private RawGltfDataReader() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/io/UriResolvers.java b/src/main/java/de/javagl/jgltf/model/io/UriResolvers.java index 0e55e0f..c7936d8 100644 --- a/src/main/java/de/javagl/jgltf/model/io/UriResolvers.java +++ b/src/main/java/de/javagl/jgltf/model/io/UriResolvers.java @@ -38,50 +38,50 @@ /** * Methods for creating functions that resolve URI to byte buffers */ -public class UriResolvers { +public class UriResolvers +{ /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(UriResolvers.class.getName()); + Logger.getLogger(UriResolvers.class.getName()); /** - * Private constructor to prevent instantiation - */ - private UriResolvers() { - // Private constructor to prevent instantiation - } - - /** - * Creates a function that resolves URI strings against the given - * base URI, and returns a byte buffer containing the data from + * Creates a function that resolves URI strings against the given + * base URI, and returns a byte buffer containing the data from * the resulting URI.
*
* The given URI strings may either be standard URI or data URI.
*
* If the returned function cannot read the data, then it will print a * warning and return null. - * + * * @param baseUri The base URI to resolve against * @return The function */ public static Function createBaseUriResolver( - URI baseUri) { + URI baseUri) + { Objects.requireNonNull(baseUri, "The baseUri may not be null"); - Function inputStreamFunction = - new Function() { - @Override - public InputStream apply(String uriString) { - try { - URI absoluteUri = IO.makeAbsolute(baseUri, uriString); - return IO.createInputStream(absoluteUri); - } catch (IOException e) { - logger.warning("Could not open input stream for URI " - + uriString + ": " + e.getMessage()); - return null; - } - } - }; + Function inputStreamFunction = + new Function() + { + @Override + public InputStream apply(String uriString) + { + try + { + URI absoluteUri = IO.makeAbsolute(baseUri, uriString); + return IO.createInputStream(absoluteUri); + } + catch (IOException e) + { + logger.warning("Could not open input stream for URI " + + uriString + ": " + e.getMessage()); + return null; + } + } + }; return reading(inputStreamFunction); } @@ -100,55 +100,66 @@ public InputStream apply(String uriString) { * @return The function */ public static Function createBasePathResolver( - Path basePath) { + Path basePath) + { Objects.requireNonNull(basePath, "The basePath may not be null"); Function inputStreamFunction = - new Function() { - @Override - public InputStream apply(String uriString) { - try { - if (IO.isDataUriString(uriString)) { - return IO.createInputStream(URI.create(uriString)); - } - Path absolutePath = IO.makeAbsolute(basePath, uriString); - return IO.createInputStream(absolutePath); - } catch (IOException e) { - logger.warning("Could not open input stream for URI " - + uriString + ": " + e.getMessage()); - return null; - } + new Function() + { + @Override + public InputStream apply(String uriString) + { + try + { + if (IO.isDataUriString(uriString)) + { + return IO.createInputStream(URI.create(uriString)); } - }; + Path absolutePath = IO.makeAbsolute(basePath, uriString); + return IO.createInputStream(absolutePath); + } + catch (IOException e) + { + logger.warning("Could not open input stream for URI " + + uriString + ": " + e.getMessage()); + return null; + } + } + }; return reading(inputStreamFunction); } /** * Create a function that maps a string to the input stream of a resource * of the given class. - * + * * @param c The class * @return The resolving function */ public static Function createResourceUriResolver( - Class c) { + Class c) + { Objects.requireNonNull(c, "The class may not be null"); Function inputStreamFunction = - new Function() { - @Override - public InputStream apply(String uriString) { - InputStream inputStream = - c.getResourceAsStream("/" + uriString); - if (inputStream == null) { - logger.warning( - "Could not obtain input stream for resource " - + "with URI " + uriString); - } - return inputStream; - } - }; + new Function() + { + @Override + public InputStream apply(String uriString) + { + InputStream inputStream = + c.getResourceAsStream("/" + uriString); + if (inputStream == null) + { + logger.warning( + "Could not obtain input stream for resource " + + "with URI " + uriString); + } + return inputStream; + } + }; return reading(inputStreamFunction); } - + /** * Returns a function that reads the data from the input stream that is * provided by the given delegate, and returns this data as a direct @@ -157,30 +168,45 @@ public InputStream apply(String uriString) { * If the delegate returns null, or an input stream that * cannot be read, then the function will print a warning and return * null. - * + * * @param inputStreamFunction The input stream function * @return The function for reading the input stream data */ private static Function reading( - Function inputStreamFunction) { - return new Function() { + Function inputStreamFunction) + { + return new Function() + { @Override - public ByteBuffer apply(T t) { - try (InputStream inputStream = inputStreamFunction.apply(t)) { - if (inputStream == null) { + public ByteBuffer apply(T t) + { + try (InputStream inputStream = inputStreamFunction.apply(t)) + { + if (inputStream == null) + { logger.warning("The input stream was null"); return null; } byte data[] = IO.readStream(inputStream); return Buffers.create(data); - } catch (IOException e) { + } + catch (IOException e) + { logger.warning("Could not read from input stream: " - + e.getMessage()); + + e.getMessage()); return null; } } - + }; } + /** + * Private constructor to prevent instantiation + */ + private UriResolvers() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/io/VersionUtils.java b/src/main/java/de/javagl/jgltf/model/io/VersionUtils.java index ab6ee96..ded34a4 100644 --- a/src/main/java/de/javagl/jgltf/model/io/VersionUtils.java +++ b/src/main/java/de/javagl/jgltf/model/io/VersionUtils.java @@ -29,28 +29,32 @@ /** * Utility methods related to version strings */ -public class VersionUtils { +public class VersionUtils +{ /** * Compare the given semantic version numbers. - * + * * @param v0 The first version number * @param v1 The second version number * @return A value that is smaller than, equal to or greater than 0, * indicating whether the first version is smaller than, equal to * or greater than the second version. */ - public static int compareVersions(String v0, String v1) { + public static int compareVersions(String v0, String v1) + { int[] sv0 = computeMajorMinorPatch(v0); int[] sv1 = computeMajorMinorPatch(v1); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) + { int c = Integer.compare(sv0[i], sv1[i]); - if (c != 0) { + if (c != 0) + { return c; } } return 0; } - + /** * Compute the semantic version numbers from the given string. The * string is assumed to be a semantic version number, consisting @@ -58,48 +62,58 @@ public static int compareVersions(String v0, String v1) { * is allowed to have a non-numeric suffix, which will be ignored * here. Any element of this pattern that is not present or cannot * be parsed will be assumed to be 0. - * + * * @param v The version string * @return An array containing 3 values: The major, minor and patch version */ - static int[] computeMajorMinorPatch(String v) { + static int[] computeMajorMinorPatch(String v) + { int result[] = new int[3]; String tokens[] = v.split("\\."); int n = Math.min(tokens.length, 3); - for (int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) + { String token = tokens[i]; result[i] = parseIntPrefix(token); } return result; } - + /** * Try to parse an integer value from the start of the given string. * For example, for the string "23a-beta", this will * return 23. If no valid number can be parsed, then * 0 is returned. - * + * * @param s The input string - * @return The integer + * @return The integer */ - private static int parseIntPrefix(String s) { + private static int parseIntPrefix(String s) + { String number = ""; - for (int j = 0; j < s.length(); j++) { + for (int j = 0; j < s.length(); j++) + { char c = s.charAt(j); - if (Character.isDigit(c)) { + if (Character.isDigit(c)) + { number += c; - } else { + } + else + { break; } } - try { + try + { return Integer.parseInt(number); - } catch (NumberFormatException e) { + } + catch (NumberFormatException e) + { return 0; } } - - + + // public static void main(String[] args) // { // String s = "1.2.0"; diff --git a/src/main/java/de/javagl/jgltf/model/io/package-info.java b/src/main/java/de/javagl/jgltf/model/io/package-info.java index 1602246..78a1a26 100644 --- a/src/main/java/de/javagl/jgltf/model/io/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/io/package-info.java @@ -1,5 +1,5 @@ /** - * Classes for reading and writing glTF data + * Classes for reading and writing glTF data */ package de.javagl.jgltf.model.io; diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/BinaryAssetCreatorV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/BinaryAssetCreatorV1.java index e869bd9..4a67239 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/BinaryAssetCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/BinaryAssetCreatorV1.java @@ -26,14 +26,6 @@ */ package de.javagl.jgltf.model.io.v1; -import de.javagl.jgltf.impl.v1.*; -import de.javagl.jgltf.model.BufferModel; -import de.javagl.jgltf.model.GltfModel; -import de.javagl.jgltf.model.ImageModel; -import de.javagl.jgltf.model.gl.ShaderModel; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.v1.*; - import java.nio.ByteBuffer; import java.util.Collections; import java.util.LinkedHashMap; @@ -41,115 +33,67 @@ import java.util.Map.Entry; import java.util.function.Function; +import de.javagl.jgltf.impl.v1.Buffer; +import de.javagl.jgltf.impl.v1.BufferView; +import de.javagl.jgltf.impl.v1.GlTF; +import de.javagl.jgltf.impl.v1.Image; +import de.javagl.jgltf.impl.v1.Shader; +import de.javagl.jgltf.model.BufferModel; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.ImageModel; +import de.javagl.jgltf.model.gl.ShaderModel; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.v1.BinaryGltfV1; +import de.javagl.jgltf.model.v1.GltfCreatorV1; +import de.javagl.jgltf.model.v1.GltfExtensionsV1; +import de.javagl.jgltf.model.v1.GltfIds; +import de.javagl.jgltf.model.v1.GltfModelV1; + /** - * A class for creating a binary {@link GltfAssetV1} from a + * A class for creating a binary {@link GltfAssetV1} from a * {@link GltfModelV1}.
*
*/ -final class BinaryAssetCreatorV1 { +final class BinaryAssetCreatorV1 +{ /** * Creates a new asset creator */ - BinaryAssetCreatorV1() { + BinaryAssetCreatorV1() + { // Default constructor } - - /** - * Compute the total size that is required for the binary glTF buffer - * for the given {@link GltfModel}, which is the sum of all buffer - * sizes of all buffers, images and shaders. - * - * @param gltfModel The {@link GltfModel} - * @return The total size for the binary glTF buffer - */ - private static int computeBinaryGltfBufferSize(GltfModelV1 gltfModel) { - int binaryGltfBufferSize = 0; - for (BufferModel bufferModel : gltfModel.getBufferModels()) { - ByteBuffer bufferData = bufferModel.getBufferData(); - binaryGltfBufferSize += bufferData.capacity(); - } - for (ImageModel imageModel : gltfModel.getImageModels()) { - ByteBuffer imageData = imageModel.getImageData(); - binaryGltfBufferSize += imageData.capacity(); - } - for (ShaderModel shaderModel : gltfModel.getShaderModels()) { - ByteBuffer shaderData = shaderModel.getShaderData(); - binaryGltfBufferSize += shaderData.capacity(); - } - return binaryGltfBufferSize; - } - - /** - * Put the contents of all byte buffers that are associated with the - * given keys into the given target buffer. This method assumes - * that the target buffer has a sufficient capacity to hold all - * buffers. - * - * @param The key type - * @param keys The mapping keys - * @param keyToByteBuffer The function that provides the byte buffer - * based on the key of the element - * @param targetBuffer The target buffer - * @return A mapping from each key to the offset inside the target buffer - */ - private static Map concatBuffers( - Iterable keys, - Function keyToByteBuffer, - ByteBuffer targetBuffer) { - Map offsets = new LinkedHashMap(); - for (K key : keys) { - ByteBuffer oldByteBuffer = keyToByteBuffer.apply(key); - int offset = targetBuffer.position(); - offsets.put(key, offset); - targetBuffer.put(oldByteBuffer.slice()); - } - return offsets; - } - - /** - * Creates a copy of the given map, as a linked hash map. If the given - * map is null, then an unmodifiable empty map will be - * returned - * - * @param map The input map - * @return The copy - */ - private static Map copy(Map map) { - if (map == null) { - return Collections.emptyMap(); - } - return new LinkedHashMap(map); - } - + /** * Create a binary {@link GltfAssetV1} from the given {@link GltfModelV1}. * The resulting asset will have a {@link GlTF} that uses the binary * glTF extension objects in its {@link Buffer}, {@link Image} and - * {@link Shader} elements, to refer to the - * {@link GltfAssetV1#getBinaryData() binary data} of the asset. - * + * {@link Shader} elements, to refer to the + * {@link GltfAssetV1#getBinaryData() binary data} of the asset. + * * @param gltfModel The {@link GltfModelV1} * @return The {@link GltfAssetV1} */ - GltfAssetV1 create(GltfModelV1 gltfModel) { + GltfAssetV1 create(GltfModelV1 gltfModel) + { GlTF outputGltf = GltfCreatorV1.create(gltfModel); - + // Create the new byte buffer for the data of the "binary_glTF" Buffer - int binaryGltfBufferSize = - computeBinaryGltfBufferSize(gltfModel); - ByteBuffer binaryGltfByteBuffer = - Buffers.create(binaryGltfBufferSize); + int binaryGltfBufferSize = + computeBinaryGltfBufferSize(gltfModel); + ByteBuffer binaryGltfByteBuffer = + Buffers.create(binaryGltfBufferSize); - // Create the "binary_glTF" Buffer, - GltfExtensionsV1.addExtensionUsed(outputGltf, - BinaryGltfV1.getBinaryGltfExtensionName()); + // Create the "binary_glTF" Buffer, + GltfExtensionsV1.addExtensionUsed(outputGltf, + BinaryGltfV1.getBinaryGltfExtensionName()); Buffer binaryGltfBuffer = new Buffer(); binaryGltfBuffer.setType("arraybuffer"); binaryGltfBuffer.setUri( - BinaryGltfV1.getBinaryGltfBufferId() + ".bin"); + BinaryGltfV1.getBinaryGltfBufferId() + ".bin"); binaryGltfBuffer.setByteLength(binaryGltfBufferSize); Map newBuffers = Collections.singletonMap( - BinaryGltfV1.getBinaryGltfBufferId(), binaryGltfBuffer); + BinaryGltfV1.getBinaryGltfBufferId(), binaryGltfBuffer); // Create defensive copies of the original maps, as linked maps // with a fixed iteration order (!). If the input maps are null, @@ -159,43 +103,44 @@ GltfAssetV1 create(GltfModelV1 gltfModel) { Map oldImages = copy(outputGltf.getImages()); Map oldShaders = copy(outputGltf.getShaders()); - // TODO This is not solved very elegantly, due to the + // TODO This is not solved very elegantly, due to the // transition of glTF 1.0 to glTF 2.0 - refactor this! - + // Create mappings from the IDs to the corresponding model elements. // This assumes that they are in the same order. Map bufferIdToBuffer = GltfUtilsV1.createMap( - oldBuffers, gltfModel.getBufferModels()); + oldBuffers, gltfModel.getBufferModels()); Map imageIdToImage = GltfUtilsV1.createMap( - oldImages, gltfModel.getImageModels()); + oldImages, gltfModel.getImageModels()); Map shaderIdToShader = GltfUtilsV1.createMap( - oldShaders, gltfModel.getShaderModels()); - + oldShaders, gltfModel.getShaderModels()); + // Place the data from buffers, images and shaders into the - // new binary glTF buffer. The mappings from IDs to offsets + // new binary glTF buffer. The mappings from IDs to offsets // inside the resulting buffer will be used to compute the // offsets for the buffer views Map bufferOffsets = concatBuffers( - oldBuffers.keySet(), - id -> bufferIdToBuffer.get(id).getBufferData(), - binaryGltfByteBuffer); + oldBuffers.keySet(), + id -> bufferIdToBuffer.get(id).getBufferData(), + binaryGltfByteBuffer); Map imageOffsets = concatBuffers( - oldImages.keySet(), - id -> imageIdToImage.get(id).getImageData(), - binaryGltfByteBuffer); + oldImages.keySet(), + id -> imageIdToImage.get(id).getImageData(), + binaryGltfByteBuffer); Map shaderOffsets = concatBuffers( - oldShaders.keySet(), - id -> shaderIdToShader.get(id).getShaderData(), - binaryGltfByteBuffer); + oldShaders.keySet(), + id -> shaderIdToShader.get(id).getShaderData(), + binaryGltfByteBuffer); binaryGltfByteBuffer.position(0); - // For all existing BufferViews, create new ones that are updated to + // For all existing BufferViews, create new ones that are updated to // refer to the new binary glTF buffer, with the appropriate offset - Map oldBufferViews = - copy(outputGltf.getBufferViews()); - Map newBufferViews = - new LinkedHashMap(); - for (Entry oldEntry : oldBufferViews.entrySet()) { + Map oldBufferViews = + copy(outputGltf.getBufferViews()); + Map newBufferViews = + new LinkedHashMap(); + for (Entry oldEntry : oldBufferViews.entrySet()) + { String id = oldEntry.getKey(); BufferView oldBufferView = oldEntry.getValue(); BufferView newBufferView = GltfUtilsV1.copy(oldBufferView); @@ -210,20 +155,21 @@ GltfAssetV1 create(GltfModelV1 gltfModel) { newBufferViews.put(id, newBufferView); } - // For all existing Images, create new ones that are updated to + // For all existing Images, create new ones that are updated to // refer to the new binary glTF buffer, using a bufferView ID // (in the binary_glTF extension object) that refers to a newly // created BufferView - Map newImages = - new LinkedHashMap(); - for (Entry oldEntry : oldImages.entrySet()) { + Map newImages = + new LinkedHashMap(); + for (Entry oldEntry : oldImages.entrySet()) + { String id = oldEntry.getKey(); Image oldImage = oldEntry.getValue(); Image newImage = GltfUtilsV1.copy(oldImage); // Create the BufferView for the image - ByteBuffer imageData = - imageIdToImage.get(id).getImageData(); + ByteBuffer imageData = + imageIdToImage.get(id).getImageData(); int byteLength = imageData.capacity(); int byteOffset = imageOffsets.get(id); BufferView imageBufferView = new BufferView(); @@ -232,14 +178,14 @@ GltfAssetV1 create(GltfModelV1 gltfModel) { imageBufferView.setByteLength(byteLength); // Store the BufferView under a newly generated ID - String generatedBufferViewId = - GltfIds.generateId("bufferView_for_image_" + id, - oldBufferViews.keySet()); + String generatedBufferViewId = + GltfIds.generateId("bufferView_for_image_" + id, + oldBufferViews.keySet()); newBufferViews.put(generatedBufferViewId, imageBufferView); // Let the image refer to the BufferView via its extension object BinaryGltfV1.setBinaryGltfBufferViewId( - newImage, generatedBufferViewId); + newImage, generatedBufferViewId); // Set the width, height and mimeType properties for the // extension object @@ -248,20 +194,21 @@ GltfAssetV1 create(GltfModelV1 gltfModel) { newImages.put(id, newImage); } - // For all existing Shaders, create new ones that are updated to + // For all existing Shaders, create new ones that are updated to // refer to the new binary glTF buffer using a bufferView ID // (in the binary_glTF extension object) that refers to a newly // created BufferView - Map newShaders = - new LinkedHashMap(); - for (Entry oldEntry : oldShaders.entrySet()) { + Map newShaders = + new LinkedHashMap(); + for (Entry oldEntry : oldShaders.entrySet()) + { String id = oldEntry.getKey(); Shader oldShader = oldEntry.getValue(); Shader newShader = GltfUtilsV1.copy(oldShader); // Create the BufferView for the shader - ByteBuffer shaderData = - shaderIdToShader.get(id).getShaderData(); + ByteBuffer shaderData = + shaderIdToShader.get(id).getShaderData(); int byteLength = shaderData.capacity(); int byteOffset = shaderOffsets.get(id); BufferView shaderBufferView = new BufferView(); @@ -271,33 +218,115 @@ GltfAssetV1 create(GltfModelV1 gltfModel) { // Store the BufferView under a newly generated ID String generatedBufferViewId = - GltfIds.generateId("bufferView_for_shader_" + id, - oldBufferViews.keySet()); + GltfIds.generateId("bufferView_for_shader_" + id, + oldBufferViews.keySet()); newBufferViews.put(generatedBufferViewId, shaderBufferView); // Let the shader refer to the BufferView via its extension object BinaryGltfV1.setBinaryGltfBufferViewId( - newShader, generatedBufferViewId); + newShader, generatedBufferViewId); newShaders.put(id, newShader); } // Place the newly created mappings into the output glTF, // if there have been non-null mappings for them in the input - if (!newBuffers.isEmpty()) { + if (!newBuffers.isEmpty()) + { outputGltf.setBuffers(newBuffers); } - if (!newImages.isEmpty()) { + if (!newImages.isEmpty()) + { outputGltf.setImages(newImages); } - if (!newShaders.isEmpty()) { + if (!newShaders.isEmpty()) + { outputGltf.setShaders(newShaders); } - if (!newBufferViews.isEmpty()) { + if (!newBufferViews.isEmpty()) + { outputGltf.setBufferViews(newBufferViews); } return new GltfAssetV1(outputGltf, binaryGltfByteBuffer); } + /** + * Compute the total size that is required for the binary glTF buffer + * for the given {@link GltfModel}, which is the sum of all buffer + * sizes of all buffers, images and shaders. + * + * @param gltfModel The {@link GltfModel} + * @return The total size for the binary glTF buffer + */ + private static int computeBinaryGltfBufferSize(GltfModelV1 gltfModel) + { + int binaryGltfBufferSize = 0; + for (BufferModel bufferModel : gltfModel.getBufferModels()) + { + ByteBuffer bufferData = bufferModel.getBufferData(); + binaryGltfBufferSize += bufferData.capacity(); + } + for (ImageModel imageModel : gltfModel.getImageModels()) + { + ByteBuffer imageData = imageModel.getImageData(); + binaryGltfBufferSize += imageData.capacity(); + } + for (ShaderModel shaderModel : gltfModel.getShaderModels()) + { + ByteBuffer shaderData = shaderModel.getShaderData(); + binaryGltfBufferSize += shaderData.capacity(); + } + return binaryGltfBufferSize; + } + + + /** + * Put the contents of all byte buffers that are associated with the + * given keys into the given target buffer. This method assumes + * that the target buffer has a sufficient capacity to hold all + * buffers. + * + * @param The key type + * + * @param keys The mapping keys + * @param keyToByteBuffer The function that provides the byte buffer + * based on the key of the element + * @param targetBuffer The target buffer + * @return A mapping from each key to the offset inside the target buffer + */ + private static Map concatBuffers( + Iterable keys, + Function keyToByteBuffer, + ByteBuffer targetBuffer) + { + Map offsets = new LinkedHashMap(); + for (K key : keys) + { + ByteBuffer oldByteBuffer = keyToByteBuffer.apply(key); + int offset = targetBuffer.position(); + offsets.put(key, offset); + targetBuffer.put(oldByteBuffer.slice()); + } + return offsets; + } + + /** + * Creates a copy of the given map, as a linked hash map. If the given + * map is null, then an unmodifiable empty map will be + * returned + * + * @param map The input map + * @return The copy + */ + private static Map copy(Map map) + { + if (map == null) + { + return Collections.emptyMap(); + } + return new LinkedHashMap(map); + } + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/DefaultAssetCreatorV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/DefaultAssetCreatorV1.java index 342b661..3df30c5 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/DefaultAssetCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/DefaultAssetCreatorV1.java @@ -26,6 +26,14 @@ */ package de.javagl.jgltf.model.io.v1; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + import de.javagl.jgltf.impl.v1.Buffer; import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Image; @@ -43,29 +51,22 @@ import de.javagl.jgltf.model.v1.GltfExtensionsV1; import de.javagl.jgltf.model.v1.GltfModelV1; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - /** - * A class for creating a {@link GltfAssetV1} with a default data + * A class for creating a {@link GltfAssetV1} with a default data * representation from a {@link GltfModelV1}.
*
- * In the default data representation, elements are referred to via URIs. + * In the default data representation, elements are referred to via URIs. * Data elements like {@link Buffer}, {@link Image} or {@link Shader} - * objects that used the binary glTF extension or data URIs will be + * objects that used the binary glTF extension or data URIs will be * converted to refer to their data using URIs. */ -final class DefaultAssetCreatorV1 { +final class DefaultAssetCreatorV1 +{ /** * The {@link GltfAssetV1} that is currently being created */ private GltfAssetV1 gltfAsset; - + /** * The set of {@link Buffer} URI strings that are already used */ @@ -80,115 +81,121 @@ final class DefaultAssetCreatorV1 { * The set of {@link Shader} URI strings that are already used */ private Set existingShaderUriStrings; - + /** * Creates a new asset creator */ - DefaultAssetCreatorV1() { + DefaultAssetCreatorV1() + { // Default constructor } - /** - * Collect all strings that are obtained from the given elements by - * applying the given function, if these strings are not null - * and no data URI strings - * - * @param elements The elements - * @param uriFunction The function to obtain the string - * @return The strings - */ - private static Set collectUriStrings(Collection elements, - Function uriFunction) { - return elements.stream() - .map(uriFunction) - .filter(Objects::nonNull) - .filter(uriString -> !IO.isDataUriString(uriString)) - .collect(Collectors.toSet()); - } - /** * Create a default {@link GltfAssetV1} from the given {@link GltfModelV1}. - * + * * @param gltfModel The input {@link GltfModelV1} * @return The default {@link GltfAssetV1} */ - GltfAssetV1 create(GltfModelV1 gltfModel) { + GltfAssetV1 create(GltfModelV1 gltfModel) + { GlTF outputGltf = GltfCreatorV1.create(gltfModel); - + // Remove the binary glTF extension, if it was used - GltfExtensionsV1.removeExtensionUsed(outputGltf, - BinaryGltfV1.getBinaryGltfExtensionName()); + GltfExtensionsV1.removeExtensionUsed(outputGltf, + BinaryGltfV1.getBinaryGltfExtensionName()); existingBufferUriStrings = collectUriStrings( - Optionals.of(outputGltf.getBuffers()).values(), - Buffer::getUri); + Optionals.of(outputGltf.getBuffers()).values(), + Buffer::getUri); existingImageUriStrings = collectUriStrings( - Optionals.of(outputGltf.getImages()).values(), - Image::getUri); + Optionals.of(outputGltf.getImages()).values(), + Image::getUri); existingShaderUriStrings = collectUriStrings( - Optionals.of(outputGltf.getShaders()).values(), - Shader::getUri); + Optionals.of(outputGltf.getShaders()).values(), + Shader::getUri); this.gltfAsset = new GltfAssetV1(outputGltf, null); - - // TODO This is not solved very elegantly, due to the + + // TODO This is not solved very elegantly, due to the // transition of glTF 1.0 to glTF 2.0 - refactor this! - + // Create mappings from the IDs to the corresponding model elements. // This assumes that they are in the same order. Map bufferIdToBuffer = GltfUtilsV1.createMap( - outputGltf.getBuffers(), - gltfModel.getBufferModels()); + outputGltf.getBuffers(), + gltfModel.getBufferModels()); Map imageIdToImage = GltfUtilsV1.createMap( - outputGltf.getImages(), - gltfModel.getImageModels()); + outputGltf.getImages(), + gltfModel.getImageModels()); Map shaderIdToShader = GltfUtilsV1.createMap( - outputGltf.getShaders(), - gltfModel.getShaderModels()); - - Optionals.of(outputGltf.getBuffers()).forEach((id, value) -> - storeBufferAsDefault(gltfModel, id, value, bufferIdToBuffer::get)); - Optionals.of(outputGltf.getImages()).forEach((id, value) -> - storeImageAsDefault(gltfModel, id, value, imageIdToImage::get)); - Optionals.of(outputGltf.getShaders()).forEach((id, value) -> - storeShaderAsDefault(gltfModel, id, value, shaderIdToShader::get)); + outputGltf.getShaders(), + gltfModel.getShaderModels()); + + Optionals.of(outputGltf.getBuffers()).forEach((id, value) -> + storeBufferAsDefault(gltfModel, id, value, bufferIdToBuffer::get)); + Optionals.of(outputGltf.getImages()).forEach((id, value) -> + storeImageAsDefault(gltfModel, id, value, imageIdToImage::get)); + Optionals.of(outputGltf.getShaders()).forEach((id, value) -> + storeShaderAsDefault(gltfModel, id, value, shaderIdToShader::get)); return gltfAsset; } /** - * Store the given {@link Buffer} with the given ID in the current + * Collect all strings that are obtained from the given elements by + * applying the given function, if these strings are not null + * and no data URI strings + * + * @param elements The elements + * @param uriFunction The function to obtain the string + * @return The strings + */ + private static Set collectUriStrings(Collection elements, + Function uriFunction) + { + return elements.stream() + .map(uriFunction) + .filter(Objects::nonNull) + .filter(uriString -> !IO.isDataUriString(uriString)) + .collect(Collectors.toSet()); + } + + + /** + * Store the given {@link Buffer} with the given ID in the current * output asset.
*
- * If the {@link Buffer#getUri() buffer URI} is null or a - * data URI, it will receive a new URI, which refers to the buffer data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Buffer#getUri() buffer URI} is null or a + * data URI, it will receive a new URI, which refers to the buffer data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
* If the given ID is the binary glTF buffer ID, "binary_glTF", - * then the buffer will also receive a new URI. + * then the buffer will also receive a new URI. *
- * The given {@link Buffer} object will be modified accordingly, if + * The given {@link Buffer} object will be modified accordingly, if * necessary: Its URI will be set to be the new URI. - * - * @param gltfModel The {@link GltfModelV1} - * @param id The ID of the {@link Buffer} - * @param buffer The {@link Buffer} - * @param lookup The lookup from ID to model + * + * @param gltfModel The {@link GltfModelV1} + * @param id The ID of the {@link Buffer} + * @param buffer The {@link Buffer} + * @param lookup The lookup from ID to model */ private void storeBufferAsDefault( - GltfModelV1 gltfModel, String id, Buffer buffer, - Function lookup) { + GltfModelV1 gltfModel, String id, Buffer buffer, + Function lookup) + { BufferModel bufferModel = lookup.apply(id); ByteBuffer bufferData = bufferModel.getBufferData(); - + String oldUriString = buffer.getUri(); String newUriString = oldUriString; if (oldUriString == null || - IO.isDataUriString(oldUriString) || - BinaryGltfV1.isBinaryGltfBufferId(id)) { + IO.isDataUriString(oldUriString) || + BinaryGltfV1.isBinaryGltfBufferId(id)) + { newUriString = UriStrings.createBufferUriString( - existingBufferUriStrings); + existingBufferUriStrings); buffer.setUri(newUriString); existingBufferUriStrings.add(newUriString); } @@ -196,84 +203,88 @@ private void storeBufferAsDefault( } /** - * Store the given {@link Image} with the given ID in the current + * Store the given {@link Image} with the given ID in the current * output asset.
*
- * If the {@link Image#getUri() image URI} is null or a - * data URI, it will receive a new URI, which refers to the image data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Image#getUri() image URI} is null or a + * data URI, it will receive a new URI, which refers to the image data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
- * The given {@link Image} object will be modified accordingly, if + * The given {@link Image} object will be modified accordingly, if * necessary: Its URI will be set to be the new URI. If it referred * to a buffer view, using the binary glTF extension, then this - * reference will be removed. - * - * @param gltfModel The {@link GltfModelV1} - * @param id The id of the {@link Image} - * @param image The {@link Image} - * @param lookup The lookup from ID to model + * reference will be removed. + * + * @param gltfModel The {@link GltfModelV1} + * @param id The id of the {@link Image} + * @param image The {@link Image} + * @param lookup The lookup from ID to model * @throws GltfException If the image format (and thus, the MIME type) - * can not be determined from the image data + * can not be determined from the image data */ private void storeImageAsDefault( - GltfModelV1 gltfModel, String id, Image image, - Function lookup) { + GltfModelV1 gltfModel, String id, Image image, + Function lookup) + { ImageModel imageModel = lookup.apply(id); ByteBuffer imageData = imageModel.getImageData(); String oldUriString = image.getUri(); String newUriString = oldUriString; if (oldUriString == null || - IO.isDataUriString(oldUriString) || - BinaryGltfV1.hasBinaryGltfExtension(image)) { + IO.isDataUriString(oldUriString) || + BinaryGltfV1.hasBinaryGltfExtension(image)) + { newUriString = UriStrings.createImageUriString( - imageModel, existingImageUriStrings); + imageModel, existingImageUriStrings); image.setUri(newUriString); existingImageUriStrings.add(newUriString); - + // Remove the extension object, if necessary image.removeExtensions(BinaryGltfV1.getBinaryGltfExtensionName()); } gltfAsset.putReferenceData(newUriString, imageData); } - + /** - * Store the given {@link Shader} with the given ID in the current + * Store the given {@link Shader} with the given ID in the current * output asset.
*
- * If the {@link Shader#getUri() shader URI} is null or a - * data URI, it will receive a new URI, which refers to the shader data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Shader#getUri() shader URI} is null or a + * data URI, it will receive a new URI, which refers to the shader data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
- * The given {@link Shader} object will be modified accordingly, if + * The given {@link Shader} object will be modified accordingly, if * necessary: Its URI will be set to be the new URI. If it referred * to a buffer view, using the binary glTF extension, then this - * reference will be removed. - * - * @param gltfModel The {@link GltfModelV1} - * @param id The id of the {@link Shader} - * @param shader The {@link Shader} - * @param lookup The lookup from ID to model + * reference will be removed. + * + * @param gltfModel The {@link GltfModelV1} + * @param id The id of the {@link Shader} + * @param shader The {@link Shader} + * @param lookup The lookup from ID to model */ private void storeShaderAsDefault( - GltfModelV1 gltfModel, String id, Shader shader, - Function lookup) { + GltfModelV1 gltfModel, String id, Shader shader, + Function lookup) + { ShaderModel shaderModel = lookup.apply(id); ByteBuffer shaderData = shaderModel.getShaderData(); String oldUriString = shader.getUri(); String newUriString = oldUriString; if (oldUriString == null || - IO.isDataUriString(oldUriString) || - BinaryGltfV1.hasBinaryGltfExtension(shader)) { + IO.isDataUriString(oldUriString) || + BinaryGltfV1.hasBinaryGltfExtension(shader)) + { newUriString = UriStrings.createShaderUriString( - shaderModel, existingShaderUriStrings); + shaderModel, existingShaderUriStrings); shader.setUri(newUriString); existingShaderUriStrings.add(newUriString); - + // Remove the extension object, if necessary shader.removeExtensions(BinaryGltfV1.getBinaryGltfExtensionName()); } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/EmbeddedAssetCreatorV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/EmbeddedAssetCreatorV1.java index 30ad207..afc8280 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/EmbeddedAssetCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/EmbeddedAssetCreatorV1.java @@ -26,6 +26,11 @@ */ package de.javagl.jgltf.model.io.v1; +import java.nio.ByteBuffer; +import java.util.Base64; +import java.util.Map; +import java.util.function.Function; + import de.javagl.jgltf.impl.v1.Buffer; import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Image; @@ -42,167 +47,172 @@ import de.javagl.jgltf.model.v1.GltfCreatorV1; import de.javagl.jgltf.model.v1.GltfModelV1; -import java.nio.ByteBuffer; -import java.util.Base64; -import java.util.Map; -import java.util.function.Function; - /** - * A class for creating a {@link GltfAssetV1} with an "embedded" data + * A class for creating a {@link GltfAssetV1} with an "embedded" data * representation from a {@link GltfModelV1}.
*
- * In the "embedded" data representation, the data of elements like - * {@link Buffer}, {@link Image} or {@link Shader} objects is stored + * In the "embedded" data representation, the data of elements like + * {@link Buffer}, {@link Image} or {@link Shader} objects is stored * in data URIs. */ -final class EmbeddedAssetCreatorV1 { +final class EmbeddedAssetCreatorV1 +{ /** * Creates a new asset creator */ - EmbeddedAssetCreatorV1() { + EmbeddedAssetCreatorV1() + { // Default constructor } /** - * Convert the given {@link Buffer} into an embedded buffer, by replacing + * Create a {@link GltfAssetV1} with "embedded" data representation from + * the given {@link GltfModelV1}.
+ *
+ * The returned {@link GltfAssetV1} will contain a {@link GlTF} where the + * the URIs that appear in {@link Buffer}, {@link Image} or {@link Shader} + * instances are replaced with data URIs that contain the corresponding + * data. Its {@link GltfAsset#getBinaryData() binary data} will be + * null, and its {@link GltfAsset#getReferenceDatas() + * reference data elements} will be empty. + * + * @param gltfModel The input {@link GltfModelV1} + * @return The embedded {@link GltfAssetV1} + */ + GltfAssetV1 create(GltfModelV1 gltfModel) + { + GlTF outputGltf = GltfCreatorV1.create(gltfModel); + + // TODO This is not solved very elegantly, due to the + // transition of glTF 1.0 to glTF 2.0 - refactor this! + + // Create mappings from the IDs to the corresponding model elements. + // This assumes that they are in the same order. + Map bufferIdToBuffer = GltfUtilsV1.createMap( + outputGltf.getBuffers(), + gltfModel.getBufferModels()); + Map imageIdToImage = GltfUtilsV1.createMap( + outputGltf.getImages(), + gltfModel.getImageModels()); + Map shaderIdToShader = GltfUtilsV1.createMap( + outputGltf.getShaders(), + gltfModel.getShaderModels()); + + Optionals.of(outputGltf.getBuffers()).forEach((id, value) -> + convertBufferToEmbedded( + gltfModel, id, value, bufferIdToBuffer::get)); + Optionals.of(outputGltf.getImages()).forEach((id, value) -> + convertImageToEmbedded( + gltfModel, id, value, imageIdToImage::get)); + Optionals.of(outputGltf.getShaders()).forEach((id, value) -> + convertShaderToEmbedded( + gltfModel, id, value, shaderIdToShader::get)); + + return new GltfAssetV1(outputGltf, null); + } + + /** + * Convert the given {@link Buffer} into an embedded buffer, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModelV1} - * @param id The ID of the {@link Buffer} - * @param buffer The {@link Buffer} - * @param lookup The lookup from ID to model + * @param id The ID of the {@link Buffer} + * @param buffer The {@link Buffer} + * @param lookup The lookup from ID to model */ private static void convertBufferToEmbedded( - GltfModelV1 gltfModel, String id, Buffer buffer, - Function lookup) { + GltfModelV1 gltfModel, String id, Buffer buffer, + Function lookup) + { String uriString = buffer.getUri(); - if (IO.isDataUriString(uriString)) { + if (IO.isDataUriString(uriString)) + { return; } BufferModel bufferModel = lookup.apply(id); ByteBuffer bufferData = bufferModel.getBufferData(); - + byte data[] = new byte[bufferData.capacity()]; bufferData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); - String dataUriString = - "data:application/gltf-buffer;base64," + encodedData; - + String dataUriString = + "data:application/gltf-buffer;base64," + encodedData; + buffer.setUri(dataUriString); } /** - * Convert the given {@link Image} into an embedded image, by replacing + * Convert the given {@link Image} into an embedded image, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModelV1} - * @param id The ID of the {@link Image} - * @param image The {@link Image} - * @param lookup The lookup from ID to model + * @param id The ID of the {@link Image} + * @param image The {@link Image} + * @param lookup The lookup from ID to model * @throws GltfException If the image format (and thus, the MIME type) - * can not be determined from the image data + * can not be determined from the image data */ private static void convertImageToEmbedded( - GltfModelV1 gltfModel, String id, Image image, - Function lookup) { + GltfModelV1 gltfModel, String id, Image image, + Function lookup) + { String uriString = image.getUri(); - if (IO.isDataUriString(uriString)) { + if (IO.isDataUriString(uriString)) + { return; } ImageModel imageModel = lookup.apply(id); ByteBuffer imageData = imageModel.getImageData(); - + String uri = image.getUri(); String imageMimeTypeString = - MimeTypes.guessImageMimeTypeString(uri, imageData); - if (imageMimeTypeString == null) { + MimeTypes.guessImageMimeTypeString(uri, imageData); + if (imageMimeTypeString == null) + { throw new GltfException( - "Could not detect MIME type of image " + id); + "Could not detect MIME type of image " + id); } byte data[] = new byte[imageData.capacity()]; imageData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); String dataUriString = - "data:" + imageMimeTypeString + ";base64," + encodedData; - + "data:" + imageMimeTypeString + ";base64," + encodedData; + image.removeExtensions(BinaryGltfV1.getBinaryGltfExtensionName()); image.setUri(dataUriString); } /** - * Convert the given {@link Shader} into an embedded shader, by replacing + * Convert the given {@link Shader} into an embedded shader, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModelV1} - * @param id The ID of the {@link Shader} - * @param shader The {@link Shader} - * @param lookup The lookup from ID to model + * @param id The ID of the {@link Shader} + * @param shader The {@link Shader} + * @param lookup The lookup from ID to model */ private static void convertShaderToEmbedded( - GltfModelV1 gltfModel, String id, Shader shader, - Function lookup) { + GltfModelV1 gltfModel, String id, Shader shader, + Function lookup) + { String uriString = shader.getUri(); - if (IO.isDataUriString(uriString)) { + if (IO.isDataUriString(uriString)) + { return; } ShaderModel shaderModel = lookup.apply(id); ByteBuffer shaderData = shaderModel.getShaderData(); - + byte data[] = new byte[shaderData.capacity()]; shaderData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); - String dataUriString = - "data:text/plain;base64," + encodedData; - + String dataUriString = + "data:text/plain;base64," + encodedData; + shader.removeExtensions(BinaryGltfV1.getBinaryGltfExtensionName()); shader.setUri(dataUriString); } - /** - * Create a {@link GltfAssetV1} with "embedded" data representation from - * the given {@link GltfModelV1}.
- *
- * The returned {@link GltfAssetV1} will contain a {@link GlTF} where the - * the URIs that appear in {@link Buffer}, {@link Image} or {@link Shader} - * instances are replaced with data URIs that contain the corresponding - * data. Its {@link GltfAsset#getBinaryData() binary data} will be - * null, and its {@link GltfAsset#getReferenceDatas() - * reference data elements} will be empty. - * - * @param gltfModel The input {@link GltfModelV1} - * @return The embedded {@link GltfAssetV1} - */ - GltfAssetV1 create(GltfModelV1 gltfModel) { - GlTF outputGltf = GltfCreatorV1.create(gltfModel); - - // TODO This is not solved very elegantly, due to the - // transition of glTF 1.0 to glTF 2.0 - refactor this! - - // Create mappings from the IDs to the corresponding model elements. - // This assumes that they are in the same order. - Map bufferIdToBuffer = GltfUtilsV1.createMap( - outputGltf.getBuffers(), - gltfModel.getBufferModels()); - Map imageIdToImage = GltfUtilsV1.createMap( - outputGltf.getImages(), - gltfModel.getImageModels()); - Map shaderIdToShader = GltfUtilsV1.createMap( - outputGltf.getShaders(), - gltfModel.getShaderModels()); - - Optionals.of(outputGltf.getBuffers()).forEach((id, value) -> - convertBufferToEmbedded( - gltfModel, id, value, bufferIdToBuffer::get)); - Optionals.of(outputGltf.getImages()).forEach((id, value) -> - convertImageToEmbedded( - gltfModel, id, value, imageIdToImage::get)); - Optionals.of(outputGltf.getShaders()).forEach((id, value) -> - convertShaderToEmbedded( - gltfModel, id, value, shaderIdToShader::get)); - - return new GltfAssetV1(outputGltf, null); - } - } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetV1.java index 1403e25..f148f07 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetV1.java @@ -26,6 +26,16 @@ */ package de.javagl.jgltf.model.io.v1; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + import de.javagl.jgltf.impl.v1.Buffer; import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Image; @@ -37,151 +47,166 @@ import de.javagl.jgltf.model.io.IO; import de.javagl.jgltf.model.v1.BinaryGltfV1; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - /** * Implementation of the {@link GltfAsset} interface for glTF 1.0. */ -public final class GltfAssetV1 implements GltfAsset { +public final class GltfAssetV1 implements GltfAsset +{ /** * The {@link GlTF} */ private final GlTF gltf; - + /** * The optional binary data */ private final ByteBuffer binaryData; - + /** * The mapping from (relative) URI strings to the associated external data */ private final Map referenceDatas; - + /** * Creates a new instance - * - * @param gltf The {@link GlTF} + * + * @param gltf The {@link GlTF} * @param binaryData The optional binary data */ - public GltfAssetV1(GlTF gltf, ByteBuffer binaryData) { + public GltfAssetV1(GlTF gltf, ByteBuffer binaryData) + { this.gltf = Objects.requireNonNull(gltf, "The gltf may not be null"); this.binaryData = binaryData; this.referenceDatas = new ConcurrentHashMap(); } - + /** * Store the given byte buffer under the given (relative) URI string - * - * @param uriString The URI string + * + * @param uriString The URI string * @param byteBuffer The byte buffer */ - void putReferenceData(String uriString, ByteBuffer byteBuffer) { - if (byteBuffer == null) { + void putReferenceData(String uriString, ByteBuffer byteBuffer) + { + if (byteBuffer == null) + { referenceDatas.remove(uriString); - } else { + } + else + { referenceDatas.put(uriString, byteBuffer); } } - + @Override - public GlTF getGltf() { + public GlTF getGltf() + { return gltf; } - + @Override - public ByteBuffer getBinaryData() { + public ByteBuffer getBinaryData() + { return Buffers.createSlice(binaryData); } - + @Override - public List getReferences() { + public List getReferences() + { List references = new ArrayList(); references.addAll(getBufferReferences()); references.addAll(getImageReferences()); references.addAll(getShaderReferences()); return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * buffers that are contained in this model. - * + * * @return The references */ - public List getBufferReferences() { + public List getBufferReferences() + { List references = new ArrayList(); Map buffers = Optionals.of(gltf.getBuffers()); - for (Entry entry : buffers.entrySet()) { + for (Entry entry : buffers.entrySet()) + { String bufferId = entry.getKey(); - if (BinaryGltfV1.isBinaryGltfBufferId(bufferId)) { + if (BinaryGltfV1.isBinaryGltfBufferId(bufferId)) + { continue; } Buffer buffer = buffers.get(bufferId); String uri = buffer.getUri(); - if (!IO.isDataUriString(uri)) { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); - GltfReference reference = - new GltfReference(bufferId, uri, target); + if (!IO.isDataUriString(uri)) + { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); + GltfReference reference = + new GltfReference(bufferId, uri, target); references.add(reference); } } return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * images that are contained in this model. - * + * * @return The references */ - public List getImageReferences() { + public List getImageReferences() + { List references = new ArrayList(); Map images = Optionals.of(gltf.getImages()); - for (Entry entry : images.entrySet()) { + for (Entry entry : images.entrySet()) + { String imageId = entry.getKey(); Image image = entry.getValue(); - if (BinaryGltfV1.hasBinaryGltfExtension(image)) { + if (BinaryGltfV1.hasBinaryGltfExtension(image)) + { continue; } String uri = image.getUri(); - if (!IO.isDataUriString(uri)) { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); - GltfReference reference = - new GltfReference(imageId, uri, target); + if (!IO.isDataUriString(uri)) + { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); + GltfReference reference = + new GltfReference(imageId, uri, target); references.add(reference); } } return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * shaders that are contained in this model. - * + * * @return The references */ - public List getShaderReferences() { + public List getShaderReferences() + { List references = new ArrayList(); Map shaders = Optionals.of(gltf.getShaders()); - for (Entry entry : shaders.entrySet()) { + for (Entry entry : shaders.entrySet()) + { String shaderId = entry.getKey(); Shader shader = entry.getValue(); - if (BinaryGltfV1.hasBinaryGltfExtension(shader)) { + if (BinaryGltfV1.hasBinaryGltfExtension(shader)) + { continue; } String uri = shader.getUri(); - if (!IO.isDataUriString(uri)) { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); - GltfReference reference = - new GltfReference(shaderId, uri, target); + if (!IO.isDataUriString(uri)) + { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); + GltfReference reference = + new GltfReference(shaderId, uri, target); references.add(reference); } } @@ -189,13 +214,15 @@ public List getShaderReferences() { } @Override - public ByteBuffer getReferenceData(String uriString) { + public ByteBuffer getReferenceData(String uriString) + { return Buffers.createSlice(referenceDatas.get(uriString)); } - + @Override - public Map getReferenceDatas() { + public Map getReferenceDatas() + { return Collections.unmodifiableMap(referenceDatas); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetWriterV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetWriterV1.java index 7c547a2..13d4c48 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetWriterV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetWriterV1.java @@ -26,10 +26,6 @@ */ package de.javagl.jgltf.model.io.v1; -import de.javagl.jgltf.impl.v1.GlTF; -import de.javagl.jgltf.model.io.GltfAssetWriter; -import de.javagl.jgltf.model.io.GltfWriter; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -39,19 +35,24 @@ import java.nio.channels.Channels; import java.nio.channels.WritableByteChannel; +import de.javagl.jgltf.impl.v1.GlTF; +import de.javagl.jgltf.model.io.GltfAssetWriter; +import de.javagl.jgltf.model.io.GltfWriter; + /** * A class for writing a glTF 1.0 asset in binary format to an output stream. - * This class contains implementations for the methods of the - * {@link GltfAssetWriter}, for glTF 1.0 assets. Clients should not use this + * This class contains implementations for the methods of the + * {@link GltfAssetWriter}, for glTF 1.0 assets. Clients should not use this * class directly, but only the {@link GltfAssetWriter}. */ -public class GltfAssetWriterV1 { +public class GltfAssetWriterV1 +{ /** * The magic binary glTF header. * This is an integer corresponding to the ASCII string "glTF" */ private static final int MAGIC_BINARY_GLTF_HEADER = 0x46546C67; - + /** * The binary glTF version that is written by this writer */ @@ -61,38 +62,42 @@ public class GltfAssetWriterV1 { * The constant indicating JSON content format for glTF 1.0 */ private static final int CONTENT_FORMAT_JSON = 0; - + /** * Default constructor */ - public GltfAssetWriterV1() { + public GltfAssetWriterV1() + { // Default constructor } /** - * Write the given {@link GltfAssetV1} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * Write the given {@link GltfAssetV1} as a binary glTF asset to the + * given output stream. The caller is responsible for closing the * given stream.
*
- * - * @param gltfAsset The {@link GltfAssetV1} + * + * @param gltfAsset The {@link GltfAssetV1} * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAssetV1 gltfAsset, OutputStream outputStream) - throws IOException { + public void writeBinary(GltfAssetV1 gltfAsset, OutputStream outputStream) + throws IOException + { // Write the JSON representation of the glTF, creating the scene data GlTF gltf = gltfAsset.getGltf(); byte sceneData[]; - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) + { GltfWriter gltfWriter = new GltfWriter(); gltfWriter.setIndenting(false); gltfWriter.write(gltf, baos); sceneData = baos.toByteArray(); } - + ByteBuffer binaryData = gltfAsset.getBinaryData(); - if (binaryData == null) { + if (binaryData == null) + { binaryData = ByteBuffer.wrap(new byte[0]); } @@ -100,26 +105,26 @@ public void writeBinary(GltfAssetV1 gltfAsset, OutputStream outputStream) byte headerData[] = new byte[20]; int magic = MAGIC_BINARY_GLTF_HEADER; int version = BINARY_GLTF_VERSION; - int length = - headerData.length + sceneData.length + binaryData.capacity(); + int length = + headerData.length + sceneData.length + binaryData.capacity(); int contentLength = sceneData.length; int contentFormat = CONTENT_FORMAT_JSON; - + IntBuffer headerBuffer = ByteBuffer.wrap(headerData) - .order(ByteOrder.LITTLE_ENDIAN).asIntBuffer(); + .order(ByteOrder.LITTLE_ENDIAN).asIntBuffer(); headerBuffer.put(magic); headerBuffer.put(version); headerBuffer.put(length); headerBuffer.put(contentLength); headerBuffer.put(contentFormat); - + // Finally, write the header, scene and binary glTF buffer @SuppressWarnings("resource") - WritableByteChannel writableByteChannel = - Channels.newChannel(outputStream); + WritableByteChannel writableByteChannel = + Channels.newChannel(outputStream); writableByteChannel.write(ByteBuffer.wrap(headerData)); writableByteChannel.write(ByteBuffer.wrap(sceneData)); writableByteChannel.write(binaryData.slice()); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetsV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetsV1.java index a924945..5a3205b 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetsV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfAssetsV1.java @@ -35,52 +35,59 @@ * This class should not be considered as part of the public API. It may * change or be omitted in the future. */ -public class GltfAssetsV1 { +public class GltfAssetsV1 +{ /** - * Private constructor to prevent instantiation - */ - private GltfAssetsV1() { - // Private constructor to prevent instantiation - } - - /** - * Create a new default {@link GltfAssetV1} from the given + * Create a new default {@link GltfAssetV1} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV1} */ - public static GltfAssetV1 createDefault(GltfModelV1 gltfModel) { + public static GltfAssetV1 createDefault(GltfModelV1 gltfModel) + { DefaultAssetCreatorV1 assetCreator = new DefaultAssetCreatorV1(); GltfAssetV1 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - + /** - * Create a new binary {@link GltfAssetV1} from the given + * Create a new binary {@link GltfAssetV1} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV1} */ - public static GltfAssetV1 createBinary(GltfModelV1 gltfModel) { + public static GltfAssetV1 createBinary(GltfModelV1 gltfModel) + { BinaryAssetCreatorV1 assetCreator = new BinaryAssetCreatorV1(); GltfAssetV1 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - + /** - * Create a new embedded {@link GltfAssetV1} from the given + * Create a new embedded {@link GltfAssetV1} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV1} */ - public static GltfAssetV1 createEmbedded(GltfModelV1 gltfModel) { + public static GltfAssetV1 createEmbedded(GltfModelV1 gltfModel) + { EmbeddedAssetCreatorV1 assetCreator = new EmbeddedAssetCreatorV1(); GltfAssetV1 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } + + + + /** + * Private constructor to prevent instantiation + */ + private GltfAssetsV1() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfModelWriterV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfModelWriterV1.java index df27f93..53fe3b0 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfModelWriterV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfModelWriterV1.java @@ -26,91 +26,98 @@ */ package de.javagl.jgltf.model.io.v1; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.model.io.GltfAssetWriter; import de.javagl.jgltf.model.io.GltfModelWriter; import de.javagl.jgltf.model.io.GltfWriter; import de.javagl.jgltf.model.v1.GltfModelV1; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - /** - * A class for writing a {@link GltfModelV1}. This class contains + * A class for writing a {@link GltfModelV1}. This class contains * implementations for the methods of the {@link GltfModelWriter}, * for glTF 1.0 assets. Clients should not use this class directly, * but only the {@link GltfModelWriter}. */ -public final class GltfModelWriterV1 { +public final class GltfModelWriterV1 +{ /** * Default constructor */ - public GltfModelWriterV1() { + public GltfModelWriterV1() + { // Default constructor } - + /** * Write the given {@link GltfModelV1} to the given file. External - * references of buffers, images and shaders that are given via - * the respective URI string will be resolved against the parent - * directory of the given file, and the corresponding data will - * be written into the corresponding files. - * + * references of buffers, images and shaders that are given via + * the respective URI string will be resolved against the parent + * directory of the given file, and the corresponding data will + * be written into the corresponding files. + * * @param gltfModel The {@link GltfModelV1} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void write(GltfModelV1 gltfModel, File file) - throws IOException { + public void write(GltfModelV1 gltfModel, File file) + throws IOException + { GltfAssetV1 gltfAsset = GltfAssetsV1.createDefault(gltfModel); GltfAssetWriter gltfAssetWriter = new GltfAssetWriter(); gltfAssetWriter.write(gltfAsset, file); } - + /** * Write the given {@link GltfModelV1} as a binary glTF asset to the * given file - * + * * @param gltfModel The {@link GltfModelV1} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModelV1 gltfModel, File file) - throws IOException { - try (OutputStream outputStream = new FileOutputStream(file)) { + public void writeBinary(GltfModelV1 gltfModel, File file) + throws IOException + { + try (OutputStream outputStream = new FileOutputStream(file)) + { writeBinary(gltfModel, outputStream); } } - + /** * Write the given {@link GltfModelV1} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModelV1} + * + * @param gltfModel The {@link GltfModelV1} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModelV1 gltfModel, OutputStream outputStream) - throws IOException { + public void writeBinary(GltfModelV1 gltfModel, OutputStream outputStream) + throws IOException + { GltfAssetV1 gltfAsset = GltfAssetsV1.createBinary(gltfModel); GltfAssetWriterV1 gltfAssetWriter = new GltfAssetWriterV1(); gltfAssetWriter.writeBinary(gltfAsset, outputStream); } - + /** * Write the given {@link GltfModelV1} as an embedded glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModelV1} + * + * @param gltfModel The {@link GltfModelV1} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeEmbedded(GltfModelV1 gltfModel, OutputStream outputStream) - throws IOException { + public void writeEmbedded(GltfModelV1 gltfModel, OutputStream outputStream) + throws IOException + { GltfAssetV1 gltfAsset = GltfAssetsV1.createEmbedded(gltfModel); GltfWriter gltfWriter = new GltfWriter(); GlTF gltf = gltfAsset.getGltf(); diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfReaderV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfReaderV1.java index d590f18..f77c7d1 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfReaderV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfReaderV1.java @@ -26,40 +26,44 @@ */ package de.javagl.jgltf.model.io.v1; -import com.google.gson.Gson; -import de.javagl.jgltf.impl.v1.GlTF; - import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import com.google.gson.Gson; + +import de.javagl.jgltf.impl.v1.GlTF; + /** * A class for reading a version 1.0 {@link GlTF} from an input stream */ -public final class GltfReaderV1 { +public final class GltfReaderV1 +{ // Note: This class could use GltfReader as a delegate, and could // then verify that the glTF has the right version. Right now, it // assumes that it is only used for glTF 1.0 inputs. - + /** * Creates a new glTF reader */ - public GltfReaderV1() { + public GltfReaderV1() + { // Default constructor } - + /** * Read the {@link GlTF} from the given stream - * + * * @param inputStream The input stream * @return The {@link GlTF} * @throws IOException If an IO error occurs */ - public GlTF read(InputStream inputStream) throws IOException { - InputStreamReader reader = new InputStreamReader(inputStream); - GlTF gltf = new Gson().fromJson(reader, GlTF.class); - reader.close(); + public GlTF read(InputStream inputStream) throws IOException + { + InputStreamReader reader = new InputStreamReader(inputStream); + GlTF gltf = new Gson().fromJson(reader, GlTF.class); + reader.close(); return gltf; } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/GltfUtilsV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/GltfUtilsV1.java index b344545..e2b2ee7 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/GltfUtilsV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/GltfUtilsV1.java @@ -26,26 +26,25 @@ */ package de.javagl.jgltf.model.io.v1; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + import com.google.gson.Gson; + import de.javagl.jgltf.impl.v1.BufferView; import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Image; import de.javagl.jgltf.impl.v1.Shader; import de.javagl.jgltf.model.GltfException; -import java.util.*; - /** * Utility methods related to {@link GlTF}s */ -class GltfUtilsV1 { - /** - * Private constructor to prevent instantiation - */ - private GltfUtilsV1() { - // Private constructor to prevent instantiation - } - +class GltfUtilsV1 +{ /** * Creates a deep copy of the given {@link GlTF}.
*
@@ -54,23 +53,25 @@ private GltfUtilsV1() { * in the copy. The goal of this method is to create a copy that is, * as far as reasonably possible, "structurally equivalent" to the * given input. - * - * @param gltf The input + * + * @param gltf The input * @return The copy * @throws GltfException If the copy can not be created */ - static GlTF copy(GlTF gltf) { - Gson gson = new Gson(); - return gson.fromJson(gson.toJsonTree(gltf, GlTF.class), GlTF.class); + static GlTF copy(GlTF gltf) + { + Gson gson = new Gson(); + return gson.fromJson(gson.toJsonTree(gltf, GlTF.class), GlTF.class); } /** * Creates a shallow copy of the given {@link BufferView} - * + * * @param bufferView The {@link BufferView} * @return The copy */ - static BufferView copy(BufferView bufferView) { + static BufferView copy(BufferView bufferView) + { BufferView copy = new BufferView(); copy.setExtensions(bufferView.getExtensions()); copy.setExtras(bufferView.getExtras()); @@ -81,14 +82,16 @@ static BufferView copy(BufferView bufferView) { copy.setTarget(bufferView.getTarget()); return copy; } - + + /** * Creates a shallow copy of the given {@link Image} - * + * * @param image The {@link Image} * @return The copy */ - static Image copy(Image image) { + static Image copy(Image image) + { Image copy = new Image(); copy.setExtensions(image.getExtensions()); copy.setExtras(image.getExtras()); @@ -96,14 +99,15 @@ static Image copy(Image image) { copy.setUri(image.getUri()); return copy; } - + /** * Creates a shallow copy of the given {@link Shader} - * + * * @param shader The {@link Shader} * @return The copy */ - static Shader copy(Shader shader) { + static Shader copy(Shader shader) + { Shader copy = new Shader(); copy.setExtensions(shader.getExtensions()); copy.setExtras(shader.getExtras()); @@ -112,35 +116,47 @@ static Shader copy(Shader shader) { copy.setUri(shader.getUri()); return copy; } - + /** * Combine the keys of the given map with the elements of the given * collection, in iteration order. - * - * @param map The map + * + * @param map The map * @param collection The collection * @return The resulting map * @throws IllegalArgumentException If the inputs have different sizes */ static Map createMap( - Map map, - Collection collection) { - if (map == null) { + Map map, + Collection collection) + { + if (map == null) + { return Collections.emptyMap(); } - if (map.size() != collection.size()) { + if (map.size() != collection.size()) + { throw new IllegalArgumentException( - "The inputs must have the same size, but the sizes are " - + map.size() + " and " + collection.size()); + "The inputs must have the same size, but the sizes are " + + map.size() + " and " + collection.size()); } Iterator iterator0 = map.keySet().iterator(); Iterator iterator1 = collection.iterator(); Map result = new LinkedHashMap(); - while (iterator0.hasNext()) { + while (iterator0.hasNext()) + { K k = iterator0.next(); V v = iterator1.next(); result.put(k, v); } return result; } + + /** + * Private constructor to prevent instantiation + */ + private GltfUtilsV1() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v1/RawBinaryGltfDataReaderV1.java b/src/main/java/de/javagl/jgltf/model/io/v1/RawBinaryGltfDataReaderV1.java index ea96401..50a0817 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v1/RawBinaryGltfDataReaderV1.java +++ b/src/main/java/de/javagl/jgltf/model/io/v1/RawBinaryGltfDataReaderV1.java @@ -26,73 +26,80 @@ */ package de.javagl.jgltf.model.io.v1; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.io.RawGltfData; - import java.io.IOException; import java.nio.ByteBuffer; import java.nio.IntBuffer; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.io.RawGltfData; + /** * A class for reading a {@link RawGltfData} from a buffer that contains * binary glTF 1.0 data */ -public class RawBinaryGltfDataReaderV1 { +public class RawBinaryGltfDataReaderV1 +{ /** * The length of the binary glTF header for glTF 1.0, in bytes */ private static final int BINARY_GLTF_VERSION_1_HEADER_LENGTH_IN_BYTES = 20; - + /** * The constant indicating JSON content format for glTF 1.0 */ private static final int CONTENT_FORMAT_JSON = 0; - - /** - * Private constructor to prevent instantiation - */ - private RawBinaryGltfDataReaderV1() { - // Private constructor to prevent instantiation - } - + /** * Read the {@link RawGltfData} from the given buffer, which contains * the binary glTF 1.0 data - * + * * @param data The input data * @return The {@link RawGltfData} * @throws IOException If an IO error occurs */ - public static RawGltfData readBinaryGltf(ByteBuffer data) - throws IOException { + public static RawGltfData readBinaryGltf(ByteBuffer data) + throws IOException + { int headerLength = BINARY_GLTF_VERSION_1_HEADER_LENGTH_IN_BYTES; - if (data.capacity() < headerLength) { + if (data.capacity() < headerLength) + { throw new IOException("Expected header of size " + headerLength - + ", but only found " + data.capacity() + " bytes"); + + ", but only found " + data.capacity() + " bytes"); } IntBuffer intData = data.asIntBuffer(); int length = intData.get(2); - if (length != data.capacity()) { + if (length != data.capacity()) + { throw new IOException( - "Data length is " + data.capacity() + ", expected " + length); + "Data length is " + data.capacity() + ", expected " + length); } - - int contentLength = intData.get(3); + + int contentLength = intData.get(3); int contentFormat = intData.get(4); - if (contentFormat != CONTENT_FORMAT_JSON) { + if (contentFormat != CONTENT_FORMAT_JSON) + { throw new IOException("Expected content format to be JSON (" - + CONTENT_FORMAT_JSON + "), but found " + contentFormat); + + CONTENT_FORMAT_JSON + "), but found " + contentFormat); } ByteBuffer contentData = Buffers.createSlice( - data, headerLength, contentLength); + data, headerLength, contentLength); int bodyByteOffset = headerLength + contentLength; int bodyByteLength = length - bodyByteOffset; ByteBuffer bodyData = null; - if (bodyByteLength > 0) { - bodyData = Buffers.create(bodyByteLength); - Buffers.bufferCopy(data, bodyByteOffset, bodyData, 0, bodyByteLength); + if (bodyByteLength > 0) + { + bodyData = Buffers.create(bodyByteLength); + Buffers.bufferCopy(data, bodyByteOffset, bodyData, 0, bodyByteLength); } - + return new RawGltfData(contentData, bodyData); } + + /** + * Private constructor to prevent instantiation + */ + private RawBinaryGltfDataReaderV1() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/BinaryAssetCreatorV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/BinaryAssetCreatorV2.java index aebf7c9..6f210c9 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/BinaryAssetCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/BinaryAssetCreatorV2.java @@ -26,6 +26,15 @@ */ package de.javagl.jgltf.model.io.v2; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; +import java.util.stream.Collectors; + import de.javagl.jgltf.impl.v2.Buffer; import de.javagl.jgltf.impl.v2.BufferView; import de.javagl.jgltf.impl.v2.GlTF; @@ -38,105 +47,47 @@ import de.javagl.jgltf.model.io.MimeTypes; import de.javagl.jgltf.model.v2.GltfCreatorV2; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.logging.Logger; -import java.util.stream.Collectors; - /** - * A class for creating a binary {@link GltfAssetV2} from a + * A class for creating a binary {@link GltfAssetV2} from a * {@link GltfModel}.
*
*/ -final class BinaryAssetCreatorV2 { +final class BinaryAssetCreatorV2 +{ /** * The logger used in this class */ private static final Logger logger = - Logger.getLogger(BinaryAssetCreatorV2.class.getName()); - + Logger.getLogger(BinaryAssetCreatorV2.class.getName()); + /** * Creates a new asset creator */ - BinaryAssetCreatorV2() { + BinaryAssetCreatorV2() + { // Default constructor } - - /** - * Compute the total size that is required for the binary glTF buffer - * for the given {@link GltfModel}, which is the sum of all buffer - * sizes of all buffers and images - * - * @param gltfModel The {@link GltfModel} - * @return The total size for the binary glTF buffer - */ - private static int computeBinaryGltfBufferSize(GltfModel gltfModel) { - int binaryGltfBufferSize = 0; - for (BufferModel bufferModel : gltfModel.getBufferModels()) { - ByteBuffer bufferData = bufferModel.getBufferData(); - binaryGltfBufferSize += bufferData.capacity(); - } - for (ImageModel imageModel : gltfModel.getImageModels()) { - ByteBuffer imageData = imageModel.getImageData(); - binaryGltfBufferSize += imageData.capacity(); - } - return binaryGltfBufferSize; - } - - /** - * Put the contents of all byte buffers of the given list into the given - * target buffer. This method assumes that the target buffer has a - * sufficient capacity to hold all buffers. - * - * @param buffers The buffers - * @param targetBuffer The target buffer - * @return A mapping from each key to the offset inside the target buffer - */ - private static Map concatBuffers( - List buffers, ByteBuffer targetBuffer) { - Map offsets = new LinkedHashMap(); - for (int i = 0; i < buffers.size(); i++) { - ByteBuffer oldByteBuffer = buffers.get(i); - int offset = targetBuffer.position(); - offsets.put(i, offset); - targetBuffer.put(oldByteBuffer.slice()); - } - return offsets; - } - - /** - * Creates a copy of the given list. If the given list is null, - * then an unmodifiable empty list will be returned - * - * @param list The input list - * @return The copy - */ - private static List copy(List list) { - if (list == null) { - return Collections.emptyList(); - } - return new ArrayList(list); - } - + /** * Create a binary {@link GltfAssetV2} from the given {@link GltfModel}. * The resulting asset will have a {@link GlTF} that uses references to * {@link BufferView} objects in its {@link Buffer} and {@link Image} - * elements. - * + * elements. + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV2} */ - GltfAssetV2 create(GltfModel gltfModel) { + GltfAssetV2 create(GltfModel gltfModel) + { GlTF outputGltf = GltfCreatorV2.create(gltfModel); - + // Create the new byte buffer for the data of the "binary_glTF" Buffer - int binaryGltfBufferSize = - computeBinaryGltfBufferSize(gltfModel); - ByteBuffer binaryGltfByteBuffer = - Buffers.create(binaryGltfBufferSize); + int binaryGltfBufferSize = + computeBinaryGltfBufferSize(gltfModel); + ByteBuffer binaryGltfByteBuffer = + Buffers.create(binaryGltfBufferSize); - // Create the binary Buffer, + // Create the binary Buffer, Buffer binaryGltfBuffer = new Buffer(); binaryGltfBuffer.setByteLength(binaryGltfBufferSize); outputGltf.setBuffers(Collections.singletonList(binaryGltfBuffer)); @@ -144,30 +95,31 @@ GltfAssetV2 create(GltfModel gltfModel) { // Create a defensive copy of the original image list List oldImages = copy(outputGltf.getImages()); - // Place the data from buffers and images into the new binary glTF - // buffer. The mappings from IDs to offsets inside the resulting + // Place the data from buffers and images into the new binary glTF + // buffer. The mappings from IDs to offsets inside the resulting // buffer will be used to compute the offsets for the buffer views - List bufferDatas = - gltfModel.getBufferModels().stream() - .map(BufferModel::getBufferData) - .collect(Collectors.toList()); + List bufferDatas = + gltfModel.getBufferModels().stream() + .map(BufferModel::getBufferData) + .collect(Collectors.toList()); Map bufferOffsets = concatBuffers( - bufferDatas, binaryGltfByteBuffer); - List imageDatas = - gltfModel.getImageModels().stream() - .map(ImageModel::getImageData) - .collect(Collectors.toList()); + bufferDatas, binaryGltfByteBuffer); + List imageDatas = + gltfModel.getImageModels().stream() + .map(ImageModel::getImageData) + .collect(Collectors.toList()); Map imageOffsets = concatBuffers( - imageDatas, binaryGltfByteBuffer); + imageDatas, binaryGltfByteBuffer); binaryGltfByteBuffer.position(0); - // For all existing BufferViews, create new ones that are updated to + // For all existing BufferViews, create new ones that are updated to // refer to the new binary glTF buffer, with the appropriate offset - List oldBufferViews = - copy(outputGltf.getBufferViews()); - List newBufferViews = - new ArrayList(); - for (int i = 0; i < oldBufferViews.size(); i++) { + List oldBufferViews = + copy(outputGltf.getBufferViews()); + List newBufferViews = + new ArrayList(); + for (int i = 0; i < oldBufferViews.size(); i++) + { BufferView oldBufferView = oldBufferViews.get(i); BufferView newBufferView = GltfUtilsV2.copy(oldBufferView); @@ -181,11 +133,12 @@ GltfAssetV2 create(GltfModel gltfModel) { newBufferViews.add(newBufferView); } - // For all existing Images, create new ones that are updated to - // refer to the new binary glTF buffer, using a bufferView + // For all existing Images, create new ones that are updated to + // refer to the new binary glTF buffer, using a bufferView // index that refers to a newly created BufferView List newImages = new ArrayList(); - for (int i = 0; i < oldImages.size(); i++) { + for (int i = 0; i < oldImages.size(); i++) + { Image oldImage = oldImages.get(i); Image newImage = GltfUtilsV2.copy(oldImage); @@ -202,30 +155,100 @@ GltfAssetV2 create(GltfModel gltfModel) { int newBufferViewIndex = newBufferViews.size(); newImage.setBufferView(newBufferViewIndex); newImage.setUri(null); - + String imageMimeTypeString = - MimeTypes.guessImageMimeTypeString( - oldImage.getUri(), imageData); - if (imageMimeTypeString == null) { + MimeTypes.guessImageMimeTypeString( + oldImage.getUri(), imageData); + if (imageMimeTypeString == null) + { logger.warning("Could not detect MIME type of image"); - } else { + } + else + { newImage.setMimeType(imageMimeTypeString); } - + newBufferViews.add(imageBufferView); newImages.add(newImage); } // Place the newly created lists into the output glTF, // if there have been non-null lists for them in the input - if (!oldImages.isEmpty()) { + if (!oldImages.isEmpty()) + { outputGltf.setImages(newImages); } - if (!newBufferViews.isEmpty()) { + if (!newBufferViews.isEmpty()) + { outputGltf.setBufferViews(newBufferViews); } return new GltfAssetV2(outputGltf, binaryGltfByteBuffer); } + /** + * Compute the total size that is required for the binary glTF buffer + * for the given {@link GltfModel}, which is the sum of all buffer + * sizes of all buffers and images + * + * @param gltfModel The {@link GltfModel} + * @return The total size for the binary glTF buffer + */ + private static int computeBinaryGltfBufferSize(GltfModel gltfModel) + { + int binaryGltfBufferSize = 0; + for (BufferModel bufferModel : gltfModel.getBufferModels()) + { + ByteBuffer bufferData = bufferModel.getBufferData(); + binaryGltfBufferSize += bufferData.capacity(); + } + for (ImageModel imageModel : gltfModel.getImageModels()) + { + ByteBuffer imageData = imageModel.getImageData(); + binaryGltfBufferSize += imageData.capacity(); + } + return binaryGltfBufferSize; + } + + /** + * Put the contents of all byte buffers of the given list into the given + * target buffer. This method assumes that the target buffer has a + * sufficient capacity to hold all buffers. + * + * @param buffers The buffers + * @param targetBuffer The target buffer + * @return A mapping from each key to the offset inside the target buffer + */ + private static Map concatBuffers( + List buffers, ByteBuffer targetBuffer) + { + Map offsets = new LinkedHashMap(); + for (int i = 0; i < buffers.size(); i++) + { + ByteBuffer oldByteBuffer = buffers.get(i); + int offset = targetBuffer.position(); + offsets.put(i, offset); + targetBuffer.put(oldByteBuffer.slice()); + } + return offsets; + } + + + /** + * Creates a copy of the given list. If the given list is null, + * then an unmodifiable empty list will be returned + * + * @param list The input list + * @return The copy + */ + private static List copy(List list) + { + if (list == null) + { + return Collections.emptyList(); + } + return new ArrayList(list); + } + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/DefaultAssetCreatorV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/DefaultAssetCreatorV2.java index 953a7e4..e50759f 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/DefaultAssetCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/DefaultAssetCreatorV2.java @@ -26,6 +26,14 @@ */ package de.javagl.jgltf.model.io.v2; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + import de.javagl.jgltf.impl.v2.Buffer; import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.impl.v2.Image; @@ -38,29 +46,22 @@ import de.javagl.jgltf.model.io.IO; import de.javagl.jgltf.model.v2.GltfCreatorV2; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - /** - * A class for creating a {@link GltfAssetV2} with a default data + * A class for creating a {@link GltfAssetV2} with a default data * representation from a {@link GltfModel}.
*
- * In the default data representation, elements are referred to via URIs. + * In the default data representation, elements are referred to via URIs. * Data elements like {@link Buffer} or {@link Image} - * objects that used the binary glTF extension or data URIs will be + * objects that used the binary glTF extension or data URIs will be * converted to refer to their data using URIs. */ -final class DefaultAssetCreatorV2 { +final class DefaultAssetCreatorV2 +{ /** * The {@link GltfAssetV2} that is currently being created */ private GltfAssetV2 gltfAsset; - + /** * The set of {@link Buffer} URI strings that are already used */ @@ -74,50 +75,36 @@ final class DefaultAssetCreatorV2 { /** * Creates a new asset creator */ - DefaultAssetCreatorV2() { + DefaultAssetCreatorV2() + { // Default constructor } - /** - * Collect all strings that are obtained from the given elements by - * applying the given function, if these strings are not null - * and no data URI strings - * - * @param elements The elements - * @param uriFunction The function to obtain the string - * @return The strings - */ - private static Set collectUriStrings(Collection elements, - Function uriFunction) { - return elements.stream() - .map(uriFunction) - .filter(Objects::nonNull) - .filter(uriString -> !IO.isDataUriString(uriString)) - .collect(Collectors.toSet()); - } - /** * Create a default {@link GltfAssetV2} from the given {@link GltfModel}. - * + * * @param gltfModel The input {@link GltfModel} * @return The default {@link GltfAssetV2} */ - GltfAssetV2 create(GltfModel gltfModel) { + GltfAssetV2 create(GltfModel gltfModel) + { GlTF outputGltf = GltfCreatorV2.create(gltfModel); List buffers = Optionals.of(outputGltf.getBuffers()); List images = Optionals.of(outputGltf.getImages()); - + existingBufferUriStrings = collectUriStrings(buffers, Buffer::getUri); existingImageUriStrings = collectUriStrings(images, Image::getUri); this.gltfAsset = new GltfAssetV2(outputGltf, null); - - for (int i = 0; i < buffers.size(); i++) { + + for (int i = 0; i < buffers.size(); i++) + { Buffer buffer = buffers.get(i); storeBufferAsDefault(gltfModel, i, buffer); } - for (int i = 0; i < images.size(); i++) { + for (int i = 0; i < images.size(); i++) + { Image image = images.get(i); storeImageAsDefault(gltfModel, i, image); } @@ -126,75 +113,99 @@ GltfAssetV2 create(GltfModel gltfModel) { } /** - * Store the given {@link Buffer} with the given index in the current + * Collect all strings that are obtained from the given elements by + * applying the given function, if these strings are not null + * and no data URI strings + * + * @param elements The elements + * @param uriFunction The function to obtain the string + * @return The strings + */ + private static Set collectUriStrings(Collection elements, + Function uriFunction) + { + return elements.stream() + .map(uriFunction) + .filter(Objects::nonNull) + .filter(uriString -> !IO.isDataUriString(uriString)) + .collect(Collectors.toSet()); + } + + /** + * Store the given {@link Buffer} with the given index in the current * output asset.
*
- * If the {@link Buffer#getUri() buffer URI} is null or a - * data URI, it will receive a new URI, which refers to the buffer data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Buffer#getUri() buffer URI} is null or a + * data URI, it will receive a new URI, which refers to the buffer data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
- * The given {@link Buffer} object will be modified accordingly, if - * necessary: Its URI will be set to be the new URI. - * - * @param gltfModel The {@link GltfModel} - * @param index The index of the {@link Buffer} - * @param buffer The {@link Buffer} + * The given {@link Buffer} object will be modified accordingly, if + * necessary: Its URI will be set to be the new URI. + * + * @param gltfModel The {@link GltfModel} + * @param index The index of the {@link Buffer} + * @param buffer The {@link Buffer} */ private void storeBufferAsDefault( - GltfModel gltfModel, int index, Buffer buffer) { + GltfModel gltfModel, int index, Buffer buffer) + { BufferModel bufferModel = gltfModel.getBufferModels().get(index); ByteBuffer bufferData = bufferModel.getBufferData(); String oldUriString = buffer.getUri(); String newUriString = oldUriString; - if (oldUriString == null || IO.isDataUriString(oldUriString)) { + if (oldUriString == null || IO.isDataUriString(oldUriString)) + { newUriString = UriStrings.createBufferUriString( - existingBufferUriStrings); + existingBufferUriStrings); buffer.setUri(newUriString); existingBufferUriStrings.add(newUriString); } - + gltfAsset.putReferenceData(newUriString, bufferData); } - + /** - * Store the given {@link Image} with the given index in the current + * Store the given {@link Image} with the given index in the current * output asset.
*
- * If the {@link Image#getUri() image URI} is null or a - * data URI, it will receive a new URI, which refers to the image data, - * which is then stored as {@link GltfAsset#getReferenceData(String) + * If the {@link Image#getUri() image URI} is null or a + * data URI, it will receive a new URI, which refers to the image data, + * which is then stored as {@link GltfAsset#getReferenceData(String) * reference data} in the asset.
*
- * The given {@link Image} object will be modified accordingly, if + * The given {@link Image} object will be modified accordingly, if * necessary: Its URI will be set to be the new URI. If it referred * to a {@link Image#getBufferView() image buffer view}, then this * reference will be set to be null. - * - * @param gltfModel The {@link GltfModel} - * @param index The index of the {@link Image} - * @param image The {@link Image} + * + * @param gltfModel The {@link GltfModel} + * @param index The index of the {@link Image} + * @param image The {@link Image} */ private void storeImageAsDefault( - GltfModel gltfModel, int index, Image image) { + GltfModel gltfModel, int index, Image image) + { ImageModel imageModel = gltfModel.getImageModels().get(index); ByteBuffer imageData = imageModel.getImageData(); String oldUriString = image.getUri(); String newUriString = oldUriString; - if (oldUriString == null || IO.isDataUriString(oldUriString)) { + if (oldUriString == null || IO.isDataUriString(oldUriString)) + { newUriString = UriStrings.createImageUriString( - imageModel, existingImageUriStrings); + imageModel, existingImageUriStrings); image.setUri(newUriString); existingImageUriStrings.add(newUriString); } - - if (image.getBufferView() != null) { + + if (image.getBufferView() != null) + { image.setBufferView(null); } - + gltfAsset.putReferenceData(newUriString, imageData); } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/EmbeddedAssetCreatorV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/EmbeddedAssetCreatorV2.java index 5e41d68..f09f961 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/EmbeddedAssetCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/EmbeddedAssetCreatorV2.java @@ -26,127 +26,141 @@ */ package de.javagl.jgltf.model.io.v2; +import java.nio.ByteBuffer; +import java.util.Base64; +import java.util.List; + import de.javagl.jgltf.impl.v2.Buffer; import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.impl.v2.Image; -import de.javagl.jgltf.model.*; +import de.javagl.jgltf.model.BufferModel; +import de.javagl.jgltf.model.GltfException; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.ImageModel; +import de.javagl.jgltf.model.Optionals; import de.javagl.jgltf.model.io.GltfAsset; import de.javagl.jgltf.model.io.IO; import de.javagl.jgltf.model.io.MimeTypes; import de.javagl.jgltf.model.v2.GltfCreatorV2; -import java.nio.ByteBuffer; -import java.util.Base64; -import java.util.List; - /** - * A class for creating a {@link GltfAssetV2} with an "embedded" data + * A class for creating a {@link GltfAssetV2} with an "embedded" data * representation from a {@link GltfModel}.
*
- * In the "embedded" data representation, the data of elements like + * In the "embedded" data representation, the data of elements like * {@link Buffer} or {@link Image} objects is stored in data URIs. */ -final class EmbeddedAssetCreatorV2 { +final class EmbeddedAssetCreatorV2 +{ /** * Creates a new asset creator */ - EmbeddedAssetCreatorV2() { + EmbeddedAssetCreatorV2() + { // Default constructor } /** - * Convert the given {@link Buffer} into an embedded buffer, by replacing + * Create a {@link GltfAssetV2} with "embedded" data representation from + * the given {@link GltfModel}.
+ *
+ * The returned {@link GltfAssetV2} will contain a {@link GlTF} where the + * the URIs that appear in {@link Buffer} and {@link Image} instances are + * replaced with data URIs that contain the corresponding data. + * Its {@link GltfAsset#getBinaryData() binary data} will be + * null, and its {@link GltfAsset#getReferenceDatas() + * reference data elements} will be empty. + * + * @param gltfModel The input {@link GltfModel} + * @return The embedded {@link GltfAssetV2} + */ + GltfAssetV2 create(GltfModel gltfModel) + { + GlTF outputGltf = GltfCreatorV2.create(gltfModel); + + List buffers = Optionals.of(outputGltf.getBuffers()); + for (int i = 0; i < buffers.size(); i++) + { + Buffer buffer = buffers.get(i); + convertBufferToEmbedded(gltfModel, i, buffer); + } + + List images = Optionals.of(outputGltf.getImages()); + for (int i = 0; i < images.size(); i++) + { + Image image = images.get(i); + convertImageToEmbedded(gltfModel, i, image); + } + + return new GltfAssetV2(outputGltf, null); + } + + /** + * Convert the given {@link Buffer} into an embedded buffer, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModel} - * @param index The index of the {@link Buffer} - * @param buffer The {@link Buffer} + * @param index The index of the {@link Buffer} + * @param buffer The {@link Buffer} */ private static void convertBufferToEmbedded( - GltfModel gltfModel, int index, Buffer buffer) { + GltfModel gltfModel, int index, Buffer buffer) + { String uriString = buffer.getUri(); - if (IO.isDataUriString(uriString)) { + if (IO.isDataUriString(uriString)) + { return; } BufferModel bufferModel = gltfModel.getBufferModels().get(index); ByteBuffer bufferData = bufferModel.getBufferData(); - + byte data[] = new byte[bufferData.capacity()]; bufferData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); - String dataUriString = - "data:application/gltf-buffer;base64," + encodedData; - + String dataUriString = + "data:application/gltf-buffer;base64," + encodedData; + buffer.setUri(dataUriString); } /** - * Convert the given {@link Image} into an embedded image, by replacing + * Convert the given {@link Image} into an embedded image, by replacing * its URI with a data URI, if the URI is not already a data URI - * + * * @param gltfModel The {@link GltfModel} - * @param index The index of the {@link Image} - * @param image The {@link Image} + * @param index The index of the {@link Image} + * @param image The {@link Image} * @throws GltfException If the image format (and thus, the MIME type) - * can not be determined from the image data + * can not be determined from the image data */ private static void convertImageToEmbedded( - GltfModel gltfModel, int index, Image image) { + GltfModel gltfModel, int index, Image image) + { String uriString = image.getUri(); - if (IO.isDataUriString(uriString)) { + if (IO.isDataUriString(uriString)) + { return; } ImageModel imageModel = gltfModel.getImageModels().get(index); ByteBuffer imageData = imageModel.getImageData(); - + String uri = image.getUri(); String imageMimeTypeString = - MimeTypes.guessImageMimeTypeString(uri, imageData); - if (imageMimeTypeString == null) { + MimeTypes.guessImageMimeTypeString(uri, imageData); + if (imageMimeTypeString == null) + { throw new GltfException( - "Could not detect MIME type of image " + index); + "Could not detect MIME type of image " + index); } byte data[] = new byte[imageData.capacity()]; imageData.slice().get(data); String encodedData = Base64.getEncoder().encodeToString(data); String dataUriString = - "data:" + imageMimeTypeString + ";base64," + encodedData; - + "data:" + imageMimeTypeString + ";base64," + encodedData; + image.setUri(dataUriString); } - /** - * Create a {@link GltfAssetV2} with "embedded" data representation from - * the given {@link GltfModel}.
- *
- * The returned {@link GltfAssetV2} will contain a {@link GlTF} where the - * the URIs that appear in {@link Buffer} and {@link Image} instances are - * replaced with data URIs that contain the corresponding data. - * Its {@link GltfAsset#getBinaryData() binary data} will be - * null, and its {@link GltfAsset#getReferenceDatas() - * reference data elements} will be empty. - * - * @param gltfModel The input {@link GltfModel} - * @return The embedded {@link GltfAssetV2} - */ - GltfAssetV2 create(GltfModel gltfModel) { - GlTF outputGltf = GltfCreatorV2.create(gltfModel); - - List buffers = Optionals.of(outputGltf.getBuffers()); - for (int i = 0; i < buffers.size(); i++) { - Buffer buffer = buffers.get(i); - convertBufferToEmbedded(gltfModel, i, buffer); - } - - List images = Optionals.of(outputGltf.getImages()); - for (int i = 0; i < images.size(); i++) { - Image image = images.get(i); - convertImageToEmbedded(gltfModel, i, image); - } - - return new GltfAssetV2(outputGltf, null); - } - } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetV2.java index 94c7e32..e5914b2 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetV2.java @@ -26,6 +26,15 @@ */ package de.javagl.jgltf.model.io.v2; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + import de.javagl.jgltf.impl.v2.Buffer; import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.impl.v2.Image; @@ -35,20 +44,16 @@ import de.javagl.jgltf.model.io.GltfReference; import de.javagl.jgltf.model.io.IO; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - /** * Implementation of the {@link GltfAsset} interface for glTF 2.0. */ -public final class GltfAssetV2 implements GltfAsset { +public final class GltfAssetV2 implements GltfAsset +{ /** * The {@link GlTF} */ private final GlTF gltf; - + /** * The optional binary data */ @@ -58,114 +63,132 @@ public final class GltfAssetV2 implements GltfAsset { * The mapping from (relative) URI strings to the associated external data */ private final Map referenceDatas; - + /** * Creates a new instance - * - * @param gltf The {@link GlTF} + * + * @param gltf The {@link GlTF} * @param binaryData The optional binary data */ - public GltfAssetV2(GlTF gltf, ByteBuffer binaryData) { + public GltfAssetV2(GlTF gltf, ByteBuffer binaryData) + { this.gltf = Objects.requireNonNull(gltf, "The gltf may not be null"); this.binaryData = binaryData; this.referenceDatas = new ConcurrentHashMap(); } - + /** * Store the given byte buffer under the given (relative) URI string - * - * @param uriString The URI string + * + * @param uriString The URI string * @param byteBuffer The byte buffer */ - void putReferenceData(String uriString, ByteBuffer byteBuffer) { - if (byteBuffer == null) { + void putReferenceData(String uriString, ByteBuffer byteBuffer) + { + if (byteBuffer == null) + { referenceDatas.remove(uriString); - } else { + } + else + { referenceDatas.put(uriString, byteBuffer); } } - + @Override - public GlTF getGltf() { + public GlTF getGltf() + { return gltf; } - + @Override - public ByteBuffer getBinaryData() { + public ByteBuffer getBinaryData() + { return Buffers.createSlice(binaryData); } - + @Override - public List getReferences() { + public List getReferences() + { List references = new ArrayList(); references.addAll(getBufferReferences()); references.addAll(getImageReferences()); return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * buffers that are contained in this model. - * + * * @return The references */ - public List getBufferReferences() { + public List getBufferReferences() + { List references = new ArrayList(); List buffers = Optionals.of(gltf.getBuffers()); - for (int i = 0; i < buffers.size(); i++) { + for (int i = 0; i < buffers.size(); i++) + { Buffer buffer = buffers.get(i); - if (buffer.getUri() == null) { + if (buffer.getUri() == null) + { // This is the binary glTF buffer continue; } String uri = buffer.getUri(); - if (!IO.isDataUriString(uri)) { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); + if (!IO.isDataUriString(uri)) + { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); GltfReference reference = - new GltfReference("buffer " + i, uri, target); + new GltfReference("buffer " + i, uri, target); references.add(reference); } } return references; } - + /** * Create a list containing all {@link GltfReference} objects for the * images that are contained in this model. - * + * * @return The references */ - public List getImageReferences() { + public List getImageReferences() + { List references = new ArrayList(); List images = Optionals.of(gltf.getImages()); - for (int i = 0; i < images.size(); i++) { + for (int i = 0; i < images.size(); i++) + { Image image = images.get(i); - if (image.getBufferView() != null) { + if (image.getBufferView() != null) + { // This is an image that refers to a buffer view continue; } String uri = image.getUri(); - if (!IO.isDataUriString(uri)) { - Consumer target = - byteBuffer -> putReferenceData(uri, byteBuffer); - GltfReference reference = - new GltfReference("image " + i, uri, target); + if (!IO.isDataUriString(uri)) + { + Consumer target = + byteBuffer -> putReferenceData(uri, byteBuffer); + GltfReference reference = + new GltfReference("image " + i, uri, target); references.add(reference); } } return references; } - + @Override - public ByteBuffer getReferenceData(String uriString) { + public ByteBuffer getReferenceData(String uriString) + { return Buffers.createSlice(referenceDatas.get(uriString)); } @Override - public Map getReferenceDatas() { + public Map getReferenceDatas() + { return Collections.unmodifiableMap(referenceDatas); } - - + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetWriterV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetWriterV2.java index 89f1ec5..231f1bb 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetWriterV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetWriterV2.java @@ -26,11 +26,6 @@ */ package de.javagl.jgltf.model.io.v2; -import de.javagl.jgltf.impl.v2.GlTF; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.io.GltfAssetWriter; -import de.javagl.jgltf.model.io.GltfWriter; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -39,19 +34,25 @@ import java.nio.channels.WritableByteChannel; import java.util.Arrays; +import de.javagl.jgltf.impl.v2.GlTF; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.io.GltfAssetWriter; +import de.javagl.jgltf.model.io.GltfWriter; + /** * A class for writing a glTF 2.0 asset in binary format to an output stream. - * This class contains implementations for the methods of the - * {@link GltfAssetWriter}, for glTF 2.0 assets. Clients should not use this + * This class contains implementations for the methods of the + * {@link GltfAssetWriter}, for glTF 2.0 assets. Clients should not use this * class directly, but only the {@link GltfAssetWriter}. */ -public final class GltfAssetWriterV2 { +public final class GltfAssetWriterV2 +{ /** * The magic binary glTF header. * This is an integer corresponding to the ASCII string "glTF" */ private static final int MAGIC_BINARY_GLTF_HEADER = 0x46546C67; - + /** * The binary glTF version that is written by this writer */ @@ -62,60 +63,67 @@ public final class GltfAssetWriterV2 { * This is an integer corresponding to the ASCII string "JSON" */ private static final int CHUNK_TYPE_JSON = 0x4E4F534A; - + /** * The constant indicating BIN chunk type for glTF 2.0 * This is an integer corresponding to the ASCII string "BIN" */ private static final int CHUNK_TYPE_BIN = 0x004E4942; - + /** * Default constructor */ - public GltfAssetWriterV2() { + public GltfAssetWriterV2() + { // Default constructor } - + /** - * Write the given {@link GltfAssetV2} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * Write the given {@link GltfAssetV2} as a binary glTF asset to the + * given output stream. The caller is responsible for closing the * given stream.
*
- * - * @param gltfAsset The {@link GltfAssetV2} + * + * @param gltfAsset The {@link GltfAssetV2} * @param outputStream The output stream * @throws IOException If an IO error occurred */ - public void writeBinary(GltfAssetV2 gltfAsset, OutputStream outputStream) - throws IOException { + public void writeBinary(GltfAssetV2 gltfAsset, OutputStream outputStream) + throws IOException + { // Write the JSON representation of the glTF GlTF gltf = gltfAsset.getGltf(); byte jsonData[]; - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) + { GltfWriter gltfWriter = new GltfWriter(); gltfWriter.setIndenting(false); gltfWriter.write(gltf, baos); jsonData = baos.toByteArray(); } // Ensure 4-byte-alignment for the jsonData - if (jsonData.length % 4 != 0) { + if (jsonData.length % 4 != 0) + { int oldLength = jsonData.length; int padding = 4 - (oldLength % 4); jsonData = Arrays.copyOf(jsonData, oldLength + padding); - for (int i = 0; i < padding; i++) { + for (int i = 0; i < padding; i++) + { jsonData[oldLength + i] = ' '; } } - + // Obtain the binary data, and ensure it's 4-byte aligned ByteBuffer binaryData = gltfAsset.getBinaryData(); - if (binaryData == null) { + if (binaryData == null) + { binaryData = ByteBuffer.wrap(new byte[0]); } - if (binaryData.capacity() % 4 != 0) { + if (binaryData.capacity() % 4 != 0) + { int padding = 4 - (binaryData.capacity() % 4); - binaryData = - Buffers.copyOf(binaryData, binaryData.capacity() + padding); + binaryData = + Buffers.copyOf(binaryData, binaryData.capacity() + padding); } // Create the JSON chunk data @@ -123,24 +131,24 @@ public void writeBinary(GltfAssetV2 gltfAsset, OutputStream outputStream) jsonChunkData.append(jsonData.length); jsonChunkData.append(CHUNK_TYPE_JSON); jsonChunkData.append(ByteBuffer.wrap(jsonData)); - + // Create the BIN chunk data ChunkData binChunkData = new ChunkData(); binChunkData.append(binaryData.capacity()); binChunkData.append(CHUNK_TYPE_BIN); binChunkData.append(binaryData); - + // Create the header data ChunkData headerData = new ChunkData(); headerData.append(MAGIC_BINARY_GLTF_HEADER); headerData.append(BINARY_GLTF_VERSION); int length = 12 + jsonData.length + 8 + binaryData.capacity() + 8; headerData.append(length); - + // Finally, write the header, JSON and BIN data to the output stream @SuppressWarnings("resource") - WritableByteChannel writableByteChannel = - Channels.newChannel(outputStream); + WritableByteChannel writableByteChannel = + Channels.newChannel(outputStream); writableByteChannel.write(headerData.get()); writableByteChannel.write(jsonChunkData.get()); writableByteChannel.write(binChunkData.get()); @@ -149,55 +157,61 @@ public void writeBinary(GltfAssetV2 gltfAsset, OutputStream outputStream) /** * Utility class for collecting the data of one binary glTF 2.0 chunk */ - private static class ChunkData { + private static class ChunkData + { /** * The stream that will collect the data */ private ByteArrayOutputStream baos; - + /** * Default constructor */ - ChunkData() { + ChunkData() + { baos = new ByteArrayOutputStream(); } - + /** * Append the given value to this data - * + * * @param value The value * @throws IOException If an IO error occurs */ - void append(int value) throws IOException { + void append(int value) throws IOException + { baos.write((value >> 0) & 0xFF); baos.write((value >> 8) & 0xFF); baos.write((value >> 16) & 0xFF); baos.write((value >> 24) & 0xFF); } - + /** * Append the given buffer to this data - * + * * @param buffer The buffer * @throws IOException If an IO error occurs */ - void append(ByteBuffer buffer) throws IOException { + void append(ByteBuffer buffer) throws IOException + { @SuppressWarnings("resource") - WritableByteChannel writableByteChannel = - Channels.newChannel(baos); + WritableByteChannel writableByteChannel = + Channels.newChannel(baos); writableByteChannel.write(buffer.slice()); } - + /** * Returns the chunk data as a (non-direct!) buffer - * + * * @return The chunk data */ - ByteBuffer get() { + ByteBuffer get() + { return ByteBuffer.wrap(baos.toByteArray()); } - + } - - + + + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetsV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetsV2.java index 485fcc1..2f5cd50 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetsV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfAssetsV2.java @@ -34,52 +34,59 @@ * This class should not be considered as part of the public API. It may * change or be omitted in the future. */ -public class GltfAssetsV2 { +public class GltfAssetsV2 +{ /** - * Private constructor to prevent instantiation - */ - private GltfAssetsV2() { - // Private constructor to prevent instantiation - } - - /** - * Create a new default {@link GltfAssetV2} from the given + * Create a new default {@link GltfAssetV2} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV2} */ - public static GltfAssetV2 createDefault(GltfModel gltfModel) { + public static GltfAssetV2 createDefault(GltfModel gltfModel) + { DefaultAssetCreatorV2 assetCreator = new DefaultAssetCreatorV2(); GltfAssetV2 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - + /** - * Create a new binary {@link GltfAssetV2} from the given + * Create a new binary {@link GltfAssetV2} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV2} */ - public static GltfAssetV2 createBinary(GltfModel gltfModel) { + public static GltfAssetV2 createBinary(GltfModel gltfModel) + { BinaryAssetCreatorV2 assetCreator = new BinaryAssetCreatorV2(); GltfAssetV2 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } - + /** - * Create a new embedded {@link GltfAssetV2} from the given + * Create a new embedded {@link GltfAssetV2} from the given * {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} * @return The {@link GltfAssetV2} */ - public static GltfAssetV2 createEmbedded(GltfModel gltfModel) { + public static GltfAssetV2 createEmbedded(GltfModel gltfModel) + { EmbeddedAssetCreatorV2 assetCreator = new EmbeddedAssetCreatorV2(); GltfAssetV2 gltfAsset = assetCreator.create(gltfModel); return gltfAsset; } + + + + /** + * Private constructor to prevent instantiation + */ + private GltfAssetsV2() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfModelWriterV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfModelWriterV2.java index 4deb205..1d88259 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfModelWriterV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfModelWriterV2.java @@ -26,75 +26,80 @@ */ package de.javagl.jgltf.model.io.v2; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.model.GltfModel; import de.javagl.jgltf.model.io.GltfAssetWriter; import de.javagl.jgltf.model.io.GltfModelWriter; import de.javagl.jgltf.model.io.GltfWriter; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; - /** - * A class for writing a {@link GltfModel}. This class contains + * A class for writing a {@link GltfModel}. This class contains * implementations for the methods of the {@link GltfModelWriter}, * for glTF 2.0 assets. Clients should not use this class directly, * but only the {@link GltfModelWriter}. */ -public final class GltfModelWriterV2 { +public final class GltfModelWriterV2 +{ /** * Default constructor */ - public GltfModelWriterV2() { + public GltfModelWriterV2() + { // Default constructor } - + /** * Write the given {@link GltfModel} to the given file. External - * references of buffers and images that are given via the respective - * URI string will be resolved against the parent directory of the - * given file, and the corresponding data will be written into - * the corresponding files. - * + * references of buffers and images that are given via the respective + * URI string will be resolved against the parent directory of the + * given file, and the corresponding data will be written into + * the corresponding files. + * * @param gltfModel The {@link GltfModel} - * @param file The file + * @param file The file * @throws IOException If an IO error occurs */ - public void write(GltfModel gltfModel, File file) - throws IOException { + public void write(GltfModel gltfModel, File file) + throws IOException + { GltfAssetV2 gltfAsset = GltfAssetsV2.createDefault(gltfModel); GltfAssetWriter gltfAssetWriter = new GltfAssetWriter(); gltfAssetWriter.write(gltfAsset, file); } - + /** * Write the given {@link GltfModel} as a binary glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeBinary(GltfModel gltfModel, OutputStream outputStream) - throws IOException { + public void writeBinary(GltfModel gltfModel, OutputStream outputStream) + throws IOException + { GltfAssetV2 gltfAsset = GltfAssetsV2.createBinary(gltfModel); GltfAssetWriterV2 gltfAssetWriter = new GltfAssetWriterV2(); gltfAssetWriter.writeBinary(gltfAsset, outputStream); } - + /** * Write the given {@link GltfModel} as an embedded glTF asset to the - * given output stream. The caller is responsible for closing the + * given output stream. The caller is responsible for closing the * given stream. - * - * @param gltfModel The {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} * @param outputStream The output stream * @throws IOException If an IO error occurs */ - public void writeEmbedded(GltfModel gltfModel, OutputStream outputStream) - throws IOException { + public void writeEmbedded(GltfModel gltfModel, OutputStream outputStream) + throws IOException + { GltfAssetV2 gltfAsset = GltfAssetsV2.createEmbedded(gltfModel); GltfWriter gltfWriter = new GltfWriter(); GlTF gltf = gltfAsset.getGltf(); diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfReaderV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfReaderV2.java index 6180e57..7c49229 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfReaderV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfReaderV2.java @@ -26,40 +26,44 @@ */ package de.javagl.jgltf.model.io.v2; -import com.google.gson.Gson; -import de.javagl.jgltf.impl.v2.GlTF; - import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import com.google.gson.Gson; + +import de.javagl.jgltf.impl.v2.GlTF; + /** * A class for reading a version 2.0 {@link GlTF} from an input stream */ -public final class GltfReaderV2 { +public final class GltfReaderV2 +{ // Note: This class could use GltfReader as a delegate, and could // then verify that the glTF has the right version. Right now, it // assumes that it is only used for glTF 2.0 inputs. - + /** * Creates a new glTF reader */ - public GltfReaderV2() { + public GltfReaderV2() + { // Default constructor } - + /** * Read the {@link GlTF} from the given stream - * + * * @param inputStream The input stream * @return The {@link GlTF} * @throws IOException If an IO error occurs */ - public GlTF read(InputStream inputStream) throws IOException { - InputStreamReader reader = new InputStreamReader(inputStream); - GlTF gltf = new Gson().fromJson(reader, GlTF.class); - reader.close(); + public GlTF read(InputStream inputStream) throws IOException + { + InputStreamReader reader = new InputStreamReader(inputStream); + GlTF gltf = new Gson().fromJson(reader, GlTF.class); + reader.close(); return gltf; } - + } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/GltfUtilsV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/GltfUtilsV2.java index fb2863b..f0a0934 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/GltfUtilsV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/GltfUtilsV2.java @@ -27,6 +27,7 @@ package de.javagl.jgltf.model.io.v2; import com.google.gson.Gson; + import de.javagl.jgltf.impl.v2.BufferView; import de.javagl.jgltf.impl.v2.GlTF; import de.javagl.jgltf.impl.v2.Image; @@ -35,14 +36,8 @@ /** * Utility methods related to {@link GlTF}s */ -class GltfUtilsV2 { - /** - * Private constructor to prevent instantiation - */ - private GltfUtilsV2() { - // Private constructor to prevent instantiation - } - +class GltfUtilsV2 +{ /** * Creates a deep copy of the given {@link GlTF}.
*
@@ -51,23 +46,25 @@ private GltfUtilsV2() { * in the copy. The goal of this method is to create a copy that is, * as far as reasonably possible, "structurally equivalent" to the * given input. - * - * @param gltf The input + * + * @param gltf The input * @return The copy * @throws GltfException If the copy can not be created */ - static GlTF copy(GlTF gltf) { - Gson gson = new Gson(); - return gson.fromJson(gson.toJsonTree(gltf, GlTF.class), GlTF.class); + static GlTF copy(GlTF gltf) + { + Gson gson = new Gson(); + return gson.fromJson(gson.toJsonTree(gltf, GlTF.class), GlTF.class); } /** * Creates a shallow copy of the given {@link BufferView} - * + * * @param bufferView The {@link BufferView} * @return The copy */ - static BufferView copy(BufferView bufferView) { + static BufferView copy(BufferView bufferView) + { BufferView copy = new BufferView(); copy.setExtensions(bufferView.getExtensions()); copy.setExtras(bufferView.getExtras()); @@ -79,14 +76,16 @@ static BufferView copy(BufferView bufferView) { copy.setByteStride(bufferView.getByteStride()); return copy; } - + + /** * Creates a shallow copy of the given {@link Image} - * + * * @param image The {@link Image} * @return The copy */ - static Image copy(Image image) { + static Image copy(Image image) + { Image copy = new Image(); copy.setExtensions(image.getExtensions()); copy.setExtras(image.getExtras()); @@ -96,4 +95,12 @@ static Image copy(Image image) { copy.setMimeType(image.getMimeType()); return copy; } + + /** + * Private constructor to prevent instantiation + */ + private GltfUtilsV2() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/io/v2/RawBinaryGltfDataReaderV2.java b/src/main/java/de/javagl/jgltf/model/io/v2/RawBinaryGltfDataReaderV2.java index 96eb258..f885c15 100644 --- a/src/main/java/de/javagl/jgltf/model/io/v2/RawBinaryGltfDataReaderV2.java +++ b/src/main/java/de/javagl/jgltf/model/io/v2/RawBinaryGltfDataReaderV2.java @@ -26,19 +26,20 @@ */ package de.javagl.jgltf.model.io.v2; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.io.RawGltfData; - import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.io.RawGltfData; + /** * A class for reading a {@link RawGltfData} from a buffer that contains * binary glTF 2.0 data. */ -public class RawBinaryGltfDataReaderV2 { +public class RawBinaryGltfDataReaderV2 +{ /** * The length of the binary glTF header for glTF 2.0, in bytes */ @@ -49,93 +50,119 @@ public class RawBinaryGltfDataReaderV2 { * This is an integer corresponding to the ASCII string "JSON" */ private static final int CHUNK_TYPE_JSON = 0x4E4F534A; - + /** * The constant indicating BIN chunk type for glTF 2.0 * This is an integer corresponding to the ASCII string "BIN" */ private static final int CHUNK_TYPE_BIN = 0x004E4942; - - /** - * Private constructor to prevent instantiation - */ - private RawBinaryGltfDataReaderV2() { - // Private constructor to prevent instantiation - } - + /** * Read the {@link RawGltfData} from the given buffer, which contains * the binary glTF 2.0 data - * + * * @param data The input data * @return The {@link RawGltfData} * @throws IOException If an IO error occurs */ - public static RawGltfData readBinaryGltf(ByteBuffer data) - throws IOException { + public static RawGltfData readBinaryGltf(ByteBuffer data) + throws IOException + { int headerLength = BINARY_GLTF_VERSION_2_HEADER_LENGTH_IN_BYTES; - if (data.capacity() < headerLength) { + if (data.capacity() < headerLength) + { throw new IOException("Expected header of size " + headerLength - + ", but only found " + data.capacity() + " bytes"); + + ", but only found " + data.capacity() + " bytes"); } int length = data.getInt(8); - if (length != data.capacity()) { + if (length != data.capacity()) + { throw new IOException( - "Data length is " + data.capacity() + ", expected " + length); + "Data length is " + data.capacity() + ", expected " + length); } - + List chunks = readChunks(data); - if (chunks.isEmpty()) { + if (chunks.isEmpty()) + { throw new IOException( - "Found no chunks in binary glTF data"); + "Found no chunks in binary glTF data"); } Chunk jsonChunk = chunks.get(0); - if (jsonChunk.type != CHUNK_TYPE_JSON) { + if (jsonChunk.type != CHUNK_TYPE_JSON) + { throw new IOException("First chunk must be of type JSON (" - + CHUNK_TYPE_JSON + "), but found " + jsonChunk.type); + + CHUNK_TYPE_JSON + "), but found " + jsonChunk.type); } ByteBuffer jsonData = jsonChunk.data; ByteBuffer binData = null; - if (chunks.size() > 1) { + if (chunks.size() > 1) + { Chunk binChunk = chunks.get(1); - if (binChunk.type != CHUNK_TYPE_BIN) { + if (binChunk.type != CHUNK_TYPE_BIN) + { throw new IOException("Second chunk must be of type BIN (" - + CHUNK_TYPE_BIN + "), but found " + jsonChunk.type); + + CHUNK_TYPE_BIN + "), but found " + jsonChunk.type); } binData = binChunk.data; } return new RawGltfData(jsonData, binData); } - + + /** + * A class representing a chunk in binary glTF 2.0 + */ + private static class Chunk + { + /** + * The length + */ + int length; + + /** + * The type + */ + int type; + + /** + * The actual chunk data + */ + ByteBuffer data; + } + /** * Read the {@link Chunk} objects from the given binary glTF 2.0 data - * + * * @param data The input data * @return The chunks * @throws IOException If an IO error occurs */ - private static List readChunks(ByteBuffer data) throws IOException { + private static List readChunks(ByteBuffer data) throws IOException + { int headerLength = BINARY_GLTF_VERSION_2_HEADER_LENGTH_IN_BYTES; List chunks = new ArrayList(); int offset = headerLength; - while (offset < data.capacity()) { + while (offset < data.capacity()) + { Chunk chunk = new Chunk(); chunk.length = data.getInt(offset); offset += 4; chunk.type = data.getInt(offset); offset += 4; - if (offset + chunk.length > data.capacity()) { + if (offset + chunk.length > data.capacity()) + { throw new IOException("The offset for the data of chunk " - + chunks.size() + " is " + offset + ", its length is " - + chunk.length + ", but " + (offset + chunk.length) - + " is larger than capacity of the buffer, which is only " - + data.capacity()); + + chunks.size() + " is " + offset + ", its length is " + + chunk.length + ", but " + (offset + chunk.length) + + " is larger than capacity of the buffer, which is only " + + data.capacity()); } - if (chunk.length > 0) { - if (chunk.type == CHUNK_TYPE_BIN) { - chunk.data = Buffers.create(chunk.length); - Buffers.bufferCopy(data, offset, chunk.data, 0, chunk.length); - } else chunk.data = Buffers.createSlice(data, offset, chunk.length); + if (chunk.length > 0) + { + if(chunk.type == CHUNK_TYPE_BIN) { + chunk.data = Buffers.create(chunk.length); + Buffers.bufferCopy(data, offset, chunk.data, 0, chunk.length); + } + else chunk.data = Buffers.createSlice(data, offset, chunk.length); } offset += chunk.length; chunks.add(chunk); @@ -144,22 +171,10 @@ private static List readChunks(ByteBuffer data) throws IOException { } /** - * A class representing a chunk in binary glTF 2.0 + * Private constructor to prevent instantiation */ - private static class Chunk { - /** - * The length - */ - int length; - - /** - * The type - */ - int type; - - /** - * The actual chunk data - */ - ByteBuffer data; + private RawBinaryGltfDataReaderV2() + { + // Private constructor to prevent instantiation } } diff --git a/src/main/java/de/javagl/jgltf/model/package-info.java b/src/main/java/de/javagl/jgltf/model/package-info.java index e476c70..0458925 100644 --- a/src/main/java/de/javagl/jgltf/model/package-info.java +++ b/src/main/java/de/javagl/jgltf/model/package-info.java @@ -1,7 +1,7 @@ /** * Classes for loading and accessing glTF data. These are basic utility * classes that offer "convenience" access to the glTF data in a form - * that is specific for Java, but not specific for the application. + * that is specific for Java, but not specific for the application. */ package de.javagl.jgltf.model; diff --git a/src/main/java/de/javagl/jgltf/model/v1/BinaryGltfV1.java b/src/main/java/de/javagl/jgltf/model/v1/BinaryGltfV1.java index 000fff1..361a155 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/BinaryGltfV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/BinaryGltfV1.java @@ -26,24 +26,30 @@ */ package de.javagl.jgltf.model.v1; -import de.javagl.jgltf.impl.v1.*; -import de.javagl.jgltf.model.GltfException; -import de.javagl.jgltf.model.image.ImageReaders; - -import javax.imageio.ImageReader; import java.io.IOException; import java.nio.ByteBuffer; +import javax.imageio.ImageReader; + +import de.javagl.jgltf.impl.v1.Buffer; +import de.javagl.jgltf.impl.v1.BufferView; +import de.javagl.jgltf.impl.v1.GlTFProperty; +import de.javagl.jgltf.impl.v1.Image; +import de.javagl.jgltf.impl.v1.Shader; +import de.javagl.jgltf.model.GltfException; +import de.javagl.jgltf.model.image.ImageReaders; + /** * Utility methods related to the binary glTF extension of glTF 1.0 */ -public class BinaryGltfV1 { +public class BinaryGltfV1 +{ /** * The name of the KHR_binary_glTF extension */ - private static final String KHRONOS_BINARY_GLTF_EXTENSION_NAME = - "KHR_binary_glTF"; - + private static final String KHRONOS_BINARY_GLTF_EXTENSION_NAME = + "KHR_binary_glTF"; + /** * The unique, universal buffer ID for the binary data that is stored * in a binary glTF file @@ -51,130 +57,145 @@ public class BinaryGltfV1 { private static final String BINARY_GLTF_BUFFER_ID = "binary_glTF"; /** - * Private constructor to prevent instantiation - */ - private BinaryGltfV1() { - // Private constructor to prevent instantiation - } - - /** - * Returns whether the given {@link GlTFProperty} has the + * Returns whether the given {@link GlTFProperty} has the * "KHR_binary_glTF" extension. This is applicable * to {@link Image} and {@link Shader} objects that may contain - * an extension object with a {@link BufferView} ID instead of - * a URI. The {@link BufferView} ID may be obtained with + * an extension object with a {@link BufferView} ID instead of + * a URI. The {@link BufferView} ID may be obtained with * {@link BinaryGltfV1#getBinaryGltfBufferViewId(GlTFProperty)}. - * + * * @param gltfProperty The {@link GlTFProperty} * @return Whether the extension exists */ - public static boolean hasBinaryGltfExtension(GlTFProperty gltfProperty) { - return GltfExtensionsV1.hasExtension(gltfProperty, - KHRONOS_BINARY_GLTF_EXTENSION_NAME); + public static boolean hasBinaryGltfExtension(GlTFProperty gltfProperty) + { + return GltfExtensionsV1.hasExtension(gltfProperty, + KHRONOS_BINARY_GLTF_EXTENSION_NAME); } /** - * Returns the value of the "bufferView" property in + * Returns the value of the "bufferView" property in * the "KHR_binary_glTF" extension object of the * given {@link GlTFProperty}, or null if either the - * extension object or the property does not exist. - * + * extension object or the property does not exist. + * * @param gltfProperty The {@link GlTFProperty} * @return The property value */ - static String getBinaryGltfBufferViewId(GlTFProperty gltfProperty) { + static String getBinaryGltfBufferViewId(GlTFProperty gltfProperty) + { return GltfExtensionsV1.getExtensionPropertyValueAsString( - gltfProperty, KHRONOS_BINARY_GLTF_EXTENSION_NAME, "bufferView"); + gltfProperty, KHRONOS_BINARY_GLTF_EXTENSION_NAME, "bufferView"); } /** - * Set the value of the "bufferView" property in + * Set the value of the "bufferView" property in * the "KHR_binary_glTF" extension object of the * given {@link GlTFProperty}. If no (or an invalid) extension * object already existed, it will be created or overwritten, - * respectively. - * + * respectively. + * * @param gltfProperty The {@link GlTFProperty} * @param bufferViewId The {@link BufferView} ID */ public static void setBinaryGltfBufferViewId( - GlTFProperty gltfProperty, String bufferViewId) { + GlTFProperty gltfProperty, String bufferViewId) + { GltfExtensionsV1.setExtensionPropertyValue( - gltfProperty, KHRONOS_BINARY_GLTF_EXTENSION_NAME, - "bufferView", bufferViewId); + gltfProperty, KHRONOS_BINARY_GLTF_EXTENSION_NAME, + "bufferView", bufferViewId); } - + /** - * Set the properties for the given {@link Image} that is stored + * Set the properties for the given {@link Image} that is stored * as a "KHR_binary_glTF" image. These properties * are - *
    + *
      *
    • The image width
    • *
    • The image height
    • *
    • The image mimeType
    • *
    - * (Note that the buffer view ID is set explicitly with + * (Note that the buffer view ID is set explicitly with * {@link #setBinaryGltfBufferViewId(GlTFProperty, String)}) - * - * @param image The image + * + * @param image The image * @param imageData The raw image data * @throws GltfException If the image data cannot be analyzed to derive - * the required information + * the required information */ public static void setBinaryGltfImageProperties( - Image image, ByteBuffer imageData) { + Image image, ByteBuffer imageData) + { ImageReader imageReader = null; - try { + try + { imageReader = ImageReaders.findImageReader(imageData); int width = imageReader.getWidth(0); int height = imageReader.getHeight(0); String mimeType = "image/" + imageReader.getFormatName(); GltfExtensionsV1.setExtensionPropertyValue(image, - KHRONOS_BINARY_GLTF_EXTENSION_NAME, "width", width); + KHRONOS_BINARY_GLTF_EXTENSION_NAME, "width", width); GltfExtensionsV1.setExtensionPropertyValue(image, - KHRONOS_BINARY_GLTF_EXTENSION_NAME, "height", height); + KHRONOS_BINARY_GLTF_EXTENSION_NAME, "height", height); GltfExtensionsV1.setExtensionPropertyValue(image, - KHRONOS_BINARY_GLTF_EXTENSION_NAME, "mimeType", mimeType); - } catch (IOException e) { + KHRONOS_BINARY_GLTF_EXTENSION_NAME, "mimeType", mimeType); + } + catch (IOException e) + { throw new GltfException( - "Could not derive image properties for binary glTF", e); - } finally { - if (imageReader != null) { + "Could not derive image properties for binary glTF", e); + } + finally + { + if (imageReader != null) + { imageReader.dispose(); } } } + /** * Returns the name of the Khronos binary glTF extension * ("KHR_binary_glTF") - * + * * @return The name of the Khronos binary glTF extension */ - public static String getBinaryGltfExtensionName() { + public static String getBinaryGltfExtensionName() + { return KHRONOS_BINARY_GLTF_EXTENSION_NAME; } /** - * Returns unique ID of the binary glTF {@link Buffer} + * Returns unique ID of the binary glTF {@link Buffer} * ("binary_glTF") - * + * * @return The binary glTF {@link Buffer} ID */ - public static String getBinaryGltfBufferId() { + public static String getBinaryGltfBufferId() + { return BINARY_GLTF_BUFFER_ID; } /** * Returns whether the given ID is the unique ID of the binary glTF * {@link Buffer} ("binary_glTF") - * + * * @param id The ID * @return Whether the given ID is the binary glTF {@link Buffer} ID */ - public static boolean isBinaryGltfBufferId(String id) { + public static boolean isBinaryGltfBufferId(String id) + { return BINARY_GLTF_BUFFER_ID.equals(id); } - + + /** + * Private constructor to prevent instantiation + */ + private BinaryGltfV1() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfCreatorV1.java b/src/main/java/de/javagl/jgltf/model/v1/GltfCreatorV1.java index 8092091..d03d2eb 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfCreatorV1.java @@ -26,905 +26,962 @@ */ package de.javagl.jgltf.model.v1; -import de.javagl.jgltf.impl.v1.*; -import de.javagl.jgltf.model.*; -import de.javagl.jgltf.model.AnimationModel.Channel; -import de.javagl.jgltf.model.AnimationModel.Sampler; -import de.javagl.jgltf.model.gl.*; -import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; - -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.function.Function; import java.util.logging.Logger; import java.util.stream.Collectors; +import de.javagl.jgltf.impl.v1.Accessor; +import de.javagl.jgltf.impl.v1.Animation; +import de.javagl.jgltf.impl.v1.AnimationChannel; +import de.javagl.jgltf.impl.v1.AnimationChannelTarget; +import de.javagl.jgltf.impl.v1.AnimationSampler; +import de.javagl.jgltf.impl.v1.Asset; +import de.javagl.jgltf.impl.v1.Buffer; +import de.javagl.jgltf.impl.v1.BufferView; +import de.javagl.jgltf.impl.v1.Camera; +import de.javagl.jgltf.impl.v1.CameraOrthographic; +import de.javagl.jgltf.impl.v1.CameraPerspective; +import de.javagl.jgltf.impl.v1.GlTF; +import de.javagl.jgltf.impl.v1.GlTFChildOfRootProperty; +import de.javagl.jgltf.impl.v1.GlTFProperty; +import de.javagl.jgltf.impl.v1.Image; +import de.javagl.jgltf.impl.v1.Material; +import de.javagl.jgltf.impl.v1.Mesh; +import de.javagl.jgltf.impl.v1.MeshPrimitive; +import de.javagl.jgltf.impl.v1.Node; +import de.javagl.jgltf.impl.v1.Program; +import de.javagl.jgltf.impl.v1.Scene; +import de.javagl.jgltf.impl.v1.Shader; +import de.javagl.jgltf.impl.v1.Skin; +import de.javagl.jgltf.impl.v1.Technique; +import de.javagl.jgltf.impl.v1.TechniqueParameters; +import de.javagl.jgltf.impl.v1.TechniqueStates; +import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; +import de.javagl.jgltf.impl.v1.Texture; +import de.javagl.jgltf.model.AccessorData; +import de.javagl.jgltf.model.AccessorDatas; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.AnimationModel; +import de.javagl.jgltf.model.AnimationModel.Channel; +import de.javagl.jgltf.model.AnimationModel.Sampler; +import de.javagl.jgltf.model.AssetModel; +import de.javagl.jgltf.model.BufferModel; +import de.javagl.jgltf.model.BufferViewModel; +import de.javagl.jgltf.model.CameraModel; +import de.javagl.jgltf.model.CameraOrthographicModel; +import de.javagl.jgltf.model.CameraPerspectiveModel; +import de.javagl.jgltf.model.ExtensionsModel; +import de.javagl.jgltf.model.GltfConstants; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.ImageModel; +import de.javagl.jgltf.model.MaterialModel; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; +import de.javagl.jgltf.model.ModelElement; +import de.javagl.jgltf.model.NamedModelElement; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.Optionals; +import de.javagl.jgltf.model.SceneModel; +import de.javagl.jgltf.model.SkinModel; +import de.javagl.jgltf.model.TextureModel; +import de.javagl.jgltf.model.gl.ProgramModel; +import de.javagl.jgltf.model.gl.ShaderModel; +import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; +import de.javagl.jgltf.model.gl.TechniqueModel; +import de.javagl.jgltf.model.gl.TechniqueParametersModel; +import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; +import de.javagl.jgltf.model.gl.TechniqueStatesModel; + /** - * A class for creating the {@link GlTF version 1.0 glTF} from a + * A class for creating the {@link GlTF version 1.0 glTF} from a * {@link GltfModel}.
    *
    - * TODO: Not all features that could be supported are supported yet. + * TODO: Not all features that could be supported are supported yet. */ -public class GltfCreatorV1 { +public class GltfCreatorV1 +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfCreatorV1.class.getName()); + private static final Logger logger = + Logger.getLogger(GltfCreatorV1.class.getName()); + + /** + * Creates a {@link GlTF} from the given {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} + * @return The {@link GlTF} + */ + public static GlTF create(GltfModel gltfModel) + { + GltfCreatorV1 creator = new GltfCreatorV1(gltfModel); + return creator.create(); + } + + /** + * Inner class containing the information that is necessary to define + * a glTF {@link de.javagl.jgltf.impl.v1.Sampler} + */ + @SuppressWarnings("javadoc") + private static class SamplerInfo + { + final Integer magFilter; + final Integer minFilter; + final Integer wrapS; + final Integer wrapT; + + SamplerInfo(TextureModel textureModel) + { + this.magFilter = textureModel.getMagFilter(); + this.minFilter = textureModel.getMinFilter(); + this.wrapS = textureModel.getWrapS(); + this.wrapT = textureModel.getWrapT(); + } + + @Override + public int hashCode() + { + return Objects.hash(magFilter, minFilter, wrapS, wrapT); + } + + @Override + public boolean equals(Object object) + { + if (this == object) + { + return true; + } + if (object == null) + { + return false; + } + if (getClass() != object.getClass()) + { + return false; + } + SamplerInfo other = (SamplerInfo) object; + if (!Objects.equals(magFilter, other.magFilter)) + { + return false; + } + if (!Objects.equals(minFilter, other.minFilter)) + { + return false; + } + if (!Objects.equals(wrapS, other.wrapS)) + { + return false; + } + if (!Objects.equals(wrapT, other.wrapT)) + { + return false; + } + return true; + } + } + /** * The {@link GltfModel} that this instance operates on */ private final GltfModel gltfModel; + /** * A map from {@link AccessorModel} objects to their IDs */ private final Map accessorIds; + /** * A map from {@link BufferModel} objects to their IDs */ private final Map bufferIds; + /** * A map from {@link BufferViewModel} objects to their IDs */ private final Map bufferViewIds; + /** * A map from {@link CameraModel} objects to their IDs */ private final Map cameraIds; + /** * A map from {@link ImageModel} objects to their IDs */ private final Map imageIds; + /** * A map from {@link MaterialModel} objects to their IDs */ private final Map materialIds; + /** * A map from {@link MeshModel} objects to their IDs */ private final Map meshIds; + /** * A map from {@link NodeModel} objects to their IDs */ private final Map nodeIds; + /** * A map from {@link ProgramModel} objects to their IDs */ private final Map programIds; + /** * A map from {@link ShaderModel} objects to their IDs */ private final Map shaderIds; + /** * A map from {@link SkinModel} objects to their IDs */ private final Map skinIds; + /** * A map from {@link TechniqueModel} objects to their IDs */ private final Map techniqueIds; + /** * A map from {@link TextureModel} objects to their IDs */ private final Map textureIds; + /** * A map from {@link SamplerInfo} objects to their IDs */ private final Map samplerIds; - + /** * Creates a new instance with the given {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} */ - private GltfCreatorV1(GltfModel gltfModel) { + private GltfCreatorV1(GltfModel gltfModel) + { this.gltfModel = Objects.requireNonNull( - gltfModel, "The gltfModel may not be null"); - + gltfModel, "The gltfModel may not be null"); + accessorIds = computeIdMap( - "accessor", gltfModel.getAccessorModels()); + "accessor", gltfModel.getAccessorModels()); bufferIds = computeIdMap( - "buffer", gltfModel.getBufferModels()); + "buffer", gltfModel.getBufferModels()); bufferViewIds = computeIdMap( - "bufferView", gltfModel.getBufferViewModels()); + "bufferView", gltfModel.getBufferViewModels()); cameraIds = computeIdMap( - "camera", gltfModel.getCameraModels()); + "camera", gltfModel.getCameraModels()); imageIds = computeIdMap( - "image", gltfModel.getImageModels()); + "image", gltfModel.getImageModels()); materialIds = computeIdMap( - "material", gltfModel.getMaterialModels()); + "material", gltfModel.getMaterialModels()); meshIds = computeIdMap( - "mesh", gltfModel.getMeshModels()); + "mesh", gltfModel.getMeshModels()); nodeIds = computeIdMap( - "node", gltfModel.getNodeModels()); + "node", gltfModel.getNodeModels()); skinIds = computeIdMap( - "skin", gltfModel.getSkinModels()); + "skin", gltfModel.getSkinModels()); textureIds = computeIdMap( - "texture", gltfModel.getTextureModels()); - - if (gltfModel instanceof GltfModelV1) { - GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; + "texture", gltfModel.getTextureModels()); + + if (gltfModel instanceof GltfModelV1) + { + GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; programIds = computeIdMap( - "program", gltfModelV1.getProgramModels()); + "program", gltfModelV1.getProgramModels()); shaderIds = computeIdMap( - "shader", gltfModelV1.getShaderModels()); + "shader", gltfModelV1.getShaderModels()); techniqueIds = computeIdMap( - "technique", gltfModelV1.getTechniqueModels()); - } else { + "technique", gltfModelV1.getTechniqueModels()); + } + else + { programIds = Collections.emptyMap(); shaderIds = Collections.emptyMap(); techniqueIds = Collections.emptyMap(); } - + samplerIds = createSamplerIds(gltfModel.getTextureModels()); } - - /** - * Creates a {@link GlTF} from the given {@link GltfModel} - * - * @param gltfModel The {@link GltfModel} - * @return The {@link GlTF} - */ - public static GlTF create(GltfModel gltfModel) { - GltfCreatorV1 creator = new GltfCreatorV1(gltfModel); - return creator.create(); - } - - /** - * Create the {@link Accessor} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @param bufferViewId The ID of the {@link BufferViewModel} - * that the {@link AccessorModel} refers to - * @return The {@link Accessor} - */ - public static Accessor createAccessor( - AccessorModel accessorModel, String bufferViewId) { - Accessor accessor = new Accessor(); - transferGltfChildOfRootPropertyElements(accessorModel, accessor); - - accessor.setBufferView(bufferViewId); - - accessor.setByteOffset(accessorModel.getByteOffset()); - accessor.setComponentType(accessorModel.getComponentType()); - accessor.setCount(accessorModel.getCount()); - accessor.setType(accessorModel.getElementType().toString()); - accessor.setByteStride(accessorModel.getByteStride()); - - AccessorData accessorData = accessorModel.getAccessorData(); - accessor.setMax(AccessorDatas.computeMax(accessorData)); - accessor.setMin(AccessorDatas.computeMin(accessorData)); - - return accessor; - } - - /** - * Create the {@link Buffer} for the given {@link BufferModel} - * - * @param bufferModel The {@link BufferModel} - * @return The {@link Buffer} - */ - public static Buffer createBuffer(BufferModel bufferModel) { - Buffer buffer = new Buffer(); - transferGltfChildOfRootPropertyElements(bufferModel, buffer); - - buffer.setUri(bufferModel.getUri()); - buffer.setByteLength(bufferModel.getByteLength()); - return buffer; - } - - /** - * Create the {@link BufferView} for the given {@link BufferViewModel} - * - * @param bufferViewModel The {@link BufferViewModel} - * @param bufferId The ID of the {@link BufferModel} that the - * {@link BufferViewModel} refers to - * @return The {@link BufferView} - */ - public static BufferView createBufferView( - BufferViewModel bufferViewModel, String bufferId) { - BufferView bufferView = new BufferView(); - transferGltfChildOfRootPropertyElements(bufferViewModel, bufferView); - - bufferView.setBuffer(bufferId); - bufferView.setByteOffset(bufferViewModel.getByteOffset()); - bufferView.setByteLength(bufferViewModel.getByteLength()); - bufferView.setTarget(bufferViewModel.getTarget()); - - return bufferView; - } - - /** - * Create a {@link de.javagl.jgltf.impl.v1.Sampler} from the given - * {@link SamplerInfo} - * - * @param samplerInfo The {@link SamplerInfo} - * @return The {@link de.javagl.jgltf.impl.v1.Sampler} - */ - private static de.javagl.jgltf.impl.v1.Sampler createSampler( - SamplerInfo samplerInfo) { - de.javagl.jgltf.impl.v1.Sampler sampler = - new de.javagl.jgltf.impl.v1.Sampler(); - sampler.setMagFilter(samplerInfo.magFilter); - sampler.setMinFilter(samplerInfo.minFilter); - sampler.setWrapS(samplerInfo.wrapS); - sampler.setWrapT(samplerInfo.wrapT); - return sampler; - } - - /** - * Transfer the extensions and extras from the given model element to - * the given property - * - * @param modelElement The model element - * @param property The property - */ - private static void transferGltfPropertyElements( - ModelElement modelElement, GlTFProperty property) { - property.setExtensions(modelElement.getExtensions()); - property.setExtras(modelElement.getExtras()); - } - - /** - * Transfer the name and extensions and extras from the given model - * element to the given property - * - * @param modelElement The model element - * @param property The property - */ - private static void transferGltfChildOfRootPropertyElements( - NamedModelElement modelElement, - GlTFChildOfRootProperty property) { - property.setName(modelElement.getName()); - transferGltfPropertyElements(modelElement, property); - } - - /** - * Creates a map that maps (unspecified) strings starting with the - * given prefix to the results of applying the given mapper to the - * given elements, or null if the given collection is - * empty - * - * @param prefix The prefix - * @param elements The elements - * @param mapper The mapper - * @return The map - */ - private static Map map( - String prefix, - Collection elements, - Function mapper) { - return map(prefix, map(elements, mapper)); - } - - /** - * Creates a map that maps (unspecified) strings starting with the - * given prefix to the given elements, or null if the - * given collection is null or empty - * - * @param prefix The prefix - * @param elements The elements - * @return The map - */ - private static Map map( - String prefix, Collection elements) { - if (elements == null || elements.isEmpty()) { - return null; - } - Map map = new LinkedHashMap(); - int index = 0; - for (T element : elements) { - map.put(prefix + "_" + index, element); - index++; - } - return map; - } - - /** - * Returns a list containing the result of mapping the given elements with - * the given function, or null if the given collection is - * empty - * - * @param collection The collection - * @param mapper The mapper - * @return The list - */ - private static List map( - Collection collection, - Function mapper) { - if (collection.isEmpty()) { - return null; - } - return collection.stream().map(mapper).collect(Collectors.toList()); - } - - /** - * Creates a map that has the same keys as the given map, mapped to - * the IDs that are looked up for the respective values, using - * the given function - * - * @param map The map - * @param idLookup The index lookup - * @return The index map - */ - private static Map resolveIds( - Map map, - Function idLookup) { - Map result = new LinkedHashMap(); - for (Entry entry : map.entrySet()) { - K key = entry.getKey(); - T value = entry.getValue(); - String id = idLookup.apply(value); - result.put(key, id); - } - return result; - } - - /** - * Create an ordered map that contains a mapping of the given elements - * to IDs that start with the given prefix - * - * @param prefix The prefix - * @param elements The elements - * @return The ID map - */ - private static Map computeIdMap( - String prefix, Collection elements) { - Map ids = new LinkedHashMap(); - int index = 0; - for (T element : elements) { - ids.put(element, prefix + "_" + index); - index++; - } - return ids; - } - + /** * Create the {@link GlTF} instance from the {@link GltfModel} - * + * * @return The {@link GlTF} instance */ - public GlTF create() { + public GlTF create() + { GlTF gltf = new GlTF(); transferGltfPropertyElements(gltfModel, gltf); - + gltf.setAccessors(map("accessor", - gltfModel.getAccessorModels(), - this::createAccessor)); + gltfModel.getAccessorModels(), + this::createAccessor)); gltf.setAnimations(map("animation", - gltfModel.getAnimationModels(), - this::createAnimation)); + gltfModel.getAnimationModels(), + this::createAnimation)); gltf.setBuffers(map("buffer", - gltfModel.getBufferModels(), - GltfCreatorV1::createBuffer)); + gltfModel.getBufferModels(), + GltfCreatorV1::createBuffer)); gltf.setBufferViews(map("bufferView", - gltfModel.getBufferViewModels(), - this::createBufferView)); - gltf.setCameras(map("camera", - gltfModel.getCameraModels(), - this::createCamera)); + gltfModel.getBufferViewModels(), + this::createBufferView)); + gltf.setCameras(map("camera", + gltfModel.getCameraModels(), + this::createCamera)); gltf.setImages(map("image", - gltfModel.getImageModels(), - this::createImage)); - gltf.setMaterials(map("material", - gltfModel.getMaterialModels(), - this::createMaterial)); - gltf.setMeshes(map("mesh", - gltfModel.getMeshModels(), - this::createMesh)); + gltfModel.getImageModels(), + this::createImage)); + gltf.setMaterials(map("material", + gltfModel.getMaterialModels(), + this::createMaterial)); + gltf.setMeshes(map("mesh", + gltfModel.getMeshModels(), + this::createMesh)); gltf.setNodes(map("node", - gltfModel.getNodeModels(), - this::createNode)); + gltfModel.getNodeModels(), + this::createNode)); gltf.setScenes(map("scene", - gltfModel.getSceneModels(), - this::createScene)); - gltf.setSkins(map("skin", - gltfModel.getSkinModels(), - this::createSkin)); - + gltfModel.getSceneModels(), + this::createScene)); + gltf.setSkins(map("skin", + gltfModel.getSkinModels(), + this::createSkin)); + gltf.setSamplers(createSamplers()); - + gltf.setTextures(map("texture", - gltfModel.getTextureModels(), - this::createTexture)); - - - if (gltfModel instanceof GltfModelV1) { - GltfModelV1 gltfModelV1 = (GltfModelV1) gltfModel; - gltf.setPrograms(map("program", - gltfModelV1.getProgramModels(), - this::createProgram)); - gltf.setShaders(map("shader", - gltfModelV1.getShaderModels(), - this::createShader)); - gltf.setTechniques(map("technique", - gltfModelV1.getTechniqueModels(), - this::createTechnique)); + gltfModel.getTextureModels(), + this::createTexture)); + + + if (gltfModel instanceof GltfModelV1) + { + GltfModelV1 gltfModelV1 = (GltfModelV1)gltfModel; + gltf.setPrograms(map("program", + gltfModelV1.getProgramModels(), + this::createProgram)); + gltf.setShaders(map("shader", + gltfModelV1.getShaderModels(), + this::createShader)); + gltf.setTechniques(map("technique", + gltfModelV1.getTechniqueModels(), + this::createTechnique)); } - - if (gltf.getScenes() != null && !gltf.getScenes().isEmpty()) { + + if (gltf.getScenes() != null && !gltf.getScenes().isEmpty()) + { gltf.setScene(gltf.getScenes().keySet().iterator().next()); } - + ExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); List extensionsUsed = extensionsModel.getExtensionsUsed(); - if (!extensionsUsed.isEmpty()) { + if (!extensionsUsed.isEmpty()) + { gltf.setExtensionsUsed(extensionsUsed); } - + Asset asset = createAsset(gltfModel.getAssetModel()); gltf.setAsset(asset); - + return gltf; } - + /** * Create the {@link Accessor} for the given {@link AccessorModel} - * + * * @param accessorModel The {@link AccessorModel} * @return The {@link Accessor} */ - private Accessor createAccessor(AccessorModel accessorModel) { - String bufferViewId = - bufferViewIds.get(accessorModel.getBufferViewModel()); + private Accessor createAccessor(AccessorModel accessorModel) + { + String bufferViewId = + bufferViewIds.get(accessorModel.getBufferViewModel()); return createAccessor(accessorModel, bufferViewId); } - + + /** + * Create the {@link Accessor} for the given {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @param bufferViewId The ID of the {@link BufferViewModel} + * that the {@link AccessorModel} refers to + * @return The {@link Accessor} + */ + public static Accessor createAccessor( + AccessorModel accessorModel, String bufferViewId) + { + Accessor accessor = new Accessor(); + transferGltfChildOfRootPropertyElements(accessorModel, accessor); + + accessor.setBufferView(bufferViewId); + + accessor.setByteOffset(accessorModel.getByteOffset()); + accessor.setComponentType(accessorModel.getComponentType()); + accessor.setCount(accessorModel.getCount()); + accessor.setType(accessorModel.getElementType().toString()); + accessor.setByteStride(accessorModel.getByteStride()); + + AccessorData accessorData = accessorModel.getAccessorData(); + accessor.setMax(AccessorDatas.computeMax(accessorData)); + accessor.setMin(AccessorDatas.computeMin(accessorData)); + + return accessor; + } + /** * Create the {@link Animation} for the given {@link AnimationModel} - * + * * @param animationModel The {@link AnimationModel} * @return The {@link Animation} */ - private Animation createAnimation(AnimationModel animationModel) { + private Animation createAnimation(AnimationModel animationModel) + { Animation animation = new Animation(); transferGltfChildOfRootPropertyElements(animationModel, animation); - + Map samplers = new LinkedHashMap(); List channels = animationModel.getChannels(); int counter = 0; - for (Channel channel : channels) { + for (Channel channel : channels) + { String id = "sampler_" + counter; samplers.put(channel.getSampler(), id); counter++; } - - List animationChannels = - new ArrayList(); - for (Channel channel : channels) { + + List animationChannels = + new ArrayList(); + for (Channel channel : channels) + { AnimationChannel animationChannel = new AnimationChannel(); - + AnimationChannelTarget target = new AnimationChannelTarget(); NodeModel nodeModel = channel.getNodeModel(); target.setId(nodeIds.get(nodeModel)); target.setPath(channel.getPath()); animationChannel.setTarget(target); - + Sampler sampler = channel.getSampler(); animationChannel.setSampler(samplers.get(sampler)); - + animationChannels.add(animationChannel); } animation.setChannels(animationChannels); - - Map animationSamplers = - new LinkedHashMap(); - for (Sampler sampler : samplers.keySet()) { + + Map animationSamplers = + new LinkedHashMap(); + for (Sampler sampler : samplers.keySet()) + { AnimationSampler animationSampler = new AnimationSampler(); animationSampler.setInput( - accessorIds.get(sampler.getInput())); + accessorIds.get(sampler.getInput())); animationSampler.setInterpolation( - sampler.getInterpolation().name()); + sampler.getInterpolation().name()); animationSampler.setOutput( - accessorIds.get(sampler.getOutput())); + accessorIds.get(sampler.getOutput())); String key = samplers.get(sampler); animationSamplers.put(key, animationSampler); } animation.setSamplers(animationSamplers); - + return animation; } + + + /** + * Create the {@link Buffer} for the given {@link BufferModel} + * + * @param bufferModel The {@link BufferModel} + * @return The {@link Buffer} + */ + public static Buffer createBuffer(BufferModel bufferModel) + { + Buffer buffer = new Buffer(); + transferGltfChildOfRootPropertyElements(bufferModel, buffer); + buffer.setUri(bufferModel.getUri()); + buffer.setByteLength(bufferModel.getByteLength()); + return buffer; + } + /** * Create the {@link BufferView} for the given {@link BufferViewModel} - * + * * @param bufferViewModel The {@link BufferViewModel} * @return The {@link BufferView} */ - private BufferView createBufferView(BufferViewModel bufferViewModel) { - String bufferId = - bufferIds.get(bufferViewModel.getBufferModel()); + private BufferView createBufferView(BufferViewModel bufferViewModel) + { + String bufferId = + bufferIds.get(bufferViewModel.getBufferModel()); return createBufferView(bufferViewModel, bufferId); } + + /** + * Create the {@link BufferView} for the given {@link BufferViewModel} + * + * @param bufferViewModel The {@link BufferViewModel} + * @param bufferId The ID of the {@link BufferModel} that the + * {@link BufferViewModel} refers to + * @return The {@link BufferView} + */ + public static BufferView createBufferView( + BufferViewModel bufferViewModel, String bufferId) + { + BufferView bufferView = new BufferView(); + transferGltfChildOfRootPropertyElements(bufferViewModel, bufferView); + + bufferView.setBuffer(bufferId); + bufferView.setByteOffset(bufferViewModel.getByteOffset()); + bufferView.setByteLength(bufferViewModel.getByteLength()); + bufferView.setTarget(bufferViewModel.getTarget()); + + return bufferView; + } + /** * Create the {@link Camera} for the given {@link CameraModel} - * + * * @param cameraModel The {@link CameraModel} * @return The {@link Camera} */ - private Camera createCamera(CameraModel cameraModel) { + private Camera createCamera(CameraModel cameraModel) + { Camera camera = new Camera(); transferGltfChildOfRootPropertyElements(cameraModel, camera); - - CameraPerspectiveModel cameraPerspectiveModel = - cameraModel.getCameraPerspectiveModel(); - CameraOrthographicModel cameraOrthographicModel = - cameraModel.getCameraOrthographicModel(); - if (cameraPerspectiveModel != null) { + + CameraPerspectiveModel cameraPerspectiveModel = + cameraModel.getCameraPerspectiveModel(); + CameraOrthographicModel cameraOrthographicModel = + cameraModel.getCameraOrthographicModel(); + if (cameraPerspectiveModel != null) + { CameraPerspective cameraPerspective = new CameraPerspective(); cameraPerspective.setAspectRatio( - cameraPerspectiveModel.getAspectRatio()); + cameraPerspectiveModel.getAspectRatio()); cameraPerspective.setYfov( - cameraPerspectiveModel.getYfov()); + cameraPerspectiveModel.getYfov()); cameraPerspective.setZfar( - cameraPerspectiveModel.getZfar()); + cameraPerspectiveModel.getZfar()); cameraPerspective.setZnear( - cameraPerspectiveModel.getZnear()); + cameraPerspectiveModel.getZnear()); camera.setPerspective(cameraPerspective); camera.setType("perspective"); - } else if (cameraOrthographicModel != null) { + } + else if (cameraOrthographicModel != null) + { CameraOrthographic cameraOrthographic = new CameraOrthographic(); cameraOrthographic.setXmag( - cameraOrthographicModel.getXmag()); + cameraOrthographicModel.getXmag()); cameraOrthographic.setYmag( - cameraOrthographicModel.getYmag()); + cameraOrthographicModel.getYmag()); cameraOrthographic.setZfar( - cameraOrthographicModel.getZfar()); + cameraOrthographicModel.getZfar()); cameraOrthographic.setZnear( - cameraOrthographicModel.getZnear()); + cameraOrthographicModel.getZnear()); camera.setOrthographic(cameraOrthographic); camera.setType("orthographic"); - } else { + } + else + { logger.severe("Camera is neither perspective nor orthographic"); } return camera; } - + /** * Create the {@link Image} for the given {@link ImageModel} - * + * * @param imageModel The {@link ImageModel} * @return The {@link Image} */ - private Image createImage(ImageModel imageModel) { + private Image createImage(ImageModel imageModel) + { Image image = new Image(); transferGltfChildOfRootPropertyElements(imageModel, image); - - String bufferView = - bufferViewIds.get(imageModel.getBufferViewModel()); - if (bufferView != null) { + + String bufferView = + bufferViewIds.get(imageModel.getBufferViewModel()); + if (bufferView != null) + { logger.severe( - "Images with BufferView are not supported in glTF 1.0"); + "Images with BufferView are not supported in glTF 1.0"); } image.setUri(imageModel.getUri()); - + return image; } - + /** * Create the {@link Material} for the given {@link MaterialModel}. * If the given {@link MaterialModel} is not a {@link MaterialModelV1}, * then a warning is printed and null is returned. - * + * * @param materialModel The {@link MaterialModel} * @return The {@link Material} */ - private Material createMaterial(MaterialModel materialModel) { - if (materialModel instanceof MaterialModelV1) { - MaterialModelV1 materialModelV1 = (MaterialModelV1) materialModel; + private Material createMaterial(MaterialModel materialModel) + { + if (materialModel instanceof MaterialModelV1) + { + MaterialModelV1 materialModelV1 = (MaterialModelV1)materialModel; return createMaterialV1(materialModelV1); } // TODO It should be possible to use a glTF 2.0 material model here logger.severe("Cannot store glTF 2.0 material in glTF 1.0"); return null; } - + /** * Create the {@link Material} for the given {@link MaterialModelV1} - * + * * @param materialModel The {@link MaterialModelV1} * @return The {@link Material} */ - private Material createMaterialV1(MaterialModelV1 materialModel) { + private Material createMaterialV1(MaterialModelV1 materialModel) + { Material material = new Material(); transferGltfChildOfRootPropertyElements(materialModel, material); - + TechniqueModel techniqueModel = materialModel.getTechniqueModel(); material.setTechnique(techniqueIds.get(techniqueModel)); - + Map modelValues = materialModel.getValues(); Map values = new LinkedHashMap(); - for (Entry valueEntry : modelValues.entrySet()) { + for (Entry valueEntry : modelValues.entrySet()) + { String parameterName = valueEntry.getKey(); Object value = valueEntry.getValue(); - if (value instanceof TextureModel) { - TextureModel textureModel = (TextureModel) value; + if (value instanceof TextureModel) + { + TextureModel textureModel = (TextureModel)value; String textureId = textureIds.get(textureModel); values.put(parameterName, textureId); - } else { + } + else + { values.put(parameterName, value); } } material.setValues(values); return material; } - + /** * Create the {@link Program} for the given {@link ProgramModel} - * + * * @param programModel The {@link ProgramModel} * @return The {@link Program} */ - private Program createProgram(ProgramModel programModel) { + private Program createProgram(ProgramModel programModel) + { Program program = new Program(); transferGltfChildOfRootPropertyElements(programModel, program); - - ShaderModel vertexShaderModel = - programModel.getVertexShaderModel(); + + ShaderModel vertexShaderModel = + programModel.getVertexShaderModel(); program.setVertexShader(shaderIds.get(vertexShaderModel)); - - ShaderModel fragmentShaderModel = - programModel.getFragmentShaderModel(); + + ShaderModel fragmentShaderModel = + programModel.getFragmentShaderModel(); program.setFragmentShader(shaderIds.get(fragmentShaderModel)); - + List modelAttributes = programModel.getAttributes(); - if (!modelAttributes.isEmpty()) { + if (!modelAttributes.isEmpty()) + { List attributes = new ArrayList(modelAttributes); program.setAttributes(attributes); } return program; } - + /** * Create the {@link Shader} for the given {@link ShaderModel} - * + * * @param shaderModel The {@link ShaderModel} * @return The {@link Shader} */ - private Shader createShader(ShaderModel shaderModel) { + private Shader createShader(ShaderModel shaderModel) + { Shader shader = new Shader(); transferGltfChildOfRootPropertyElements(shaderModel, shader); - + ShaderType shaderType = shaderModel.getShaderType(); - if (shaderType == ShaderType.VERTEX_SHADER) { + if (shaderType == ShaderType.VERTEX_SHADER) + { shader.setType(GltfConstants.GL_VERTEX_SHADER); - } else if (shaderType == ShaderType.FRAGMENT_SHADER) { + } + else if (shaderType == ShaderType.FRAGMENT_SHADER) + { shader.setType(GltfConstants.GL_FRAGMENT_SHADER); - } else { + } + else + { logger.severe("Invalid shader type: " + shaderType); } shader.setUri(shaderModel.getUri()); return shader; } - + /** * Create the {@link Technique} for the given {@link TechniqueModel} - * + * * @param techniqueModel The {@link TechniqueModel} * @return The {@link Technique} */ - private Technique createTechnique(TechniqueModel techniqueModel) { + private Technique createTechnique(TechniqueModel techniqueModel) + { Technique technique = new Technique(); transferGltfChildOfRootPropertyElements(techniqueModel, technique); - + ProgramModel programModel = techniqueModel.getProgramModel(); technique.setProgram(programIds.get(programModel)); Map uniforms = techniqueModel.getUniforms(); technique.setUniforms(new LinkedHashMap(uniforms)); - + Map attributes = techniqueModel.getAttributes(); technique.setAttributes(new LinkedHashMap(attributes)); - - Map parametersModel = - techniqueModel.getParameters(); - if (!parametersModel.isEmpty()) { - Map parameters = - new LinkedHashMap(); - - for (Entry entry : - parametersModel.entrySet()) { + + Map parametersModel = + techniqueModel.getParameters(); + if (!parametersModel.isEmpty()) + { + Map parameters = + new LinkedHashMap(); + + for (Entry entry : + parametersModel.entrySet()) + { String key = entry.getKey(); - TechniqueParametersModel techniqueParametersModel = - entry.getValue(); - + TechniqueParametersModel techniqueParametersModel = + entry.getValue(); + TechniqueParameters techniqueParameters = - createTechniqueParameters(techniqueParametersModel); - + createTechniqueParameters(techniqueParametersModel); + parameters.put(key, techniqueParameters); } technique.setParameters(parameters); } technique.setStates(createTechniqueStates( - techniqueModel.getTechniqueStatesModel())); - + techniqueModel.getTechniqueStatesModel())); + return technique; } - + /** * Returns the {@link TechniqueParameters} object for the given * {@link TechniqueParametersModel} - * + * * @param techniqueParametersModel The {@link TechniqueParametersModel} * @return The {@link TechniqueParameters} */ private TechniqueParameters createTechniqueParameters( - TechniqueParametersModel techniqueParametersModel) { + TechniqueParametersModel techniqueParametersModel) + { TechniqueParameters techniqueParameters = new TechniqueParameters(); - + techniqueParameters.setSemantic(techniqueParametersModel.getSemantic()); techniqueParameters.setType(techniqueParametersModel.getType()); techniqueParameters.setCount(techniqueParametersModel.getCount()); techniqueParameters.setValue(techniqueParametersModel.getValue()); - + NodeModel nodeModel = techniqueParametersModel.getNodeModel(); techniqueParameters.setNode(nodeIds.get(nodeModel)); - + return techniqueParameters; } - + /** * Returns the {@link TechniqueStates} object for the given * {@link TechniqueStatesModel} - * + * * @param techniqueStatesModel The {@link TechniqueStatesModel} * @return The {@link TechniqueStates} */ private TechniqueStates createTechniqueStates( - TechniqueStatesModel techniqueStatesModel) { - if (techniqueStatesModel == null) { + TechniqueStatesModel techniqueStatesModel) + { + if (techniqueStatesModel == null) + { return null; } TechniqueStates techniqueStates = new TechniqueStates(); - + List enable = techniqueStatesModel.getEnable(); - if (enable != null) { + if (enable != null) + { techniqueStates.setEnable(new ArrayList(enable)); } - + techniqueStates.setFunctions(createTechniqueStatesFunctions( - techniqueStatesModel.getTechniqueStatesFunctionsModel())); - + techniqueStatesModel.getTechniqueStatesFunctionsModel())); + return techniqueStates; } - + /** * Returns the {@link TechniqueStatesFunctions} object for the given * {@link TechniqueStatesFunctionsModel} - * - * @param techniqueStatesFunctionsModel The - * {@link TechniqueStatesFunctionsModel} + * + * @param techniqueStatesFunctionsModel The + * {@link TechniqueStatesFunctionsModel} * @return The {@link TechniqueStatesFunctions} */ private TechniqueStatesFunctions createTechniqueStatesFunctions( - TechniqueStatesFunctionsModel techniqueStatesFunctionsModel) { - if (techniqueStatesFunctionsModel == null) { + TechniqueStatesFunctionsModel techniqueStatesFunctionsModel) + { + if (techniqueStatesFunctionsModel == null) + { return null; } - TechniqueStatesFunctions techniqueStatesFunctions = - new TechniqueStatesFunctions(); - + TechniqueStatesFunctions techniqueStatesFunctions = + new TechniqueStatesFunctions(); + techniqueStatesFunctions.setBlendColor(Optionals.clone( - techniqueStatesFunctionsModel.getBlendColor())); + techniqueStatesFunctionsModel.getBlendColor())); techniqueStatesFunctions.setBlendEquationSeparate(Optionals.clone( - techniqueStatesFunctionsModel.getBlendEquationSeparate())); + techniqueStatesFunctionsModel.getBlendEquationSeparate())); techniqueStatesFunctions.setBlendFuncSeparate(Optionals.clone( - techniqueStatesFunctionsModel.getBlendFuncSeparate())); + techniqueStatesFunctionsModel.getBlendFuncSeparate())); techniqueStatesFunctions.setColorMask(Optionals.clone( - techniqueStatesFunctionsModel.getColorMask())); + techniqueStatesFunctionsModel.getColorMask())); techniqueStatesFunctions.setCullFace(Optionals.clone( - techniqueStatesFunctionsModel.getCullFace())); + techniqueStatesFunctionsModel.getCullFace())); techniqueStatesFunctions.setDepthFunc(Optionals.clone( - techniqueStatesFunctionsModel.getDepthFunc())); + techniqueStatesFunctionsModel.getDepthFunc())); techniqueStatesFunctions.setDepthMask(Optionals.clone( - techniqueStatesFunctionsModel.getDepthMask())); + techniqueStatesFunctionsModel.getDepthMask())); techniqueStatesFunctions.setDepthRange(Optionals.clone( - techniqueStatesFunctionsModel.getDepthRange())); + techniqueStatesFunctionsModel.getDepthRange())); techniqueStatesFunctions.setFrontFace(Optionals.clone( - techniqueStatesFunctionsModel.getFrontFace())); + techniqueStatesFunctionsModel.getFrontFace())); techniqueStatesFunctions.setLineWidth(Optionals.clone( - techniqueStatesFunctionsModel.getLineWidth())); + techniqueStatesFunctionsModel.getLineWidth())); techniqueStatesFunctions.setPolygonOffset(Optionals.clone( - techniqueStatesFunctionsModel.getPolygonOffset())); - + techniqueStatesFunctionsModel.getPolygonOffset())); + return techniqueStatesFunctions; } - + + /** * Create the {@link Mesh} for the given {@link MeshModel} - * + * * @param meshModel The {@link MeshModel} * @return The {@link Mesh} */ - private Mesh createMesh(MeshModel meshModel) { + private Mesh createMesh(MeshModel meshModel) + { Mesh mesh = new Mesh(); transferGltfChildOfRootPropertyElements(meshModel, mesh); - + List meshPrimitives = new ArrayList(); - List meshPrimitiveModels = - meshModel.getMeshPrimitiveModels(); - for (MeshPrimitiveModel meshPrimitiveModel : meshPrimitiveModels) { - MeshPrimitive meshPrimitive = - createMeshPrimitive(meshPrimitiveModel); + List meshPrimitiveModels = + meshModel.getMeshPrimitiveModels(); + for (MeshPrimitiveModel meshPrimitiveModel : meshPrimitiveModels) + { + MeshPrimitive meshPrimitive = + createMeshPrimitive(meshPrimitiveModel); meshPrimitives.add(meshPrimitive); } mesh.setPrimitives(meshPrimitives); - - if (meshModel.getWeights() != null) { + + if (meshModel.getWeights() != null) + { logger.severe("Morph target weights are not supported in glTF 1.0"); } return mesh; } - + /** * Create the {@link MeshPrimitive} for the given {@link MeshPrimitiveModel} - * + * * @param meshPrimitiveModel The {@link MeshPrimitiveModel} * @return The {@link MeshPrimitive} */ private MeshPrimitive createMeshPrimitive( - MeshPrimitiveModel meshPrimitiveModel) { + MeshPrimitiveModel meshPrimitiveModel) + { MeshPrimitive meshPrimitive = new MeshPrimitive(); transferGltfPropertyElements(meshPrimitiveModel, meshPrimitive); meshPrimitive.setMode(meshPrimitiveModel.getMode()); - + Map attributes = resolveIds( - meshPrimitiveModel.getAttributes(), - accessorIds::get); + meshPrimitiveModel.getAttributes(), + accessorIds::get); meshPrimitive.setAttributes(attributes); AccessorModel Ids = meshPrimitiveModel.getIndices(); meshPrimitive.setIndices(accessorIds.get(Ids)); - - List> modelTargetsList = - meshPrimitiveModel.getTargets(); - if (!modelTargetsList.isEmpty()) { + + List> modelTargetsList = + meshPrimitiveModel.getTargets(); + if (!modelTargetsList.isEmpty()) + { logger.severe("Morph targets are not supported in glTF 1.0"); } - + String material = materialIds.get( - meshPrimitiveModel.getMaterialModel()); + meshPrimitiveModel.getMaterialModel()); meshPrimitive.setMaterial(material); - + return meshPrimitive; } /** * Create the {@link Node} for the given {@link NodeModel} - * + * * @param nodeModel The {@link NodeModel} * @return The {@link Node} */ - private Node createNode(NodeModel nodeModel) { + private Node createNode(NodeModel nodeModel) + { Node node = new Node(); transferGltfChildOfRootPropertyElements(nodeModel, node); - - if (!nodeModel.getChildren().isEmpty()) { + + if (!nodeModel.getChildren().isEmpty()) + { node.setChildren(map( - nodeModel.getChildren(), nodeIds::get)); + nodeModel.getChildren(), nodeIds::get)); } node.setTranslation(Optionals.clone(nodeModel.getTranslation())); node.setRotation(Optionals.clone(nodeModel.getRotation())); node.setScale(Optionals.clone(nodeModel.getScale())); node.setMatrix(Optionals.clone(nodeModel.getMatrix())); - + String camera = cameraIds.get(nodeModel.getCameraModel()); node.setCamera(camera); - + String skin = skinIds.get(nodeModel.getSkinModel()); node.setSkin(skin); - - if (nodeModel.getWeights() != null) { + + if (nodeModel.getWeights() != null) + { logger.severe("Morph target weights are not supported in glTF 1.0"); } - + List nodeMeshModels = nodeModel.getMeshModels(); - if (!nodeMeshModels.isEmpty()) { + if (!nodeMeshModels.isEmpty()) + { List meshes = new ArrayList(); - for (MeshModel meshModel : nodeMeshModels) { + for (MeshModel meshModel : nodeMeshModels) + { String id = meshIds.get(meshModel); meshes.add(id); } @@ -932,175 +989,295 @@ private Node createNode(NodeModel nodeModel) { } return node; } - + /** * Create the {@link Scene} for the given {@link SceneModel} - * + * * @param sceneModel The {@link SceneModel} * @return The {@link Scene} */ - private Scene createScene(SceneModel sceneModel) { + private Scene createScene(SceneModel sceneModel) + { Scene scene = new Scene(); transferGltfChildOfRootPropertyElements(sceneModel, scene); - + scene.setNodes(map( - sceneModel.getNodeModels(), nodeIds::get)); + sceneModel.getNodeModels(), nodeIds::get)); return scene; } - + /** * Create the {@link Skin} for the given {@link SkinModel} - * + * * @param skinModel The {@link SkinModel} * @return The {@link Skin} */ - private Skin createSkin(SkinModel skinModel) { + private Skin createSkin(SkinModel skinModel) + { Skin skin = new Skin(); transferGltfChildOfRootPropertyElements(skinModel, skin); - - String inverseBindMatrices = - accessorIds.get(skinModel.getInverseBindMatrices()); + + String inverseBindMatrices = + accessorIds.get(skinModel.getInverseBindMatrices()); skin.setInverseBindMatrices(inverseBindMatrices); - + // TODO Not implemented yet logger.severe("Skins are not yet fully supported"); - + return skin; } - + /** * Create a mapping from {@link SamplerInfo} objects to IDs, - * based on the {@link SamplerInfo} objects that are + * based on the {@link SamplerInfo} objects that are * created from the given {@link TextureModel} objects - * + * * @param textureModels The {@link TextureModel} objects * @return The IDs */ private Map createSamplerIds( - List textureModels) { - Map samplerIndices = - new LinkedHashMap(); - for (TextureModel textureModel : textureModels) { + List textureModels) + { + Map samplerIndices = + new LinkedHashMap(); + for (TextureModel textureModel : textureModels) + { SamplerInfo samplerInfo = new SamplerInfo(textureModel); - if (!samplerIndices.containsKey(samplerInfo)) { - samplerIndices.put(samplerInfo, - "sampler_" + samplerIndices.size()); + if (!samplerIndices.containsKey(samplerInfo)) + { + samplerIndices.put(samplerInfo, + "sampler_" + samplerIndices.size()); } } return samplerIndices; } - + /** * Create the {@link de.javagl.jgltf.impl.v1.Sampler} objects for * the current glTF model, returning null if there * are no samplers. - * + * * @return The samplers */ - private Map createSamplers() { - if (samplerIds.isEmpty()) { + private Map createSamplers() + { + if (samplerIds.isEmpty()) + { return null; } - Map samplers = - new LinkedHashMap(); - for (SamplerInfo samplerInfo : samplerIds.keySet()) { - de.javagl.jgltf.impl.v1.Sampler sampler = - createSampler(samplerInfo); + Map samplers = + new LinkedHashMap(); + for (SamplerInfo samplerInfo : samplerIds.keySet()) + { + de.javagl.jgltf.impl.v1.Sampler sampler = + createSampler(samplerInfo); String key = samplerIds.get(samplerInfo); samplers.put(key, sampler); } return samplers; } + + /** + * Create a {@link de.javagl.jgltf.impl.v1.Sampler} from the given + * {@link SamplerInfo} + * + * @param samplerInfo The {@link SamplerInfo} + * @return The {@link de.javagl.jgltf.impl.v1.Sampler} + */ + private static de.javagl.jgltf.impl.v1.Sampler createSampler( + SamplerInfo samplerInfo) + { + de.javagl.jgltf.impl.v1.Sampler sampler = + new de.javagl.jgltf.impl.v1.Sampler(); + sampler.setMagFilter(samplerInfo.magFilter); + sampler.setMinFilter(samplerInfo.minFilter); + sampler.setWrapS(samplerInfo.wrapS); + sampler.setWrapT(samplerInfo.wrapT); + return sampler; + } + /** * Creates a texture for the given {@link TextureModel} - * + * * @param textureModel The {@link TextureModel} * @return The {@link Texture} */ - private Texture createTexture(TextureModel textureModel) { + private Texture createTexture(TextureModel textureModel) + { Texture texture = new Texture(); transferGltfChildOfRootPropertyElements(textureModel, texture); - + SamplerInfo samplerInfo = new SamplerInfo(textureModel); String id = samplerIds.get(samplerInfo); texture.setSampler(id); - + texture.setSource(imageIds.get(textureModel.getImageModel())); - + return texture; } - + /** * Creates an asset for the given {@link AssetModel} - * + * * @param assetModel The {@link AssetModel} * @return The {@link Asset} */ - private Asset createAsset(AssetModel assetModel) { + private Asset createAsset(AssetModel assetModel) + { Asset asset = new Asset(); asset.setVersion("1.0"); asset.setGenerator("JglTF from https://github.com/javagl/JglTF"); - + transferGltfPropertyElements(assetModel, asset); - - if (assetModel.getCopyright() != null) { + + if (assetModel.getCopyright() != null) + { asset.setCopyright(assetModel.getCopyright()); } - if (assetModel.getGenerator() != null) { + if (assetModel.getGenerator() != null) + { asset.setGenerator(assetModel.getGenerator()); } return asset; } /** - * Inner class containing the information that is necessary to define - * a glTF {@link de.javagl.jgltf.impl.v1.Sampler} + * Transfer the extensions and extras from the given model element to + * the given property + * + * @param modelElement The model element + * @param property The property */ - @SuppressWarnings("javadoc") - private static class SamplerInfo { - final Integer magFilter; - final Integer minFilter; - final Integer wrapS; - final Integer wrapT; + private static void transferGltfPropertyElements( + ModelElement modelElement, GlTFProperty property) + { + property.setExtensions(modelElement.getExtensions()); + property.setExtras(modelElement.getExtras()); + } + + /** + * Transfer the name and extensions and extras from the given model + * element to the given property + * + * @param modelElement The model element + * @param property The property + */ + private static void transferGltfChildOfRootPropertyElements( + NamedModelElement modelElement, + GlTFChildOfRootProperty property) + { + property.setName(modelElement.getName()); + transferGltfPropertyElements(modelElement, property); + } + + /** + * Creates a map that maps (unspecified) strings starting with the + * given prefix to the results of applying the given mapper to the + * given elements, or null if the given collection is + * empty + * + * @param prefix The prefix + * @param elements The elements + * @param mapper The mapper + * @return The map + */ + private static Map map( + String prefix, + Collection elements, + Function mapper) + { + return map(prefix, map(elements, mapper)); + } - SamplerInfo(TextureModel textureModel) { - this.magFilter = textureModel.getMagFilter(); - this.minFilter = textureModel.getMinFilter(); - this.wrapS = textureModel.getWrapS(); - this.wrapT = textureModel.getWrapT(); + /** + * Creates a map that maps (unspecified) strings starting with the + * given prefix to the given elements, or null if the + * given collection is null or empty + * + * @param prefix The prefix + * @param elements The elements + * @return The map + */ + private static Map map( + String prefix, Collection elements) + { + if (elements == null || elements.isEmpty()) + { + return null; } - - @Override - public int hashCode() { - return Objects.hash(magFilter, minFilter, wrapS, wrapT); + Map map = new LinkedHashMap(); + int index = 0; + for (T element : elements) + { + map.put(prefix + "_" + index, element); + index++; } + return map; + } + + /** + * Returns a list containing the result of mapping the given elements with + * the given function, or null if the given collection is + * empty + * + * @param collection The collection + * @param mapper The mapper + * @return The list + */ + private static List map( + Collection collection, + Function mapper) + { + if (collection.isEmpty()) + { + return null; + } + return collection.stream().map(mapper).collect(Collectors.toList()); + } - @Override - public boolean equals(Object object) { - if (this == object) { - return true; - } - if (object == null) { - return false; - } - if (getClass() != object.getClass()) { - return false; - } - SamplerInfo other = (SamplerInfo) object; - if (!Objects.equals(magFilter, other.magFilter)) { - return false; - } - if (!Objects.equals(minFilter, other.minFilter)) { - return false; - } - if (!Objects.equals(wrapS, other.wrapS)) { - return false; - } - if (!Objects.equals(wrapT, other.wrapT)) { - return false; - } - return true; + /** + * Creates a map that has the same keys as the given map, mapped to + * the IDs that are looked up for the respective values, using + * the given function + * + * @param map The map + * @param idLookup The index lookup + * @return The index map + */ + private static Map resolveIds( + Map map, + Function idLookup) + { + Map result = new LinkedHashMap(); + for (Entry entry : map.entrySet()) + { + K key = entry.getKey(); + T value = entry.getValue(); + String id = idLookup.apply(value); + result.put(key, id); } + return result; + } + + /** + * Create an ordered map that contains a mapping of the given elements + * to IDs that start with the given prefix + * + * @param prefix The prefix + * @param elements The elements + * @return The ID map + */ + private static Map computeIdMap( + String prefix, Collection elements) + { + Map ids = new LinkedHashMap(); + int index = 0; + for (T element : elements) + { + ids.put(element, prefix + "_" + index); + index++; + } + return ids; } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfExtensionsV1.java b/src/main/java/de/javagl/jgltf/model/v1/GltfExtensionsV1.java index 9d60978..7080784 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfExtensionsV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfExtensionsV1.java @@ -26,178 +26,201 @@ */ package de.javagl.jgltf.model.v1; -import com.google.gson.Gson; -import de.javagl.jgltf.impl.v1.GlTF; -import de.javagl.jgltf.impl.v1.GlTFProperty; - import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import com.google.gson.Gson; + +import de.javagl.jgltf.impl.v1.GlTF; +import de.javagl.jgltf.impl.v1.GlTFProperty; + /** * Utility methods related to glTF extensions for glTF 1.0 */ -public class GltfExtensionsV1 { +public class GltfExtensionsV1 +{ /** - * Private constructor to prevent instantiation - */ - private GltfExtensionsV1() { - // Private constructor to prevent instantiation - } - - /** - * If the {@link GlTF#getExtensionsUsed() used extensions} of the given + * If the {@link GlTF#getExtensionsUsed() used extensions} of the given * {@link GlTF} is null or does not contain the given * extension name, then it will be set to a new list that contains all * previous extension names, and the given one. - * - * @param gltf The {@link GlTF} + * + * @param gltf The {@link GlTF} * @param extensionName The name of the extension to add */ - public static void addExtensionUsed(GlTF gltf, String extensionName) { + public static void addExtensionUsed(GlTF gltf, String extensionName) + { List oldExtensionsUsed = gltf.getExtensionsUsed(); - if (oldExtensionsUsed == null || - !oldExtensionsUsed.contains(extensionName)) { + if (oldExtensionsUsed == null || + !oldExtensionsUsed.contains(extensionName)) + { gltf.addExtensionsUsed(extensionName); } } - + /** - * If the {@link GlTF#getExtensionsUsed() used extensions} of the given - * {@link GlTF} contains the given extension name, then it will be set + * If the {@link GlTF#getExtensionsUsed() used extensions} of the given + * {@link GlTF} contains the given extension name, then it will be set * to a new list that contains all previous extension names, except * for the given one. - * - * @param gltf The {@link GlTF} + * + * @param gltf The {@link GlTF} * @param extensionName The name of the extension to remove */ - public static void removeExtensionUsed(GlTF gltf, String extensionName) { + public static void removeExtensionUsed(GlTF gltf, String extensionName) + { List oldExtensionsUsed = gltf.getExtensionsUsed(); - if (oldExtensionsUsed != null && - oldExtensionsUsed.contains(extensionName)) { + if (oldExtensionsUsed != null && + oldExtensionsUsed.contains(extensionName)) + { gltf.removeExtensionsUsed(extensionName); } } - + /** - * Return the key-value mapping that is stored as the - * {@link GlTFProperty#getExtensions() extension} with the given name - * in the given {@link GlTFProperty}, or null if no such + * Return the key-value mapping that is stored as the + * {@link GlTFProperty#getExtensions() extension} with the given name + * in the given {@link GlTFProperty}, or null if no such * entry can be found. - * - * @param gltfProperty The {@link GlTFProperty} + * + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name * @return The extension property mapping, or null */ private static Map getExtensionMap( - GlTFProperty gltfProperty, String extensionName) { + GlTFProperty gltfProperty, String extensionName) + { Map extensions = gltfProperty.getExtensions(); - if (extensions == null) { + if (extensions == null) + { return null; } Object value = extensions.get(extensionName); - if (value == null) { + if (value == null) + { return null; } - if (value instanceof Map) { - Map map = (Map) value; + if (value instanceof Map) + { + Map map = (Map)value; @SuppressWarnings("unchecked") - Map result = (Map) map; - return result; + Map result = (Map)map; + return result; } return null; } - + + /** - * Returns whether a non-null key-value mapping is stored + * Returns whether a non-null key-value mapping is stored * as the {@link GlTFProperty#getExtensions() extension} with the * given name in the given glTF property. - * - * @param gltfProperty The {@link GlTFProperty} + + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name * @return Whether the specified extension mapping exists */ static boolean hasExtension( - GlTFProperty gltfProperty, String extensionName) { + GlTFProperty gltfProperty, String extensionName) + { return getExtensionMap(gltfProperty, extensionName) != null; } - + /** - * Returns the value of the specified property in the key-value mapping - * that is stored as the {@link GlTFProperty#getExtensions() extension} + * Returns the value of the specified property in the key-value mapping + * that is stored as the {@link GlTFProperty#getExtensions() extension} * with the given name in the given glTF property. If the specified * extension does not exist, or does not have the specified property, * then null is returned. - * - * @param gltfProperty The {@link GlTFProperty} + * + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name - * @param propertyName The property name + * @param propertyName The property name * @return The value, as a string. */ static String getExtensionPropertyValueAsString( - GlTFProperty gltfProperty, String extensionName, String propertyName) { - Map extensionMap = - getExtensionMap(gltfProperty, extensionName); - if (extensionMap == null) { + GlTFProperty gltfProperty, String extensionName, String propertyName) + { + Map extensionMap = + getExtensionMap(gltfProperty, extensionName); + if (extensionMap == null) + { return null; } Object value = extensionMap.get(propertyName); - if (value == null) { + if (value == null) + { return null; } return String.valueOf(value); } - + /** * Stores the given property value under the given property key in the * key-value mapping that is stored under the given extension name in - * the {@link GlTFProperty#getExtensions() extensions} of the given + * the {@link GlTFProperty#getExtensions() extensions} of the given * {@link GlTFProperty}. If the mapping for the given extension name * did not exist, it will be created. If it already existed but was * no key-value mapping, then its old value will be overwritten. - * - * @param gltfProperty The {@link GlTFProperty} + * + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name - * @param propertyName The property name + * @param propertyName The property name * @param propertyValue The value */ static void setExtensionPropertyValue( - GlTFProperty gltfProperty, String extensionName, - String propertyName, Object propertyValue) { - Map extensionMap = - getExtensionMap(gltfProperty, extensionName); - if (extensionMap == null) { + GlTFProperty gltfProperty, String extensionName, + String propertyName, Object propertyValue) + { + Map extensionMap = + getExtensionMap(gltfProperty, extensionName); + if (extensionMap == null) + { extensionMap = new LinkedHashMap(); gltfProperty.addExtensions(extensionName, extensionMap); } extensionMap.put(propertyName, propertyValue); } - + + /** * Fetch the value of the specified extension object from the given - * {@link GlTFProperty}, converted into the given target type. + * {@link GlTFProperty}, converted into the given target type. * Returns null if the given {@link GlTFProperty} does * not have the specified extension. - * - * @param gltfProperty The {@link GlTFProperty} + * + * @param gltfProperty The {@link GlTFProperty} * @param extensionName The extension name - * @param type The type to convert the object to + * @param type The type to convert the object to * @return The object * @throws IllegalArgumentException If the specified extension object - * cannot be converted to the desired target type + * cannot be converted to the desired target type */ static T fetchExtensionObject( - GlTFProperty gltfProperty, String extensionName, Class type) { + GlTFProperty gltfProperty, String extensionName, Class type) + { Map extensions = gltfProperty.getExtensions(); - if (extensions == null) { + if (extensions == null) + { return null; } Object extensionObject = extensions.get(extensionName); - if (extensionObject == null) { + if (extensionObject == null) + { return null; } Gson gson = new Gson(); return gson.fromJson(gson.toJsonTree(extensionObject), type); } + + + /** + * Private constructor to prevent instantiation + */ + private GltfExtensionsV1() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfIds.java b/src/main/java/de/javagl/jgltf/model/v1/GltfIds.java index c6c4f12..50f5597 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfIds.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfIds.java @@ -26,35 +26,31 @@ */ package de.javagl.jgltf.model.v1; -import de.javagl.jgltf.impl.v1.GlTF; - import java.util.Collections; import java.util.Map; import java.util.Set; +import de.javagl.jgltf.impl.v1.GlTF; + /** * Utility methods for generating IDs for {@link GlTF} objects */ -public class GltfIds { - /** - * Private constructor to prevent instantiation - */ - private GltfIds() { - // Private constructor to prevent instantiation - } - +public class GltfIds +{ /** * Generate an unspecified ID string with the given prefix that is not * yet contained in the key set of the given map - * + * * @param prefix The prefix for the ID string - * @param map The map from the existing IDs. This may be null. + * @param map The map from the existing IDs. This may be null. * @return The new ID */ public static String generateId( - String prefix, Map map) { + String prefix, Map map) + { Set set = Collections.emptySet(); - if (map != null) { + if (map != null) + { set = map.keySet(); } return generateId(prefix, set); @@ -63,25 +59,37 @@ public static String generateId( /** * Generate an unspecified ID string with the given prefix that is not * yet contained in the given set - * + * * @param prefix The prefix for the ID string - * @param set The set of the existing IDs. This may be null. + * @param set The set of the existing IDs. This may be null. * @return The new ID */ public static String generateId( - String prefix, Set set) { + String prefix, Set set) + { Set localSet = Collections.emptySet(); - if (set != null) { + if (set != null) + { localSet = set; } int counter = localSet.size(); - while (true) { + while (true) + { String id = prefix + counter; - if (!localSet.contains(id)) { + if (!localSet.contains(id)) + { return id; } counter++; } } + /** + * Private constructor to prevent instantiation + */ + private GltfIds() + { + // Private constructor to prevent instantiation + } + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfModelCreatorV1.java b/src/main/java/de/javagl/jgltf/model/v1/GltfModelCreatorV1.java index 875fa17..be2e272 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfModelCreatorV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfModelCreatorV1.java @@ -26,19 +26,106 @@ */ package de.javagl.jgltf.model.v1; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.logging.Logger; + import com.google.gson.Gson; import com.google.gson.JsonElement; import com.modularmods.mcgltf.MCglTF; -import de.javagl.jgltf.impl.v1.*; -import de.javagl.jgltf.model.*; + +import de.javagl.jgltf.impl.v1.Accessor; +import de.javagl.jgltf.impl.v1.Animation; +import de.javagl.jgltf.impl.v1.AnimationChannel; +import de.javagl.jgltf.impl.v1.AnimationChannelTarget; +import de.javagl.jgltf.impl.v1.AnimationSampler; +import de.javagl.jgltf.impl.v1.Asset; +import de.javagl.jgltf.impl.v1.Buffer; +import de.javagl.jgltf.impl.v1.BufferView; +import de.javagl.jgltf.impl.v1.Camera; +import de.javagl.jgltf.impl.v1.CameraOrthographic; +import de.javagl.jgltf.impl.v1.CameraPerspective; +import de.javagl.jgltf.impl.v1.GlTF; +import de.javagl.jgltf.impl.v1.GlTFChildOfRootProperty; +import de.javagl.jgltf.impl.v1.GlTFProperty; +import de.javagl.jgltf.impl.v1.Image; +import de.javagl.jgltf.impl.v1.Material; +import de.javagl.jgltf.impl.v1.Mesh; +import de.javagl.jgltf.impl.v1.MeshPrimitive; +import de.javagl.jgltf.impl.v1.Node; +import de.javagl.jgltf.impl.v1.Program; +import de.javagl.jgltf.impl.v1.Sampler; +import de.javagl.jgltf.impl.v1.Scene; +import de.javagl.jgltf.impl.v1.Shader; +import de.javagl.jgltf.impl.v1.Skin; +import de.javagl.jgltf.impl.v1.Technique; +import de.javagl.jgltf.impl.v1.TechniqueParameters; +import de.javagl.jgltf.impl.v1.TechniqueStates; +import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; +import de.javagl.jgltf.impl.v1.Texture; +import de.javagl.jgltf.model.AccessorDatas; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.Accessors; +import de.javagl.jgltf.model.AnimationModel; import de.javagl.jgltf.model.AnimationModel.Channel; import de.javagl.jgltf.model.AnimationModel.Interpolation; -import de.javagl.jgltf.model.gl.*; +import de.javagl.jgltf.model.AssetModel; +import de.javagl.jgltf.model.BufferModel; +import de.javagl.jgltf.model.BufferViewModel; +import de.javagl.jgltf.model.CameraModel; +import de.javagl.jgltf.model.ElementType; +import de.javagl.jgltf.model.ExtensionsModel; +import de.javagl.jgltf.model.GltfConstants; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.ImageModel; +import de.javagl.jgltf.model.MaterialModel; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.Optionals; +import de.javagl.jgltf.model.SceneModel; +import de.javagl.jgltf.model.SkinModel; +import de.javagl.jgltf.model.TextureModel; +import de.javagl.jgltf.model.gl.ProgramModel; +import de.javagl.jgltf.model.gl.ShaderModel; import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; -import de.javagl.jgltf.model.gl.impl.*; -import de.javagl.jgltf.model.impl.*; +import de.javagl.jgltf.model.gl.TechniqueModel; +import de.javagl.jgltf.model.gl.TechniqueParametersModel; +import de.javagl.jgltf.model.gl.TechniqueStatesModel; +import de.javagl.jgltf.model.gl.impl.DefaultProgramModel; +import de.javagl.jgltf.model.gl.impl.DefaultShaderModel; +import de.javagl.jgltf.model.gl.impl.DefaultTechniqueModel; +import de.javagl.jgltf.model.gl.impl.DefaultTechniqueParametersModel; +import de.javagl.jgltf.model.gl.impl.DefaultTechniqueStatesFunctionsModel; +import de.javagl.jgltf.model.gl.impl.DefaultTechniqueStatesModel; +import de.javagl.jgltf.model.impl.AbstractModelElement; +import de.javagl.jgltf.model.impl.AbstractNamedModelElement; +import de.javagl.jgltf.model.impl.DefaultAccessorModel; +import de.javagl.jgltf.model.impl.DefaultAnimationModel; import de.javagl.jgltf.model.impl.DefaultAnimationModel.DefaultChannel; import de.javagl.jgltf.model.impl.DefaultAnimationModel.DefaultSampler; +import de.javagl.jgltf.model.impl.DefaultAssetModel; +import de.javagl.jgltf.model.impl.DefaultBufferModel; +import de.javagl.jgltf.model.impl.DefaultBufferViewModel; +import de.javagl.jgltf.model.impl.DefaultCameraModel; +import de.javagl.jgltf.model.impl.DefaultCameraOrthographicModel; +import de.javagl.jgltf.model.impl.DefaultCameraPerspectiveModel; +import de.javagl.jgltf.model.impl.DefaultExtensionsModel; +import de.javagl.jgltf.model.impl.DefaultGltfModel; +import de.javagl.jgltf.model.impl.DefaultImageModel; +import de.javagl.jgltf.model.impl.DefaultMeshModel; +import de.javagl.jgltf.model.impl.DefaultMeshPrimitiveModel; +import de.javagl.jgltf.model.impl.DefaultNodeModel; +import de.javagl.jgltf.model.impl.DefaultSceneModel; +import de.javagl.jgltf.model.impl.DefaultSkinModel; +import de.javagl.jgltf.model.impl.DefaultTextureModel; import de.javagl.jgltf.model.io.Buffers; import de.javagl.jgltf.model.io.GltfAsset; import de.javagl.jgltf.model.io.IO; @@ -48,323 +135,77 @@ import de.javagl.jgltf.model.v1.gl.TechniqueStatesFunctionsModels; import net.minecraft.resources.ResourceLocation; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.Map.Entry; -import java.util.function.Function; -import java.util.function.IntFunction; -import java.util.logging.Logger; - /** * A class that is responsible for filling a {@link DefaultGltfModel} with * the model instances that are created from a {@link GltfAssetV1} */ -public class GltfModelCreatorV1 { +public class GltfModelCreatorV1 +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfModelCreatorV1.class.getName()); + private static final Logger logger = + Logger.getLogger(GltfModelCreatorV1.class.getName()); + + /** + * Create the {@link GltfModel} for the given {@link GltfAssetV1} + * + * @param gltfAsset The {@link GltfAssetV1} + * @return The {@link GltfModel} + */ + public static GltfModelV1 create(GltfAssetV1 gltfAsset) + { + GltfModelV1 gltfModel = new GltfModelV1(); + GltfModelCreatorV1 creator = + new GltfModelCreatorV1(gltfAsset, gltfModel); + creator.create(); + return gltfModel; + } + /** * The {@link IndexMappingSet} */ private final IndexMappingSet indexMappingSet; + /** * The {@link GltfAsset} of this model */ private final GltfAsset gltfAsset; + /** * The {@link GlTF} of this model */ private final GlTF gltf; + /** * The {@link GltfModel} that is built */ private final GltfModelV1 gltfModel; - + /** * Creates a new model for the given glTF - * + * * @param gltfAsset The {@link GltfAssetV1} * @param gltfModel The {@link GltfModel} */ GltfModelCreatorV1( - GltfAssetV1 gltfAsset, GltfModelV1 gltfModel) { - this.gltfAsset = Objects.requireNonNull(gltfAsset, - "The gltfAsset may not be null"); + GltfAssetV1 gltfAsset, GltfModelV1 gltfModel) + { + this.gltfAsset = Objects.requireNonNull(gltfAsset, + "The gltfAsset may not be null"); this.gltf = gltfAsset.getGltf(); - this.gltfModel = Objects.requireNonNull(gltfModel, - "The gltfModel may not be null"); + this.gltfModel = Objects.requireNonNull(gltfModel, + "The gltfModel may not be null"); this.indexMappingSet = IndexMappingSets.create(gltfAsset.getGltf()); } - - /** - * Create the {@link GltfModel} for the given {@link GltfAssetV1} - * - * @param gltfAsset The {@link GltfAssetV1} - * @return The {@link GltfModel} - */ - public static GltfModelV1 create(GltfAssetV1 gltfAsset) { - GltfModelV1 gltfModel = new GltfModelV1(); - GltfModelCreatorV1 creator = - new GltfModelCreatorV1(gltfAsset, gltfModel); - creator.create(); - return gltfModel; - } - - /** - * Create a {@link DefaultAccessorModel} for the given {@link Accessor} - * - * @param accessor The {@link Accessor} - * @return The {@link AccessorModel} - */ - private static DefaultAccessorModel createAccessorModel(Accessor accessor) { - Integer componentType = accessor.getComponentType(); - Integer byteOffset = accessor.getByteOffset(); - Integer count = accessor.getCount(); - ElementType elementType = ElementType.forString(accessor.getType()); - Integer byteStride = accessor.getByteStride(); - if (byteStride == null) { - byteStride = elementType.getNumComponents() * - Accessors.getNumBytesForAccessorComponentType( - componentType); - } - DefaultAccessorModel accessorModel = new DefaultAccessorModel( - componentType, count, elementType); - accessorModel.setByteOffset(byteOffset); - accessorModel.setByteStride(byteStride); - return accessorModel; - } - - /** - * Create a {@link DefaultBufferViewModel} for the given {@link BufferView} - * - * @param bufferView The {@link BufferView} - * @return The {@link BufferViewModel} - */ - private static DefaultBufferViewModel createBufferViewModel( - BufferView bufferView) { - int byteOffset = bufferView.getByteOffset(); - Integer byteLength = bufferView.getByteLength(); - if (byteLength == null) { - logger.warning("No byteLength found in BufferView"); - byteLength = 0; - } - Integer target = bufferView.getTarget(); - DefaultBufferViewModel bufferViewModel = - new DefaultBufferViewModel(target); - bufferViewModel.setByteOffset(byteOffset); - bufferViewModel.setByteLength(byteLength); - return bufferViewModel; - } - - /** - * Computes the {@link AccessorModel#getByteStride() byte stride} of - * the given {@link AccessorModel} instances. If the given instances - * do not have the same byte stride, then a warning will be printed. - * - * @param accessorModels The {@link AccessorModel} instances - * @return The common byte stride - */ - private static int computeCommonByteStride( - Iterable accessorModels) { - int commonByteStride = -1; - for (AccessorModel accessorModel : accessorModels) { - int byteStride = accessorModel.getByteStride(); - if (commonByteStride == -1) { - commonByteStride = byteStride; - } else { - if (commonByteStride != byteStride) { - logger.warning("The accessor models do not have the " - + "same byte stride: " + commonByteStride - + " and " + byteStride); - } - } - } - return commonByteStride; - } - - /** - * Compute the mapping from joint names to the ID of the {@link Node} with - * the respective {@link Node#getJointName() joint name} - * - * @param gltf The {@link GlTF} - * @return The mapping - */ - private static Map computeJointNameToNodeIdMap(GlTF gltf) { - Map map = new LinkedHashMap(); - Map nodes = Optionals.of(gltf.getNodes()); - for (Entry entry : nodes.entrySet()) { - String nodeId = entry.getKey(); - Node node = entry.getValue(); - if (node.getJointName() != null) { - String oldNodeId = map.put(node.getJointName(), nodeId); - if (oldNodeId != null) { - logger.warning("Joint name " + node.getJointName() - + " is mapped to nodes with IDs " + nodeId + " and " - + oldNodeId); - } - } - } - return map; - } - - /** - * Add all {@link TechniqueParametersModel} instances for the - * attributes of the given {@link Technique} to the given - * {@link TechniqueModel} - * - * @param technique The {@link Technique} - * @param techniqueModel The {@link TechniqueModel} - * @param nodeLookup The function for looking up the {@link NodeModel} - * for a given node ID. This may be null, but if its is - * null and there is a non-null node ID - * in the technique parameters, then an error message will be - * printed. - */ - private static void addParameters(Technique technique, - DefaultTechniqueModel techniqueModel, - Function nodeLookup) { - Map parameters = - Optionals.of(technique.getParameters()); - for (Entry entry : parameters.entrySet()) { - String parameterName = entry.getKey(); - TechniqueParameters parameter = entry.getValue(); - - int type = parameter.getType(); - int count = Optionals.of(parameter.getCount(), 1); - String semantic = parameter.getSemantic(); - Object value = parameter.getValue(); - String nodeId = parameter.getNode(); - NodeModel nodeModel = null; - if (nodeId != null) { - if (nodeLookup == null) { - logger.severe("No lookup function found for the nodes"); - } else { - nodeModel = nodeLookup.apply(nodeId); - } - } - - TechniqueParametersModel techniqueParametersModel = - new DefaultTechniqueParametersModel( - type, count, semantic, value, nodeModel); - techniqueModel.addParameter( - parameterName, techniqueParametersModel); - } - } - - /** - * Add all attribute entries of the given {@link Technique} to the given - * {@link TechniqueModel} - * - * @param technique The {@link Technique} - * @param techniqueModel The {@link TechniqueModel} - */ - private static void addAttributes(Technique technique, - DefaultTechniqueModel techniqueModel) { - Map attributes = - Optionals.of(technique.getAttributes()); - for (Entry entry : attributes.entrySet()) { - String attributeName = entry.getKey(); - String parameterName = entry.getValue(); - techniqueModel.addAttribute(attributeName, parameterName); - } - } - - /** - * Add all uniform entries of the given {@link Technique} to the given - * {@link TechniqueModel} - * - * @param technique The {@link Technique} - * @param techniqueModel The {@link TechniqueModel} - */ - private static void addUniforms(Technique technique, - DefaultTechniqueModel techniqueModel) { - Map uniforms = - Optionals.of(technique.getUniforms()); - for (Entry entry : uniforms.entrySet()) { - String uniformName = entry.getKey(); - String parameterName = entry.getValue(); - techniqueModel.addUniform(uniformName, parameterName); - } - } - - /** - * Initialize the given {@link TechniqueModel} with the values that are - * obtained from the given {@link Technique} - * - * @param techniqueModel The {@link TechniqueModel} - * @param technique The {@link Technique} - * @param nodeLookup The function for looking up the {@link NodeModel} - * for a given node ID. This may be null, but if its is - * null and there is a non-null node ID - * in the technique parameters, then an error message will be - * printed. - */ - public static void initTechniqueModel( - DefaultTechniqueModel techniqueModel, Technique technique, - Function nodeLookup) { - transferGltfChildOfRootPropertyElements(technique, techniqueModel); - - addParameters(technique, techniqueModel, nodeLookup); - addAttributes(technique, techniqueModel); - addUniforms(technique, techniqueModel); - - List enableModel = null; - DefaultTechniqueStatesFunctionsModel techniqueStatesFunctionsModel = - null; - TechniqueStates states = technique.getStates(); - if (states != null) { - List enable = states.getEnable(); - if (enable != null) { - enableModel = new ArrayList(enable); - } - TechniqueStatesFunctions functions = states.getFunctions(); - if (functions != null) { - techniqueStatesFunctionsModel = - TechniqueStatesFunctionsModels.create(functions); - } - - TechniqueStatesModel techniqueStatesModel = - new DefaultTechniqueStatesModel( - enableModel, techniqueStatesFunctionsModel); - techniqueModel.setTechniqueStatesModel(techniqueStatesModel); - } - } - - /** - * Transfer the extensions and extras from the given property to - * the given target - * - * @param property The property - * @param modelElement The target - */ - private static void transferGltfPropertyElements( - GlTFProperty property, AbstractModelElement modelElement) { - modelElement.setExtensions(property.getExtensions()); - modelElement.setExtras(property.getExtras()); - } - - /** - * Transfer the name and extensions and extras from the given property to - * the given target - * - * @param property The property - * @param modelElement The target - */ - private static void transferGltfChildOfRootPropertyElements( - GlTFChildOfRootProperty property, - AbstractNamedModelElement modelElement) { - modelElement.setName(property.getName()); - transferGltfPropertyElements(property, modelElement); - } - + /** * Create and initialize all models */ - void create() { + void create() + { transferGltfPropertyElements(gltf, gltfModel); - + createAccessorModels(); createAnimationModels(); createBufferModels(); @@ -380,14 +221,14 @@ void create() { createShaderModels(); createProgramModels(); createTechniqueModels(); - + initBufferModels(); initBufferViewModels(); - + initAccessorModels(); - + assignBufferViewByteStrides(); - + initAnimationModels(); initImageModels(); initTechniqueModels(); @@ -399,135 +240,206 @@ void create() { initTextureModels(); initShaderModels(); initProgramModels(); - + initExtensionsModel(); initAssetModel(); } - + /** * Create the {@link AccessorModel} instances */ - private void createAccessorModels() { + private void createAccessorModels() + { Map accessors = Optionals.of(gltf.getAccessors()); - for (Accessor accessor : accessors.values()) { + for (Accessor accessor : accessors.values()) + { DefaultAccessorModel accessorModel = createAccessorModel(accessor); gltfModel.addAccessorModel(accessorModel); } } + /** + * Create a {@link DefaultAccessorModel} for the given {@link Accessor} + * + * @param accessor The {@link Accessor} + * @return The {@link AccessorModel} + */ + private static DefaultAccessorModel createAccessorModel(Accessor accessor) + { + Integer componentType = accessor.getComponentType(); + Integer byteOffset = accessor.getByteOffset(); + Integer count = accessor.getCount(); + ElementType elementType = ElementType.forString(accessor.getType()); + Integer byteStride = accessor.getByteStride(); + if (byteStride == null) + { + byteStride = elementType.getNumComponents() * + Accessors.getNumBytesForAccessorComponentType( + componentType); + } + DefaultAccessorModel accessorModel = new DefaultAccessorModel( + componentType, count, elementType); + accessorModel.setByteOffset(byteOffset); + accessorModel.setByteStride(byteStride); + return accessorModel; + } + /** * Create the {@link AnimationModel} instances */ - private void createAnimationModels() { + private void createAnimationModels() + { Map animations = Optionals.of(gltf.getAnimations()); - for (int i = 0; i < animations.size(); i++) { + for (int i = 0; i < animations.size(); i++) + { gltfModel.addAnimationModel(new DefaultAnimationModel()); } } - + /** * Create the {@link BufferModel} instances */ - private void createBufferModels() { + private void createBufferModels() + { Map buffers = Optionals.of(gltf.getBuffers()); - for (Buffer buffer : buffers.values()) { + for (Buffer buffer : buffers.values()) + { DefaultBufferModel bufferModel = new DefaultBufferModel(); bufferModel.setUri(buffer.getUri()); gltfModel.addBufferModel(bufferModel); } } - + /** * Create the {@link BufferViewModel} instances */ - private void createBufferViewModels() { - Map bufferViews = - Optionals.of(gltf.getBufferViews()); - for (BufferView bufferView : bufferViews.values()) { - DefaultBufferViewModel bufferViewModel = - createBufferViewModel(bufferView); + private void createBufferViewModels() + { + Map bufferViews = + Optionals.of(gltf.getBufferViews()); + for (BufferView bufferView : bufferViews.values()) + { + DefaultBufferViewModel bufferViewModel = + createBufferViewModel(bufferView); gltfModel.addBufferViewModel(bufferViewModel); } } - + /** * Create the {@link CameraModel} instances */ - private void createCameraModels() { - Map cameras = - Optionals.of(gltf.getCameras()); - for (Camera camera : cameras.values()) { + private void createCameraModels() + { + Map cameras = + Optionals.of(gltf.getCameras()); + for (Camera camera : cameras.values()) + { String type = camera.getType(); - if ("perspective".equals(type)) { + if ("perspective".equals(type)) + { CameraPerspective cameraPerspective = camera.getPerspective(); - DefaultCameraPerspectiveModel cameraPerspectiveModel = - new DefaultCameraPerspectiveModel(); + DefaultCameraPerspectiveModel cameraPerspectiveModel = + new DefaultCameraPerspectiveModel(); cameraPerspectiveModel.setAspectRatio( - cameraPerspective.getAspectRatio()); + cameraPerspective.getAspectRatio()); cameraPerspectiveModel.setYfov( - cameraPerspective.getYfov()); + cameraPerspective.getYfov()); cameraPerspectiveModel.setZfar( - cameraPerspective.getZfar()); + cameraPerspective.getZfar()); cameraPerspectiveModel.setZnear( - cameraPerspective.getZnear()); - DefaultCameraModel cameraModel = - new DefaultCameraModel(); + cameraPerspective.getZnear()); + DefaultCameraModel cameraModel = + new DefaultCameraModel(); cameraModel.setCameraPerspectiveModel(cameraPerspectiveModel); gltfModel.addCameraModel(cameraModel); - } else if ("orthographic".equals(type)) { - CameraOrthographic cameraOrthographic = - camera.getOrthographic(); - DefaultCameraOrthographicModel cameraOrthographicModel = - new DefaultCameraOrthographicModel(); + } + else if ("orthographic".equals(type)) + { + CameraOrthographic cameraOrthographic = + camera.getOrthographic(); + DefaultCameraOrthographicModel cameraOrthographicModel = + new DefaultCameraOrthographicModel(); cameraOrthographicModel.setXmag( - cameraOrthographic.getXmag()); + cameraOrthographic.getXmag()); cameraOrthographicModel.setYmag( - cameraOrthographic.getYmag()); + cameraOrthographic.getYmag()); cameraOrthographicModel.setZfar( - cameraOrthographic.getZfar()); + cameraOrthographic.getZfar()); cameraOrthographicModel.setZnear( - cameraOrthographic.getZnear()); - DefaultCameraModel cameraModel = - new DefaultCameraModel(); + cameraOrthographic.getZnear()); + DefaultCameraModel cameraModel = + new DefaultCameraModel(); cameraModel.setCameraOrthographicModel(cameraOrthographicModel); gltfModel.addCameraModel(cameraModel); - } else { + } + else + { logger.severe("Invalid camera type: " + type); } } } + /** + * Create a {@link DefaultBufferViewModel} for the given {@link BufferView} + * + * @param bufferView The {@link BufferView} + * @return The {@link BufferViewModel} + */ + private static DefaultBufferViewModel createBufferViewModel( + BufferView bufferView) + { + int byteOffset = bufferView.getByteOffset(); + Integer byteLength = bufferView.getByteLength(); + if (byteLength == null) + { + logger.warning("No byteLength found in BufferView"); + byteLength = 0; + } + Integer target = bufferView.getTarget(); + DefaultBufferViewModel bufferViewModel = + new DefaultBufferViewModel(target); + bufferViewModel.setByteOffset(byteOffset); + bufferViewModel.setByteLength(byteLength); + return bufferViewModel; + } + /** * Create the {@link ImageModel} instances */ - private void createImageModels() { - Map images = - Optionals.of(gltf.getImages()); - for (Image image : images.values()) { - DefaultImageModel imageModel = - new DefaultImageModel(); + private void createImageModels() + { + Map images = + Optionals.of(gltf.getImages()); + for (Image image : images.values()) + { + DefaultImageModel imageModel = + new DefaultImageModel(); String uri = image.getUri(); imageModel.setUri(uri); gltfModel.addImageModel(imageModel); } } - + /** * Create the {@link MaterialModel} instances */ - private void createMaterialModels() { + private void createMaterialModels() + { Map materials = Optionals.of(gltf.getMaterials()); - for (int i = 0; i < materials.size(); i++) { + for (int i = 0; i < materials.size(); i++) + { gltfModel.addMaterialModel(new MaterialModelV1()); } } - + /** * Create the {@link MeshModel} instances */ - private void createMeshModels() { + private void createMeshModels() + { Map meshes = Optionals.of(gltf.getMeshes()); - for (int i = 0; i < meshes.size(); i++) { + for (int i = 0; i < meshes.size(); i++) + { gltfModel.addMeshModel(new DefaultMeshModel()); } } @@ -535,9 +447,11 @@ private void createMeshModels() { /** * Create the {@link NodeModel} instances */ - private void createNodeModels() { + private void createNodeModels() + { Map nodes = Optionals.of(gltf.getNodes()); - for (int i = 0; i < nodes.size(); i++) { + for (int i = 0; i < nodes.size(); i++) + { gltfModel.addNodeModel(new DefaultNodeModel()); } } @@ -545,19 +459,23 @@ private void createNodeModels() { /** * Create the {@link SceneModel} instances */ - private void createSceneModels() { + private void createSceneModels() + { Map scenes = Optionals.of(gltf.getScenes()); - for (int i = 0; i < scenes.size(); i++) { + for (int i = 0; i < scenes.size(); i++) + { gltfModel.addSceneModel(new DefaultSceneModel()); } } - + /** * Create the {@link SkinModel} instances */ - private void createSkinModels() { + private void createSkinModels() + { Map skins = Optionals.of(gltf.getSkins()); - for (Entry entry : skins.entrySet()) { + for (Entry entry : skins.entrySet()) + { Skin skin = entry.getValue(); float[] bindShapeMatrix = skin.getBindShapeMatrix(); DefaultSkinModel skinModel = new DefaultSkinModel(); @@ -569,23 +487,25 @@ private void createSkinModels() { /** * Create the {@link TextureModel} instances */ - private void createTextureModels() { + private void createTextureModels() + { Map textures = Optionals.of(gltf.getTextures()); Map samplers = Optionals.of(gltf.getSamplers()); - for (Entry entry : textures.entrySet()) { + for (Entry entry : textures.entrySet()) + { Texture texture = entry.getValue(); String samplerId = texture.getSampler(); Sampler sampler = samplers.get(samplerId); - + int magFilter = Optionals.of( - sampler.getMagFilter(), sampler.defaultMagFilter()); + sampler.getMagFilter(), sampler.defaultMagFilter()); int minFilter = Optionals.of( - sampler.getMinFilter(), sampler.defaultMinFilter()); + sampler.getMinFilter(), sampler.defaultMinFilter()); int wrapS = Optionals.of( - sampler.getWrapS(), sampler.defaultWrapS()); + sampler.getWrapS(), sampler.defaultWrapS()); int wrapT = Optionals.of( - sampler.getWrapT(), sampler.defaultWrapT()); - + sampler.getWrapT(), sampler.defaultWrapT()); + DefaultTextureModel textureModel = new DefaultTextureModel(); textureModel.setMagFilter(magFilter); textureModel.setMinFilter(minFilter); @@ -594,23 +514,28 @@ private void createTextureModels() { gltfModel.addTextureModel(textureModel); } } - + /** * Create the {@link ShaderModel} instances */ - private void createShaderModels() { + private void createShaderModels() + { Map shaders = Optionals.of(gltf.getShaders()); - for (Entry entry : shaders.entrySet()) { + for (Entry entry : shaders.entrySet()) + { Shader shader = entry.getValue(); Integer type = shader.getType(); ShaderType shaderType = null; - if (type == GltfConstants.GL_VERTEX_SHADER) { + if (type == GltfConstants.GL_VERTEX_SHADER) + { shaderType = ShaderType.VERTEX_SHADER; - } else { + } + else + { shaderType = ShaderType.FRAGMENT_SHADER; } DefaultShaderModel shaderModel = - new DefaultShaderModel(shader.getUri(), shaderType); + new DefaultShaderModel(shader.getUri(), shaderType); gltfModel.addShaderModel(shaderModel); } } @@ -618,39 +543,46 @@ private void createShaderModels() { /** * Create the {@link ProgramModel} instances */ - private void createProgramModels() { + private void createProgramModels() + { Map programs = Optionals.of(gltf.getPrograms()); - for (int i = 0; i < programs.size(); i++) { + for (int i = 0; i < programs.size(); i++) + { gltfModel.addProgramModel(new DefaultProgramModel()); } } - + /** * Create the {@link TechniqueModel} instances */ - private void createTechniqueModels() { + private void createTechniqueModels() + { Map techniques = Optionals.of(gltf.getTechniques()); - for (int i = 0; i < techniques.size(); i++) { + for (int i = 0; i < techniques.size(); i++) + { gltfModel.addTechniqueModel(new DefaultTechniqueModel()); } } + /** * Initialize the {@link AccessorModel} instances */ - private void initAccessorModels() { + private void initAccessorModels() + { Map accessors = Optionals.of(gltf.getAccessors()); - for (Entry entry : accessors.entrySet()) { + for (Entry entry : accessors.entrySet()) + { String accessorId = entry.getKey(); Accessor accessor = entry.getValue(); String bufferViewId = accessor.getBufferView(); - BufferViewModel bufferViewModel = - get("bufferViews", bufferViewId, - gltfModel::getBufferViewModel); + BufferViewModel bufferViewModel = + get("bufferViews", bufferViewId, + gltfModel::getBufferViewModel); DefaultAccessorModel accessorModel = - get("accessors", accessorId, - gltfModel::getAccessorModel); - + get("accessors", accessorId, + gltfModel::getAccessorModel); + transferGltfChildOfRootPropertyElements(accessor, accessorModel); accessorModel.setBufferViewModel(bufferViewModel); accessorModel.setAccessorData(AccessorDatas.create(accessorModel)); @@ -660,352 +592,433 @@ private void initAccessorModels() { /** * Initialize the {@link AnimationModel} instances */ - private void initAnimationModels() { + private void initAnimationModels() + { Map animations = Optionals.of(gltf.getAnimations()); - for (Entry entry : animations.entrySet()) { + for (Entry entry : animations.entrySet()) + { String animationId = entry.getKey(); Animation animation = entry.getValue(); DefaultAnimationModel animationModel = - get("animations", animationId, - gltfModel::getAnimationModel); + get("animations", animationId, + gltfModel::getAnimationModel); transferGltfChildOfRootPropertyElements(animation, animationModel); - List channels = - Optionals.of(animation.getChannels()); - for (AnimationChannel animationChannel : channels) { + List channels = + Optionals.of(animation.getChannels()); + for (AnimationChannel animationChannel : channels) + { Channel channel = createChannel(animation, animationChannel); animationModel.addChannel(channel); } } } - + /** * Initialize the {@link ImageModel} instances */ - private void initImageModels() { + private void initImageModels() + { Map images = Optionals.of(gltf.getImages()); - for (Entry entry : images.entrySet()) { + for (Entry entry : images.entrySet()) + { String imageId = entry.getKey(); Image image = entry.getValue(); DefaultImageModel imageModel = - get("images", imageId, gltfModel::getImageModel); + get("images", imageId, gltfModel::getImageModel); transferGltfChildOfRootPropertyElements(image, imageModel); - + Object extras = image.getExtras(); - if (extras != null) { - JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); - if (extra != null) { - imageModel.setImageData(MCglTF.getInstance().getImageResource(new ResourceLocation(extra.getAsString()))); - continue; - } - } - - if (BinaryGltfV1.hasBinaryGltfExtension(image)) { - String bufferViewId = - BinaryGltfV1.getBinaryGltfBufferViewId(image); + if(extras != null) { + JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); + if(extra != null) { + imageModel.setImageData(MCglTF.getInstance().getImageResource(new ResourceLocation(extra.getAsString()))); + continue; + } + } + + if (BinaryGltfV1.hasBinaryGltfExtension(image)) + { + String bufferViewId = + BinaryGltfV1.getBinaryGltfBufferViewId(image); BufferViewModel bufferViewModel = - get("bufferViews", bufferViewId, - gltfModel::getBufferViewModel); + get("bufferViews", bufferViewId, + gltfModel::getBufferViewModel); imageModel.setBufferViewModel(bufferViewModel); - } else { + } + else + { String uri = image.getUri(); - if (IO.isDataUriString(uri)) { + if (IO.isDataUriString(uri)) + { byte data[] = IO.readDataUri(uri); ByteBuffer imageData = Buffers.create(data); imageModel.setImageData(imageData); - } else { + } + else + { ByteBuffer imageData = gltfAsset.getReferenceData(uri); imageModel.setImageData(imageData); } } } } - + /** * Create the {@link Channel} object for the given animation and animation * channel - * - * @param animation The {@link Animation} + * + * @param animation The {@link Animation} * @param animationChannel The {@link AnimationChannel} * @return The {@link Channel} */ private Channel createChannel( - Animation animation, AnimationChannel animationChannel) { - Map parameters = - Optionals.of(animation.getParameters()); - Map samplers = - Optionals.of(animation.getSamplers()); + Animation animation, AnimationChannel animationChannel) + { + Map parameters = + Optionals.of(animation.getParameters()); + Map samplers = + Optionals.of(animation.getSamplers()); String samplerId = animationChannel.getSampler(); AnimationSampler animationSampler = samplers.get(samplerId); - + String inputParameterId = animationSampler.getInput(); String inputAccessorId = parameters.get(inputParameterId); - if (inputAccessorId == null) { - // This was valid for a short time, when glTF 2.0 was still - // called glTF 1.1. The check here is not perfectly reliable, - // but there should be a decreasing number of glTF 1.0 models + if (inputAccessorId == null) + { + // This was valid for a short time, when glTF 2.0 was still + // called glTF 1.1. The check here is not perfectly reliable, + // but there should be a decreasing number of glTF 1.0 models // out there, and even fewer glTF 1.1 ones. logger.warning( - "Assuming " + inputParameterId + " to be an accessor ID"); + "Assuming " + inputParameterId + " to be an accessor ID"); inputAccessorId = inputParameterId; } - AccessorModel inputAccessorModel = - get("accessors", inputAccessorId, gltfModel::getAccessorModel); - + AccessorModel inputAccessorModel = + get("accessors", inputAccessorId, gltfModel::getAccessorModel); + String outputParameterId = animationSampler.getOutput(); String outputAccessorId = parameters.get(outputParameterId); - if (outputAccessorId == null) { - // This was valid for a short time, when glTF 2.0 was still - // called glTF 1.1. The check here is not perfectly reliable, - // but there should be a decreasing number of glTF 1.0 models + if (outputAccessorId == null) + { + // This was valid for a short time, when glTF 2.0 was still + // called glTF 1.1. The check here is not perfectly reliable, + // but there should be a decreasing number of glTF 1.0 models // out there, and even fewer glTF 1.1 ones. logger.warning( - "Assuming " + outputParameterId + " to be an accessor ID"); + "Assuming " + outputParameterId + " to be an accessor ID"); outputAccessorId = outputParameterId; } - AccessorModel outputAccessorModel = - get("accessors", outputAccessorId, gltfModel::getAccessorModel); - - String interpolationString = - animationSampler.getInterpolation(); - Interpolation interpolation = - interpolationString == null ? Interpolation.LINEAR : - Interpolation.valueOf(interpolationString); - + AccessorModel outputAccessorModel = + get("accessors", outputAccessorId, gltfModel::getAccessorModel); + + String interpolationString = + animationSampler.getInterpolation(); + Interpolation interpolation = + interpolationString == null ? Interpolation.LINEAR : + Interpolation.valueOf(interpolationString); + AnimationModel.Sampler sampler = new DefaultSampler( - inputAccessorModel, interpolation, outputAccessorModel); - - AnimationChannelTarget animationChannelTarget = - animationChannel.getTarget(); + inputAccessorModel, interpolation, outputAccessorModel); + + AnimationChannelTarget animationChannelTarget = + animationChannel.getTarget(); String nodeId = animationChannelTarget.getId(); String path = animationChannelTarget.getPath(); - + NodeModel nodeModel = get("nodes", nodeId, gltfModel::getNodeModel); - + Channel channel = - new DefaultChannel(sampler, nodeModel, path); + new DefaultChannel(sampler, nodeModel, path); return channel; } /** * Initialize the {@link BufferModel} instances */ - private void initBufferModels() { + private void initBufferModels() + { ByteBuffer binaryData = null; ByteBuffer b = gltfAsset.getBinaryData(); - if (b != null && b.capacity() > 0) { + if (b != null && b.capacity() > 0) + { binaryData = b; } - + Map buffers = Optionals.of(gltf.getBuffers()); - for (Entry entry : buffers.entrySet()) { + for (Entry entry : buffers.entrySet()) + { String bufferId = entry.getKey(); Buffer buffer = entry.getValue(); - DefaultBufferModel bufferModel = - get("buffers", bufferId, gltfModel::getBufferModel); + DefaultBufferModel bufferModel = + get("buffers", bufferId, gltfModel::getBufferModel); transferGltfChildOfRootPropertyElements(buffer, bufferModel); - + Object extras = buffer.getExtras(); - if (extras != null) { - JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); - if (extra != null) { - bufferModel.setBufferData(MCglTF.getInstance().getBufferResource(new ResourceLocation(extra.getAsString()))); - continue; - } - } - - if (BinaryGltfV1.isBinaryGltfBufferId(bufferId)) { - if (binaryData == null) { + if(extras != null) { + JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); + if(extra != null) { + bufferModel.setBufferData(MCglTF.getInstance().getBufferResource(new ResourceLocation(extra.getAsString()))); + continue; + } + } + + if (BinaryGltfV1.isBinaryGltfBufferId(bufferId)) + { + if (binaryData == null) + { logger.severe("The glTF contains a buffer with the binary" - + " buffer ID, but no binary data has been given"); + + " buffer ID, but no binary data has been given"); continue; } bufferModel.setBufferData(binaryData); - } else { + } + else + { String uri = buffer.getUri(); - if (IO.isDataUriString(uri)) { + if (IO.isDataUriString(uri)) + { byte data[] = IO.readDataUri(uri); ByteBuffer bufferData = Buffers.create(data); bufferModel.setBufferData(bufferData); - } else { + } + else + { ByteBuffer bufferData = gltfAsset.getReferenceData(uri); bufferModel.setBufferData(bufferData); } } } } - + + /** * Initialize the {@link BufferViewModel} instances */ - private void initBufferViewModels() { - Map bufferViews = - Optionals.of(gltf.getBufferViews()); - for (Entry entry : bufferViews.entrySet()) { + private void initBufferViewModels() + { + Map bufferViews = + Optionals.of(gltf.getBufferViews()); + for (Entry entry : bufferViews.entrySet()) + { String bufferViewId = entry.getKey(); BufferView bufferView = entry.getValue(); - + String bufferId = bufferView.getBuffer(); - BufferModel bufferModel = - get("buffers", bufferId, gltfModel::getBufferModel); - DefaultBufferViewModel bufferViewModel = - get("bufferViews", bufferViewId, gltfModel::getBufferViewModel); + BufferModel bufferModel = + get("buffers", bufferId, gltfModel::getBufferModel); + DefaultBufferViewModel bufferViewModel = + get("bufferViews", bufferViewId, gltfModel::getBufferViewModel); transferGltfChildOfRootPropertyElements( - bufferView, bufferViewModel); + bufferView, bufferViewModel); bufferViewModel.setBufferModel(bufferModel); } } - + /** * Compute all {@link AccessorModel} instances that refer to the * given {@link BufferViewModel} - * + * * @param bufferViewModel The {@link BufferViewModel} * @return The list of {@link AccessorModel} instances */ private List computeAccessorModelsOf( - BufferViewModel bufferViewModel) { - List result = - new ArrayList(); + BufferViewModel bufferViewModel) + { + List result = + new ArrayList(); int n = gltfModel.getAccessorModels().size(); - for (int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) + { DefaultAccessorModel accessorModel = gltfModel.getAccessorModel(i); BufferViewModel b = accessorModel.getBufferViewModel(); - if (bufferViewModel.equals(b)) { + if (bufferViewModel.equals(b)) + { result.add(accessorModel); } } return result; } + + /** + * Computes the {@link AccessorModel#getByteStride() byte stride} of + * the given {@link AccessorModel} instances. If the given instances + * do not have the same byte stride, then a warning will be printed. + * + * @param accessorModels The {@link AccessorModel} instances + * @return The common byte stride + */ + private static int computeCommonByteStride( + Iterable accessorModels) + { + int commonByteStride = -1; + for (AccessorModel accessorModel : accessorModels) + { + int byteStride = accessorModel.getByteStride(); + if (commonByteStride == -1) + { + commonByteStride = byteStride; + } + else + { + if (commonByteStride != byteStride) + { + logger.warning("The accessor models do not have the " + + "same byte stride: " + commonByteStride + + " and " + byteStride); + } + } + } + return commonByteStride; + } + /** * Set the {@link BufferViewModel#getByteStride() byte strides} of all - * {@link BufferViewModel} instances, depending on the + * {@link BufferViewModel} instances, depending on the * {@link AccessorModel} instances that refer to them */ - private void assignBufferViewByteStrides() { + private void assignBufferViewByteStrides() + { int n = gltfModel.getBufferModels().size(); - for (int i = 0; i < n; i++) { - DefaultBufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(i); - List accessorModelsOfBufferView = - computeAccessorModelsOf(bufferViewModel); - if (accessorModelsOfBufferView.size() > 1) { - int byteStride = - computeCommonByteStride(accessorModelsOfBufferView); + for (int i = 0; i < n; i++) + { + DefaultBufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(i); + List accessorModelsOfBufferView = + computeAccessorModelsOf(bufferViewModel); + if (accessorModelsOfBufferView.size() > 1) + { + int byteStride = + computeCommonByteStride(accessorModelsOfBufferView); bufferViewModel.setByteStride(byteStride); } } } - + /** * Initialize the {@link MeshModel} instances */ - private void initMeshModels() { - Map meshes = - Optionals.of(gltf.getMeshes()); - for (Entry entry : meshes.entrySet()) { + private void initMeshModels() + { + Map meshes = + Optionals.of(gltf.getMeshes()); + for (Entry entry : meshes.entrySet()) + { String meshId = entry.getKey(); Mesh mesh = entry.getValue(); - List primitives = - Optionals.of(mesh.getPrimitives()); - DefaultMeshModel meshModel = - get("meshes", meshId, gltfModel::getMeshModel); + List primitives = + Optionals.of(mesh.getPrimitives()); + DefaultMeshModel meshModel = + get("meshes", meshId, gltfModel::getMeshModel); transferGltfChildOfRootPropertyElements(mesh, meshModel); - for (MeshPrimitive meshPrimitive : primitives) { - MeshPrimitiveModel meshPrimitiveModel = - createMeshPrimitiveModel(meshPrimitive); + for (MeshPrimitive meshPrimitive : primitives) + { + MeshPrimitiveModel meshPrimitiveModel = + createMeshPrimitiveModel(meshPrimitive); meshModel.addMeshPrimitiveModel(meshPrimitiveModel); } } } - + /** * Create a {@link MeshPrimitiveModel} for the given {@link MeshPrimitive} - * + * * @param meshPrimitive The {@link MeshPrimitive} * @return The {@link MeshPrimitiveModel} */ private DefaultMeshPrimitiveModel createMeshPrimitiveModel( - MeshPrimitive meshPrimitive) { + MeshPrimitive meshPrimitive) + { Integer mode = Optionals.of( - meshPrimitive.getMode(), - meshPrimitive.defaultMode()); - DefaultMeshPrimitiveModel meshPrimitiveModel = - new DefaultMeshPrimitiveModel(mode); + meshPrimitive.getMode(), + meshPrimitive.defaultMode()); + DefaultMeshPrimitiveModel meshPrimitiveModel = + new DefaultMeshPrimitiveModel(mode); transferGltfPropertyElements(meshPrimitive, meshPrimitiveModel); - + String indicesId = meshPrimitive.getIndices(); - if (indicesId != null) { - AccessorModel indices = - get("accessors", indicesId, gltfModel::getAccessorModel); + if (indicesId != null) + { + AccessorModel indices = + get("accessors", indicesId, gltfModel::getAccessorModel); meshPrimitiveModel.setIndices(indices); } - Map attributes = - Optionals.of(meshPrimitive.getAttributes()); - for (Entry entry : attributes.entrySet()) { + Map attributes = + Optionals.of(meshPrimitive.getAttributes()); + for (Entry entry : attributes.entrySet()) + { String attributeName = entry.getKey(); String attributeId = entry.getValue(); - - AccessorModel attribute = - get("accessors", attributeId, gltfModel::getAccessorModel); + + AccessorModel attribute = + get("accessors", attributeId, gltfModel::getAccessorModel); meshPrimitiveModel.putAttribute(attributeName, attribute); } - + String materialId = meshPrimitive.getMaterial(); if (materialId == null || - GltfDefaults.isDefaultMaterialId(materialId)) { + GltfDefaults.isDefaultMaterialId(materialId)) + { meshPrimitiveModel.setMaterialModel( - DefaultModels.getDefaultMaterialModel()); - } else { - MaterialModel materialModel = - get("materials", materialId, gltfModel::getMaterialModel); + DefaultModels.getDefaultMaterialModel()); + } + else + { + MaterialModel materialModel = + get("materials", materialId, gltfModel::getMaterialModel); meshPrimitiveModel.setMaterialModel(materialModel); } - + return meshPrimitiveModel; } /** * Initialize the {@link NodeModel} instances */ - private void initNodeModels() { + private void initNodeModels() + { Map nodes = Optionals.of(gltf.getNodes()); - for (Entry entry : nodes.entrySet()) { + for (Entry entry : nodes.entrySet()) + { String nodeId = entry.getKey(); Node node = entry.getValue(); - - DefaultNodeModel nodeModel = - get("nodes", nodeId, gltfModel::getNodeModel); + + DefaultNodeModel nodeModel = + get("nodes", nodeId, gltfModel::getNodeModel); transferGltfChildOfRootPropertyElements(node, nodeModel); - + List childIds = Optionals.of(node.getChildren()); - for (String childId : childIds) { - DefaultNodeModel child = - get("nodes", childId, gltfModel::getNodeModel); + for (String childId : childIds) + { + DefaultNodeModel child = + get("nodes", childId, gltfModel::getNodeModel); nodeModel.addChild(child); } List meshIds = Optionals.of(node.getMeshes()); - for (String meshId : meshIds) { - MeshModel meshModel = - get("meshes", meshId, gltfModel::getMeshModel); + for (String meshId : meshIds) + { + MeshModel meshModel = + get("meshes", meshId, gltfModel::getMeshModel); nodeModel.addMeshModel(meshModel); } String skinId = node.getSkin(); - if (skinId != null) { - SkinModel skinModel = - get("skins", skinId, gltfModel::getSkinModel); + if (skinId != null) + { + SkinModel skinModel = + get("skins", skinId, gltfModel::getSkinModel); nodeModel.setSkinModel(skinModel); } String cameraId = node.getCamera(); - if (cameraId != null) { - CameraModel cameraModel = - get("cameras", cameraId, gltfModel::getCameraModel); + if (cameraId != null) + { + CameraModel cameraModel = + get("cameras", cameraId, gltfModel::getCameraModel); nodeModel.setCameraModel(cameraModel); } - + float matrix[] = node.getMatrix(); float translation[] = node.getTranslation(); float rotation[] = node.getRotation(); @@ -1016,266 +1029,503 @@ private void initNodeModels() { nodeModel.setScale(Optionals.clone(scale)); } } - + /** * Initialize the {@link SceneModel} instances */ - private void initSceneModels() { + private void initSceneModels() + { Map scenes = Optionals.of(gltf.getScenes()); - for (Entry entry : scenes.entrySet()) { + for (Entry entry : scenes.entrySet()) + { String sceneId = entry.getKey(); Scene scene = entry.getValue(); DefaultSceneModel sceneModel = - get("scenes", sceneId, gltfModel::getSceneModel); + get("scenes", sceneId, gltfModel::getSceneModel); transferGltfChildOfRootPropertyElements(scene, sceneModel); - + List nodes = Optionals.of(scene.getNodes()); - for (String nodeId : nodes) { - NodeModel nodeModel = - get("nodes", nodeId, gltfModel::getNodeModel); + for (String nodeId : nodes) + { + NodeModel nodeModel = + get("nodes", nodeId, gltfModel::getNodeModel); sceneModel.addNode(nodeModel); } } } + + /** + * Compute the mapping from joint names to the ID of the {@link Node} with + * the respective {@link Node#getJointName() joint name} + * + * @param gltf The {@link GlTF} + * @return The mapping + */ + private static Map computeJointNameToNodeIdMap(GlTF gltf) + { + Map map = new LinkedHashMap(); + Map nodes = Optionals.of(gltf.getNodes()); + for (Entry entry : nodes.entrySet()) + { + String nodeId = entry.getKey(); + Node node = entry.getValue(); + if (node.getJointName() != null) + { + String oldNodeId = map.put(node.getJointName(), nodeId); + if (oldNodeId != null) + { + logger.warning("Joint name " + node.getJointName() + + " is mapped to nodes with IDs " + nodeId + " and " + + oldNodeId); + } + } + } + return map; + } /** * Initialize the {@link SkinModel} instances */ - private void initSkinModels() { - Map jointNameToNodeIdMap = - computeJointNameToNodeIdMap(gltf); + private void initSkinModels() + { + Map jointNameToNodeIdMap = + computeJointNameToNodeIdMap(gltf); Map skins = Optionals.of(gltf.getSkins()); - for (Entry entry : skins.entrySet()) { + for (Entry entry : skins.entrySet()) + { String skinId = entry.getKey(); Skin skin = entry.getValue(); - DefaultSkinModel skinModel = - get("skins", skinId, gltfModel::getSkinModel); + DefaultSkinModel skinModel = + get("skins", skinId, gltfModel::getSkinModel); transferGltfChildOfRootPropertyElements(skin, skinModel); - + List jointNames = skin.getJointNames(); - for (String jointName : jointNames) { + for (String jointName : jointNames) + { String nodeId = jointNameToNodeIdMap.get(jointName); - NodeModel nodeModel = - get("nodes", nodeId, gltfModel::getNodeModel); + NodeModel nodeModel = + get("nodes", nodeId, gltfModel::getNodeModel); skinModel.addJoint(nodeModel); } - + String inverseBindMatricesId = skin.getInverseBindMatrices(); AccessorModel inverseBindMatrices = - get("accessors", inverseBindMatricesId, - gltfModel::getAccessorModel); + get("accessors", inverseBindMatricesId, + gltfModel::getAccessorModel); skinModel.setInverseBindMatrices(inverseBindMatrices); } } - + /** * Initialize the {@link TextureModel} instances */ - private void initTextureModels() { + private void initTextureModels() + { Map textures = Optionals.of(gltf.getTextures()); - for (Entry entry : textures.entrySet()) { + for (Entry entry : textures.entrySet()) + { String textureId = entry.getKey(); Texture texture = entry.getValue(); - DefaultTextureModel textureModel = - get("textures", textureId, gltfModel::getTextureModel); + DefaultTextureModel textureModel = + get("textures", textureId, gltfModel::getTextureModel); transferGltfChildOfRootPropertyElements(texture, textureModel); - + String imageId = texture.getSource(); - DefaultImageModel imageModel = - get("images", imageId, gltfModel::getImageModel); + DefaultImageModel imageModel = + get("images", imageId, gltfModel::getImageModel); textureModel.setImageModel(imageModel); } } - + /** * Initialize the {@link ShaderModel} instances */ - private void initShaderModels() { + private void initShaderModels() + { Map shaders = Optionals.of(gltf.getShaders()); - for (Entry entry : shaders.entrySet()) { + for (Entry entry : shaders.entrySet()) + { String shaderId = entry.getKey(); Shader shader = entry.getValue(); - DefaultShaderModel shaderModel = - get("shaders", shaderId, gltfModel::getShaderModel); + DefaultShaderModel shaderModel = + get("shaders", shaderId, gltfModel::getShaderModel); transferGltfChildOfRootPropertyElements(shader, shaderModel); - - if (BinaryGltfV1.hasBinaryGltfExtension(shader)) { - String bufferViewId = - BinaryGltfV1.getBinaryGltfBufferViewId(shader); + + if (BinaryGltfV1.hasBinaryGltfExtension(shader)) + { + String bufferViewId = + BinaryGltfV1.getBinaryGltfBufferViewId(shader); BufferViewModel bufferViewModel = - get("bufferViews", bufferViewId, - gltfModel::getBufferViewModel); - + get("bufferViews", bufferViewId, + gltfModel::getBufferViewModel); + shaderModel.setShaderData(bufferViewModel.getBufferViewData()); - } else { + } + else + { String uri = shader.getUri(); - if (IO.isDataUriString(uri)) { + if (IO.isDataUriString(uri)) + { byte data[] = IO.readDataUri(uri); ByteBuffer shaderData = Buffers.create(data); shaderModel.setShaderData(shaderData); - } else { + } + else + { ByteBuffer shaderData = gltfAsset.getReferenceData(uri); shaderModel.setShaderData(shaderData); } } } } - + /** * Initialize the {@link ProgramModel} instances */ - void initProgramModels() { + void initProgramModels() + { Map programs = Optionals.of(gltf.getPrograms()); - for (Entry entry : programs.entrySet()) { + for (Entry entry : programs.entrySet()) + { String programId = entry.getKey(); Program program = entry.getValue(); - DefaultProgramModel programModel = - get("programs", programId, gltfModel::getProgramModel); + DefaultProgramModel programModel = + get("programs", programId, gltfModel::getProgramModel); transferGltfChildOfRootPropertyElements(program, programModel); - + String vertexShaderId = program.getVertexShader(); DefaultShaderModel vertexShaderModel = - get("shaders", vertexShaderId, gltfModel::getShaderModel); + get("shaders", vertexShaderId, gltfModel::getShaderModel); programModel.setVertexShaderModel(vertexShaderModel); - + String fragmentShaderId = program.getFragmentShader(); DefaultShaderModel fragmentShaderModel = - get("shaders", fragmentShaderId, gltfModel::getShaderModel); + get("shaders", fragmentShaderId, gltfModel::getShaderModel); programModel.setFragmentShaderModel(fragmentShaderModel); - + List attributes = Optionals.of(program.getAttributes()); - for (String attribute : attributes) { + for (String attribute : attributes) + { programModel.addAttribute(attribute); } } } + + /** + * Add all {@link TechniqueParametersModel} instances for the + * attributes of the given {@link Technique} to the given + * {@link TechniqueModel} + * + * @param technique The {@link Technique} + * @param techniqueModel The {@link TechniqueModel} + * @param nodeLookup The function for looking up the {@link NodeModel} + * for a given node ID. This may be null, but if its is + * null and there is a non-null node ID + * in the technique parameters, then an error message will be + * printed. + */ + private static void addParameters(Technique technique, + DefaultTechniqueModel techniqueModel, + Function nodeLookup) + { + Map parameters = + Optionals.of(technique.getParameters()); + for (Entry entry : parameters.entrySet()) + { + String parameterName = entry.getKey(); + TechniqueParameters parameter = entry.getValue(); + + int type = parameter.getType(); + int count = Optionals.of(parameter.getCount(), 1); + String semantic = parameter.getSemantic(); + Object value = parameter.getValue(); + String nodeId = parameter.getNode(); + NodeModel nodeModel = null; + if (nodeId != null) + { + if (nodeLookup == null) + { + logger.severe("No lookup function found for the nodes"); + } + else + { + nodeModel = nodeLookup.apply(nodeId); + } + } + + TechniqueParametersModel techniqueParametersModel = + new DefaultTechniqueParametersModel( + type, count, semantic, value, nodeModel); + techniqueModel.addParameter( + parameterName, techniqueParametersModel); + } + } + + /** + * Add all attribute entries of the given {@link Technique} to the given + * {@link TechniqueModel} + * + * @param technique The {@link Technique} + * @param techniqueModel The {@link TechniqueModel} + */ + private static void addAttributes(Technique technique, + DefaultTechniqueModel techniqueModel) + { + Map attributes = + Optionals.of(technique.getAttributes()); + for (Entry entry : attributes.entrySet()) + { + String attributeName = entry.getKey(); + String parameterName = entry.getValue(); + techniqueModel.addAttribute(attributeName, parameterName); + } + } + + /** + * Add all uniform entries of the given {@link Technique} to the given + * {@link TechniqueModel} + * + * @param technique The {@link Technique} + * @param techniqueModel The {@link TechniqueModel} + */ + private static void addUniforms(Technique technique, + DefaultTechniqueModel techniqueModel) + { + Map uniforms = + Optionals.of(technique.getUniforms()); + for (Entry entry : uniforms.entrySet()) + { + String uniformName = entry.getKey(); + String parameterName = entry.getValue(); + techniqueModel.addUniform(uniformName, parameterName); + } + } + + /** * Initialize the {@link TechniqueModel} instances */ - private void initTechniqueModels() { + private void initTechniqueModels() + { Map techniques = Optionals.of(gltf.getTechniques()); - for (Entry entry : techniques.entrySet()) { + for (Entry entry : techniques.entrySet()) + { String techniqueId = entry.getKey(); Technique technique = entry.getValue(); - - DefaultTechniqueModel techniqueModel = - get("techniques", techniqueId, gltfModel::getTechniqueModel); - + + DefaultTechniqueModel techniqueModel = + get("techniques", techniqueId, gltfModel::getTechniqueModel); + String programId = technique.getProgram(); - DefaultProgramModel programModel = - get("programs", programId, gltfModel::getProgramModel); + DefaultProgramModel programModel = + get("programs", programId, gltfModel::getProgramModel); techniqueModel.setProgramModel(programModel); - Function nodeLookup = nodeId -> - get("nodes", nodeId, gltfModel::getNodeModel); - + Function nodeLookup = nodeId -> + get("nodes", nodeId, gltfModel::getNodeModel); + initTechniqueModel(techniqueModel, technique, nodeLookup); - + } } + /** + * Initialize the given {@link TechniqueModel} with the values that are + * obtained from the given {@link Technique} + * + * @param techniqueModel The {@link TechniqueModel} + * @param technique The {@link Technique} + * @param nodeLookup The function for looking up the {@link NodeModel} + * for a given node ID. This may be null, but if its is + * null and there is a non-null node ID + * in the technique parameters, then an error message will be + * printed. + */ + public static void initTechniqueModel( + DefaultTechniqueModel techniqueModel, Technique technique, + Function nodeLookup) + { + transferGltfChildOfRootPropertyElements(technique, techniqueModel); + + addParameters(technique, techniqueModel, nodeLookup); + addAttributes(technique, techniqueModel); + addUniforms(technique, techniqueModel); + + List enableModel = null; + DefaultTechniqueStatesFunctionsModel techniqueStatesFunctionsModel = + null; + TechniqueStates states = technique.getStates(); + if (states != null) + { + List enable = states.getEnable(); + if (enable != null) + { + enableModel = new ArrayList(enable); + } + TechniqueStatesFunctions functions = states.getFunctions(); + if (functions != null) + { + techniqueStatesFunctionsModel = + TechniqueStatesFunctionsModels.create(functions); + } + + TechniqueStatesModel techniqueStatesModel = + new DefaultTechniqueStatesModel( + enableModel, techniqueStatesFunctionsModel); + techniqueModel.setTechniqueStatesModel(techniqueStatesModel); + } + } + + /** * Initialize the {@link MaterialModel} instances */ - private void initMaterialModels() { + private void initMaterialModels() + { Map materials = Optionals.of(gltf.getMaterials()); - for (Entry entry : materials.entrySet()) { + for (Entry entry : materials.entrySet()) + { String materialId = entry.getKey(); Material material = entry.getValue(); - MaterialModelV1 materialModel = - (MaterialModelV1) get("materials", - materialId, gltfModel::getMaterialModel); - + MaterialModelV1 materialModel = + (MaterialModelV1) get("materials", + materialId, gltfModel::getMaterialModel); + transferGltfChildOfRootPropertyElements(material, materialModel); - + String techniqueId = material.getTechnique(); TechniqueModel techniqueModel; if (techniqueId == null || - GltfDefaults.isDefaultTechniqueId(techniqueId)) { + GltfDefaults.isDefaultTechniqueId(techniqueId)) + { techniqueModel = DefaultModels.getDefaultTechniqueModel(); - } else { + } + else + { techniqueModel = - get("techniques", techniqueId, - gltfModel::getTechniqueModel); + get("techniques", techniqueId, + gltfModel::getTechniqueModel); } materialModel.setTechniqueModel(techniqueModel); - - - Map modelValues = - new LinkedHashMap(); + + + Map modelValues = + new LinkedHashMap(); Map values = Optionals.of(material.getValues()); - for (Entry valueEntry : values.entrySet()) { + for (Entry valueEntry : values.entrySet()) + { String parameterName = valueEntry.getKey(); - TechniqueParametersModel techniqueParametersModel = - techniqueModel.getParameters().get(parameterName); + TechniqueParametersModel techniqueParametersModel = + techniqueModel.getParameters().get(parameterName); if (techniqueParametersModel != null && - techniqueParametersModel.getType() == - GltfConstants.GL_SAMPLER_2D) { + techniqueParametersModel.getType() == + GltfConstants.GL_SAMPLER_2D) + { TextureModel textureModel = null; Object value = valueEntry.getValue(); - if (value != null) { + if (value != null) + { String textureId = String.valueOf(value); - textureModel = get("textures", textureId, - gltfModel::getTextureModel); + textureModel = get("textures", textureId, + gltfModel::getTextureModel); } modelValues.put(parameterName, textureModel); - } else { + } + else + { modelValues.put(parameterName, valueEntry.getValue()); } } materialModel.setValues(modelValues); } } - + /** * Initialize the {@link ExtensionsModel} with the extensions that * are used in the glTF. */ - private void initExtensionsModel() { + private void initExtensionsModel() + { // Note that glTF 1.0 only had 'extensionsUsed', no 'extensionsRequired' List extensionsUsed = gltf.getExtensionsUsed(); DefaultExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); extensionsModel.addExtensionsUsed(extensionsUsed); } - + /** * Initialize the {@link AssetModel} with the asset information that * was given in the glTF. */ - private void initAssetModel() { + private void initAssetModel() + { Asset asset = gltf.getAsset(); - if (asset != null) { + if (asset != null) + { DefaultAssetModel assetModel = gltfModel.getAssetModel(); transferGltfPropertyElements(asset, assetModel); assetModel.setCopyright(asset.getCopyright()); assetModel.setGenerator(asset.getGenerator()); } } - + + + /** + * Transfer the extensions and extras from the given property to + * the given target + * + * @param property The property + * @param modelElement The target + */ + private static void transferGltfPropertyElements( + GlTFProperty property, AbstractModelElement modelElement) + { + modelElement.setExtensions(property.getExtensions()); + modelElement.setExtras(property.getExtras()); + } + + /** + * Transfer the name and extensions and extras from the given property to + * the given target + * + * @param property The property + * @param modelElement The target + */ + private static void transferGltfChildOfRootPropertyElements( + GlTFChildOfRootProperty property, + AbstractNamedModelElement modelElement) + { + modelElement.setName(property.getName()); + transferGltfPropertyElements(property, modelElement); + } + + /** - * Return the element from the given getter, based on the - * {@link #indexMappingSet} for the given name and ID. - * If the ID is null, then null is + * Return the element from the given getter, based on the + * {@link #indexMappingSet} for the given name and ID. + * If the ID is null, then null is * returned. If there is no proper index stored for the given * ID, then a warning will be printed and null * will be returned. - * - * @param The element type - * @param name The name - * @param id The ID + * + * @param The element type + * + * @param name The name + * @param id The ID * @param getter The getter * @return The element */ - private T get(String name, String id, IntFunction getter) { + private T get(String name, String id, IntFunction getter) + { Integer index = indexMappingSet.getIndex(name, id); - if (index == null) { + if (index == null) + { logger.severe("No index found for " + name + " ID " + id); return null; } T element = getter.apply(index); return element; } - + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/GltfModelV1.java b/src/main/java/de/javagl/jgltf/model/v1/GltfModelV1.java index e2475b7..d51fe44 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/GltfModelV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/GltfModelV1.java @@ -26,6 +26,12 @@ */ package de.javagl.jgltf.model.v1; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + import de.javagl.jgltf.impl.v1.GlTF; import de.javagl.jgltf.impl.v1.Program; import de.javagl.jgltf.impl.v1.Shader; @@ -40,12 +46,11 @@ import de.javagl.jgltf.model.impl.DefaultGltfModel; import de.javagl.jgltf.model.io.v1.GltfAssetV1; -import java.util.*; - /** * Implementation of a {@link GltfModel}, based on a {@link GlTF glTF 1.0}.
    */ -public final class GltfModelV1 extends DefaultGltfModel implements GltfModel { +public final class GltfModelV1 extends DefaultGltfModel implements GltfModel +{ /** * The {@link ShaderModel} instances that have been created from * the {@link Shader} instances @@ -57,7 +62,7 @@ public final class GltfModelV1 extends DefaultGltfModel implements GltfModel { * the {@link Program} instances */ private final List programModels; - + /** * The {@link TechniqueModel} instances that have been created from * the {@link Technique} instances @@ -66,57 +71,63 @@ public final class GltfModelV1 extends DefaultGltfModel implements GltfModel { /** * Creates a new model for the given glTF - * + * * @param gltfAsset The {@link GltfAssetV1} */ - public GltfModelV1(GltfAssetV1 gltfAsset) { - Objects.requireNonNull(gltfAsset, - "The gltfAsset may not be null"); + public GltfModelV1(GltfAssetV1 gltfAsset) + { + Objects.requireNonNull(gltfAsset, + "The gltfAsset may not be null"); this.shaderModels = new ArrayList(); this.programModels = new ArrayList(); this.techniqueModels = new ArrayList(); - - GltfModelCreatorV1 gltfModelCreatorV1 = - new GltfModelCreatorV1(gltfAsset, this); + + GltfModelCreatorV1 gltfModelCreatorV1 = + new GltfModelCreatorV1(gltfAsset, this); gltfModelCreatorV1.create(); } - + /** * Creates a new, empty model */ - public GltfModelV1() { + public GltfModelV1() + { this.shaderModels = new ArrayList(); this.programModels = new ArrayList(); this.techniqueModels = new ArrayList(); } - + /** * Add the given {@link ShaderModel} to this model - * + * * @param shaderModel The instance to add */ - public void addShaderModel(DefaultShaderModel shaderModel) { + public void addShaderModel(DefaultShaderModel shaderModel) + { shaderModels.add(shaderModel); } /** * Remove the given {@link ShaderModel} from this model - * + * * @param shaderModel The instance to remove */ - public void removeShaderModel(DefaultShaderModel shaderModel) { + public void removeShaderModel(DefaultShaderModel shaderModel) + { shaderModels.remove(shaderModel); } /** * Add the given {@link ShaderModel} instances to this model - * + * * @param shaderModels The instances to add */ public void addShaderModels( - Collection shaderModels) { - for (DefaultShaderModel shaderModel : shaderModels) { + Collection shaderModels) + { + for (DefaultShaderModel shaderModel : shaderModels) + { addShaderModel(shaderModel); } } @@ -127,53 +138,60 @@ public void addShaderModels( * @param index The index * @return The {@link ShaderModel} */ - public DefaultShaderModel getShaderModel(int index) { + public DefaultShaderModel getShaderModel(int index) + { return shaderModels.get(index); } /** * Remove all {@link ShaderModel} instances */ - public void clearShaderModels() { + public void clearShaderModels() + { shaderModels.clear(); } - + /** - * Returns an unmodifiable view on the list of {@link ShaderModel} + * Returns an unmodifiable view on the list of {@link ShaderModel} * instances that have been created for the glTF. - * + * * @return The {@link ShaderModel} instances */ - public List getShaderModels() { + public List getShaderModels() + { return Collections.unmodifiableList(shaderModels); } /** * Add the given {@link ProgramModel} to this model - * + * * @param programModel The instance to add */ - public void addProgramModel(DefaultProgramModel programModel) { + public void addProgramModel(DefaultProgramModel programModel) + { programModels.add(programModel); } /** * Remove the given {@link ProgramModel} from this model - * + * * @param programModel The instance to remove */ - public void removeProgramModel(DefaultProgramModel programModel) { + public void removeProgramModel(DefaultProgramModel programModel) + { programModels.remove(programModel); } /** * Add the given {@link ProgramModel} instances to this model - * + * * @param programModels The instances to add */ public void addProgramModels( - Collection programModels) { - for (DefaultProgramModel programModel : programModels) { + Collection programModels) + { + for (DefaultProgramModel programModel : programModels) + { addProgramModel(programModel); } } @@ -184,54 +202,61 @@ public void addProgramModels( * @param index The index * @return The {@link ProgramModel} */ - public DefaultProgramModel getProgramModel(int index) { + public DefaultProgramModel getProgramModel(int index) + { return programModels.get(index); } /** * Remove all {@link ProgramModel} instances */ - public void clearProgramModels() { + public void clearProgramModels() + { programModels.clear(); } - + /** - * Returns an unmodifiable view on the list of {@link ProgramModel} + * Returns an unmodifiable view on the list of {@link ProgramModel} * instances that have been created for the glTF. - * + * * @return The {@link ProgramModel} instances */ - public List getProgramModels() { + public List getProgramModels() + { return Collections.unmodifiableList(programModels); } - - + + /** * Add the given {@link TechniqueModel} to this model - * + * * @param techniqueModel The instance to add */ - public void addTechniqueModel(DefaultTechniqueModel techniqueModel) { + public void addTechniqueModel(DefaultTechniqueModel techniqueModel) + { techniqueModels.add(techniqueModel); } /** * Remove the given {@link TechniqueModel} from this model - * + * * @param techniqueModel The instance to remove */ - public void removeTechniqueModel(DefaultTechniqueModel techniqueModel) { + public void removeTechniqueModel(DefaultTechniqueModel techniqueModel) + { techniqueModels.remove(techniqueModel); } /** * Add the given {@link TechniqueModel} instances to this model - * + * * @param techniqueModels The instances to add */ public void addTechniqueModels( - Collection techniqueModels) { - for (DefaultTechniqueModel techniqueModel : techniqueModels) { + Collection techniqueModels) + { + for (DefaultTechniqueModel techniqueModel : techniqueModels) + { addTechniqueModel(techniqueModel); } } @@ -242,25 +267,28 @@ public void addTechniqueModels( * @param index The index * @return The {@link TechniqueModel} */ - public DefaultTechniqueModel getTechniqueModel(int index) { + public DefaultTechniqueModel getTechniqueModel(int index) + { return techniqueModels.get(index); } /** * Remove all {@link TechniqueModel} instances */ - public void clearTechniqueModels() { + public void clearTechniqueModels() + { techniqueModels.clear(); } - + /** - * Returns an unmodifiable view on the list of {@link TechniqueModel} + * Returns an unmodifiable view on the list of {@link TechniqueModel} * instances that have been created for the glTF. - * + * * @return The {@link TechniqueModel} instances */ - public List getTechniqueModels() { + public List getTechniqueModels() + { return Collections.unmodifiableList(techniqueModels); } - + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSet.java b/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSet.java index e1a43ab..8ec230a 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSet.java +++ b/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSet.java @@ -33,61 +33,68 @@ * Helper class storing a set of index mappings, identified via names. * Each index mapping maps string IDs to integer values. */ -final class IndexMappingSet { +final class IndexMappingSet +{ /** * The index mappings */ private final Map> indexMappings; - + /** * Default constructor */ - IndexMappingSet() { - indexMappings = new LinkedHashMap>(); + IndexMappingSet() + { + indexMappings = new LinkedHashMap>(); } - + /** * Return the index mapping for the given name, creating it if necessary - * + * * @param name The name * @return The index mapping */ - private Map get(Object name) { - Map indexMapping = - indexMappings.computeIfAbsent(name, - n -> new LinkedHashMap()); + private Map get(Object name) + { + Map indexMapping = + indexMappings.computeIfAbsent(name, + n -> new LinkedHashMap()); return indexMapping; } - + /** * Generate an index mapping for the given name. This mapping will map * the keys of the given map to consecutive integer values, starting * with 0, in iteration order. - * - * @param name The name - * @param map The map to initialize the mapping from + * + * @param name The name + * @param map The map to initialize the mapping from */ - void generate(Object name, Map map) { - if (map != null) { + void generate(Object name, Map map) + { + if (map != null) + { get(name).putAll(IndexMappings.computeIndexMapping(map)); } } - + /** - * Returns the integer that is stored in the index mapping under the + * Returns the integer that is stored in the index mapping under the * given key, in the index mapping that is identified with * the given map name - * + * * @param name The name of the index mapping - * @param key The key to look up in the index mapping + * @param key The key to look up in the index mapping * @return The index */ - Integer getIndex(String name, String key) { - if (key == null) { + Integer getIndex(String name, String key) + { + if (key == null) + { return null; } return get(name).get(key); } - - + + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSets.java b/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSets.java index e236d38..18e2fb6 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSets.java +++ b/src/main/java/de/javagl/jgltf/model/v1/IndexMappingSets.java @@ -31,23 +31,18 @@ /** * Utility methods to create {@link IndexMappingSet} instances */ -class IndexMappingSets { - /** - * Private constructor to prevent instantiation - */ - private IndexMappingSets() { - // Private constructor to prevent instantiation - } - +class IndexMappingSets +{ /** * Compute the {@link IndexMappingSet} for the given glTF instance. * The {@link IndexMappingSet} will contain index mappings for all - * top-level dictionaries of the given glTF. - * + * top-level dictionaries of the given glTF. + * * @param gltf The glTF * @return The {@link IndexMappingSet} */ - static IndexMappingSet create(GlTF gltf) { + static IndexMappingSet create(GlTF gltf) + { IndexMappingSet indexMappingSet = new IndexMappingSet(); indexMappingSet.generate("accessors", gltf.getAccessors()); indexMappingSet.generate("animations", gltf.getAnimations()); @@ -67,4 +62,12 @@ static IndexMappingSet create(GlTF gltf) { indexMappingSet.generate("textures", gltf.getTextures()); return indexMappingSet; } + + /** + * Private constructor to prevent instantiation + */ + private IndexMappingSets() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/IndexMappings.java b/src/main/java/de/javagl/jgltf/model/v1/IndexMappings.java index d44f8da..93f7751 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/IndexMappings.java +++ b/src/main/java/de/javagl/jgltf/model/v1/IndexMappings.java @@ -33,35 +33,40 @@ /** * Utility methods to compute index mappings */ -class IndexMappings { +class IndexMappings +{ /** - * Private constructor to prevent instantiation - */ - private IndexMappings() { - // Private constructor to prevent instantiation - } - - /** - * Compute the index mapping for the given map. If the given map is + * Compute the index mapping for the given map. If the given map is * null, then an empty map will be returned. Otherwise, - * the method will iterate through the given map, and return a - * map where the keys of the given map are associated with + * the method will iterate through the given map, and return a + * map where the keys of the given map are associated with * consecutive integers, starting with 0, in iteration order. - * + * * @param map The input map * @return The index mapping */ - static Map computeIndexMapping(Map map) { - if (map == null) { + static Map computeIndexMapping(Map map) + { + if (map == null) + { return Collections.emptyMap(); } - Map indexMapping = - new LinkedHashMap(); + Map indexMapping = + new LinkedHashMap(); int indexCounter = 0; - for (String key : map.keySet()) { + for (String key : map.keySet()) + { indexMapping.put(key, indexCounter); indexCounter++; } return indexMapping; } + + /** + * Private constructor to prevent instantiation + */ + private IndexMappings() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/MaterialModelV1.java b/src/main/java/de/javagl/jgltf/model/v1/MaterialModelV1.java index 6fc532c..23904d5 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/MaterialModelV1.java +++ b/src/main/java/de/javagl/jgltf/model/v1/MaterialModelV1.java @@ -26,30 +26,31 @@ */ package de.javagl.jgltf.model.v1; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + import de.javagl.jgltf.impl.v1.Material; import de.javagl.jgltf.model.MaterialModel; import de.javagl.jgltf.model.TextureModel; import de.javagl.jgltf.model.gl.TechniqueModel; import de.javagl.jgltf.model.impl.AbstractNamedModelElement; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; - /** * Implementation of a {@link MaterialModel} for glTF 1.0.
    - *
    + *
    * Note: This class is actually no longer specific for glTF 1.0. It might * be renamed to "TechniqueBasedMaterialModel" and moved to a different * package in the future. */ public final class MaterialModelV1 extends AbstractNamedModelElement - implements MaterialModel { + implements MaterialModel +{ /** * The {@link TechniqueModel} */ private TechniqueModel techniqueModel; - + /** * The material parameter values */ @@ -58,54 +59,62 @@ public final class MaterialModelV1 extends AbstractNamedModelElement /** * Creates a new instance */ - public MaterialModelV1() { + public MaterialModelV1() + { this.values = Collections.emptyMap(); } - + /** - * Returns the {@link TechniqueModel} - * - * @return The {@link TechniqueModel} + * Set the material parameter values to be an unmodifiable shallow + * copy of the given map (or the empty map if the given map is + * null) + * + * @param values The material parameter values */ - public TechniqueModel getTechniqueModel() { - return techniqueModel; + public void setValues(Map values) + { + if (values == null) + { + this.values = Collections.emptyMap(); + } + else + { + this.values = Collections.unmodifiableMap( + new LinkedHashMap(values)); + } } - + /** - * Set the {@link TechniqueModel} - * + * Set the {@link TechniqueModel} + * * @param techniqueModel The {@link TechniqueModel} */ - public void setTechniqueModel(TechniqueModel techniqueModel) { + public void setTechniqueModel(TechniqueModel techniqueModel) + { this.techniqueModel = techniqueModel; } /** - * Returns the parameter values of this material. Note that if any - * parameter value of the original {@link Material} is the texture ID - * for a parameter of type GL_SAMPLER2D, then the respective value - * will be the appropriate {@link TextureModel} instance. - * - * @return The values + * Returns the {@link TechniqueModel} + * + * @return The {@link TechniqueModel} */ - public Map getValues() { - return values; + public TechniqueModel getTechniqueModel() + { + return techniqueModel; } /** - * Set the material parameter values to be an unmodifiable shallow - * copy of the given map (or the empty map if the given map is - * null) - * - * @param values The material parameter values + * Returns the parameter values of this material. Note that if any + * parameter value of the original {@link Material} is the texture ID + * for a parameter of type GL_SAMPLER2D, then the respective value + * will be the appropriate {@link TextureModel} instance. + * + * @return The values */ - public void setValues(Map values) { - if (values == null) { - this.values = Collections.emptyMap(); - } else { - this.values = Collections.unmodifiableMap( - new LinkedHashMap(values)); - } + public Map getValues() + { + return values; } - + } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/DefaultModels.java b/src/main/java/de/javagl/jgltf/model/v1/gl/DefaultModels.java index f9ecb68..e4e7832 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/DefaultModels.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/DefaultModels.java @@ -26,17 +26,6 @@ */ package de.javagl.jgltf.model.v1.gl; -import de.javagl.jgltf.impl.v1.*; -import de.javagl.jgltf.model.MaterialModel; -import de.javagl.jgltf.model.NodeModel; -import de.javagl.jgltf.model.Optionals; -import de.javagl.jgltf.model.gl.*; -import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; -import de.javagl.jgltf.model.gl.impl.*; -import de.javagl.jgltf.model.io.Buffers; -import de.javagl.jgltf.model.io.IO; -import de.javagl.jgltf.model.v1.MaterialModelV1; - import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -46,84 +35,111 @@ import java.util.Map.Entry; import java.util.logging.Logger; +import de.javagl.jgltf.impl.v1.Material; +import de.javagl.jgltf.impl.v1.Shader; +import de.javagl.jgltf.impl.v1.Technique; +import de.javagl.jgltf.impl.v1.TechniqueParameters; +import de.javagl.jgltf.impl.v1.TechniqueStates; +import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; +import de.javagl.jgltf.model.MaterialModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.Optionals; +import de.javagl.jgltf.model.gl.ProgramModel; +import de.javagl.jgltf.model.gl.ShaderModel; +import de.javagl.jgltf.model.gl.ShaderModel.ShaderType; +import de.javagl.jgltf.model.gl.TechniqueModel; +import de.javagl.jgltf.model.gl.TechniqueParametersModel; +import de.javagl.jgltf.model.gl.TechniqueStatesFunctionsModel; +import de.javagl.jgltf.model.gl.TechniqueStatesModel; +import de.javagl.jgltf.model.gl.impl.DefaultProgramModel; +import de.javagl.jgltf.model.gl.impl.DefaultShaderModel; +import de.javagl.jgltf.model.gl.impl.DefaultTechniqueModel; +import de.javagl.jgltf.model.gl.impl.DefaultTechniqueParametersModel; +import de.javagl.jgltf.model.gl.impl.DefaultTechniqueStatesModel; +import de.javagl.jgltf.model.io.Buffers; +import de.javagl.jgltf.model.io.IO; +import de.javagl.jgltf.model.v1.MaterialModelV1; + /** - * A class containing the default {@link TechniqueModel} and + * A class containing the default {@link TechniqueModel} and * {@link MaterialModel} instances that correspond to the * default {@link Technique} and {@link Material} of glTF 1.0. */ -public class DefaultModels { +public class DefaultModels +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(DefaultModels.class.getName()); - + private static final Logger logger = + Logger.getLogger(DefaultModels.class.getName()); + /** * The default vertex {@link ShaderModel} */ private static final DefaultShaderModel DEFAULT_VERTEX_SHADER_MODEL; - + /** * The default fragment {@link ShaderModel} */ private static final DefaultShaderModel DEFAULT_FRAGMENT_SHADER_MODEL; - + /** * The default {@link ProgramModel} */ private static final DefaultProgramModel DEFAULT_PROGRAM_MODEL; - + /** * The default {@link TechniqueModel} */ private static final DefaultTechniqueModel DEFAULT_TECHNIQUE_MODEL; - + /** * The default {@link MaterialModel} */ private static final MaterialModelV1 DEFAULT_MATERIAL_MODEL; - - static { + + static + { // Create models for the default vertex- and fragment shader Shader vertexShader = GltfDefaults.getDefaultVertexShader(); - DEFAULT_VERTEX_SHADER_MODEL = - new DefaultShaderModel(vertexShader.getUri(), - ShaderType.VERTEX_SHADER); + DEFAULT_VERTEX_SHADER_MODEL = + new DefaultShaderModel(vertexShader.getUri(), + ShaderType.VERTEX_SHADER); initShaderData(DEFAULT_VERTEX_SHADER_MODEL); - + Shader fragmentShader = GltfDefaults.getDefaultFragmentShader(); - DEFAULT_FRAGMENT_SHADER_MODEL = - new DefaultShaderModel(fragmentShader.getUri(), - ShaderType.FRAGMENT_SHADER); + DEFAULT_FRAGMENT_SHADER_MODEL = + new DefaultShaderModel(fragmentShader.getUri(), + ShaderType.FRAGMENT_SHADER); initShaderData(DEFAULT_FRAGMENT_SHADER_MODEL); - + // Create a model for the default program DEFAULT_PROGRAM_MODEL = new DefaultProgramModel(); DEFAULT_PROGRAM_MODEL.setVertexShaderModel( - DEFAULT_VERTEX_SHADER_MODEL); + DEFAULT_VERTEX_SHADER_MODEL); DEFAULT_PROGRAM_MODEL.setFragmentShaderModel( - DEFAULT_FRAGMENT_SHADER_MODEL); - + DEFAULT_FRAGMENT_SHADER_MODEL); + // Create a model for the default technique Technique technique = GltfDefaults.getDefaultTechnique(); DEFAULT_TECHNIQUE_MODEL = new DefaultTechniqueModel(); DEFAULT_TECHNIQUE_MODEL.setProgramModel(DEFAULT_PROGRAM_MODEL); - + addParametersForDefaultTechnique(technique, DEFAULT_TECHNIQUE_MODEL); addAttributes(technique, DEFAULT_TECHNIQUE_MODEL); addUniforms(technique, DEFAULT_TECHNIQUE_MODEL); - + TechniqueStates states = technique.getStates(); List enable = Optionals.of( - states.getEnable(), - states.defaultEnable()); - + states.getEnable(), + states.defaultEnable()); + TechniqueStatesFunctions functions = states.getFunctions(); TechniqueStatesFunctionsModel techniqueStatesFunctionsModel = - TechniqueStatesFunctionsModels.create(functions); - TechniqueStatesModel techniqueStatesModel = - new DefaultTechniqueStatesModel( - enable, techniqueStatesFunctionsModel); + TechniqueStatesFunctionsModels.create(functions); + TechniqueStatesModel techniqueStatesModel = + new DefaultTechniqueStatesModel( + enable, techniqueStatesFunctionsModel); DEFAULT_TECHNIQUE_MODEL.setTechniqueStatesModel(techniqueStatesModel); // Create a model for the default material @@ -132,36 +148,34 @@ public class DefaultModels { DEFAULT_MATERIAL_MODEL.setValues(material.getValues()); DEFAULT_MATERIAL_MODEL.setTechniqueModel(DEFAULT_TECHNIQUE_MODEL); } - - /** - * Private constructor to prevent instantiation - */ - private DefaultModels() { - // Private constructor to prevent instantiation - } - + /** * Return the default {@link MaterialModel} - * + * * @return The default {@link MaterialModel} */ - public static MaterialModel getDefaultMaterialModel() { + public static MaterialModel getDefaultMaterialModel() + { return DEFAULT_MATERIAL_MODEL; } - + /** - * Initialize the {@link DefaultShaderModel#setShaderData(ByteBuffer) + * Initialize the {@link DefaultShaderModel#setShaderData(ByteBuffer) * shader data} for the given {@link ShaderModel} - * + * * @param shaderModel The {@link ShaderModel} */ - private static void initShaderData(DefaultShaderModel shaderModel) { - try { + private static void initShaderData(DefaultShaderModel shaderModel) + { + try + { URI uri = new URI(shaderModel.getUri()); byte[] data = IO.read(uri); ByteBuffer shaderData = Buffers.create(data); shaderModel.setShaderData(shaderData); - } catch (URISyntaxException | IOException e) { + } + catch (URISyntaxException | IOException e) + { // This should never happen: The default shaders have valid // data URI that contain the shader data. logger.severe("Failed to initialize shader data"); @@ -170,57 +184,62 @@ private static void initShaderData(DefaultShaderModel shaderModel) { /** * Return the default {@link TechniqueModel} - * + * * @return The default {@link TechniqueModel} */ - public static TechniqueModel getDefaultTechniqueModel() { + public static TechniqueModel getDefaultTechniqueModel() + { return DEFAULT_TECHNIQUE_MODEL; } - + /** - * Add all {@link TechniqueParametersModel} instances for the + * Add all {@link TechniqueParametersModel} instances for the * attributes of the given {@link Technique} to the given * {@link TechniqueModel} - * - * @param technique The {@link Technique} + * + * @param technique The {@link Technique} * @param techniqueModel The {@link TechniqueModel} */ private static void addParametersForDefaultTechnique( - Technique technique, DefaultTechniqueModel techniqueModel) { - Map parameters = - Optionals.of(technique.getParameters()); - for (Entry entry : parameters.entrySet()) { + Technique technique, DefaultTechniqueModel techniqueModel) + { + Map parameters = + Optionals.of(technique.getParameters()); + for (Entry entry : parameters.entrySet()) + { String parameterName = entry.getKey(); TechniqueParameters parameter = entry.getValue(); - + int type = parameter.getType(); int count = Optionals.of(parameter.getCount(), 1); String semantic = parameter.getSemantic(); Object value = parameter.getValue(); - + // The NodeModel is always null in the default technique NodeModel nodeModel = null; - + TechniqueParametersModel techniqueParametersModel = - new DefaultTechniqueParametersModel( - type, count, semantic, value, nodeModel); + new DefaultTechniqueParametersModel( + type, count, semantic, value, nodeModel); techniqueModel.addParameter( - parameterName, techniqueParametersModel); + parameterName, techniqueParametersModel); } } - + /** * Add all attribute entries of the given {@link Technique} to the given * {@link TechniqueModel} - * - * @param technique The {@link Technique} + * + * @param technique The {@link Technique} * @param techniqueModel The {@link TechniqueModel} */ private static void addAttributes(Technique technique, - DefaultTechniqueModel techniqueModel) { - Map attributes = - Optionals.of(technique.getAttributes()); - for (Entry entry : attributes.entrySet()) { + DefaultTechniqueModel techniqueModel) + { + Map attributes = + Optionals.of(technique.getAttributes()); + for (Entry entry : attributes.entrySet()) + { String attributeName = entry.getKey(); String parameterName = entry.getValue(); techniqueModel.addAttribute(attributeName, parameterName); @@ -230,20 +249,31 @@ private static void addAttributes(Technique technique, /** * Add all uniform entries of the given {@link Technique} to the given * {@link TechniqueModel} - * - * @param technique The {@link Technique} + * + * @param technique The {@link Technique} * @param techniqueModel The {@link TechniqueModel} */ private static void addUniforms(Technique technique, - DefaultTechniqueModel techniqueModel) { - Map uniforms = - Optionals.of(technique.getUniforms()); - for (Entry entry : uniforms.entrySet()) { + DefaultTechniqueModel techniqueModel) + { + Map uniforms = + Optionals.of(technique.getUniforms()); + for (Entry entry : uniforms.entrySet()) + { String uniformName = entry.getKey(); String parameterName = entry.getValue(); techniqueModel.addUniform(uniformName, parameterName); } } - - + + + /** + * Private constructor to prevent instantiation + */ + private DefaultModels() + { + // Private constructor to prevent instantiation + } + + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/GltfDefaults.java b/src/main/java/de/javagl/jgltf/model/v1/gl/GltfDefaults.java index 77ba553..ccde61d 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/GltfDefaults.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/GltfDefaults.java @@ -32,135 +32,143 @@ import de.javagl.jgltf.impl.v1.Technique; /** - * A class containing the default {@link Shader}, {@link Program}, - * {@link Technique} and {@link Material} objects according to + * A class containing the default {@link Shader}, {@link Program}, + * {@link Technique} and {@link Material} objects according to * "Appendix A" of the specification. */ -public class GltfDefaults { +public class GltfDefaults +{ /** * An ID for the default vertex {@link Shader} */ - private static final String DEFAULT_VERTEX_SHADER_ID = - GltfDefaults.class.getName() + ".DEFAULT_VERTEX_SHADER_ID"; + private static final String DEFAULT_VERTEX_SHADER_ID = + GltfDefaults.class.getName() + ".DEFAULT_VERTEX_SHADER_ID"; /** * An ID for the default fragment {@link Shader} */ - private static final String DEFAULT_FRAGMENT_SHADER_ID = - GltfDefaults.class.getName() + ".DEFAULT_FRAGMENT_SHADER_ID"; - + private static final String DEFAULT_FRAGMENT_SHADER_ID = + GltfDefaults.class.getName() + ".DEFAULT_FRAGMENT_SHADER_ID"; + /** * An ID for the default {@link Program} */ - private static final String DEFAULT_PROGRAM_ID = - GltfDefaults.class.getName() + ".DEFAULT_PROGRAM_ID"; - + private static final String DEFAULT_PROGRAM_ID = + GltfDefaults.class.getName() + ".DEFAULT_PROGRAM_ID"; + /** * An ID for the default {@link Technique} */ - private static final String DEFAULT_TECHNIQUE_ID = - GltfDefaults.class.getName() + ".DEFAULT_TECHNIQUE_ID"; - + private static final String DEFAULT_TECHNIQUE_ID = + GltfDefaults.class.getName() + ".DEFAULT_TECHNIQUE_ID"; + /** * An ID for the default {@link Material} */ - private static final String DEFAULT_MATERIAL_ID = - GltfDefaults.class.getName() + ".DEFAULT_MATERIAL_ID"; - + private static final String DEFAULT_MATERIAL_ID = + GltfDefaults.class.getName() + ".DEFAULT_MATERIAL_ID"; + /** * The default vertex {@link Shader} */ - private static final Shader DEFAULT_VERTEX_SHADER = - Shaders.createDefaultVertexShader(); - + private static final Shader DEFAULT_VERTEX_SHADER = + Shaders.createDefaultVertexShader(); + /** * The default fragment {@link Shader} */ - private static final Shader DEFAULT_FRAGMENT_SHADER = - Shaders.createDefaultFragmentShader(); - + private static final Shader DEFAULT_FRAGMENT_SHADER = + Shaders.createDefaultFragmentShader(); + /** * The default {@link Program} */ - private static final Program DEFAULT_PROGRAM = - Programs.createDefaultProgram( - DEFAULT_VERTEX_SHADER_ID, DEFAULT_FRAGMENT_SHADER_ID); - + private static final Program DEFAULT_PROGRAM = + Programs.createDefaultProgram( + DEFAULT_VERTEX_SHADER_ID, DEFAULT_FRAGMENT_SHADER_ID); + /** * The default {@link Technique} */ - private static final Technique DEFAULT_TECHNIQUE = - Techniques.createDefaultTechnique(DEFAULT_PROGRAM_ID); - + private static final Technique DEFAULT_TECHNIQUE = + Techniques.createDefaultTechnique(DEFAULT_PROGRAM_ID); + /** * The default {@link Material} */ - private static final Material DEFAULT_MATERIAL = - Materials.createDefaultMaterial(DEFAULT_TECHNIQUE_ID); - - /** - * Private constructor to prevent instantiation - */ - private GltfDefaults() { - // Private constructor to prevent instantiation - } - + private static final Material DEFAULT_MATERIAL = + Materials.createDefaultMaterial(DEFAULT_TECHNIQUE_ID); + /** * Returns whether the given ID is the default ID as defined in this class - * + * * @param id The ID * @return Whether the given ID is the default ID */ - public static boolean isDefaultTechniqueId(String id) { + public static boolean isDefaultTechniqueId(String id) + { return DEFAULT_TECHNIQUE_ID.equals(id); } - + /** * Returns whether the given ID is the default ID as defined in this class - * + * * @param id The ID * @return Whether the given ID is the default ID */ - public static boolean isDefaultMaterialId(String id) { + public static boolean isDefaultMaterialId(String id) + { return DEFAULT_MATERIAL_ID.equals(id); } - + /** * Returns the default vertex {@link Shader} - * + * * @return The {@link Shader} */ - static Shader getDefaultVertexShader() { + static Shader getDefaultVertexShader() + { return DEFAULT_VERTEX_SHADER; } - + /** * Returns the default fragment {@link Shader} - * + * * @return The {@link Shader} */ - static Shader getDefaultFragmentShader() { + static Shader getDefaultFragmentShader() + { return DEFAULT_FRAGMENT_SHADER; } - + /** * Returns the default {@link Technique} - * + * * @return The {@link Technique} */ - static Technique getDefaultTechnique() { + static Technique getDefaultTechnique() + { return DEFAULT_TECHNIQUE; } - + /** * Returns the default {@link Material} - * + * * @return The {@link Material} */ - static Material getDefaultMaterial() { + static Material getDefaultMaterial() + { return DEFAULT_MATERIAL; } - + + /** + * Private constructor to prevent instantiation + */ + private GltfDefaults() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/Materials.java b/src/main/java/de/javagl/jgltf/model/v1/gl/Materials.java index 4fa1120..765d549 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/Materials.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/Materials.java @@ -26,38 +26,41 @@ */ package de.javagl.jgltf.model.v1.gl; +import java.util.Arrays; + import de.javagl.jgltf.impl.v1.Material; import de.javagl.jgltf.impl.v1.Technique; -import java.util.Arrays; - /** * Utility methods for {@link Material}s */ -class Materials { - /** - * Private constructor to prevent instantiation - */ - private Materials() { - // Private constructor to prevent instantiation - } - +class Materials +{ /** * Create a default {@link Material} with the given {@link Technique} ID, * that is assumed to refer to a {@link Techniques#createDefaultTechnique( - *String) default technique}.
    + * String) default technique}.
    *
    - * The returned {@link Material} is the default {@link Material}, as - * described in "Appendix A" of the glTF 1.0 specification. - * + * The returned {@link Material} is the default {@link Material}, as + * described in "Appendix A" of the glTF 1.0 specification. + * * @param techniqueId The {@link Technique} ID * @return The default {@link Material} */ - static Material createDefaultMaterial(String techniqueId) { + static Material createDefaultMaterial(String techniqueId) + { Material material = new Material(); material.addValues("emission", Arrays.asList(0.5, 0.5, 0.5, 1.0)); material.setTechnique(techniqueId); return material; } + + /** + * Private constructor to prevent instantiation + */ + private Materials() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/Programs.java b/src/main/java/de/javagl/jgltf/model/v1/gl/Programs.java index 1474a71..309261b 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/Programs.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/Programs.java @@ -33,36 +33,39 @@ /** * Utility methods for {@link Program}s */ -class Programs { +class Programs +{ /** - * Private constructor to prevent instantiation - */ - private Programs() { - // Private constructor to prevent instantiation - } - - /** - * Creates a default {@link Program} with the given vertex- and + * Creates a default {@link Program} with the given vertex- and * fragment {@link Shader} IDs, which are assumed to refer to * the {@link Shaders#createDefaultVertexShader() default vertex shader} - * and {@link Shaders#createDefaultFragmentShader() default fragment + * and {@link Shaders#createDefaultFragmentShader() default fragment * shader}.
    *
    - * The returned {@link Program} is the {@link Program} for the default - * {@link Material}, as described in "Appendix A" of the - * glTF 1.0 specification. - * - * @param vertexShaderId The vertex {@link Shader} ID + * The returned {@link Program} is the {@link Program} for the default + * {@link Material}, as described in "Appendix A" of the + * glTF 1.0 specification. + * + * @param vertexShaderId The vertex {@link Shader} ID * @param fragmentShaderId The fragment {@link Shader} ID * @return The default {@link Program} */ static Program createDefaultProgram( - String vertexShaderId, String fragmentShaderId) { + String vertexShaderId, String fragmentShaderId) + { Program program = new Program(); program.setVertexShader(vertexShaderId); program.setFragmentShader(fragmentShaderId); program.addAttributes("a_position"); return program; } + + /** + * Private constructor to prevent instantiation + */ + private Programs() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/Shaders.java b/src/main/java/de/javagl/jgltf/model/v1/gl/Shaders.java index 66dea72..ee697d3 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/Shaders.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/Shaders.java @@ -26,95 +26,99 @@ */ package de.javagl.jgltf.model.v1.gl; +import java.util.Base64; + import de.javagl.jgltf.impl.v1.Material; import de.javagl.jgltf.impl.v1.Shader; import de.javagl.jgltf.model.GltfConstants; -import java.util.Base64; - /** * Utility methods for {@link Shader}s. */ -class Shaders { +class Shaders +{ /** * The source code of the default vertex shader */ - private static final String DEFAULT_VERTEX_SHADER_CODE = - "#ifdef GL_ES" + "\n" + - " precision highp float;" + "\n" + - "#endif" + "\n" + "\n" + - "uniform mat4 u_modelViewMatrix;" + "\n" + - "uniform mat4 u_projectionMatrix;" + "\n" + - "attribute vec3 a_position;" + "\n" + - "void main(void)" + "\n" + - "{" + "\n" + - " gl_Position = u_projectionMatrix * u_modelViewMatrix *" + "\n" + - " vec4(a_position,1.0);" + "\n" + - "}" + "\n" + - "\n"; - + private static final String DEFAULT_VERTEX_SHADER_CODE = + "#ifdef GL_ES" + "\n" + + " precision highp float;" + "\n" + + "#endif"+ "\n" + "\n" + + "uniform mat4 u_modelViewMatrix;" + "\n" + + "uniform mat4 u_projectionMatrix;" + "\n" + + "attribute vec3 a_position;" + "\n" + + "void main(void)" + "\n" + + "{" + "\n" + + " gl_Position = u_projectionMatrix * u_modelViewMatrix *" + "\n" + + " vec4(a_position,1.0);" + "\n" + + "}" + "\n" + + "\n"; + /** * The source code of the default fragment shader */ private static final String DEFAULT_FRAGMENT_SHADER_CODE = - "#ifdef GL_ES" + "\n" + - " precision highp float;" + "\n" + - "#endif" + "\n" + "\n" + - "uniform vec4 u_emission;" + "\n" + - "void main(void)" + "\n" + - "{" + "\n" + - " gl_FragColor = u_emission;" + "\n" + - "}" + "\n" + - "\n"; - - - /** - * Private constructor to prevent instantiation - */ - private Shaders() { - // Private constructor to prevent instantiation - } - + "#ifdef GL_ES" + "\n" + + " precision highp float;" + "\n" + + "#endif"+ "\n" + "\n" + + "uniform vec4 u_emission;" + "\n" + + "void main(void)" + "\n" + + "{" + "\n" + + " gl_FragColor = u_emission;" + "\n" + + "}" + "\n" + + "\n"; + + /** - * Creates a default vertex {@link Shader}, with an embedded + * Creates a default vertex {@link Shader}, with an embedded * representation of the source code in form of a data URI.
    *
    - * The returned {@link Shader} is the vertex {@link Shader} for the - * default {@link Material}, as described in "Appendix A" of the - * specification. - * + * The returned {@link Shader} is the vertex {@link Shader} for the + * default {@link Material}, as described in "Appendix A" of the + * specification. + * * @return The default {@link Shader} */ - static Shader createDefaultVertexShader() { + static Shader createDefaultVertexShader() + { Shader shader = new Shader(); shader.setType(GltfConstants.GL_VERTEX_SHADER); - String encodedCode = - Base64.getEncoder().encodeToString( - DEFAULT_VERTEX_SHADER_CODE.getBytes()); + String encodedCode = + Base64.getEncoder().encodeToString( + DEFAULT_VERTEX_SHADER_CODE.getBytes()); String dataUriString = "data:text/plain;base64," + encodedCode; shader.setUri(dataUriString); return shader; } /** - * Creates a default fragment {@link Shader}, with an embedded + * Creates a default fragment {@link Shader}, with an embedded * representation of the source code in form of a data URI.
    *
    - * The returned {@link Shader} is the fragment {@link Shader} for the - * default {@link Material}, as described in "Appendix A" of the - * specification. - * + * The returned {@link Shader} is the fragment {@link Shader} for the + * default {@link Material}, as described in "Appendix A" of the + * specification. + * * @return The default {@link Shader} */ - static Shader createDefaultFragmentShader() { + static Shader createDefaultFragmentShader() + { Shader shader = new Shader(); shader.setType(GltfConstants.GL_FRAGMENT_SHADER); - String encodedCode = - Base64.getEncoder().encodeToString( - DEFAULT_FRAGMENT_SHADER_CODE.getBytes()); + String encodedCode = + Base64.getEncoder().encodeToString( + DEFAULT_FRAGMENT_SHADER_CODE.getBytes()); String dataUriString = "data:text/plain;base64," + encodedCode; shader.setUri(dataUriString); return shader; } + + /** + * Private constructor to prevent instantiation + */ + private Shaders() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/TechniqueStatesFunctionsModels.java b/src/main/java/de/javagl/jgltf/model/v1/gl/TechniqueStatesFunctionsModels.java index ab38782..a80ba1c 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/TechniqueStatesFunctionsModels.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/TechniqueStatesFunctionsModels.java @@ -35,48 +35,51 @@ * Methods to create {@link TechniqueStatesFunctionsModel} instances from * glTF 1.0 {@link TechniqueStatesFunctions} objects */ -public class TechniqueStatesFunctionsModels { - /** - * Private constructor to prevent instantiation - */ - private TechniqueStatesFunctionsModels() { - // Private constructor to prevent instantiation - } - +public class TechniqueStatesFunctionsModels +{ /** * Creates a new {@link TechniqueStatesFunctionsModel} object from the * given {@link TechniqueStatesFunctions} - * + * * @param techniqueStatesFunctions The {@link TechniqueStatesFunctions} * @return The {@link TechniqueStatesFunctionsModel} */ public static DefaultTechniqueStatesFunctionsModel create( - TechniqueStatesFunctions techniqueStatesFunctions) { - DefaultTechniqueStatesFunctionsModel techniqueStatesFunctionsModel = - new DefaultTechniqueStatesFunctionsModel(); + TechniqueStatesFunctions techniqueStatesFunctions) + { + DefaultTechniqueStatesFunctionsModel techniqueStatesFunctionsModel = + new DefaultTechniqueStatesFunctionsModel(); techniqueStatesFunctionsModel.setBlendColor(Optionals.clone( - techniqueStatesFunctions.getBlendColor())); + techniqueStatesFunctions.getBlendColor())); techniqueStatesFunctionsModel.setBlendEquationSeparate(Optionals.clone( - techniqueStatesFunctions.getBlendEquationSeparate())); + techniqueStatesFunctions.getBlendEquationSeparate())); techniqueStatesFunctionsModel.setBlendFuncSeparate(Optionals.clone( - techniqueStatesFunctions.getBlendFuncSeparate())); + techniqueStatesFunctions.getBlendFuncSeparate())); techniqueStatesFunctionsModel.setColorMask(Optionals.clone( - techniqueStatesFunctions.getColorMask())); + techniqueStatesFunctions.getColorMask())); techniqueStatesFunctionsModel.setCullFace(Optionals.clone( - techniqueStatesFunctions.getCullFace())); + techniqueStatesFunctions.getCullFace())); techniqueStatesFunctionsModel.setDepthFunc(Optionals.clone( - techniqueStatesFunctions.getDepthFunc())); + techniqueStatesFunctions.getDepthFunc())); techniqueStatesFunctionsModel.setDepthMask(Optionals.clone( - techniqueStatesFunctions.getDepthMask())); + techniqueStatesFunctions.getDepthMask())); techniqueStatesFunctionsModel.setDepthRange(Optionals.clone( - techniqueStatesFunctions.getDepthRange())); + techniqueStatesFunctions.getDepthRange())); techniqueStatesFunctionsModel.setFrontFace(Optionals.clone( - techniqueStatesFunctions.getFrontFace())); + techniqueStatesFunctions.getFrontFace())); techniqueStatesFunctionsModel.setLineWidth(Optionals.clone( - techniqueStatesFunctions.getLineWidth())); + techniqueStatesFunctions.getLineWidth())); techniqueStatesFunctionsModel.setPolygonOffset(Optionals.clone( - techniqueStatesFunctions.getPolygonOffset())); - + techniqueStatesFunctions.getPolygonOffset())); + return techniqueStatesFunctionsModel; } + + /** + * Private constructor to prevent instantiation + */ + private TechniqueStatesFunctionsModels() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/v1/gl/Techniques.java b/src/main/java/de/javagl/jgltf/model/v1/gl/Techniques.java index e379c6b..0ba3c20 100644 --- a/src/main/java/de/javagl/jgltf/model/v1/gl/Techniques.java +++ b/src/main/java/de/javagl/jgltf/model/v1/gl/Techniques.java @@ -26,140 +26,145 @@ */ package de.javagl.jgltf.model.v1.gl; -import de.javagl.jgltf.impl.v1.*; -import de.javagl.jgltf.model.GltfConstants; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import de.javagl.jgltf.impl.v1.Material; +import de.javagl.jgltf.impl.v1.Program; +import de.javagl.jgltf.impl.v1.Technique; +import de.javagl.jgltf.impl.v1.TechniqueParameters; +import de.javagl.jgltf.impl.v1.TechniqueStates; +import de.javagl.jgltf.impl.v1.TechniqueStatesFunctions; +import de.javagl.jgltf.model.GltfConstants; + /** * Utility methods related to {@link Technique}s */ -public class Techniques { - /** - * Private constructor to prevent instantiation - */ - private Techniques() { - // Private constructor to prevent instantiation - } - +public class Techniques +{ /** * Create a default {@link Technique} with the given {@link Program} ID, * which is assumed to refer to a {@link Programs#createDefaultProgram( - *String, String) default program}.
    + * String, String) default program}.
    *
    - * The returned {@link Technique} is the {@link Technique} for the - * default {@link Material}, as described in "Appendix A" of the - * glTF 1.0 specification. - * + * The returned {@link Technique} is the {@link Technique} for the + * default {@link Material}, as described in "Appendix A" of the + * glTF 1.0 specification. + * * @param programId The {@link Program} ID * @return The default {@link Technique} */ - static Technique createDefaultTechnique(String programId) { + static Technique createDefaultTechnique(String programId) + { Technique technique = new Technique(); technique.addAttributes("a_position", "position"); - technique.addParameters("modelViewMatrix", - createDefaultTechniqueParameters( - "MODELVIEW", GltfConstants.GL_FLOAT_MAT4, null)); - technique.addParameters("projectionMatrix", - createDefaultTechniqueParameters( - "PROJECTION", GltfConstants.GL_FLOAT_MAT4, null)); - technique.addParameters("emission", - createDefaultTechniqueParameters( - null, GltfConstants.GL_FLOAT_VEC4, - Arrays.asList(0.5f, 0.5f, 0.5f, 1.0f))); - technique.addParameters("position", - createDefaultTechniqueParameters( - "POSITION", GltfConstants.GL_FLOAT_VEC3, null)); + technique.addParameters("modelViewMatrix", + createDefaultTechniqueParameters( + "MODELVIEW", GltfConstants.GL_FLOAT_MAT4, null)); + technique.addParameters("projectionMatrix", + createDefaultTechniqueParameters( + "PROJECTION", GltfConstants.GL_FLOAT_MAT4, null)); + technique.addParameters("emission", + createDefaultTechniqueParameters( + null, GltfConstants.GL_FLOAT_VEC4, + Arrays.asList(0.5f, 0.5f, 0.5f, 1.0f))); + technique.addParameters("position", + createDefaultTechniqueParameters( + "POSITION", GltfConstants.GL_FLOAT_VEC3, null)); technique.setStates(createDefaultTechniqueStates()); technique.setProgram(programId); - + technique.addUniforms("u_modelViewMatrix", "modelViewMatrix"); technique.addUniforms("u_projectionMatrix", "projectionMatrix"); technique.addUniforms("u_emission", "emission"); - + return technique; } - + /** * Create the default {@link TechniqueStates} - * + * * @return The default {@link TechniqueStates} */ - private static TechniqueStates createDefaultTechniqueStates() { + private static TechniqueStates createDefaultTechniqueStates() + { TechniqueStates techniqueStates = new TechniqueStates(); techniqueStates.setEnable( - new ArrayList(techniqueStates.defaultEnable())); + new ArrayList(techniqueStates.defaultEnable())); techniqueStates.setFunctions(createDefaultTechniqueStatesFunctions()); return techniqueStates; } - + /** * Create the default {@link TechniqueStatesFunctions} - * + * * @return The default {@link TechniqueStatesFunctions} */ - public static TechniqueStatesFunctions - createDefaultTechniqueStatesFunctions() { - TechniqueStatesFunctions techniqueStatesFunctions = - new TechniqueStatesFunctions(); + public static TechniqueStatesFunctions + createDefaultTechniqueStatesFunctions() + { + TechniqueStatesFunctions techniqueStatesFunctions = + new TechniqueStatesFunctions(); techniqueStatesFunctions.setBlendColor( - techniqueStatesFunctions.defaultBlendColor()); + techniqueStatesFunctions.defaultBlendColor()); techniqueStatesFunctions.setBlendEquationSeparate( - techniqueStatesFunctions.defaultBlendEquationSeparate()); + techniqueStatesFunctions.defaultBlendEquationSeparate()); techniqueStatesFunctions.setBlendFuncSeparate( - techniqueStatesFunctions.defaultBlendFuncSeparate()); + techniqueStatesFunctions.defaultBlendFuncSeparate()); techniqueStatesFunctions.setColorMask( - techniqueStatesFunctions.defaultColorMask()); + techniqueStatesFunctions.defaultColorMask()); techniqueStatesFunctions.setCullFace( - techniqueStatesFunctions.defaultCullFace()); + techniqueStatesFunctions.defaultCullFace()); techniqueStatesFunctions.setDepthFunc( - techniqueStatesFunctions.defaultDepthFunc()); + techniqueStatesFunctions.defaultDepthFunc()); techniqueStatesFunctions.setDepthMask( - techniqueStatesFunctions.defaultDepthMask()); + techniqueStatesFunctions.defaultDepthMask()); techniqueStatesFunctions.setDepthRange( - techniqueStatesFunctions.defaultDepthRange()); + techniqueStatesFunctions.defaultDepthRange()); techniqueStatesFunctions.setFrontFace( - techniqueStatesFunctions.defaultFrontFace()); + techniqueStatesFunctions.defaultFrontFace()); techniqueStatesFunctions.setLineWidth( - techniqueStatesFunctions.defaultLineWidth()); + techniqueStatesFunctions.defaultLineWidth()); techniqueStatesFunctions.setPolygonOffset( - techniqueStatesFunctions.defaultPolygonOffset()); + techniqueStatesFunctions.defaultPolygonOffset()); techniqueStatesFunctions.setScissor( - techniqueStatesFunctions.defaultScissor()); + techniqueStatesFunctions.defaultScissor()); return techniqueStatesFunctions; } /** * Create default {@link TechniqueParameters} with the given semantic, * type and value - * + * * @param semantic The semantic - * @param type The type - * @param value The value + * @param type The type + * @param value The value * @return The default {@link TechniqueParameters} */ private static TechniqueParameters createDefaultTechniqueParameters( - String semantic, Integer type, Object value) { + String semantic, Integer type, Object value) + { TechniqueParameters techniqueParameters = new TechniqueParameters(); techniqueParameters.setSemantic(semantic); techniqueParameters.setType(type); techniqueParameters.setValue(value); return techniqueParameters; } - + /** - * Returns the set of states that should be enabled for the given + * Returns the set of states that should be enabled for the given * {@link Technique} - * + * * @param technique The {@link Technique} * @return The enabled states */ - public static List obtainEnabledStates(Technique technique) { + public static List obtainEnabledStates(Technique technique) + { TechniqueStates states = obtainTechniqueStates(technique); List enable = states.getEnable(); - if (enable == null) { + if (enable == null) + { return states.defaultEnable(); } return enable; @@ -167,43 +172,55 @@ public static List obtainEnabledStates(Technique technique) { /** * Return the {@link TechniqueStates} from the given {@link Technique}, - * or the {@link TechniqueStates} from the + * or the {@link TechniqueStates} from the * {@link GltfDefaults#getDefaultTechnique() default technique} if - * the given {@link Technique} is null or does not + * the given {@link Technique} is null or does not * contain any {@link TechniqueStates} - * + * * @param technique The {@link Technique} * @return The {@link TechniqueStates} */ - private static TechniqueStates obtainTechniqueStates(Technique technique) { + private static TechniqueStates obtainTechniqueStates(Technique technique) + { TechniqueStates states = technique.getStates(); - if (states == null) { + if (states == null) + { return GltfDefaults.getDefaultTechnique().getStates(); } return states; } /** - * Return the {@link TechniqueStatesFunctions} from the - * {@link TechniqueStates} of the given {@link Technique}, or the - * {@link TechniqueStatesFunctions} from the + * Return the {@link TechniqueStatesFunctions} from the + * {@link TechniqueStates} of the given {@link Technique}, or the + * {@link TechniqueStatesFunctions} from the * {@link GltfDefaults#getDefaultTechnique() default technique} if - * the given {@link Technique} is null or does not + * the given {@link Technique} is null or does not * contain any {@link TechniqueStates} or {@link TechniqueStatesFunctions} - * + * * @param technique The {@link Technique} * @return The {@link TechniqueStatesFunctions} */ public static TechniqueStatesFunctions obtainTechniqueStatesFunctions( - Technique technique) { + Technique technique) + { TechniqueStates states = obtainTechniqueStates(technique); TechniqueStatesFunctions functions = states.getFunctions(); - if (functions == null) { - TechniqueStates defaultStates = - GltfDefaults.getDefaultTechnique().getStates(); + if (functions == null) + { + TechniqueStates defaultStates = + GltfDefaults.getDefaultTechnique().getStates(); return defaultStates.getFunctions(); } return functions; } - + + /** + * Private constructor to prevent instantiation + */ + private Techniques() + { + // Private constructor to prevent instantiation + } + } diff --git a/src/main/java/de/javagl/jgltf/model/v2/AccessorSparseUtils.java b/src/main/java/de/javagl/jgltf/model/v2/AccessorSparseUtils.java index bc3ca27..b387ae3 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/AccessorSparseUtils.java +++ b/src/main/java/de/javagl/jgltf/model/v2/AccessorSparseUtils.java @@ -26,10 +26,14 @@ */ package de.javagl.jgltf.model.v2; -import de.javagl.jgltf.model.*; - import java.util.logging.Logger; +import de.javagl.jgltf.model.AccessorByteData; +import de.javagl.jgltf.model.AccessorData; +import de.javagl.jgltf.model.AccessorFloatData; +import de.javagl.jgltf.model.AccessorIntData; +import de.javagl.jgltf.model.AccessorShortData; + /** * Utility methods related to sparse accessors.
    *
    @@ -39,190 +43,208 @@ *
    * Yes, Java does not play out so well with different primitive types... */ -class AccessorSparseUtils { +class AccessorSparseUtils +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(AccessorSparseUtils.class.getName()); - - /** - * Private constructor to prevent instantiation - */ - private AccessorSparseUtils() { - // Private constructor to prevent instantiation - } - + private static final Logger logger = + Logger.getLogger(AccessorSparseUtils.class.getName()); + /** - * Extract indices from the given {@link AccessorData}. The given + * Extract indices from the given {@link AccessorData}. The given * {@link AccessorData} must contain an integral type. That is, * its {@link AccessorData#getComponentType() component type} must * be byte.class, short.class or * int.class. - * + * * @param accessorData The {@link AccessorData} * @return The indices * @throws IllegalArgumentException If the given data does not contain - * an integral type + * an integral type */ - private static int[] extractIndices(AccessorData accessorData) { - if (accessorData.getComponentType() == byte.class) { - AccessorByteData accessorByteData = - (AccessorByteData) accessorData; + private static int[] extractIndices(AccessorData accessorData) + { + if (accessorData.getComponentType() == byte.class) + { + AccessorByteData accessorByteData = + (AccessorByteData)accessorData; int numElements = accessorByteData.getNumElements(); int indices[] = new int[numElements]; - for (int i = 0; i < numElements; i++) { + for (int i=0; i *
    - * The baseAccessorData is the data that the dense data - * will be initialized with, before applying the substitution + * The baseAccessorData is the data that the dense data + * will be initialized with, before applying the substitution * that is defined by the given sparse indices and values.
    *
    * The sparseIndicesAccessorData is an {@link AccessorData} - * that was created from the accessor.sparse.indices + * that was created from the accessor.sparse.indices * structure.
    - *
    + *
    * The sparseValuesAccessorData is an {@link AccessorData} - * that was created from the accessor.sparse.values + * that was created from the accessor.sparse.values * structure.
    - *
    + *
    * This method does very few sanity checks. The caller is responsible - * for calling it only with arguments that are valid (in terms of + * for calling it only with arguments that are valid (in terms of * indices and data types). - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ static void substituteAccessorData( - AccessorData denseAccessorData, - AccessorData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorData sparseValuesAccessorData) { + AccessorData denseAccessorData, + AccessorData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorData sparseValuesAccessorData) + { Class componentType = denseAccessorData.getComponentType(); - if (componentType == byte.class) { - AccessorByteData sparseValuesAccessorByteData = - (AccessorByteData) sparseValuesAccessorData; + if (componentType == byte.class) + { + AccessorByteData sparseValuesAccessorByteData = + (AccessorByteData)sparseValuesAccessorData; AccessorByteData baseAccessorByteData = - (AccessorByteData) baseAccessorData; + (AccessorByteData)baseAccessorData; AccessorByteData denseAccessorByteData = - (AccessorByteData) denseAccessorData; + (AccessorByteData)denseAccessorData; substituteByteAccessorData( - denseAccessorByteData, - baseAccessorByteData, - sparseIndicesAccessorData, - sparseValuesAccessorByteData); - } else if (componentType == short.class) { - AccessorShortData sparseValuesAccessorShortData = - (AccessorShortData) sparseValuesAccessorData; + denseAccessorByteData, + baseAccessorByteData, + sparseIndicesAccessorData, + sparseValuesAccessorByteData); + } + else if (componentType == short.class) + { + AccessorShortData sparseValuesAccessorShortData = + (AccessorShortData)sparseValuesAccessorData; AccessorShortData baseAccessorShortData = - (AccessorShortData) baseAccessorData; + (AccessorShortData)baseAccessorData; AccessorShortData denseAccessorShortData = - (AccessorShortData) denseAccessorData; + (AccessorShortData)denseAccessorData; substituteShortAccessorData( - denseAccessorShortData, - baseAccessorShortData, - sparseIndicesAccessorData, - sparseValuesAccessorShortData); - } else if (componentType == int.class) { - AccessorIntData sparseValuesAccessorIntData = - (AccessorIntData) sparseValuesAccessorData; + denseAccessorShortData, + baseAccessorShortData, + sparseIndicesAccessorData, + sparseValuesAccessorShortData); + } + else if (componentType == int.class) + { + AccessorIntData sparseValuesAccessorIntData = + (AccessorIntData)sparseValuesAccessorData; AccessorIntData baseAccessorIntData = - (AccessorIntData) baseAccessorData; + (AccessorIntData)baseAccessorData; AccessorIntData denseAccessorIntData = - (AccessorIntData) denseAccessorData; + (AccessorIntData)denseAccessorData; substituteIntAccessorData( - denseAccessorIntData, - baseAccessorIntData, - sparseIndicesAccessorData, - sparseValuesAccessorIntData); - } else if (componentType == float.class) { - AccessorFloatData sparseValuesAccessorFloatData = - (AccessorFloatData) sparseValuesAccessorData; + denseAccessorIntData, + baseAccessorIntData, + sparseIndicesAccessorData, + sparseValuesAccessorIntData); + } + else if (componentType == float.class) + { + AccessorFloatData sparseValuesAccessorFloatData = + (AccessorFloatData)sparseValuesAccessorData; AccessorFloatData baseAccessorFloatData = - (AccessorFloatData) baseAccessorData; + (AccessorFloatData)baseAccessorData; AccessorFloatData denseAccessorFloatData = - (AccessorFloatData) denseAccessorData; - + (AccessorFloatData)denseAccessorData; + substituteFloatAccessorData( - denseAccessorFloatData, - baseAccessorFloatData, - sparseIndicesAccessorData, - sparseValuesAccessorFloatData); - } else { + denseAccessorFloatData, + baseAccessorFloatData, + sparseIndicesAccessorData, + sparseValuesAccessorFloatData); + } + else + { logger.warning("Invalid component type for accessor: " - + componentType); + + componentType); } } - + + /** * See {@link #substituteAccessorData} - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ private static void substituteByteAccessorData( - AccessorByteData denseAccessorData, - AccessorByteData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorByteData sparseValuesAccessorData) { + AccessorByteData denseAccessorData, + AccessorByteData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorByteData sparseValuesAccessorData) + { int numElements = denseAccessorData.getNumElements(); - int numComponentsPerElement = - denseAccessorData.getNumComponentsPerElement(); - - if (baseAccessorData != null) { + int numComponentsPerElement = + denseAccessorData.getNumComponentsPerElement(); + + if (baseAccessorData != null) + { // Fill the dense AccessorData with the base data - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponentsPerElement; c++) { + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponentsPerElement; c++) + { byte value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } - + // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); - for (int i = 0; i < indices.length; i++) { + for (int i = 0; i < indices.length; i++) + { int targetElementIndex = indices[i]; - for (int c = 0; c < numComponentsPerElement; c++) { + for (int c = 0; c < numComponentsPerElement; c++) + { byte substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } @@ -231,38 +253,44 @@ private static void substituteByteAccessorData( /** * See {@link #substituteAccessorData} - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ private static void substituteShortAccessorData( - AccessorShortData denseAccessorData, - AccessorShortData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorShortData sparseValuesAccessorData) { + AccessorShortData denseAccessorData, + AccessorShortData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorShortData sparseValuesAccessorData) + { int numElements = denseAccessorData.getNumElements(); - int numComponentsPerElement = - denseAccessorData.getNumComponentsPerElement(); - - if (baseAccessorData != null) { + int numComponentsPerElement = + denseAccessorData.getNumComponentsPerElement(); + + if (baseAccessorData != null) + { // Fill the dense AccessorData with the base data - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponentsPerElement; c++) { + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponentsPerElement; c++) + { short value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } - + // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); - for (int i = 0; i < indices.length; i++) { + for (int i = 0; i < indices.length; i++) + { int targetElementIndex = indices[i]; - for (int c = 0; c < numComponentsPerElement; c++) { + for (int c = 0; c < numComponentsPerElement; c++) + { short substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } @@ -271,81 +299,102 @@ private static void substituteShortAccessorData( /** * See {@link #substituteAccessorData} - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ private static void substituteIntAccessorData( - AccessorIntData denseAccessorData, - AccessorIntData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorIntData sparseValuesAccessorData) { + AccessorIntData denseAccessorData, + AccessorIntData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorIntData sparseValuesAccessorData) + { int numElements = denseAccessorData.getNumElements(); - int numComponentsPerElement = - denseAccessorData.getNumComponentsPerElement(); - - if (baseAccessorData != null) { + int numComponentsPerElement = + denseAccessorData.getNumComponentsPerElement(); + + if (baseAccessorData != null) + { // Fill the dense AccessorData with the base data - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponentsPerElement; c++) { + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponentsPerElement; c++) + { int value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } - + // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); - for (int i = 0; i < indices.length; i++) { + for (int i = 0; i < indices.length; i++) + { int targetElementIndex = indices[i]; - for (int c = 0; c < numComponentsPerElement; c++) { + for (int c = 0; c < numComponentsPerElement; c++) + { int substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } } } - + /** * See {@link #substituteAccessorData} - * - * @param denseAccessorData The dense {@link AccessorData} to be filled - * @param baseAccessorData The optional "base" {@link AccessorData} + * + * @param denseAccessorData The dense {@link AccessorData} to be filled + * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} - * @param sparseValuesAccessorData The sparse values {@link AccessorData} + * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does - * not contain data with an integral type (byte, short, int). + * not contain data with an integral type (byte, short, int). */ private static void substituteFloatAccessorData( - AccessorFloatData denseAccessorData, - AccessorFloatData baseAccessorData, - AccessorData sparseIndicesAccessorData, - AccessorFloatData sparseValuesAccessorData) { + AccessorFloatData denseAccessorData, + AccessorFloatData baseAccessorData, + AccessorData sparseIndicesAccessorData, + AccessorFloatData sparseValuesAccessorData) + { int numElements = denseAccessorData.getNumElements(); - int numComponentsPerElement = - denseAccessorData.getNumComponentsPerElement(); - - if (baseAccessorData != null) { + int numComponentsPerElement = + denseAccessorData.getNumComponentsPerElement(); + + if (baseAccessorData != null) + { // Fill the dense AccessorData with the base data - for (int e = 0; e < numElements; e++) { - for (int c = 0; c < numComponentsPerElement; c++) { + for (int e = 0; e < numElements; e++) + { + for (int c = 0; c < numComponentsPerElement; c++) + { float value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } - + // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); - for (int i = 0; i < indices.length; i++) { + for (int i = 0; i < indices.length; i++) + { int targetElementIndex = indices[i]; - for (int c = 0; c < numComponentsPerElement; c++) { + for (int c = 0; c < numComponentsPerElement; c++) + { float substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } } } + + + /** + * Private constructor to prevent instantiation + */ + private AccessorSparseUtils() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/de/javagl/jgltf/model/v2/GltfCreatorV2.java b/src/main/java/de/javagl/jgltf/model/v2/GltfCreatorV2.java index 70bc60a..0e3d106 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/GltfCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/v2/GltfCreatorV2.java @@ -26,94 +26,235 @@ */ package de.javagl.jgltf.model.v2; -import de.javagl.jgltf.impl.v2.*; -import de.javagl.jgltf.model.*; -import de.javagl.jgltf.model.AnimationModel.Channel; -import de.javagl.jgltf.model.AnimationModel.Sampler; -import de.javagl.jgltf.model.impl.DefaultNodeModel; -import de.javagl.jgltf.model.v2.MaterialModelV2.AlphaMode; - -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.function.Function; import java.util.logging.Logger; import java.util.stream.Collectors; +import de.javagl.jgltf.impl.v2.Accessor; +import de.javagl.jgltf.impl.v2.Animation; +import de.javagl.jgltf.impl.v2.AnimationChannel; +import de.javagl.jgltf.impl.v2.AnimationChannelTarget; +import de.javagl.jgltf.impl.v2.AnimationSampler; +import de.javagl.jgltf.impl.v2.Asset; +import de.javagl.jgltf.impl.v2.Buffer; +import de.javagl.jgltf.impl.v2.BufferView; +import de.javagl.jgltf.impl.v2.Camera; +import de.javagl.jgltf.impl.v2.CameraOrthographic; +import de.javagl.jgltf.impl.v2.CameraPerspective; +import de.javagl.jgltf.impl.v2.GlTF; +import de.javagl.jgltf.impl.v2.GlTFChildOfRootProperty; +import de.javagl.jgltf.impl.v2.GlTFProperty; +import de.javagl.jgltf.impl.v2.Image; +import de.javagl.jgltf.impl.v2.Material; +import de.javagl.jgltf.impl.v2.MaterialNormalTextureInfo; +import de.javagl.jgltf.impl.v2.MaterialOcclusionTextureInfo; +import de.javagl.jgltf.impl.v2.MaterialPbrMetallicRoughness; +import de.javagl.jgltf.impl.v2.Mesh; +import de.javagl.jgltf.impl.v2.MeshPrimitive; +import de.javagl.jgltf.impl.v2.Node; +import de.javagl.jgltf.impl.v2.Scene; +import de.javagl.jgltf.impl.v2.Skin; +import de.javagl.jgltf.impl.v2.Texture; +import de.javagl.jgltf.impl.v2.TextureInfo; +import de.javagl.jgltf.model.AccessorData; +import de.javagl.jgltf.model.AccessorDatas; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.AnimationModel; +import de.javagl.jgltf.model.AssetModel; +import de.javagl.jgltf.model.AnimationModel.Channel; +import de.javagl.jgltf.model.AnimationModel.Sampler; +import de.javagl.jgltf.model.BufferModel; +import de.javagl.jgltf.model.BufferViewModel; +import de.javagl.jgltf.model.CameraModel; +import de.javagl.jgltf.model.CameraOrthographicModel; +import de.javagl.jgltf.model.CameraPerspectiveModel; +import de.javagl.jgltf.model.ExtensionsModel; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.ImageModel; +import de.javagl.jgltf.model.MaterialModel; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; +import de.javagl.jgltf.model.ModelElement; +import de.javagl.jgltf.model.NamedModelElement; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.Optionals; +import de.javagl.jgltf.model.SceneModel; +import de.javagl.jgltf.model.SkinModel; +import de.javagl.jgltf.model.TextureModel; +import de.javagl.jgltf.model.impl.DefaultNodeModel; +import de.javagl.jgltf.model.v2.MaterialModelV2.AlphaMode; + /** - * A class for creating the {@link GlTF version 2.0 glTF} from a - * {@link GltfModel} + * A class for creating the {@link GlTF version 2.0 glTF} from a + * {@link GltfModel} */ -public class GltfCreatorV2 { +public class GltfCreatorV2 +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfCreatorV2.class.getName()); + private static final Logger logger = + Logger.getLogger(GltfCreatorV2.class.getName()); + + /** + * Creates a {@link GlTF} from the given {@link GltfModel} + * + * @param gltfModel The {@link GltfModel} + * @return The {@link GlTF} + */ + public static GlTF create(GltfModel gltfModel) + { + GltfCreatorV2 creator = new GltfCreatorV2(gltfModel); + return creator.create(); + } + + /** + * Inner class containing the information that is necessary to define + * a glTF {@link de.javagl.jgltf.impl.v2.Sampler} + */ + @SuppressWarnings("javadoc") + private static class SamplerInfo + { + final Integer magFilter; + final Integer minFilter; + final Integer wrapS; + final Integer wrapT; + + SamplerInfo(TextureModel textureModel) + { + this.magFilter = textureModel.getMagFilter(); + this.minFilter = textureModel.getMinFilter(); + this.wrapS = textureModel.getWrapS(); + this.wrapT = textureModel.getWrapT(); + } + + @Override + public int hashCode() + { + return Objects.hash(magFilter, minFilter, wrapS, wrapT); + } + + @Override + public boolean equals(Object object) + { + if (this == object) + { + return true; + } + if (object == null) + { + return false; + } + if (getClass() != object.getClass()) + { + return false; + } + SamplerInfo other = (SamplerInfo) object; + if (!Objects.equals(magFilter, other.magFilter)) + { + return false; + } + if (!Objects.equals(minFilter, other.minFilter)) + { + return false; + } + if (!Objects.equals(wrapS, other.wrapS)) + { + return false; + } + if (!Objects.equals(wrapT, other.wrapT)) + { + return false; + } + return true; + } + } + /** * The {@link GltfModel} that this instance operates on */ private final GltfModel gltfModel; + /** * A list of {@link NodeModel} instances that are the same as the * ones in the {@link GltfModel}, but extended so that each node - * refers to at most one {@link MeshModel}. + * refers to at most one {@link MeshModel}. * See {@link #createNodesWithSingleMeshes(List)} */ private final List nodesWithSingleMeshes; + /** * A map from {@link AccessorModel} objects to their indices */ private final Map accessorIndices; + /** * A map from {@link BufferModel} objects to their indices */ private final Map bufferIndices; + /** * A map from {@link BufferViewModel} objects to their indices */ private final Map bufferViewIndices; + /** * A map from {@link CameraModel} objects to their indices */ private final Map cameraIndices; + /** * A map from {@link ImageModel} objects to their indices */ private final Map imageIndices; + /** * A map from {@link MaterialModel} objects to their indices */ private final Map materialIndices; + /** * A map from {@link MeshModel} objects to their indices */ private final Map meshIndices; + /** * A map from {@link NodeModel} objects to their indices */ private final Map nodeIndices; + /** * A map from {@link SkinModel} objects to their indices */ private final Map skinIndices; + /** * A map from {@link TextureModel} objects to their indices */ private final Map textureIndices; + /** * A map from {@link SamplerInfo} objects to their indices */ private final Map samplerIndices; - + /** * Creates a new instance with the given {@link GltfModel} - * + * * @param gltfModel The {@link GltfModel} */ - private GltfCreatorV2(GltfModel gltfModel) { + private GltfCreatorV2(GltfModel gltfModel) + { this.gltfModel = Objects.requireNonNull( - gltfModel, "The gltfModel may not be null"); - + gltfModel, "The gltfModel may not be null"); + accessorIndices = computeIndexMap(gltfModel.getAccessorModels()); bufferIndices = computeIndexMap(gltfModel.getBufferModels()); bufferViewIndices = computeIndexMap(gltfModel.getBufferViewModels()); @@ -121,49 +262,104 @@ private GltfCreatorV2(GltfModel gltfModel) { imageIndices = computeIndexMap(gltfModel.getImageModels()); materialIndices = computeIndexMap(gltfModel.getMaterialModels()); meshIndices = computeIndexMap(gltfModel.getMeshModels()); - - this.nodesWithSingleMeshes = - createNodesWithSingleMeshes(gltfModel.getNodeModels()); + + this.nodesWithSingleMeshes = + createNodesWithSingleMeshes(gltfModel.getNodeModels()); nodeIndices = computeIndexMap(nodesWithSingleMeshes); skinIndices = computeIndexMap(gltfModel.getSkinModels()); textureIndices = computeIndexMap(gltfModel.getTextureModels()); - + samplerIndices = createSamplerIndices(gltfModel.getTextureModels()); } - + /** - * Creates a {@link GlTF} from the given {@link GltfModel} - * - * @param gltfModel The {@link GltfModel} - * @return The {@link GlTF} + * Create the {@link GlTF} instance from the {@link GltfModel} + * + * @return The {@link GlTF} instance */ - public static GlTF create(GltfModel gltfModel) { - GltfCreatorV2 creator = new GltfCreatorV2(gltfModel); - return creator.create(); + public GlTF create() + { + GlTF gltf = new GlTF(); + transferGltfPropertyElements(gltfModel, gltf); + + gltf.setAccessors(map( + gltfModel.getAccessorModels(), this::createAccessor)); + gltf.setAnimations(map( + gltfModel.getAnimationModels(), this::createAnimation)); + gltf.setBuffers(map( + gltfModel.getBufferModels(), GltfCreatorV2::createBuffer)); + gltf.setBufferViews(map( + gltfModel.getBufferViewModels(), this::createBufferView)); + gltf.setCameras(map( + gltfModel.getCameraModels(), this::createCamera)); + gltf.setImages(map( + gltfModel.getImageModels(), this::createImage)); + gltf.setMaterials(map( + gltfModel.getMaterialModels(), this::createMaterial)); + gltf.setMeshes(map( + gltfModel.getMeshModels(), this::createMesh)); + gltf.setNodes(map( + nodesWithSingleMeshes, this::createNode)); + gltf.setScenes(map( + gltfModel.getSceneModels(), this::createScene)); + gltf.setSkins(map( + gltfModel.getSkinModels(), this::createSkin)); + + gltf.setSamplers(createSamplers()); + + gltf.setTextures(map( + gltfModel.getTextureModels(), this::createTexture)); + + if (gltf.getScenes() != null && !gltf.getScenes().isEmpty()) + { + gltf.setScene(0); + } + + ExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); + List extensionsUsed = extensionsModel.getExtensionsUsed(); + if (!extensionsUsed.isEmpty()) + { + gltf.setExtensionsUsed(extensionsUsed); + } + List extensionsRequired = + extensionsModel.getExtensionsRequired(); + if (!extensionsRequired.isEmpty()) + { + gltf.setExtensionsRequired(extensionsRequired); + } + + Asset asset = createAsset(gltfModel.getAssetModel()); + gltf.setAsset(asset); + + return gltf; } - + /** * Creates a list of nodes that contains the same elements as the given - * list, but replaces each node that has multiple {@link MeshModel} + * list, but replaces each node that has multiple {@link MeshModel} * references with a new node that has the appropriate number of child * nodes that each refers to one {@link MeshModel} - * + * * @param nodeModels The input {@link NodeModel} objects * @return The resulting {@link NodeModel} objects */ private static List createNodesWithSingleMeshes( - List nodeModels) { + List nodeModels) + { List newNodes = new ArrayList(); - List nodeModelsWithSingleMeshes = - new ArrayList(nodeModels); - for (int i = 0; i < nodeModelsWithSingleMeshes.size(); i++) { + List nodeModelsWithSingleMeshes = + new ArrayList(nodeModels); + for (int i=0; i meshModels = nodeModel.getMeshModels(); - if (meshModels.size() > 1) { - DefaultNodeModel newParentNodeModel = - new DefaultNodeModel(nodeModel); - - for (int j = 0; j < meshModels.size(); j++) { + if (meshModels.size() > 1) + { + DefaultNodeModel newParentNodeModel = + new DefaultNodeModel(nodeModel); + + for (int j=0; j createNodesWithSingleMeshes( nodeModelsWithSingleMeshes.addAll(newNodes); return nodeModelsWithSingleMeshes; } - + + /** + * Create the {@link Accessor} for the given {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} + * @return The {@link Accessor} + */ + private Accessor createAccessor(AccessorModel accessorModel) + { + Integer bufferViewIndex = + bufferViewIndices.get(accessorModel.getBufferViewModel()); + return createAccessor(accessorModel, bufferViewIndex); + } + /** * Create the {@link Accessor} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} + * + * @param accessorModel The {@link AccessorModel} * @param bufferViewIndex The index of the {@link BufferViewModel} - * that the {@link AccessorModel} refers to + * that the {@link AccessorModel} refers to * @return The {@link Accessor} */ public static Accessor createAccessor( - AccessorModel accessorModel, Integer bufferViewIndex) { + AccessorModel accessorModel, Integer bufferViewIndex) + { Accessor accessor = new Accessor(); transferGltfChildOfRootPropertyElements(accessorModel, accessor); - + accessor.setBufferView(bufferViewIndex); - + accessor.setByteOffset(accessorModel.getByteOffset()); accessor.setComponentType(accessorModel.getComponentType()); accessor.setCount(accessorModel.getCount()); accessor.setType(accessorModel.getElementType().toString()); accessor.setNormalized( - accessorModel.isNormalized() ? true : null); - + accessorModel.isNormalized() ? true : null); + AccessorData accessorData = accessorModel.getAccessorData(); accessor.setMax(AccessorDatas.computeMax(accessorData)); accessor.setMin(AccessorDatas.computeMin(accessorData)); - + return accessor; } - - /** - * Create the {@link Buffer} for the given {@link BufferModel} - * - * @param bufferModel The {@link BufferModel} - * @return The {@link Buffer} - */ - public static Buffer createBuffer(BufferModel bufferModel) { - Buffer buffer = new Buffer(); - transferGltfChildOfRootPropertyElements(bufferModel, buffer); - - buffer.setUri(bufferModel.getUri()); - buffer.setByteLength(bufferModel.getByteLength()); - return buffer; - } - - /** - * Create the {@link BufferView} for the given {@link BufferViewModel} - * - * @param bufferViewModel The {@link BufferViewModel} - * @param bufferIndex The index of the {@link BufferModel} that the - * {@link BufferViewModel} refers to - * @return The {@link BufferView} - */ - public static BufferView createBufferView( - BufferViewModel bufferViewModel, Integer bufferIndex) { - BufferView bufferView = new BufferView(); - transferGltfChildOfRootPropertyElements(bufferViewModel, bufferView); - - bufferView.setBuffer(bufferIndex); - bufferView.setByteOffset(bufferViewModel.getByteOffset()); - bufferView.setByteLength(bufferViewModel.getByteLength()); - bufferView.setByteStride(bufferViewModel.getByteStride()); - bufferView.setTarget(bufferViewModel.getTarget()); - - return bufferView; - } - - /** - * Create a {@link de.javagl.jgltf.impl.v2.Sampler} from the given - * {@link SamplerInfo} - * - * @param samplerInfo The {@link SamplerInfo} - * @return The {@link de.javagl.jgltf.impl.v2.Sampler} - */ - private static de.javagl.jgltf.impl.v2.Sampler createSampler( - SamplerInfo samplerInfo) { - de.javagl.jgltf.impl.v2.Sampler sampler = - new de.javagl.jgltf.impl.v2.Sampler(); - sampler.setMagFilter(samplerInfo.magFilter); - sampler.setMinFilter(samplerInfo.minFilter); - sampler.setWrapS(samplerInfo.wrapS); - sampler.setWrapT(samplerInfo.wrapT); - return sampler; - } - - /** - * Transfer the extensions and extras from the given model element to - * the given property - * - * @param modelElement The model element - * @param property The property - */ - private static void transferGltfPropertyElements( - ModelElement modelElement, GlTFProperty property) { - property.setExtensions(modelElement.getExtensions()); - property.setExtras(modelElement.getExtras()); - } - - /** - * Transfer the name and extensions and extras from the given model - * element to the given property - * - * @param modelElement The model element - * @param property The property - */ - private static void transferGltfChildOfRootPropertyElements( - NamedModelElement modelElement, - GlTFChildOfRootProperty property) { - property.setName(modelElement.getName()); - transferGltfPropertyElements(modelElement, property); - } - - /** - * Returns a list containing the result of mapping the given elements with - * the given function, or null if the given collection is - * empty - * - * @param collection The collection - * @param mapper The mapper - * @return The list - */ - private static List map( - Collection collection, - Function mapper) { - if (collection.isEmpty()) { - return null; - } - return collection.stream().map(mapper).collect(Collectors.toList()); - } - - /** - * Creates a map that has the same keys as the given map, mapped to - * the indices that are looked up for the respective values, using - * the given function - * - * @param map The map - * @param indexLookup The index lookup - * @return The index map - */ - private static Map resolveIndices( - Map map, - Function indexLookup) { - Map result = new LinkedHashMap(); - for (Entry entry : map.entrySet()) { - K key = entry.getKey(); - T value = entry.getValue(); - Integer index = indexLookup.apply(value); - result.put(key, index); - } - return result; - } - - /** - * Create an ordered map that contains a mapping of the given elements - * to consecutive integers - * - * @param elements The elements - * @return The index map - */ - private static Map computeIndexMap( - Collection elements) { - Map indices = new LinkedHashMap(); - int index = 0; - for (T element : elements) { - indices.put(element, index); - index++; - } - return indices; - } - - /** - * Returns a new list containing the elements of the given array, - * or null if the given array is null - * - * @param array The array - * @return The list - */ - private static List toList(float array[]) { - if (array == null) { - return null; - } - List list = new ArrayList(); - for (float f : array) { - list.add(f); - } - return list; - } - - /** - * Create the {@link GlTF} instance from the {@link GltfModel} - * - * @return The {@link GlTF} instance - */ - public GlTF create() { - GlTF gltf = new GlTF(); - transferGltfPropertyElements(gltfModel, gltf); - - gltf.setAccessors(map( - gltfModel.getAccessorModels(), this::createAccessor)); - gltf.setAnimations(map( - gltfModel.getAnimationModels(), this::createAnimation)); - gltf.setBuffers(map( - gltfModel.getBufferModels(), GltfCreatorV2::createBuffer)); - gltf.setBufferViews(map( - gltfModel.getBufferViewModels(), this::createBufferView)); - gltf.setCameras(map( - gltfModel.getCameraModels(), this::createCamera)); - gltf.setImages(map( - gltfModel.getImageModels(), this::createImage)); - gltf.setMaterials(map( - gltfModel.getMaterialModels(), this::createMaterial)); - gltf.setMeshes(map( - gltfModel.getMeshModels(), this::createMesh)); - gltf.setNodes(map( - nodesWithSingleMeshes, this::createNode)); - gltf.setScenes(map( - gltfModel.getSceneModels(), this::createScene)); - gltf.setSkins(map( - gltfModel.getSkinModels(), this::createSkin)); - - gltf.setSamplers(createSamplers()); - - gltf.setTextures(map( - gltfModel.getTextureModels(), this::createTexture)); - - if (gltf.getScenes() != null && !gltf.getScenes().isEmpty()) { - gltf.setScene(0); - } - - ExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); - List extensionsUsed = extensionsModel.getExtensionsUsed(); - if (!extensionsUsed.isEmpty()) { - gltf.setExtensionsUsed(extensionsUsed); - } - List extensionsRequired = - extensionsModel.getExtensionsRequired(); - if (!extensionsRequired.isEmpty()) { - gltf.setExtensionsRequired(extensionsRequired); - } - - Asset asset = createAsset(gltfModel.getAssetModel()); - gltf.setAsset(asset); - - return gltf; - } - - /** - * Create the {@link Accessor} for the given {@link AccessorModel} - * - * @param accessorModel The {@link AccessorModel} - * @return The {@link Accessor} - */ - private Accessor createAccessor(AccessorModel accessorModel) { - Integer bufferViewIndex = - bufferViewIndices.get(accessorModel.getBufferViewModel()); - return createAccessor(accessorModel, bufferViewIndex); - } - + /** * Create the {@link Animation} for the given {@link AnimationModel} - * + * * @param animationModel The {@link AnimationModel} * @return The {@link Animation} */ - private Animation createAnimation(AnimationModel animationModel) { + private Animation createAnimation(AnimationModel animationModel) + { Animation animation = new Animation(); transferGltfChildOfRootPropertyElements(animationModel, animation); - + List samplers = new ArrayList(); List channels = animationModel.getChannels(); - for (Channel channel : channels) { + for (Channel channel : channels) + { samplers.add(channel.getSampler()); } - - List animationChannels = - new ArrayList(); - for (Channel channel : channels) { + + List animationChannels = + new ArrayList(); + for (Channel channel : channels) + { AnimationChannel animationChannel = new AnimationChannel(); - + AnimationChannelTarget target = new AnimationChannelTarget(); NodeModel nodeModel = channel.getNodeModel(); target.setNode(nodeIndices.get(nodeModel)); target.setPath(channel.getPath()); animationChannel.setTarget(target); - + Sampler sampler = channel.getSampler(); animationChannel.setSampler(samplers.indexOf(sampler)); - + animationChannels.add(animationChannel); } animation.setChannels(animationChannels); - - List animationSamplers = - new ArrayList(); - for (Sampler sampler : samplers) { + + List animationSamplers = + new ArrayList(); + for (Sampler sampler : samplers) + { AnimationSampler animationSampler = new AnimationSampler(); animationSampler.setInput( - accessorIndices.get(sampler.getInput())); + accessorIndices.get(sampler.getInput())); animationSampler.setInterpolation( - sampler.getInterpolation().name()); + sampler.getInterpolation().name()); animationSampler.setOutput( - accessorIndices.get(sampler.getOutput())); + accessorIndices.get(sampler.getOutput())); animationSamplers.add(animationSampler); } animation.setSamplers(animationSamplers); - + return animation; } + + + /** + * Create the {@link Buffer} for the given {@link BufferModel} + * + * @param bufferModel The {@link BufferModel} + * @return The {@link Buffer} + */ + public static Buffer createBuffer(BufferModel bufferModel) + { + Buffer buffer = new Buffer(); + transferGltfChildOfRootPropertyElements(bufferModel, buffer); + buffer.setUri(bufferModel.getUri()); + buffer.setByteLength(bufferModel.getByteLength()); + return buffer; + } + /** * Create the {@link BufferView} for the given {@link BufferViewModel} - * + * * @param bufferViewModel The {@link BufferViewModel} * @return The {@link BufferView} */ - private BufferView createBufferView(BufferViewModel bufferViewModel) { - Integer bufferIndex = - bufferIndices.get(bufferViewModel.getBufferModel()); + private BufferView createBufferView(BufferViewModel bufferViewModel) + { + Integer bufferIndex = + bufferIndices.get(bufferViewModel.getBufferModel()); return createBufferView(bufferViewModel, bufferIndex); } + + /** + * Create the {@link BufferView} for the given {@link BufferViewModel} + * + * @param bufferViewModel The {@link BufferViewModel} + * @param bufferIndex The index of the {@link BufferModel} that the + * {@link BufferViewModel} refers to + * @return The {@link BufferView} + */ + public static BufferView createBufferView( + BufferViewModel bufferViewModel, Integer bufferIndex) + { + BufferView bufferView = new BufferView(); + transferGltfChildOfRootPropertyElements(bufferViewModel, bufferView); + + bufferView.setBuffer(bufferIndex); + bufferView.setByteOffset(bufferViewModel.getByteOffset()); + bufferView.setByteLength(bufferViewModel.getByteLength()); + bufferView.setByteStride(bufferViewModel.getByteStride()); + bufferView.setTarget(bufferViewModel.getTarget()); + + return bufferView; + } + /** * Create the {@link Camera} for the given {@link CameraModel} - * + * * @param cameraModel The {@link CameraModel} * @return The {@link Camera} */ - private Camera createCamera(CameraModel cameraModel) { + private Camera createCamera(CameraModel cameraModel) + { Camera camera = new Camera(); transferGltfChildOfRootPropertyElements(cameraModel, camera); - - CameraPerspectiveModel cameraPerspectiveModel = - cameraModel.getCameraPerspectiveModel(); - CameraOrthographicModel cameraOrthographicModel = - cameraModel.getCameraOrthographicModel(); - if (cameraPerspectiveModel != null) { + + CameraPerspectiveModel cameraPerspectiveModel = + cameraModel.getCameraPerspectiveModel(); + CameraOrthographicModel cameraOrthographicModel = + cameraModel.getCameraOrthographicModel(); + if (cameraPerspectiveModel != null) + { CameraPerspective cameraPerspective = new CameraPerspective(); cameraPerspective.setAspectRatio( - cameraPerspectiveModel.getAspectRatio()); + cameraPerspectiveModel.getAspectRatio()); cameraPerspective.setYfov( - cameraPerspectiveModel.getYfov()); + cameraPerspectiveModel.getYfov()); cameraPerspective.setZfar( - cameraPerspectiveModel.getZfar()); + cameraPerspectiveModel.getZfar()); cameraPerspective.setZnear( - cameraPerspectiveModel.getZnear()); + cameraPerspectiveModel.getZnear()); camera.setPerspective(cameraPerspective); camera.setType("perspective"); - } else if (cameraOrthographicModel != null) { + } + else if (cameraOrthographicModel != null) + { CameraOrthographic cameraOrthographic = new CameraOrthographic(); cameraOrthographic.setXmag( - cameraOrthographicModel.getXmag()); + cameraOrthographicModel.getXmag()); cameraOrthographic.setYmag( - cameraOrthographicModel.getYmag()); + cameraOrthographicModel.getYmag()); cameraOrthographic.setZfar( - cameraOrthographicModel.getZfar()); + cameraOrthographicModel.getZfar()); cameraOrthographic.setZnear( - cameraOrthographicModel.getZnear()); + cameraOrthographicModel.getZnear()); camera.setOrthographic(cameraOrthographic); camera.setType("orthographic"); - } else { + } + else + { logger.severe("Camera is neither perspective nor orthographic"); } return camera; } - + /** * Create the {@link Image} for the given {@link ImageModel} - * + * * @param imageModel The {@link ImageModel} * @return The {@link Image} */ - private Image createImage(ImageModel imageModel) { + private Image createImage(ImageModel imageModel) + { Image image = new Image(); transferGltfChildOfRootPropertyElements(imageModel, image); - - Integer bufferView = - bufferViewIndices.get(imageModel.getBufferViewModel()); + + Integer bufferView = + bufferViewIndices.get(imageModel.getBufferViewModel()); image.setBufferView(bufferView); - + image.setMimeType(imageModel.getMimeType()); image.setUri(imageModel.getUri()); - + return image; } - + /** * Create the {@link Material} for the given {@link MaterialModel}. * If the given {@link MaterialModel} is not a {@link MaterialModelV2}, * then a warning is printed and null is returned. - * + * * @param materialModel The {@link MaterialModel} * @return The {@link Material} */ - private Material createMaterial(MaterialModel materialModel) { - if (materialModel instanceof MaterialModelV2) { - MaterialModelV2 materialModelV2 = (MaterialModelV2) materialModel; + private Material createMaterial(MaterialModel materialModel) + { + if (materialModel instanceof MaterialModelV2) + { + MaterialModelV2 materialModelV2 = (MaterialModelV2)materialModel; return createMaterialV2(materialModelV2); } // TODO It should be possible to use a glTF 1.0 material model here logger.severe("Cannot store glTF 1.0 material in glTF 2.0"); return null; } - + /** * Create the {@link Material} for the given {@link MaterialModelV2} - * + * * @param materialModel The {@link MaterialModelV2} * @return The {@link Material} */ - private Material createMaterialV2(MaterialModelV2 materialModel) { + private Material createMaterialV2(MaterialModelV2 materialModel) + { Material material = new Material(); transferGltfChildOfRootPropertyElements(materialModel, material); - + AlphaMode alphaMode = materialModel.getAlphaMode(); - if (alphaMode == null) { + if (alphaMode == null) + { material.setAlphaMode(AlphaMode.OPAQUE.name()); - } else { + } + else + { material.setAlphaMode(alphaMode.name()); } - if (AlphaMode.MASK.equals(alphaMode)) { + if (AlphaMode.MASK.equals(alphaMode)) + { material.setAlphaCutoff(materialModel.getAlphaCutoff()); } material.setDoubleSided(materialModel.isDoubleSided()); - - MaterialPbrMetallicRoughness pbrMetallicRoughness = - new MaterialPbrMetallicRoughness(); + + MaterialPbrMetallicRoughness pbrMetallicRoughness = + new MaterialPbrMetallicRoughness(); material.setPbrMetallicRoughness(pbrMetallicRoughness); pbrMetallicRoughness.setBaseColorFactor( - materialModel.getBaseColorFactor()); - TextureModel baseColorTexture = - materialModel.getBaseColorTexture(); - if (baseColorTexture != null) { + materialModel.getBaseColorFactor()); + TextureModel baseColorTexture = + materialModel.getBaseColorTexture(); + if (baseColorTexture != null) + { TextureInfo baseColorTextureInfo = new TextureInfo(); baseColorTextureInfo.setIndex( - textureIndices.get(baseColorTexture)); + textureIndices.get(baseColorTexture)); baseColorTextureInfo.setTexCoord( - materialModel.getBaseColorTexcoord()); + materialModel.getBaseColorTexcoord()); pbrMetallicRoughness.setBaseColorTexture(baseColorTextureInfo); } pbrMetallicRoughness.setMetallicFactor( - materialModel.getMetallicFactor()); + materialModel.getMetallicFactor()); pbrMetallicRoughness.setRoughnessFactor( - materialModel.getRoughnessFactor()); - TextureModel metallicRoughnessTexture = - materialModel.getMetallicRoughnessTexture(); - if (metallicRoughnessTexture != null) { + materialModel.getRoughnessFactor()); + TextureModel metallicRoughnessTexture = + materialModel.getMetallicRoughnessTexture(); + if (metallicRoughnessTexture != null) + { TextureInfo metallicRoughnessTextureInfo = new TextureInfo(); metallicRoughnessTextureInfo.setIndex( - textureIndices.get(metallicRoughnessTexture)); + textureIndices.get(metallicRoughnessTexture)); metallicRoughnessTextureInfo.setTexCoord( - materialModel.getMetallicRoughnessTexcoord()); + materialModel.getMetallicRoughnessTexcoord()); pbrMetallicRoughness.setMetallicRoughnessTexture( - metallicRoughnessTextureInfo); + metallicRoughnessTextureInfo); } - + TextureModel normalTexture = materialModel.getNormalTexture(); - if (normalTexture != null) { - MaterialNormalTextureInfo normalTextureInfo = - new MaterialNormalTextureInfo(); + if (normalTexture != null) + { + MaterialNormalTextureInfo normalTextureInfo = + new MaterialNormalTextureInfo(); normalTextureInfo.setIndex( - textureIndices.get(normalTexture)); + textureIndices.get(normalTexture)); normalTextureInfo.setTexCoord( - materialModel.getNormalTexcoord()); + materialModel.getNormalTexcoord()); normalTextureInfo.setScale( - materialModel.getNormalScale()); + materialModel.getNormalScale()); material.setNormalTexture(normalTextureInfo); } TextureModel occlusionTexture = materialModel.getOcclusionTexture(); - if (occlusionTexture != null) { - MaterialOcclusionTextureInfo occlusionTextureInfo = - new MaterialOcclusionTextureInfo(); + if (occlusionTexture != null) + { + MaterialOcclusionTextureInfo occlusionTextureInfo = + new MaterialOcclusionTextureInfo(); occlusionTextureInfo.setIndex( - textureIndices.get(occlusionTexture)); + textureIndices.get(occlusionTexture)); occlusionTextureInfo.setTexCoord( - materialModel.getOcclusionTexcoord()); + materialModel.getOcclusionTexcoord()); occlusionTextureInfo.setStrength( - materialModel.getOcclusionStrength()); + materialModel.getOcclusionStrength()); material.setOcclusionTexture(occlusionTextureInfo); } - - TextureModel emissiveTexture = - materialModel.getEmissiveTexture(); - if (emissiveTexture != null) { + + TextureModel emissiveTexture = + materialModel.getEmissiveTexture(); + if (emissiveTexture != null) + { TextureInfo emissiveTextureInfo = new TextureInfo(); emissiveTextureInfo.setIndex( - textureIndices.get(emissiveTexture)); + textureIndices.get(emissiveTexture)); emissiveTextureInfo.setTexCoord( - materialModel.getEmissiveTexcoord()); + materialModel.getEmissiveTexcoord()); material.setEmissiveFactor( - materialModel.getEmissiveFactor()); + materialModel.getEmissiveFactor()); material.setEmissiveTexture(emissiveTextureInfo); } - + return material; } - + /** * Create the {@link Mesh} for the given {@link MeshModel} - * + * * @param meshModel The {@link MeshModel} * @return The {@link Mesh} */ - private Mesh createMesh(MeshModel meshModel) { + private Mesh createMesh(MeshModel meshModel) + { Mesh mesh = new Mesh(); transferGltfChildOfRootPropertyElements(meshModel, mesh); - + List meshPrimitives = new ArrayList(); - List meshPrimitiveModels = - meshModel.getMeshPrimitiveModels(); - for (MeshPrimitiveModel meshPrimitiveModel : meshPrimitiveModels) { - MeshPrimitive meshPrimitive = - createMeshPrimitive(meshPrimitiveModel); + List meshPrimitiveModels = + meshModel.getMeshPrimitiveModels(); + for (MeshPrimitiveModel meshPrimitiveModel : meshPrimitiveModels) + { + MeshPrimitive meshPrimitive = + createMeshPrimitive(meshPrimitiveModel); meshPrimitives.add(meshPrimitive); } mesh.setPrimitives(meshPrimitives); mesh.setWeights(toList(meshModel.getWeights())); return mesh; } - + /** * Create the {@link MeshPrimitive} for the given {@link MeshPrimitiveModel} - * + * * @param meshPrimitiveModel The {@link MeshPrimitiveModel} * @return The {@link MeshPrimitive} */ private MeshPrimitive createMeshPrimitive( - MeshPrimitiveModel meshPrimitiveModel) { + MeshPrimitiveModel meshPrimitiveModel) + { MeshPrimitive meshPrimitive = new MeshPrimitive(); transferGltfPropertyElements(meshPrimitiveModel, meshPrimitive); meshPrimitive.setMode(meshPrimitiveModel.getMode()); - + Map attributes = resolveIndices( - meshPrimitiveModel.getAttributes(), - accessorIndices::get); + meshPrimitiveModel.getAttributes(), + accessorIndices::get); meshPrimitive.setAttributes(attributes); AccessorModel indices = meshPrimitiveModel.getIndices(); meshPrimitive.setIndices(accessorIndices.get(indices)); - - List> modelTargetsList = - meshPrimitiveModel.getTargets(); - if (!modelTargetsList.isEmpty()) { - List> targetsList = - new ArrayList>(); - for (Map modelTargets : modelTargetsList) { + + List> modelTargetsList = + meshPrimitiveModel.getTargets(); + if (!modelTargetsList.isEmpty()) + { + List> targetsList = + new ArrayList>(); + for (Map modelTargets : modelTargetsList) + { Map targets = resolveIndices( - modelTargets, accessorIndices::get); + modelTargets, accessorIndices::get); targetsList.add(targets); } meshPrimitive.setTargets(targetsList); } - + Integer material = materialIndices.get( - meshPrimitiveModel.getMaterialModel()); + meshPrimitiveModel.getMaterialModel()); meshPrimitive.setMaterial(material); - + return meshPrimitive; } /** * Create the {@link Node} for the given {@link NodeModel} - * + * * @param nodeModel The {@link NodeModel} * @return The {@link Node} */ - private Node createNode(NodeModel nodeModel) { + private Node createNode(NodeModel nodeModel) + { Node node = new Node(); transferGltfChildOfRootPropertyElements(nodeModel, node); - - if (!nodeModel.getChildren().isEmpty()) { + + if (!nodeModel.getChildren().isEmpty()) + { node.setChildren(map( - nodeModel.getChildren(), nodeIndices::get)); + nodeModel.getChildren(), nodeIndices::get)); } node.setTranslation(Optionals.clone(nodeModel.getTranslation())); node.setRotation(Optionals.clone(nodeModel.getRotation())); node.setScale(Optionals.clone(nodeModel.getScale())); node.setMatrix(Optionals.clone(nodeModel.getMatrix())); - + Integer camera = cameraIndices.get(nodeModel.getCameraModel()); node.setCamera(camera); - + Integer skin = skinIndices.get(nodeModel.getSkinModel()); node.setSkin(skin); - + node.setWeights(toList(nodeModel.getWeights())); - + List nodeMeshModels = nodeModel.getMeshModels(); - if (nodeMeshModels.size() > 1) { + if (nodeMeshModels.size() > 1) + { // This should never me the case here, because this method // is called with the nodes that have been preprocessed // using #createNodesWithSingleMeshes logger.severe("Warning: glTF 2.0 only supports one mesh per node"); } - if (!nodeMeshModels.isEmpty()) { + if (!nodeMeshModels.isEmpty()) + { MeshModel nodeMeshModel = nodeMeshModels.get(0); Integer mesh = meshIndices.get(nodeMeshModel); node.setMesh(mesh); } return node; } - + /** * Create the {@link Scene} for the given {@link SceneModel} - * + * * @param sceneModel The {@link SceneModel} * @return The {@link Scene} */ - private Scene createScene(SceneModel sceneModel) { + private Scene createScene(SceneModel sceneModel) + { Scene scene = new Scene(); transferGltfChildOfRootPropertyElements(sceneModel, scene); - + scene.setNodes(map( - sceneModel.getNodeModels(), nodeIndices::get)); + sceneModel.getNodeModels(), nodeIndices::get)); return scene; } - + /** * Create the {@link Skin} for the given {@link SkinModel} - * + * * @param skinModel The {@link SkinModel} * @return The {@link Skin} */ - private Skin createSkin(SkinModel skinModel) { + private Skin createSkin(SkinModel skinModel) + { Skin skin = new Skin(); transferGltfChildOfRootPropertyElements(skinModel, skin); - - Integer inverseBindMatrices = - accessorIndices.get(skinModel.getInverseBindMatrices()); + + Integer inverseBindMatrices = + accessorIndices.get(skinModel.getInverseBindMatrices()); skin.setInverseBindMatrices(inverseBindMatrices); - + skin.setJoints(map( - skinModel.getJoints(), nodeIndices::get)); - + skinModel.getJoints(), nodeIndices::get)); + Integer skeleton = nodeIndices.get(skinModel.getSkeleton()); skin.setSkeleton(skeleton); - + return skin; } - + /** * Create a mapping from {@link SamplerInfo} objects to consecutive - * indices, based on the {@link SamplerInfo} objects that are + * indices, based on the {@link SamplerInfo} objects that are * created from the given {@link TextureModel} objects - * + * * @param textureModels The {@link TextureModel} objects * @return The indices */ private Map createSamplerIndices( - List textureModels) { - Map samplerIndices = - new LinkedHashMap(); - for (TextureModel textureModel : textureModels) { + List textureModels) + { + Map samplerIndices = + new LinkedHashMap(); + for (TextureModel textureModel : textureModels) + { SamplerInfo samplerInfo = new SamplerInfo(textureModel); - if (!samplerIndices.containsKey(samplerInfo)) { + if (!samplerIndices.containsKey(samplerInfo)) + { samplerIndices.put(samplerInfo, samplerIndices.size()); } } return samplerIndices; } - + /** * Create the {@link de.javagl.jgltf.impl.v2.Sampler} objects for * the current glTF model, returning null if there * are no samplers. - * + * * @return The samplers */ - private List createSamplers() { - if (samplerIndices.isEmpty()) { + private List createSamplers() + { + if (samplerIndices.isEmpty()) + { return null; } - List samplers = - new ArrayList(); - for (SamplerInfo samplerInfo : samplerIndices.keySet()) { - de.javagl.jgltf.impl.v2.Sampler sampler = - createSampler(samplerInfo); + List samplers = + new ArrayList(); + for (SamplerInfo samplerInfo : samplerIndices.keySet()) + { + de.javagl.jgltf.impl.v2.Sampler sampler = + createSampler(samplerInfo); samplers.add(sampler); } return samplers; } + + /** + * Create a {@link de.javagl.jgltf.impl.v2.Sampler} from the given + * {@link SamplerInfo} + * + * @param samplerInfo The {@link SamplerInfo} + * @return The {@link de.javagl.jgltf.impl.v2.Sampler} + */ + private static de.javagl.jgltf.impl.v2.Sampler createSampler( + SamplerInfo samplerInfo) + { + de.javagl.jgltf.impl.v2.Sampler sampler = + new de.javagl.jgltf.impl.v2.Sampler(); + sampler.setMagFilter(samplerInfo.magFilter); + sampler.setMinFilter(samplerInfo.minFilter); + sampler.setWrapS(samplerInfo.wrapS); + sampler.setWrapT(samplerInfo.wrapT); + return sampler; + } + /** * Creates a texture for the given {@link TextureModel} - * + * * @param textureModel The {@link TextureModel} * @return The {@link Texture} */ - private Texture createTexture(TextureModel textureModel) { + private Texture createTexture(TextureModel textureModel) + { Texture texture = new Texture(); transferGltfChildOfRootPropertyElements(textureModel, texture); - + SamplerInfo samplerInfo = new SamplerInfo(textureModel); Integer index = samplerIndices.get(samplerInfo); texture.setSampler(index); - + texture.setSource(imageIndices.get(textureModel.getImageModel())); - + return texture; } - + /** * Creates an asset for the given {@link AssetModel} - * + * * @param assetModel The {@link AssetModel} * @return The {@link Asset} */ - private Asset createAsset(AssetModel assetModel) { + private Asset createAsset(AssetModel assetModel) + { Asset asset = new Asset(); asset.setVersion("2.0"); asset.setGenerator("JglTF from https://github.com/javagl/JglTF"); - + transferGltfPropertyElements(assetModel, asset); - - if (assetModel.getCopyright() != null) { + + if (assetModel.getCopyright() != null) + { asset.setCopyright(assetModel.getCopyright()); } - if (assetModel.getGenerator() != null) { + if (assetModel.getGenerator() != null) + { asset.setGenerator(assetModel.getGenerator()); } return asset; } - + /** - * Inner class containing the information that is necessary to define - * a glTF {@link de.javagl.jgltf.impl.v2.Sampler} + * Transfer the extensions and extras from the given model element to + * the given property + * + * @param modelElement The model element + * @param property The property */ - @SuppressWarnings("javadoc") - private static class SamplerInfo { - final Integer magFilter; - final Integer minFilter; - final Integer wrapS; - final Integer wrapT; - - SamplerInfo(TextureModel textureModel) { - this.magFilter = textureModel.getMagFilter(); - this.minFilter = textureModel.getMinFilter(); - this.wrapS = textureModel.getWrapS(); - this.wrapT = textureModel.getWrapT(); + private static void transferGltfPropertyElements( + ModelElement modelElement, GlTFProperty property) + { + property.setExtensions(modelElement.getExtensions()); + property.setExtras(modelElement.getExtras()); + } + + /** + * Transfer the name and extensions and extras from the given model + * element to the given property + * + * @param modelElement The model element + * @param property The property + */ + private static void transferGltfChildOfRootPropertyElements( + NamedModelElement modelElement, + GlTFChildOfRootProperty property) + { + property.setName(modelElement.getName()); + transferGltfPropertyElements(modelElement, property); + } + + /** + * Returns a list containing the result of mapping the given elements with + * the given function, or null if the given collection is + * empty + * + * @param collection The collection + * @param mapper The mapper + * @return The list + */ + private static List map( + Collection collection, + Function mapper) + { + if (collection.isEmpty()) + { + return null; } + return collection.stream().map(mapper).collect(Collectors.toList()); + } - @Override - public int hashCode() { - return Objects.hash(magFilter, minFilter, wrapS, wrapT); + /** + * Creates a map that has the same keys as the given map, mapped to + * the indices that are looked up for the respective values, using + * the given function + * + * @param map The map + * @param indexLookup The index lookup + * @return The index map + */ + private static Map resolveIndices( + Map map, + Function indexLookup) + { + Map result = new LinkedHashMap(); + for (Entry entry : map.entrySet()) + { + K key = entry.getKey(); + T value = entry.getValue(); + Integer index = indexLookup.apply(value); + result.put(key, index); } - - @Override - public boolean equals(Object object) { - if (this == object) { - return true; - } - if (object == null) { - return false; - } - if (getClass() != object.getClass()) { - return false; - } - SamplerInfo other = (SamplerInfo) object; - if (!Objects.equals(magFilter, other.magFilter)) { - return false; - } - if (!Objects.equals(minFilter, other.minFilter)) { - return false; - } - if (!Objects.equals(wrapS, other.wrapS)) { - return false; - } - if (!Objects.equals(wrapT, other.wrapT)) { - return false; - } - return true; + return result; + } + + /** + * Create an ordered map that contains a mapping of the given elements + * to consecutive integers + * + * @param elements The elements + * @return The index map + */ + private static Map computeIndexMap( + Collection elements) + { + Map indices = new LinkedHashMap(); + int index = 0; + for (T element : elements) + { + indices.put(element, index); + index++; } + return indices; + } + + + /** + * Returns a new list containing the elements of the given array, + * or null if the given array is null + * + * @param array The array + * @return The list + */ + private static List toList(float array[]) + { + if (array == null) + { + return null; + } + List list = new ArrayList(); + for (float f : array) + { + list.add(f); + } + return list; } } \ No newline at end of file diff --git a/src/main/java/de/javagl/jgltf/model/v2/GltfModelCreatorV2.java b/src/main/java/de/javagl/jgltf/model/v2/GltfModelCreatorV2.java index a11ec45..c2f7396 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/GltfModelCreatorV2.java +++ b/src/main/java/de/javagl/jgltf/model/v2/GltfModelCreatorV2.java @@ -26,16 +26,94 @@ */ package de.javagl.jgltf.model.v2; +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.logging.Logger; + import com.google.gson.Gson; import com.google.gson.JsonElement; import com.modularmods.mcgltf.MCglTF; -import de.javagl.jgltf.impl.v2.*; -import de.javagl.jgltf.model.*; + +import de.javagl.jgltf.impl.v2.GlTFChildOfRootProperty; +import de.javagl.jgltf.impl.v2.GlTFProperty; +import de.javagl.jgltf.impl.v2.Asset; +import de.javagl.jgltf.impl.v2.Accessor; +import de.javagl.jgltf.impl.v2.AccessorSparse; +import de.javagl.jgltf.impl.v2.AccessorSparseIndices; +import de.javagl.jgltf.impl.v2.AccessorSparseValues; +import de.javagl.jgltf.impl.v2.Animation; +import de.javagl.jgltf.impl.v2.AnimationChannel; +import de.javagl.jgltf.impl.v2.AnimationChannelTarget; +import de.javagl.jgltf.impl.v2.AnimationSampler; +import de.javagl.jgltf.impl.v2.Buffer; +import de.javagl.jgltf.impl.v2.BufferView; +import de.javagl.jgltf.impl.v2.Camera; +import de.javagl.jgltf.impl.v2.CameraOrthographic; +import de.javagl.jgltf.impl.v2.CameraPerspective; +import de.javagl.jgltf.impl.v2.GlTF; +import de.javagl.jgltf.impl.v2.Image; +import de.javagl.jgltf.impl.v2.Material; +import de.javagl.jgltf.impl.v2.MaterialNormalTextureInfo; +import de.javagl.jgltf.impl.v2.MaterialOcclusionTextureInfo; +import de.javagl.jgltf.impl.v2.MaterialPbrMetallicRoughness; +import de.javagl.jgltf.impl.v2.Mesh; +import de.javagl.jgltf.impl.v2.MeshPrimitive; +import de.javagl.jgltf.impl.v2.Node; +import de.javagl.jgltf.impl.v2.Sampler; +import de.javagl.jgltf.impl.v2.Scene; +import de.javagl.jgltf.impl.v2.Skin; +import de.javagl.jgltf.impl.v2.Texture; +import de.javagl.jgltf.impl.v2.TextureInfo; +import de.javagl.jgltf.model.AccessorData; +import de.javagl.jgltf.model.AccessorDatas; +import de.javagl.jgltf.model.AccessorModel; +import de.javagl.jgltf.model.AnimationModel; +import de.javagl.jgltf.model.AssetModel; import de.javagl.jgltf.model.AnimationModel.Channel; import de.javagl.jgltf.model.AnimationModel.Interpolation; -import de.javagl.jgltf.model.impl.*; +import de.javagl.jgltf.model.BufferModel; +import de.javagl.jgltf.model.BufferViewModel; +import de.javagl.jgltf.model.CameraModel; +import de.javagl.jgltf.model.ElementType; +import de.javagl.jgltf.model.ExtensionsModel; +import de.javagl.jgltf.model.GltfConstants; +import de.javagl.jgltf.model.GltfModel; +import de.javagl.jgltf.model.ImageModel; +import de.javagl.jgltf.model.MaterialModel; +import de.javagl.jgltf.model.MeshModel; +import de.javagl.jgltf.model.MeshPrimitiveModel; +import de.javagl.jgltf.model.NodeModel; +import de.javagl.jgltf.model.Optionals; +import de.javagl.jgltf.model.SceneModel; +import de.javagl.jgltf.model.SkinModel; +import de.javagl.jgltf.model.TextureModel; +import de.javagl.jgltf.model.impl.AbstractModelElement; +import de.javagl.jgltf.model.impl.AbstractNamedModelElement; +import de.javagl.jgltf.model.impl.DefaultAccessorModel; +import de.javagl.jgltf.model.impl.DefaultAnimationModel; +import de.javagl.jgltf.model.impl.DefaultAssetModel; import de.javagl.jgltf.model.impl.DefaultAnimationModel.DefaultChannel; import de.javagl.jgltf.model.impl.DefaultAnimationModel.DefaultSampler; +import de.javagl.jgltf.model.impl.DefaultBufferModel; +import de.javagl.jgltf.model.impl.DefaultBufferViewModel; +import de.javagl.jgltf.model.impl.DefaultCameraModel; +import de.javagl.jgltf.model.impl.DefaultCameraOrthographicModel; +import de.javagl.jgltf.model.impl.DefaultCameraPerspectiveModel; +import de.javagl.jgltf.model.impl.DefaultExtensionsModel; +import de.javagl.jgltf.model.impl.DefaultGltfModel; +import de.javagl.jgltf.model.impl.DefaultImageModel; +import de.javagl.jgltf.model.impl.DefaultMeshModel; +import de.javagl.jgltf.model.impl.DefaultMeshPrimitiveModel; +import de.javagl.jgltf.model.impl.DefaultNodeModel; +import de.javagl.jgltf.model.impl.DefaultSceneModel; +import de.javagl.jgltf.model.impl.DefaultSkinModel; +import de.javagl.jgltf.model.impl.DefaultTextureModel; import de.javagl.jgltf.model.io.Buffers; import de.javagl.jgltf.model.io.GltfAsset; import de.javagl.jgltf.model.io.IO; @@ -44,142 +122,70 @@ import de.javagl.jgltf.model.v2.gl.Materials; import net.minecraft.resources.ResourceLocation; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.Map.Entry; -import java.util.function.Consumer; -import java.util.logging.Logger; - /** * A class that is responsible for filling a {@link DefaultGltfModel} with * the model instances that are created from a {@link GltfAssetV2} */ -public class GltfModelCreatorV2 { +public class GltfModelCreatorV2 +{ /** * The logger used in this class */ - private static final Logger logger = - Logger.getLogger(GltfModelCreatorV2.class.getName()); - /** - * The {@link GltfAsset} of the model - */ - private final GltfAsset gltfAsset; - /** - * The {@link GlTF} of this model - */ - private final GlTF gltf; - /** - * The {@link GltfModel} that is built - */ - private final DefaultGltfModel gltfModel; - - /** - * Creates a new model for the given glTF - * - * @param gltfAsset The {@link GltfAssetV2} - * @param gltfModel The {@link GltfModel} - */ - GltfModelCreatorV2(GltfAssetV2 gltfAsset, DefaultGltfModel gltfModel) { - this.gltfAsset = Objects.requireNonNull(gltfAsset, - "The gltfAsset may not be null"); - this.gltf = gltfAsset.getGltf(); - this.gltfModel = Objects.requireNonNull(gltfModel, - "The gltfModel may not be null"); - } + private static final Logger logger = + Logger.getLogger(GltfModelCreatorV2.class.getName()); /** * Create the {@link GltfModel} for the given {@link GltfAssetV2} - * + * * @param gltfAsset The {@link GltfAssetV2} * @return The {@link GltfModel} */ - public static DefaultGltfModel create(GltfAssetV2 gltfAsset) { + public static DefaultGltfModel create(GltfAssetV2 gltfAsset) + { DefaultGltfModel gltfModel = new DefaultGltfModel(); - GltfModelCreatorV2 creator = - new GltfModelCreatorV2(gltfAsset, gltfModel); + GltfModelCreatorV2 creator = + new GltfModelCreatorV2(gltfAsset, gltfModel); creator.create(); return gltfModel; } - + /** - * Create a {@link DefaultBufferViewModel} for the given {@link BufferView} - * - * @param bufferView The {@link BufferView} - * @return The {@link BufferViewModel} + * The {@link GltfAsset} of the model */ - private static DefaultBufferViewModel createBufferViewModel( - BufferView bufferView) { - int byteOffset = Optionals.of(bufferView.getByteOffset(), 0); - int byteLength = bufferView.getByteLength(); - Integer byteStride = bufferView.getByteStride(); - Integer target = bufferView.getTarget(); - DefaultBufferViewModel bufferViewModel = - new DefaultBufferViewModel(target); - bufferViewModel.setByteOffset(byteOffset); - bufferViewModel.setByteLength(byteLength); - bufferViewModel.setByteStride(byteStride); - return bufferViewModel; - } - + private final GltfAsset gltfAsset; + /** - * Create a new {@link BufferViewModel} with an associated - * {@link BufferModel} that serves as the basis for a sparse accessor, or - * an accessor that does not refer to a {@link BufferView}) - * - * @param uriString The URI string that will be assigned to the - * {@link BufferModel} that is created internally. This string - * is not strictly required, but helpful for debugging, at least - * @param bufferData The buffer data - * @return The new {@link BufferViewModel} + * The {@link GlTF} of this model */ - private static DefaultBufferViewModel createBufferViewModel( - String uriString, ByteBuffer bufferData) { - DefaultBufferModel bufferModel = new DefaultBufferModel(); - bufferModel.setUri(uriString); - bufferModel.setBufferData(bufferData); - - DefaultBufferViewModel bufferViewModel = - new DefaultBufferViewModel(null); - bufferViewModel.setByteOffset(0); - bufferViewModel.setByteLength(bufferData.capacity()); - bufferViewModel.setBufferModel(bufferModel); - - return bufferViewModel; - } - + private final GlTF gltf; + /** - * Transfer the extensions and extras from the given property to - * the given target - * - * @param property The property - * @param modelElement The target + * The {@link GltfModel} that is built */ - private static void transferGltfPropertyElements( - GlTFProperty property, AbstractModelElement modelElement) { - modelElement.setExtensions(property.getExtensions()); - modelElement.setExtras(property.getExtras()); - } - + private final DefaultGltfModel gltfModel; + /** - * Transfer the name and extensions and extras from the given property to - * the given target - * - * @param property The property - * @param modelElement The target + * Creates a new model for the given glTF + * + * @param gltfAsset The {@link GltfAssetV2} + * @param gltfModel The {@link GltfModel} */ - private static void transferGltfChildOfRootPropertyElements( - GlTFChildOfRootProperty property, - AbstractNamedModelElement modelElement) { - modelElement.setName(property.getName()); - transferGltfPropertyElements(property, modelElement); + GltfModelCreatorV2(GltfAssetV2 gltfAsset, DefaultGltfModel gltfModel) + { + this.gltfAsset = Objects.requireNonNull(gltfAsset, + "The gltfAsset may not be null"); + this.gltf = gltfAsset.getGltf(); + this.gltfModel = Objects.requireNonNull(gltfModel, + "The gltfModel may not be null"); } - + /** * Create and initialize all models */ - void create() { + void create() + { transferGltfPropertyElements(gltf, gltfModel); - + createAccessorModels(); createAnimationModels(); createBufferModels(); @@ -195,7 +201,7 @@ void create() { initBufferModels(); initBufferViewModels(); - + initAccessorModels(); initAnimationModels(); initImageModels(); @@ -205,23 +211,25 @@ void create() { initSkinModels(); initTextureModels(); initMaterialModels(); - + initExtensionsModel(); initAssetModel(); } - + /** * Create the {@link AccessorModel} instances */ - private void createAccessorModels() { + private void createAccessorModels() + { List accessors = Optionals.of(gltf.getAccessors()); - for (int i = 0; i < accessors.size(); i++) { + for (int i = 0; i < accessors.size(); i++) + { Accessor accessor = accessors.get(i); Integer componentType = accessor.getComponentType(); Integer count = accessor.getCount(); ElementType elementType = ElementType.forString(accessor.getType()); - DefaultAccessorModel accessorModel = new DefaultAccessorModel( - componentType, count, elementType); + DefaultAccessorModel accessorModel = new DefaultAccessorModel( + componentType, count, elementType); gltfModel.addAccessorModel(accessorModel); } } @@ -229,120 +237,160 @@ private void createAccessorModels() { /** * Create the {@link AnimationModel} instances */ - private void createAnimationModels() { + private void createAnimationModels() + { List animations = Optionals.of(gltf.getAnimations()); - for (int i = 0; i < animations.size(); i++) { + for (int i = 0; i < animations.size(); i++) + { gltfModel.addAnimationModel(new DefaultAnimationModel()); } } - + /** * Create the {@link BufferModel} instances */ - private void createBufferModels() { + private void createBufferModels() + { List buffers = Optionals.of(gltf.getBuffers()); - for (int i = 0; i < buffers.size(); i++) { + for (int i = 0; i < buffers.size(); i++) + { Buffer buffer = buffers.get(i); DefaultBufferModel bufferModel = new DefaultBufferModel(); bufferModel.setUri(buffer.getUri()); gltfModel.addBufferModel(bufferModel); } } - + /** * Create the {@link CameraModel} instances */ - private void createCameraModels() { + private void createCameraModels() + { List cameras = Optionals.of(gltf.getCameras()); - for (int i = 0; i < cameras.size(); i++) { + for (int i = 0; i < cameras.size(); i++) + { Camera camera = cameras.get(i); String type = camera.getType(); - if ("perspective".equals(type)) { + if ("perspective".equals(type)) + { CameraPerspective cameraPerspective = camera.getPerspective(); - DefaultCameraPerspectiveModel cameraPerspectiveModel = - new DefaultCameraPerspectiveModel(); + DefaultCameraPerspectiveModel cameraPerspectiveModel = + new DefaultCameraPerspectiveModel(); cameraPerspectiveModel.setAspectRatio( - cameraPerspective.getAspectRatio()); + cameraPerspective.getAspectRatio()); cameraPerspectiveModel.setYfov( - cameraPerspective.getYfov()); + cameraPerspective.getYfov()); cameraPerspectiveModel.setZfar( - cameraPerspective.getZfar()); + cameraPerspective.getZfar()); cameraPerspectiveModel.setZnear( - cameraPerspective.getZnear()); - DefaultCameraModel cameraModel = - new DefaultCameraModel(); + cameraPerspective.getZnear()); + DefaultCameraModel cameraModel = + new DefaultCameraModel(); cameraModel.setCameraPerspectiveModel(cameraPerspectiveModel); gltfModel.addCameraModel(cameraModel); - } else if ("orthographic".equals(type)) { - CameraOrthographic cameraOrthographic = - camera.getOrthographic(); - DefaultCameraOrthographicModel cameraOrthographicModel = - new DefaultCameraOrthographicModel(); + } + else if ("orthographic".equals(type)) + { + CameraOrthographic cameraOrthographic = + camera.getOrthographic(); + DefaultCameraOrthographicModel cameraOrthographicModel = + new DefaultCameraOrthographicModel(); cameraOrthographicModel.setXmag( - cameraOrthographic.getXmag()); + cameraOrthographic.getXmag()); cameraOrthographicModel.setYmag( - cameraOrthographic.getYmag()); + cameraOrthographic.getYmag()); cameraOrthographicModel.setZfar( - cameraOrthographic.getZfar()); + cameraOrthographic.getZfar()); cameraOrthographicModel.setZnear( - cameraOrthographic.getZnear()); - DefaultCameraModel cameraModel = - new DefaultCameraModel(); + cameraOrthographic.getZnear()); + DefaultCameraModel cameraModel = + new DefaultCameraModel(); cameraModel.setCameraOrthographicModel(cameraOrthographicModel); gltfModel.addCameraModel(cameraModel); - } else { + } + else + { logger.severe("Invalid camera type: " + type); } } } - + /** * Create the {@link BufferViewModel} instances */ - private void createBufferViewModels() { + private void createBufferViewModels() + { List bufferViews = Optionals.of(gltf.getBufferViews()); - for (int i = 0; i < bufferViews.size(); i++) { + for (int i = 0; i < bufferViews.size(); i++) + { BufferView bufferView = bufferViews.get(i); - DefaultBufferViewModel bufferViewModel = - createBufferViewModel(bufferView); + DefaultBufferViewModel bufferViewModel = + createBufferViewModel(bufferView); gltfModel.addBufferViewModel(bufferViewModel); } } + /** + * Create a {@link DefaultBufferViewModel} for the given {@link BufferView} + * + * @param bufferView The {@link BufferView} + * @return The {@link BufferViewModel} + */ + private static DefaultBufferViewModel createBufferViewModel( + BufferView bufferView) + { + int byteOffset = Optionals.of(bufferView.getByteOffset(), 0); + int byteLength = bufferView.getByteLength(); + Integer byteStride = bufferView.getByteStride(); + Integer target = bufferView.getTarget(); + DefaultBufferViewModel bufferViewModel = + new DefaultBufferViewModel(target); + bufferViewModel.setByteOffset(byteOffset); + bufferViewModel.setByteLength(byteLength); + bufferViewModel.setByteStride(byteStride); + return bufferViewModel; + } + /** * Create the {@link ImageModel} instances */ - private void createImageModels() { + private void createImageModels() + { List images = Optionals.of(gltf.getImages()); - for (int i = 0; i < images.size(); i++) { + for (int i = 0; i < images.size(); i++) + { Image image = images.get(i); String mimeType = image.getMimeType(); - DefaultImageModel imageModel = - new DefaultImageModel(); + DefaultImageModel imageModel = + new DefaultImageModel(); imageModel.setMimeType(mimeType); String uri = image.getUri(); imageModel.setUri(uri); gltfModel.addImageModel(imageModel); } } - + /** * Create the {@link MaterialModel} instances */ - private void createMaterialModels() { + private void createMaterialModels() + { List materials = Optionals.of(gltf.getMaterials()); - for (int i = 0; i < materials.size(); i++) { + for (int i = 0; i < materials.size(); i++) + { MaterialModelV2 materialModel = new MaterialModelV2(); gltfModel.addMaterialModel(materialModel); } } - + /** * Create the {@link MeshModel} instances */ - private void createMeshModels() { + private void createMeshModels() + { List meshes = Optionals.of(gltf.getMeshes()); - for (int i = 0; i < meshes.size(); i++) { + for (int i = 0; i < meshes.size(); i++) + { gltfModel.addMeshModel(new DefaultMeshModel()); } } @@ -350,9 +398,11 @@ private void createMeshModels() { /** * Create the {@link NodeModel} instances */ - private void createNodeModels() { + private void createNodeModels() + { List nodes = Optionals.of(gltf.getNodes()); - for (int i = 0; i < nodes.size(); i++) { + for (int i = 0; i < nodes.size(); i++) + { gltfModel.addNodeModel(new DefaultNodeModel()); } } @@ -360,48 +410,55 @@ private void createNodeModels() { /** * Create the {@link SceneModel} instances */ - private void createSceneModels() { + private void createSceneModels() + { List scenes = Optionals.of(gltf.getScenes()); - for (int i = 0; i < scenes.size(); i++) { + for (int i = 0; i < scenes.size(); i++) + { gltfModel.addSceneModel(new DefaultSceneModel()); } } - + /** * Create the {@link SkinModel} instances */ - private void createSkinModels() { + private void createSkinModels() + { List skins = Optionals.of(gltf.getSkins()); - for (int i = 0; i < skins.size(); i++) { + for (int i = 0; i < skins.size(); i++) + { gltfModel.addSkinModel(new DefaultSkinModel()); } } - + /** * Create the {@link TextureModel} instances */ - private void createTextureModels() { + private void createTextureModels() + { List textures = Optionals.of(gltf.getTextures()); List samplers = Optionals.of(gltf.getSamplers()); - for (int i = 0; i < textures.size(); i++) { + for (int i = 0; i < textures.size(); i++) + { Texture texture = textures.get(i); Integer samplerIndex = texture.getSampler(); - + Integer magFilter = GltfConstants.GL_LINEAR; Integer minFilter = GltfConstants.GL_LINEAR; Integer wrapS = GltfConstants.GL_REPEAT; Integer wrapT = GltfConstants.GL_REPEAT; - - if (samplerIndex != null) { + + if (samplerIndex != null) + { Sampler sampler = samplers.get(samplerIndex); magFilter = sampler.getMagFilter(); minFilter = sampler.getMinFilter(); wrapS = Optionals.of( - sampler.getWrapS(), sampler.defaultWrapS()); + sampler.getWrapS(), sampler.defaultWrapS()); wrapT = Optionals.of( - sampler.getWrapT(), sampler.defaultWrapT()); + sampler.getWrapT(), sampler.defaultWrapT()); } - + DefaultTextureModel textureModel = new DefaultTextureModel(); textureModel.setMagFilter(magFilter); textureModel.setMinFilter(minFilter); @@ -410,58 +467,69 @@ private void createTextureModels() { gltfModel.addTextureModel(textureModel); } } - + /** * Initialize the {@link AccessorModel} instances */ - private void initAccessorModels() { + private void initAccessorModels() + { List accessors = Optionals.of(gltf.getAccessors()); - for (int i = 0; i < accessors.size(); i++) { + for (int i = 0; i < accessors.size(); i++) + { Accessor accessor = accessors.get(i); - DefaultAccessorModel accessorModel = - gltfModel.getAccessorModel(i); + DefaultAccessorModel accessorModel = + gltfModel.getAccessorModel(i); transferGltfChildOfRootPropertyElements(accessor, accessorModel); - + int byteOffset = Optionals.of(accessor.getByteOffset(), 0); accessorModel.setByteOffset(byteOffset); - + Boolean normalized = accessor.isNormalized(); accessorModel.setNormalized(Boolean.TRUE.equals(normalized)); AccessorSparse accessorSparse = accessor.getSparse(); - if (accessorSparse == null) { + if (accessorSparse == null) + { initDenseAccessorModel(i, accessor, accessorModel); - } else { + } + else + { initSparseAccessorModel(i, accessor, accessorModel); } } } + /** - * Initialize the {@link AccessorModel} by setting its + * Initialize the {@link AccessorModel} by setting its * {@link AccessorModel#getBufferViewModel() buffer view model} * for the case that the accessor is dense (i.e. not sparse) - * + * * @param accessorIndex The accessor index. Only used for constructing - * the URI string of buffers that may have to be created internally - * @param accessor The {@link Accessor} + * the URI string of buffers that may have to be created internally + * @param accessor The {@link Accessor} * @param accessorModel The {@link AccessorModel} */ private void initDenseAccessorModel(int accessorIndex, - Accessor accessor, DefaultAccessorModel accessorModel) { + Accessor accessor, DefaultAccessorModel accessorModel) + { Integer bufferViewIndex = accessor.getBufferView(); - if (bufferViewIndex != null) { - // When there is a BufferView referenced from the accessor, then + if (bufferViewIndex != null) + { + // When there is a BufferView referenced from the accessor, then // the corresponding BufferViewModel may be assigned directly - BufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); + BufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); accessorModel.setBufferViewModel(bufferViewModel); Integer byteStride = bufferViewModel.getByteStride(); - if (byteStride != null) { + if (byteStride != null) + { accessorModel.setByteStride(byteStride); } accessorModel.setAccessorData(AccessorDatas.create(accessorModel)); - } else { + } + else + { // When there is no BufferView referenced from the accessor, // then a NEW BufferViewModel (and Buffer) have to be created int count = accessorModel.getCount(); @@ -469,279 +537,334 @@ private void initDenseAccessorModel(int accessorIndex, int byteLength = elementSizeInBytes * count; ByteBuffer bufferData = Buffers.create(byteLength); String uriString = "buffer_for_accessor" + accessorIndex + ".bin"; - BufferViewModel bufferViewModel = - createBufferViewModel(uriString, bufferData); + BufferViewModel bufferViewModel = + createBufferViewModel(uriString, bufferData); accessorModel.setBufferViewModel(bufferViewModel); accessorModel.setAccessorData(AccessorDatas.create(accessorModel)); } } - + /** - * Initialize the given {@link AccessorModel} by setting its + * Initialize the given {@link AccessorModel} by setting its * {@link AccessorModel#getBufferViewModel() buffer view model} - * for the case that the accessor is sparse. - * + * for the case that the accessor is sparse. + * * @param accessorIndex The accessor index. Only used for constructing - * the URI string of buffers that may have to be created internally - * @param accessor The {@link Accessor} + * the URI string of buffers that may have to be created internally + * @param accessor The {@link Accessor} * @param accessorModel The {@link AccessorModel} */ private void initSparseAccessorModel(int accessorIndex, - Accessor accessor, DefaultAccessorModel accessorModel) { + Accessor accessor, DefaultAccessorModel accessorModel) + { // When the (sparse!) Accessor already refers to a BufferView, // then this BufferView has to be replaced with a new one, - // to which the data substitution will be applied + // to which the data substitution will be applied int count = accessorModel.getCount(); int elementSizeInBytes = accessorModel.getElementSizeInBytes(); int byteLength = elementSizeInBytes * count; ByteBuffer bufferData = Buffers.create(byteLength); String uriString = "buffer_for_accessor" + accessorIndex + ".bin"; - DefaultBufferViewModel denseBufferViewModel = - createBufferViewModel(uriString, bufferData); + DefaultBufferViewModel denseBufferViewModel = + createBufferViewModel(uriString, bufferData); accessorModel.setBufferViewModel(denseBufferViewModel); accessorModel.setByteOffset(0); - + Integer bufferViewIndex = accessor.getBufferView(); - if (bufferViewIndex != null) { + if (bufferViewIndex != null) + { // If the accessor refers to a BufferView, then the corresponding - // data serves as the basis for the initialization of the values, + // data serves as the basis for the initialization of the values, // before the sparse substitution is applied - Consumer sparseSubstitutionCallback = denseByteBuffer -> + Consumer sparseSubstitutionCallback = denseByteBuffer -> { logger.fine("Substituting sparse accessor data," - + " based on existing buffer view"); - - DefaultBufferViewModel baseBufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); - ByteBuffer baseBufferViewData = - baseBufferViewModel.getBufferViewData(); + + " based on existing buffer view"); + + DefaultBufferViewModel baseBufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); + ByteBuffer baseBufferViewData = + baseBufferViewModel.getBufferViewData(); AccessorData baseAccessorData = AccessorDatas.create( - accessorModel, baseBufferViewData); - AccessorData denseAccessorData = - AccessorDatas.create(accessorModel, bufferData); - substituteSparseAccessorData(accessor, accessorModel, - denseAccessorData, baseAccessorData); + accessorModel, baseBufferViewData); + AccessorData denseAccessorData = + AccessorDatas.create(accessorModel, bufferData); + substituteSparseAccessorData(accessor, accessorModel, + denseAccessorData, baseAccessorData); }; denseBufferViewModel.setSparseSubstitutionCallback( - sparseSubstitutionCallback); - } else { + sparseSubstitutionCallback); + } + else + { // When the sparse accessor does not yet refer to a BufferView, - // then a new one is created, - Consumer sparseSubstitutionCallback = denseByteBuffer -> + // then a new one is created, + Consumer sparseSubstitutionCallback = denseByteBuffer -> { logger.fine("Substituting sparse accessor data, " - + "without an existing buffer view"); - - AccessorData denseAccessorData = - AccessorDatas.create(accessorModel, bufferData); - substituteSparseAccessorData(accessor, accessorModel, - denseAccessorData, null); + + "without an existing buffer view"); + + AccessorData denseAccessorData = + AccessorDatas.create(accessorModel, bufferData); + substituteSparseAccessorData(accessor, accessorModel, + denseAccessorData, null); }; denseBufferViewModel.setSparseSubstitutionCallback( - sparseSubstitutionCallback); + sparseSubstitutionCallback); } } + + /** + * Create a new {@link BufferViewModel} with an associated + * {@link BufferModel} that serves as the basis for a sparse accessor, or + * an accessor that does not refer to a {@link BufferView}) + * + * @param uriString The URI string that will be assigned to the + * {@link BufferModel} that is created internally. This string + * is not strictly required, but helpful for debugging, at least + * @param bufferData The buffer data + * @return The new {@link BufferViewModel} + */ + private static DefaultBufferViewModel createBufferViewModel( + String uriString, ByteBuffer bufferData) + { + DefaultBufferModel bufferModel = new DefaultBufferModel(); + bufferModel.setUri(uriString); + bufferModel.setBufferData(bufferData); + DefaultBufferViewModel bufferViewModel = + new DefaultBufferViewModel(null); + bufferViewModel.setByteOffset(0); + bufferViewModel.setByteLength(bufferData.capacity()); + bufferViewModel.setBufferModel(bufferModel); + + return bufferViewModel; + } + /** - * Substitute the sparse accessor data in the given dense + * Substitute the sparse accessor data in the given dense * {@link AccessorData} for the given {@link AccessorModel} - * based on the sparse accessor data that is defined in the given + * based on the sparse accessor data that is defined in the given * {@link Accessor}. - * - * @param accessor The {@link Accessor} - * @param accessorModel The {@link AccessorModel} + * + * @param accessor The {@link Accessor} + * @param accessorModel The {@link AccessorModel} * @param denseAccessorData The dense {@link AccessorData} - * @param baseAccessorData The optional {@link AccessorData} that contains - * the base data. If this is not null, then it will be used - * to initialize the {@link AccessorData}, before the sparse data - * substitution takes place + * @param baseAccessorData The optional {@link AccessorData} that contains + * the base data. If this is not null, then it will be used + * to initialize the {@link AccessorData}, before the sparse data + * substitution takes place */ private void substituteSparseAccessorData( - Accessor accessor, AccessorModel accessorModel, - AccessorData denseAccessorData, AccessorData baseAccessorData) { + Accessor accessor, AccessorModel accessorModel, + AccessorData denseAccessorData, AccessorData baseAccessorData) + { AccessorSparse accessorSparse = accessor.getSparse(); int count = accessorSparse.getCount(); - - AccessorSparseIndices accessorSparseIndices = - accessorSparse.getIndices(); - AccessorData sparseIndicesAccessorData = - createSparseIndicesAccessorData(accessorSparseIndices, count); - + + AccessorSparseIndices accessorSparseIndices = + accessorSparse.getIndices(); + AccessorData sparseIndicesAccessorData = + createSparseIndicesAccessorData(accessorSparseIndices, count); + AccessorSparseValues accessorSparseValues = accessorSparse.getValues(); ElementType elementType = accessorModel.getElementType(); AccessorData sparseValuesAccessorData = - createSparseValuesAccessorData(accessorSparseValues, - accessorModel.getComponentType(), - elementType, count); - + createSparseValuesAccessorData(accessorSparseValues, + accessorModel.getComponentType(), + elementType, count); + AccessorSparseUtils.substituteAccessorData( - denseAccessorData, - baseAccessorData, - sparseIndicesAccessorData, - sparseValuesAccessorData); + denseAccessorData, + baseAccessorData, + sparseIndicesAccessorData, + sparseValuesAccessorData); } - + + /** - * Create the {@link AccessorData} for the given + * Create the {@link AccessorData} for the given * {@link AccessorSparseIndices} - * + * * @param accessorSparseIndices The {@link AccessorSparseIndices} - * @param count The count from the {@link AccessorSparse} + * @param count The count from the {@link AccessorSparse} * @return The {@link AccessorData} */ private AccessorData createSparseIndicesAccessorData( - AccessorSparseIndices accessorSparseIndices, int count) { + AccessorSparseIndices accessorSparseIndices, int count) + { Integer componentType = accessorSparseIndices.getComponentType(); Integer bufferViewIndex = accessorSparseIndices.getBufferView(); - BufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); + BufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); ByteBuffer bufferViewData = bufferViewModel.getBufferViewData(); int byteOffset = Optionals.of(accessorSparseIndices.getByteOffset(), 0); return AccessorDatas.create( - componentType, bufferViewData, byteOffset, - count, ElementType.SCALAR, null); + componentType, bufferViewData, byteOffset, + count, ElementType.SCALAR, null); } - + /** - * Create the {@link AccessorData} for the given + * Create the {@link AccessorData} for the given * {@link AccessorSparseValues} - * + * * @param accessorSparseValues The {@link AccessorSparseValues} - * @param componentType The component type of the {@link Accessor} - * @param elementType The {@link ElementType} - * of the {@link AccessorModel#getElementType() accessor element type} - * @param count The count from the {@link AccessorSparse} + * @param componentType The component type of the {@link Accessor} + * @param elementType The {@link ElementType} + * of the {@link AccessorModel#getElementType() accessor element type} + * @param count The count from the {@link AccessorSparse} * @return The {@link AccessorData} */ private AccessorData createSparseValuesAccessorData( - AccessorSparseValues accessorSparseValues, - int componentType, ElementType elementType, int count) { + AccessorSparseValues accessorSparseValues, + int componentType, ElementType elementType, int count) + { Integer bufferViewIndex = accessorSparseValues.getBufferView(); - BufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); + BufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); ByteBuffer bufferViewData = bufferViewModel.getBufferViewData(); int byteOffset = Optionals.of(accessorSparseValues.getByteOffset(), 0); return AccessorDatas.create( - componentType, bufferViewData, byteOffset, count, - elementType, null); + componentType, bufferViewData, byteOffset, count, + elementType, null); } - + /** * Initialize the {@link AnimationModel} instances */ - private void initAnimationModels() { + private void initAnimationModels() + { List animations = Optionals.of(gltf.getAnimations()); - for (int i = 0; i < animations.size(); i++) { + for (int i = 0; i < animations.size(); i++) + { Animation animation = animations.get(i); - DefaultAnimationModel animationModel = - gltfModel.getAnimationModel(i); + DefaultAnimationModel animationModel = + gltfModel.getAnimationModel(i); transferGltfChildOfRootPropertyElements(animation, animationModel); - - List channels = - Optionals.of(animation.getChannels()); - for (AnimationChannel animationChannel : channels) { + + List channels = + Optionals.of(animation.getChannels()); + for (AnimationChannel animationChannel : channels) + { Channel channel = createChannel(animation, animationChannel); animationModel.addChannel(channel); } } } - + /** * Create the {@link Channel} object for the given animation and animation * channel - * - * @param animation The {@link Animation} + * + * @param animation The {@link Animation} * @param animationChannel The {@link AnimationChannel} * @return The {@link Channel} */ private Channel createChannel( - Animation animation, AnimationChannel animationChannel) { - List samplers = - Optionals.of(animation.getSamplers()); + Animation animation, AnimationChannel animationChannel) + { + List samplers = + Optionals.of(animation.getSamplers()); int samplerIndex = animationChannel.getSampler(); AnimationSampler animationSampler = samplers.get(samplerIndex); - + int inputAccessorIndex = animationSampler.getInput(); - AccessorModel inputAccessorModel = - gltfModel.getAccessorModel(inputAccessorIndex); - + AccessorModel inputAccessorModel = + gltfModel.getAccessorModel(inputAccessorIndex); + int outputAccessorIndex = animationSampler.getOutput(); - AccessorModel outputAccessorModel = - gltfModel.getAccessorModel(outputAccessorIndex); - - String interpolationString = - animationSampler.getInterpolation(); - Interpolation interpolation = - interpolationString == null ? Interpolation.LINEAR : - Interpolation.valueOf(interpolationString); - + AccessorModel outputAccessorModel = + gltfModel.getAccessorModel(outputAccessorIndex); + + String interpolationString = + animationSampler.getInterpolation(); + Interpolation interpolation = + interpolationString == null ? Interpolation.LINEAR : + Interpolation.valueOf(interpolationString); + AnimationModel.Sampler sampler = new DefaultSampler( - inputAccessorModel, interpolation, outputAccessorModel); - - AnimationChannelTarget animationChannelTarget = - animationChannel.getTarget(); - + inputAccessorModel, interpolation, outputAccessorModel); + + AnimationChannelTarget animationChannelTarget = + animationChannel.getTarget(); + Integer nodeIndex = animationChannelTarget.getNode(); NodeModel nodeModel = null; - if (nodeIndex == null) { + if (nodeIndex == null) + { // Should not happen yet. Targets always refer to nodes logger.warning("No node index given for animation channel target"); - } else { + } + else + { nodeModel = gltfModel.getNodeModel(nodeIndex); } String path = animationChannelTarget.getPath(); - + Channel channel = - new DefaultChannel(sampler, nodeModel, path); + new DefaultChannel(sampler, nodeModel, path); return channel; } /** * Initialize the {@link BufferModel} instances */ - private void initBufferModels() { + private void initBufferModels() + { List buffers = Optionals.of(gltf.getBuffers()); ByteBuffer binaryData = null; ByteBuffer b = gltfAsset.getBinaryData(); - if (b != null && b.capacity() > 0) { + if (b != null && b.capacity() > 0) + { binaryData = b; } - - if (buffers.isEmpty() && binaryData != null) { + + if (buffers.isEmpty() && binaryData != null) + { logger.warning("Binary data was given, but no buffers"); return; } - for (int i = 0; i < buffers.size(); i++) { + for (int i = 0; i < buffers.size(); i++) + { Buffer buffer = buffers.get(i); DefaultBufferModel bufferModel = gltfModel.getBufferModel(i); transferGltfChildOfRootPropertyElements(buffer, bufferModel); - + Object extras = buffer.getExtras(); - if (extras != null) { - JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); - if (extra != null) { - bufferModel.setBufferData(MCglTF.getInstance().getBufferResource(new ResourceLocation(extra.getAsString()))); - continue; - } - } - - if (i == 0 && binaryData != null) { + if(extras != null) { + JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); + if(extra != null) { + bufferModel.setBufferData(MCglTF.getInstance().getBufferResource(new ResourceLocation(extra.getAsString()))); + continue; + } + } + + if (i == 0 && binaryData != null) + { bufferModel.setBufferData(binaryData); - } else { + } + else + { String uri = buffer.getUri(); - if (IO.isDataUriString(uri)) { + if (IO.isDataUriString(uri)) + { byte data[] = IO.readDataUri(uri); ByteBuffer bufferData = Buffers.create(data); bufferModel.setBufferData(bufferData); - } else { - if (uri == null) { + } + else + { + if (uri == null) + { logger.warning("Buffer " + i + " does not have " - + "a uri. Binary chunks that are not the main GLB " - + "buffer are not supported."); - } else { + + "a uri. Binary chunks that are not the main GLB " + + "buffer are not supported."); + } + else + { ByteBuffer bufferData = gltfAsset.getReferenceData(uri); bufferModel.setBufferData(bufferData); } @@ -749,138 +872,157 @@ private void initBufferModels() { } } } - + + /** * Initialize the {@link BufferViewModel} instances */ - private void initBufferViewModels() { + private void initBufferViewModels() + { List bufferViews = Optionals.of(gltf.getBufferViews()); - for (int i = 0; i < bufferViews.size(); i++) { + for (int i = 0; i < bufferViews.size(); i++) + { BufferView bufferView = bufferViews.get(i); - - DefaultBufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(i); + + DefaultBufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(i); transferGltfChildOfRootPropertyElements( - bufferView, bufferViewModel); - + bufferView, bufferViewModel); + int bufferIndex = bufferView.getBuffer(); BufferModel bufferModel = gltfModel.getBufferModel(bufferIndex); bufferViewModel.setBufferModel(bufferModel); } } + /** * Initialize the {@link MeshModel} instances */ - private void initMeshModels() { + private void initMeshModels() + { List meshes = Optionals.of(gltf.getMeshes()); - for (int i = 0; i < meshes.size(); i++) { + for (int i = 0; i < meshes.size(); i++) + { Mesh mesh = meshes.get(i); DefaultMeshModel meshModel = gltfModel.getMeshModel(i); transferGltfChildOfRootPropertyElements(mesh, meshModel); - - List primitives = - Optionals.of(mesh.getPrimitives()); - for (MeshPrimitive meshPrimitive : primitives) { - MeshPrimitiveModel meshPrimitiveModel = - createMeshPrimitiveModel(meshPrimitive); + + List primitives = + Optionals.of(mesh.getPrimitives()); + for (MeshPrimitive meshPrimitive : primitives) + { + MeshPrimitiveModel meshPrimitiveModel = + createMeshPrimitiveModel(meshPrimitive); meshModel.addMeshPrimitiveModel(meshPrimitiveModel); } } } - + /** - * Create a {@link MeshPrimitiveModel} for the given + * Create a {@link MeshPrimitiveModel} for the given * {@link MeshPrimitive}.
    - * + * * @param meshPrimitive The {@link MeshPrimitive} * @return The {@link MeshPrimitiveModel} */ private DefaultMeshPrimitiveModel createMeshPrimitiveModel( - MeshPrimitive meshPrimitive) { + MeshPrimitive meshPrimitive) + { Integer mode = Optionals.of( - meshPrimitive.getMode(), - meshPrimitive.defaultMode()); - DefaultMeshPrimitiveModel meshPrimitiveModel = - new DefaultMeshPrimitiveModel(mode); + meshPrimitive.getMode(), + meshPrimitive.defaultMode()); + DefaultMeshPrimitiveModel meshPrimitiveModel = + new DefaultMeshPrimitiveModel(mode); transferGltfPropertyElements(meshPrimitive, meshPrimitiveModel); - + Integer indicesIndex = meshPrimitive.getIndices(); - if (indicesIndex != null) { + if (indicesIndex != null) + { AccessorModel indices = gltfModel.getAccessorModel(indicesIndex); meshPrimitiveModel.setIndices(indices); } - Map attributes = - Optionals.of(meshPrimitive.getAttributes()); - for (Entry entry : attributes.entrySet()) { + Map attributes = + Optionals.of(meshPrimitive.getAttributes()); + for (Entry entry : attributes.entrySet()) + { String attributeName = entry.getKey(); int attributeIndex = entry.getValue(); - AccessorModel attribute = - gltfModel.getAccessorModel(attributeIndex); + AccessorModel attribute = + gltfModel.getAccessorModel(attributeIndex); meshPrimitiveModel.putAttribute(attributeName, attribute); } - + List> morphTargets = - Optionals.of(meshPrimitive.getTargets()); - for (Map morphTarget : morphTargets) { - Map morphTargetModel = - new LinkedHashMap(); - for (Entry entry : morphTarget.entrySet()) { + Optionals.of(meshPrimitive.getTargets()); + for (Map morphTarget : morphTargets) + { + Map morphTargetModel = + new LinkedHashMap(); + for (Entry entry : morphTarget.entrySet()) + { String attribute = entry.getKey(); Integer accessorIndex = entry.getValue(); - AccessorModel accessorModel = - gltfModel.getAccessorModel(accessorIndex); + AccessorModel accessorModel = + gltfModel.getAccessorModel(accessorIndex); morphTargetModel.put(attribute, accessorModel); } meshPrimitiveModel.addTarget( - Collections.unmodifiableMap(morphTargetModel)); + Collections.unmodifiableMap(morphTargetModel)); } - + Integer materialIndex = meshPrimitive.getMaterial(); - if (materialIndex != null) { - MaterialModelV2 materialModel = - (MaterialModelV2) gltfModel.getMaterialModel(materialIndex); + if (materialIndex != null) + { + MaterialModelV2 materialModel = + (MaterialModelV2) gltfModel.getMaterialModel(materialIndex); meshPrimitiveModel.setMaterialModel(materialModel); } - + return meshPrimitiveModel; } /** * Initialize the {@link NodeModel} instances */ - private void initNodeModels() { + private void initNodeModels() + { List nodes = Optionals.of(gltf.getNodes()); - for (int i = 0; i < nodes.size(); i++) { + for (int i = 0; i < nodes.size(); i++) + { Node node = nodes.get(i); - + DefaultNodeModel nodeModel = gltfModel.getNodeModel(i); - transferGltfChildOfRootPropertyElements(node, nodeModel); - + transferGltfChildOfRootPropertyElements(node, nodeModel); + List childIndices = Optionals.of(node.getChildren()); - for (Integer childIndex : childIndices) { + for (Integer childIndex : childIndices) + { DefaultNodeModel child = gltfModel.getNodeModel(childIndex); nodeModel.addChild(child); } - + Integer meshIndex = node.getMesh(); - if (meshIndex != null) { + if (meshIndex != null) + { MeshModel meshModel = gltfModel.getMeshModel(meshIndex); nodeModel.addMeshModel(meshModel); } - + Integer skinIndex = node.getSkin(); - if (skinIndex != null) { + if (skinIndex != null) + { SkinModel skinModel = gltfModel.getSkinModel(skinIndex); nodeModel.setSkinModel(skinModel); } - + Integer cameraIndex = node.getCamera(); - if (cameraIndex != null) { + if (cameraIndex != null) + { CameraModel cameraModel = gltfModel.getCameraModel(cameraIndex); nodeModel.setCameraModel(cameraModel); } - + float matrix[] = node.getMatrix(); float translation[] = node.getTranslation(); float rotation[] = node.getRotation(); @@ -889,244 +1031,275 @@ private void initNodeModels() { nodeModel.setTranslation(Optionals.clone(translation)); nodeModel.setRotation(Optionals.clone(rotation)); nodeModel.setScale(Optionals.clone(scale)); - + List weights = node.getWeights(); - if (weights != null) { + if (weights != null) + { float weightsArray[] = new float[weights.size()]; - for (int j = 0; j < weights.size(); j++) { + for (int j = 0; j < weights.size(); j++) + { weightsArray[j] = weights.get(j); } nodeModel.setWeights(weightsArray); } } } + /** * Initialize the {@link SceneModel} instances */ - private void initSceneModels() { + private void initSceneModels() + { List scenes = Optionals.of(gltf.getScenes()); - for (int i = 0; i < scenes.size(); i++) { + for (int i = 0; i < scenes.size(); i++) + { Scene scene = scenes.get(i); DefaultSceneModel sceneModel = gltfModel.getSceneModel(i); - transferGltfChildOfRootPropertyElements(scene, sceneModel); - + transferGltfChildOfRootPropertyElements(scene, sceneModel); + List nodeIndices = Optionals.of(scene.getNodes()); - for (Integer nodeIndex : nodeIndices) { + for (Integer nodeIndex : nodeIndices) + { NodeModel nodeModel = gltfModel.getNodeModel(nodeIndex); sceneModel.addNode(nodeModel); } } } - + /** * Initialize the {@link SkinModel} instances */ - private void initSkinModels() { + private void initSkinModels() + { List skins = Optionals.of(gltf.getSkins()); - for (int i = 0; i < skins.size(); i++) { + for (int i = 0; i < skins.size(); i++) + { Skin skin = skins.get(i); DefaultSkinModel skinModel = gltfModel.getSkinModel(i); transferGltfChildOfRootPropertyElements(skin, skinModel); - + List jointIndices = skin.getJoints(); - for (Integer jointIndex : jointIndices) { + for (Integer jointIndex : jointIndices) + { NodeModel jointNodeModel = gltfModel.getNodeModel(jointIndex); skinModel.addJoint(jointNodeModel); } - + Integer inverseBindMatricesIndex = skin.getInverseBindMatrices(); - AccessorModel inverseBindMatrices = - gltfModel.getAccessorModel(inverseBindMatricesIndex); + AccessorModel inverseBindMatrices = + gltfModel.getAccessorModel(inverseBindMatricesIndex); skinModel.setInverseBindMatrices(inverseBindMatrices); } } - + /** * Initialize the {@link TextureModel} instances */ - private void initTextureModels() { + private void initTextureModels() + { List textures = Optionals.of(gltf.getTextures()); - for (int i = 0; i < textures.size(); i++) { + for (int i = 0; i < textures.size(); i++) + { Texture texture = textures.get(i); DefaultTextureModel textureModel = gltfModel.getTextureModel(i); transferGltfChildOfRootPropertyElements(texture, textureModel); - + // The source may be null when the image data is provided // by an extension. Integer imageIndex = texture.getSource(); - if (imageIndex != null) { - DefaultImageModel imageModel = - gltfModel.getImageModel(imageIndex); + if (imageIndex != null) + { + DefaultImageModel imageModel = + gltfModel.getImageModel(imageIndex); textureModel.setImageModel(imageModel); } } } - + /** * Initialize the {@link ImageModel} instances */ - private void initImageModels() { + private void initImageModels() + { List images = Optionals.of(gltf.getImages()); - for (int i = 0; i < images.size(); i++) { + for (int i = 0; i < images.size(); i++) + { Image image = images.get(i); DefaultImageModel imageModel = gltfModel.getImageModel(i); transferGltfChildOfRootPropertyElements(image, imageModel); - + Object extras = image.getExtras(); - if (extras != null) { - JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); - if (extra != null) { - imageModel.setImageData(MCglTF.getInstance().getImageResource(new ResourceLocation(extra.getAsString()))); - continue; - } - } - + if(extras != null) { + JsonElement extra = new Gson().toJsonTree(extras).getAsJsonObject().get(MCglTF.RESOURCE_LOCATION); + if(extra != null) { + imageModel.setImageData(MCglTF.getInstance().getImageResource(new ResourceLocation(extra.getAsString()))); + continue; + } + } + Integer bufferViewIndex = image.getBufferView(); - if (bufferViewIndex != null) { - BufferViewModel bufferViewModel = - gltfModel.getBufferViewModel(bufferViewIndex); + if (bufferViewIndex != null) + { + BufferViewModel bufferViewModel = + gltfModel.getBufferViewModel(bufferViewIndex); imageModel.setBufferViewModel(bufferViewModel); - } else { + } + else + { String uri = image.getUri(); - if (IO.isDataUriString(uri)) { + if (IO.isDataUriString(uri)) + { byte data[] = IO.readDataUri(uri); ByteBuffer imageData = Buffers.create(data); imageModel.setImageData(imageData); - } else { + } + else + { ByteBuffer imageData = gltfAsset.getReferenceData(uri); imageModel.setImageData(imageData); } } } } - + /** * Initialize the {@link MaterialModel} instances */ - private void initMaterialModels() { + private void initMaterialModels() + { List materials = Optionals.of(gltf.getMaterials()); - for (int i = 0; i < materials.size(); i++) { + for (int i = 0; i < materials.size(); i++) + { Material material = materials.get(i); - MaterialModelV2 materialModel = - (MaterialModelV2) gltfModel.getMaterialModel(i); - - transferGltfChildOfRootPropertyElements(material, materialModel); + MaterialModelV2 materialModel = + (MaterialModelV2) gltfModel.getMaterialModel(i); + + transferGltfChildOfRootPropertyElements(material, materialModel); initMaterialModel(materialModel, material); } } - + /** * Initialize the given {@link MaterialModelV2} based on the given * {@link Material} - * + * * @param materialModel The {@link MaterialModelV2} - * @param material The {@link Material} + * @param material The {@link Material} */ private void initMaterialModel( - MaterialModelV2 materialModel, Material material) { - MaterialPbrMetallicRoughness pbrMetallicRoughness = - material.getPbrMetallicRoughness(); - if (pbrMetallicRoughness == null) { - pbrMetallicRoughness = - Materials.createDefaultMaterialPbrMetallicRoughness(); + MaterialModelV2 materialModel, Material material) + { + MaterialPbrMetallicRoughness pbrMetallicRoughness = + material.getPbrMetallicRoughness(); + if (pbrMetallicRoughness == null) + { + pbrMetallicRoughness = + Materials.createDefaultMaterialPbrMetallicRoughness(); } - + String alphaModeString = material.getAlphaMode(); - if (alphaModeString != null) { + if (alphaModeString != null) + { materialModel.setAlphaMode(AlphaMode.valueOf(alphaModeString)); } materialModel.setAlphaCutoff( - Optionals.of(material.getAlphaCutoff(), 0.5f)); - + Optionals.of(material.getAlphaCutoff(), 0.5f)); + materialModel.setDoubleSided( - Boolean.TRUE.equals(material.isDoubleSided())); - - TextureInfo baseColorTextureInfo = - pbrMetallicRoughness.getBaseColorTexture(); - if (baseColorTextureInfo != null) { + Boolean.TRUE.equals(material.isDoubleSided())); + + TextureInfo baseColorTextureInfo = + pbrMetallicRoughness.getBaseColorTexture(); + if (baseColorTextureInfo != null) + { int index = baseColorTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setBaseColorTexture(textureModel); materialModel.setBaseColorTexcoord( - baseColorTextureInfo.getTexCoord()); + baseColorTextureInfo.getTexCoord()); } float[] baseColorFactor = Optionals.of( - pbrMetallicRoughness.getBaseColorFactor(), - pbrMetallicRoughness.defaultBaseColorFactor()); + pbrMetallicRoughness.getBaseColorFactor(), + pbrMetallicRoughness.defaultBaseColorFactor()); materialModel.setBaseColorFactor(baseColorFactor); - - TextureInfo metallicRoughnessTextureInfo = - pbrMetallicRoughness.getMetallicRoughnessTexture(); - if (metallicRoughnessTextureInfo != null) { + + TextureInfo metallicRoughnessTextureInfo = + pbrMetallicRoughness.getMetallicRoughnessTexture(); + if (metallicRoughnessTextureInfo != null) + { int index = metallicRoughnessTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setMetallicRoughnessTexture(textureModel); materialModel.setMetallicRoughnessTexcoord( - metallicRoughnessTextureInfo.getTexCoord()); + metallicRoughnessTextureInfo.getTexCoord()); } float metallicFactor = Optionals.of( - pbrMetallicRoughness.getMetallicFactor(), - pbrMetallicRoughness.defaultMetallicFactor()); + pbrMetallicRoughness.getMetallicFactor(), + pbrMetallicRoughness.defaultMetallicFactor()); materialModel.setMetallicFactor(metallicFactor); - + float roughnessFactor = Optionals.of( - pbrMetallicRoughness.getRoughnessFactor(), - pbrMetallicRoughness.defaultRoughnessFactor()); + pbrMetallicRoughness.getRoughnessFactor(), + pbrMetallicRoughness.defaultRoughnessFactor()); materialModel.setRoughnessFactor(roughnessFactor); - - MaterialNormalTextureInfo normalTextureInfo = - material.getNormalTexture(); - if (normalTextureInfo != null) { + + MaterialNormalTextureInfo normalTextureInfo = + material.getNormalTexture(); + if (normalTextureInfo != null) + { int index = normalTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setNormalTexture(textureModel); materialModel.setNormalTexcoord( - normalTextureInfo.getTexCoord()); - + normalTextureInfo.getTexCoord()); + float normalScale = Optionals.of( - normalTextureInfo.getScale(), - normalTextureInfo.defaultScale()); + normalTextureInfo.getScale(), + normalTextureInfo.defaultScale()); materialModel.setNormalScale(normalScale); } - MaterialOcclusionTextureInfo occlusionTextureInfo = - material.getOcclusionTexture(); - if (occlusionTextureInfo != null) { + MaterialOcclusionTextureInfo occlusionTextureInfo = + material.getOcclusionTexture(); + if (occlusionTextureInfo != null) + { int index = occlusionTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setOcclusionTexture(textureModel); materialModel.setOcclusionTexcoord( - occlusionTextureInfo.getTexCoord()); - + occlusionTextureInfo.getTexCoord()); + float occlusionStrength = Optionals.of( - occlusionTextureInfo.getStrength(), - occlusionTextureInfo.defaultStrength()); + occlusionTextureInfo.getStrength(), + occlusionTextureInfo.defaultStrength()); materialModel.setOcclusionStrength(occlusionStrength); } - TextureInfo emissiveTextureInfo = - material.getEmissiveTexture(); - if (emissiveTextureInfo != null) { + TextureInfo emissiveTextureInfo = + material.getEmissiveTexture(); + if (emissiveTextureInfo != null) + { int index = emissiveTextureInfo.getIndex(); TextureModel textureModel = gltfModel.getTextureModel(index); materialModel.setEmissiveTexture(textureModel); materialModel.setEmissiveTexcoord( - emissiveTextureInfo.getTexCoord()); + emissiveTextureInfo.getTexCoord()); } - + float[] emissiveFactor = Optionals.of( - material.getEmissiveFactor(), - material.defaultEmissiveFactor()); + material.getEmissiveFactor(), + material.defaultEmissiveFactor()); materialModel.setEmissiveFactor(emissiveFactor); } - + /** * Initialize the {@link ExtensionsModel} with the extensions that * are used or required in the glTF. */ - private void initExtensionsModel() { + private void initExtensionsModel() + { List extensionsUsed = gltf.getExtensionsUsed(); List extensionsRequired = gltf.getExtensionsRequired(); DefaultExtensionsModel extensionsModel = gltfModel.getExtensionsModel(); @@ -1138,14 +1311,45 @@ private void initExtensionsModel() { * Initialize the {@link AssetModel} with the asset information that * was given in the glTF. */ - private void initAssetModel() { + private void initAssetModel() + { Asset asset = gltf.getAsset(); - if (asset != null) { + if (asset != null) + { DefaultAssetModel assetModel = gltfModel.getAssetModel(); transferGltfPropertyElements(asset, assetModel); assetModel.setCopyright(asset.getCopyright()); assetModel.setGenerator(asset.getGenerator()); } } - + + /** + * Transfer the extensions and extras from the given property to + * the given target + * + * @param property The property + * @param modelElement The target + */ + private static void transferGltfPropertyElements( + GlTFProperty property, AbstractModelElement modelElement) + { + modelElement.setExtensions(property.getExtensions()); + modelElement.setExtras(property.getExtras()); + } + + /** + * Transfer the name and extensions and extras from the given property to + * the given target + * + * @param property The property + * @param modelElement The target + */ + private static void transferGltfChildOfRootPropertyElements( + GlTFChildOfRootProperty property, + AbstractNamedModelElement modelElement) + { + modelElement.setName(property.getName()); + transferGltfPropertyElements(property, modelElement); + } + } diff --git a/src/main/java/de/javagl/jgltf/model/v2/MaterialModelV2.java b/src/main/java/de/javagl/jgltf/model/v2/MaterialModelV2.java index 449b368..d263846 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/MaterialModelV2.java +++ b/src/main/java/de/javagl/jgltf/model/v2/MaterialModelV2.java @@ -33,479 +33,539 @@ /** * Implementation of a {@link MaterialModel} for glTF 2.0.
    *
    - * Note: This class might be renamed to "PbrBasedMaterialModel" and moved to + * Note: This class might be renamed to "PbrBasedMaterialModel" and moved to * a different package in the future. */ public final class MaterialModelV2 extends AbstractNamedModelElement - implements MaterialModel { + implements MaterialModel +{ + /** + * Alpha modes + */ + public static enum AlphaMode + { + /** + * Opaque mode + */ + OPAQUE, + + /** + * Masking mode + */ + MASK, + + /** + * Blend mode + */ + BLEND + } + /** * The base color factor */ private float[] baseColorFactor; + /** * The base color texture */ private TextureModel baseColorTexture; + /** * The texture coordinate set for the base color texture */ private Integer baseColorTexcoord; + /** * The metallic factor */ private float metallicFactor; + /** * The roughness factor */ private float roughnessFactor; + /** * The metallic-roughness texture */ private TextureModel metallicRoughnessTexture; + /** * The texture coordinate set for the metallic-roughness texture */ private Integer metallicRoughnessTexcoord; + /** * The normal texture */ private TextureModel normalTexture; + /** * The texture coordinate set for the normal texture */ private Integer normalTexcoord; + /** * The normal scale */ private float normalScale; + /** * The occlusion texture */ private TextureModel occlusionTexture; + /** * The texture coordinate set for the occlusion texture */ private Integer occlusionTexcoord; + /** * The occlusion strength */ private float occlusionStrength; + /** * The emissive texture */ private TextureModel emissiveTexture; + /** * The texture coordinate set for the emissive texture */ private Integer emissiveTexcoord; + /** * The emissive factor */ private float[] emissiveFactor; + /** * The alpha mode */ private AlphaMode alphaMode; + /** * The alpha cutoff */ private float alphaCutoff; + /** * Whether the material is double sided */ private boolean doubleSided; - + + /** * Creates a new instance with default values */ - public MaterialModelV2() { - baseColorFactor = new float[]{1.0f, 1.0f, 1.0f, 1.0f}; + public MaterialModelV2() + { + baseColorFactor = new float[]{ 1.0f, 1.0f, 1.0f, 1.0f }; baseColorTexture = null; baseColorTexcoord = null; - + metallicFactor = 1.0f; roughnessFactor = 1.0f; metallicRoughnessTexture = null; metallicRoughnessTexcoord = null; - + normalScale = 1.0f; normalTexture = null; normalTexcoord = null; - + occlusionTexture = null; occlusionTexcoord = null; occlusionStrength = 1.0f; - + emissiveTexture = null; emissiveTexcoord = null; - emissiveFactor = new float[]{0.0f, 0.0f, 0.0f}; + emissiveFactor = new float[]{0.0f, 0.0f, 0.0f }; alphaMode = AlphaMode.OPAQUE; alphaCutoff = 0.5f; - + doubleSided = false; } - + /** * Returns the base color factor - * + * * @return The base color factor */ - public float[] getBaseColorFactor() { + public float[] getBaseColorFactor() + { return baseColorFactor; } /** * Set the base color factor - * + * * @param baseColorFactor The base color factor */ - public void setBaseColorFactor(float[] baseColorFactor) { + public void setBaseColorFactor(float[] baseColorFactor) + { this.baseColorFactor = baseColorFactor; } /** * Returns the base color texture - * + * * @return The base color texture */ - public TextureModel getBaseColorTexture() { + public TextureModel getBaseColorTexture() + { return baseColorTexture; } /** * Set the base color texture - * + * * @param baseColorTexture The base color texture */ - public void setBaseColorTexture(TextureModel baseColorTexture) { + public void setBaseColorTexture(TextureModel baseColorTexture) + { this.baseColorTexture = baseColorTexture; } - + /** * Return the base color texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getBaseColorTexcoord() { + public Integer getBaseColorTexcoord() + { return baseColorTexcoord; } - + /** * Set the base color texture coordinate set - * + * * @param baseColorTexcoord The texture coordinate set */ - public void setBaseColorTexcoord(Integer baseColorTexcoord) { + public void setBaseColorTexcoord(Integer baseColorTexcoord) + { this.baseColorTexcoord = baseColorTexcoord; } /** * Returns the metallic factor - * + * * @return The metallic factor */ - public float getMetallicFactor() { + public float getMetallicFactor() + { return metallicFactor; } /** * Set the metallic factor - * + * * @param metallicFactor The metallic factor */ - public void setMetallicFactor(float metallicFactor) { + public void setMetallicFactor(float metallicFactor) + { this.metallicFactor = metallicFactor; } /** * Returns the roughness factor - * + * * @return The roughness factor */ - public float getRoughnessFactor() { + public float getRoughnessFactor() + { return roughnessFactor; } /** * Set the roughness factor - * + * * @param roughnessFactor The roughness factor */ - public void setRoughnessFactor(float roughnessFactor) { + public void setRoughnessFactor(float roughnessFactor) + { this.roughnessFactor = roughnessFactor; } /** * Returns the metallic-roughness-texture - * + * * @return The metallic-roughness texture */ - public TextureModel getMetallicRoughnessTexture() { + public TextureModel getMetallicRoughnessTexture() + { return metallicRoughnessTexture; } /** * Set the metallic-roughness-texture - * + * * @param metallicRoughnessTexture The metallic-roughness-texture */ public void setMetallicRoughnessTexture( - TextureModel metallicRoughnessTexture) { + TextureModel metallicRoughnessTexture) + { this.metallicRoughnessTexture = metallicRoughnessTexture; } - + /** * Returns the metallic-roughness texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getMetallicRoughnessTexcoord() { + public Integer getMetallicRoughnessTexcoord() + { return metallicRoughnessTexcoord; } - + /** * Set the metallic-roughness texture coordinate set - * + * * @param metallicRoughnessTexcoord The texture coordinate set */ - public void setMetallicRoughnessTexcoord(Integer metallicRoughnessTexcoord) { + public void setMetallicRoughnessTexcoord(Integer metallicRoughnessTexcoord) + { this.metallicRoughnessTexcoord = metallicRoughnessTexcoord; } /** * Returns the normal texture - * + * * @return The normal texture */ - public TextureModel getNormalTexture() { + public TextureModel getNormalTexture() + { return normalTexture; } /** * Set the normal texture - * + * * @param normalTexture The normal texture */ - public void setNormalTexture(TextureModel normalTexture) { + public void setNormalTexture(TextureModel normalTexture) + { this.normalTexture = normalTexture; } - + /** * Returns the normal texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getNormalTexcoord() { + public Integer getNormalTexcoord() + { return normalTexcoord; } - + /** * Set the normal texture coordinate set - * + * * @param normalTexcoord The texture coordinate set */ - public void setNormalTexcoord(Integer normalTexcoord) { + public void setNormalTexcoord(Integer normalTexcoord) + { this.normalTexcoord = normalTexcoord; } /** * Returns the normal scale - * + * * @return The normal scale */ - public float getNormalScale() { + public float getNormalScale() + { return normalScale; } /** * Set the normal scale - * + * * @param normalScale The normal scale */ - public void setNormalScale(float normalScale) { + public void setNormalScale(float normalScale) + { this.normalScale = normalScale; } - + /** * Returns the occlusion texture - * + * * @return The occlusion texture */ - public TextureModel getOcclusionTexture() { + public TextureModel getOcclusionTexture() + { return occlusionTexture; } /** * Set the occlusion texture - * + * * @param occlusionTexture The occlusion texture */ - public void setOcclusionTexture(TextureModel occlusionTexture) { + public void setOcclusionTexture(TextureModel occlusionTexture) + { this.occlusionTexture = occlusionTexture; } - + /** * Returns the occlusion texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getOcclusionTexcoord() { + public Integer getOcclusionTexcoord() + { return occlusionTexcoord; } - + /** * Set the occlusion texture coordinate set - * + * * @param occlusionTexcoord The texture coordinate set */ - public void setOcclusionTexcoord(Integer occlusionTexcoord) { + public void setOcclusionTexcoord(Integer occlusionTexcoord) + { this.occlusionTexcoord = occlusionTexcoord; } /** * Returns the occlusion strength - * + * * @return The occlusion strength */ - public float getOcclusionStrength() { + public float getOcclusionStrength() + { return occlusionStrength; } /** * Set the occlusion strength - * + * * @param occlusionStrength The occlusion strength */ - public void setOcclusionStrength(float occlusionStrength) { + public void setOcclusionStrength(float occlusionStrength) + { this.occlusionStrength = occlusionStrength; } /** * Returns the emissive texture - * + * * @return The emissive texture */ - public TextureModel getEmissiveTexture() { + public TextureModel getEmissiveTexture() + { return emissiveTexture; } /** * Set the emissive texture - * + * * @param emissiveTexture The emissive texture */ - public void setEmissiveTexture(TextureModel emissiveTexture) { + public void setEmissiveTexture(TextureModel emissiveTexture) + { this.emissiveTexture = emissiveTexture; } - + /** * Set the emissive texture coordinate set - * + * * @return The texture coordinate set */ - public Integer getEmissiveTexcoord() { + public Integer getEmissiveTexcoord() + { return emissiveTexcoord; } - + /** * Set the emissive texture coordinate set - * + * * @param emissiveTexcoord The texture coordinate set */ - public void setEmissiveTexcoord(Integer emissiveTexcoord) { + public void setEmissiveTexcoord(Integer emissiveTexcoord) + { this.emissiveTexcoord = emissiveTexcoord; } - + /** * Returns the emissive factor - * + * * @return The emissive factor */ - public float[] getEmissiveFactor() { + public float[] getEmissiveFactor() + { return emissiveFactor; } /** * Set the emissive factor - * + * * @param emissiveFactor The emissive factor */ - public void setEmissiveFactor(float[] emissiveFactor) { + public void setEmissiveFactor(float[] emissiveFactor) + { this.emissiveFactor = emissiveFactor; } /** * Returns the alpha mode - * + * * @return The alpha mode */ - public AlphaMode getAlphaMode() { + public AlphaMode getAlphaMode() + { return alphaMode; } /** * Set the alpha mode - * + * * @param alphaMode The alpha mode */ - public void setAlphaMode(AlphaMode alphaMode) { + public void setAlphaMode(AlphaMode alphaMode) + { this.alphaMode = alphaMode; } /** * Returns the alpha cutoff - * + * * @return The alpha cutoff */ - public float getAlphaCutoff() { + public float getAlphaCutoff() + { return alphaCutoff; } /** * Set the alpha cutoff - * + * * @param alphaCutoff The alpha cutoff */ - public void setAlphaCutoff(float alphaCutoff) { + public void setAlphaCutoff(float alphaCutoff) + { this.alphaCutoff = alphaCutoff; } /** * Returns whether the material is double sided - * + * * @return Whether the material is double sided */ - public boolean isDoubleSided() { + public boolean isDoubleSided() + { return doubleSided; } /** * Set whether the material is double sided - * + * * @param doubleSided Whether the material is double sided */ - public void setDoubleSided(boolean doubleSided) { + public void setDoubleSided(boolean doubleSided) + { this.doubleSided = doubleSided; } - - /** - * Alpha modes - */ - public static enum AlphaMode { - /** - * Opaque mode - */ - OPAQUE, - - /** - * Masking mode - */ - MASK, - - /** - * Blend mode - */ - BLEND - } } diff --git a/src/main/java/de/javagl/jgltf/model/v2/gl/Materials.java b/src/main/java/de/javagl/jgltf/model/v2/gl/Materials.java index fadba0a..9fa46e6 100644 --- a/src/main/java/de/javagl/jgltf/model/v2/gl/Materials.java +++ b/src/main/java/de/javagl/jgltf/model/v2/gl/Materials.java @@ -32,23 +32,18 @@ /** * Methods to create instances of classes related to a {@link Material} */ -public class Materials { - /** - * Private constructor to prevent instantiation - */ - private Materials() { - // Private constructor to prevent instantiation - } - +public class Materials +{ /** * Create a {@link Material} with all default values - * + * * @return The {@link Material} */ - public static Material createDefaultMaterial() { + public static Material createDefaultMaterial() + { Material material = new Material(); material.setPbrMetallicRoughness( - createDefaultMaterialPbrMetallicRoughness()); + createDefaultMaterialPbrMetallicRoughness()); material.setNormalTexture(null); material.setOcclusionTexture(null); material.setEmissiveTexture(null); @@ -58,19 +53,28 @@ public static Material createDefaultMaterial() { material.setDoubleSided(material.defaultDoubleSided()); return material; } - + /** * Create a {@link MaterialPbrMetallicRoughness} with all default values - * + * * @return The {@link MaterialPbrMetallicRoughness} */ - public static MaterialPbrMetallicRoughness - createDefaultMaterialPbrMetallicRoughness() { - MaterialPbrMetallicRoughness result = - new MaterialPbrMetallicRoughness(); + public static MaterialPbrMetallicRoughness + createDefaultMaterialPbrMetallicRoughness() + { + MaterialPbrMetallicRoughness result = + new MaterialPbrMetallicRoughness(); result.setBaseColorFactor(result.defaultBaseColorFactor()); result.setMetallicFactor(result.defaultMetallicFactor()); result.setRoughnessFactor(result.defaultRoughnessFactor()); return result; } + + /** + * Private constructor to prevent instantiation + */ + private Materials() + { + // Private constructor to prevent instantiation + } } diff --git a/src/main/java/simplelibs/SimpleConfig.java b/src/main/java/simplelibs/SimpleConfig.java index c2ef34b..9f34da7 100644 --- a/src/main/java/simplelibs/SimpleConfig.java +++ b/src/main/java/simplelibs/SimpleConfig.java @@ -41,30 +41,51 @@ public class SimpleConfig { private final ConfigRequest request; private boolean broken = false; - private SimpleConfig(ConfigRequest request) { - this.request = request; - String identifier = "Config '" + request.filename + "'"; + public interface DefaultConfig { + String get( String namespace ); - if (!request.file.exists()) { - LOGGER.info(identifier + " is missing, generating default one..."); + static String empty( String namespace ) { + return ""; + } + } - try { - createConfig(); - } catch (IOException e) { - LOGGER.error(identifier + " failed to generate!"); - LOGGER.trace(e); - broken = true; - } + public static class ConfigRequest { + + private final File file; + private final String filename; + private DefaultConfig provider; + + private ConfigRequest(File file, String filename ) { + this.file = file; + this.filename = filename; + this.provider = DefaultConfig::empty; } - if (!broken) { - try { - loadConfig(); - } catch (Exception e) { - LOGGER.error(identifier + " failed to load!"); - LOGGER.trace(e); - broken = true; - } + /** + * Sets the default config provider, used to generate the + * config if it's missing. + * + * @param provider default config provider + * @return current config request object + * @see DefaultConfig + */ + public ConfigRequest provider( DefaultConfig provider ) { + this.provider = provider; + return this; + } + + /** + * Loads the config from the filesystem. + * + * @return config object + * @see SimpleConfig + */ + public SimpleConfig request() { + return new SimpleConfig( this ); + } + + private String getConfig() { + return provider.get( filename ) + "\n"; } } @@ -76,62 +97,90 @@ private SimpleConfig(ConfigRequest request) { * @param filename - name of the config file * @return new config request object */ - public static ConfigRequest of(String filename) { + public static ConfigRequest of( String filename ) { Path path = FabricLoader.getInstance().getConfigDir(); - return new ConfigRequest(path.resolve(filename + ".properties").toFile(), filename); + return new ConfigRequest( path.resolve( filename + ".properties" ).toFile(), filename ); } private void createConfig() throws IOException { // try creating missing files request.file.getParentFile().mkdirs(); - Files.createFile(request.file.toPath()); + Files.createFile( request.file.toPath() ); // write default config data PrintWriter writer = new PrintWriter(request.file, "UTF-8"); - writer.write(request.getConfig()); + writer.write( request.getConfig() ); writer.close(); } private void loadConfig() throws IOException { - try (Scanner reader = new Scanner(request.file)) { - for (int line = 1; reader.hasNextLine(); line++) { - parseConfigEntry(reader.nextLine(), line); - } - } + try (Scanner reader = new Scanner( request.file )) { + for( int line = 1; reader.hasNextLine(); line ++ ) { + parseConfigEntry( reader.nextLine(), line ); + } + } } - private void parseConfigEntry(String entry, int line) { - if (!entry.isEmpty() && !entry.startsWith("#")) { + private void parseConfigEntry( String entry, int line ) { + if( !entry.isEmpty() && !entry.startsWith( "#" ) ) { String[] parts = entry.split("=", 2); - if (parts.length == 2) { - config.put(parts[0], parts[1]); - } else { + if( parts.length == 2 ) { + config.put( parts[0], parts[1] ); + }else{ throw new RuntimeException("Syntax error in config file on line " + line + "!"); } } } + private SimpleConfig( ConfigRequest request ) { + this.request = request; + String identifier = "Config '" + request.filename + "'"; + + if( !request.file.exists() ) { + LOGGER.info( identifier + " is missing, generating default one..." ); + + try { + createConfig(); + } catch (IOException e) { + LOGGER.error( identifier + " failed to generate!" ); + LOGGER.trace( e ); + broken = true; + } + } + + if( !broken ) { + try { + loadConfig(); + } catch (Exception e) { + LOGGER.error( identifier + " failed to load!" ); + LOGGER.trace( e ); + broken = true; + } + } + + } + /** * Queries a value from config, returns `null` if the * key does not exist. * - * @return value corresponding to the given key - * @see SimpleConfig#getOrDefault + * @return value corresponding to the given key + * @see SimpleConfig#getOrDefault */ @Deprecated - public String get(String key) { - return config.get(key); + public String get( String key ) { + return config.get( key ); } /** * Returns string value from config corresponding to the given * key, or the default string if the key is missing. * - * @return value corresponding to the given key, or the default value + * @return value corresponding to the given key, or the default value */ - public String getOrDefault(String key, String def) { + public String getOrDefault( String key, String def ) { String val = get(key); return val == null ? def : val; } @@ -140,11 +189,11 @@ public String getOrDefault(String key, String def) { * Returns integer value from config corresponding to the given * key, or the default integer if the key is missing or invalid. * - * @return value corresponding to the given key, or the default value + * @return value corresponding to the given key, or the default value */ - public int getOrDefault(String key, int def) { + public int getOrDefault( String key, int def ) { try { - return Integer.parseInt(get(key)); + return Integer.parseInt( get(key) ); } catch (Exception e) { return def; } @@ -154,11 +203,11 @@ public int getOrDefault(String key, int def) { * Returns boolean value from config corresponding to the given * key, or the default boolean if the key is missing. * - * @return value corresponding to the given key, or the default value + * @return value corresponding to the given key, or the default value */ - public boolean getOrDefault(String key, boolean def) { + public boolean getOrDefault( String key, boolean def ) { String val = get(key); - if (val != null) { + if( val != null ) { return val.equalsIgnoreCase("true"); } @@ -169,11 +218,11 @@ public boolean getOrDefault(String key, boolean def) { * Returns double value from config corresponding to the given * key, or the default string if the key is missing or invalid. * - * @return value corresponding to the given key, or the default value + * @return value corresponding to the given key, or the default value */ - public double getOrDefault(String key, double def) { + public double getOrDefault( String key, double def ) { try { - return Double.parseDouble(get(key)); + return Double.parseDouble( get(key) ); } catch (Exception e) { return def; } @@ -196,57 +245,8 @@ public boolean isBroken() { * @return true if the operation was successful */ public boolean delete() { - LOGGER.warn("Config '" + request.filename + "' was removed from existence! Restart the game to regenerate it."); + LOGGER.warn( "Config '" + request.filename + "' was removed from existence! Restart the game to regenerate it." ); return request.file.delete(); } - public interface DefaultConfig { - static String empty(String namespace) { - return ""; - } - - String get(String namespace); - } - - public static class ConfigRequest { - - private final File file; - private final String filename; - private DefaultConfig provider; - - private ConfigRequest(File file, String filename) { - this.file = file; - this.filename = filename; - this.provider = DefaultConfig::empty; - } - - /** - * Sets the default config provider, used to generate the - * config if it's missing. - * - * @param provider default config provider - * @return current config request object - * @see DefaultConfig - */ - public ConfigRequest provider(DefaultConfig provider) { - this.provider = provider; - return this; - } - - /** - * Loads the config from the filesystem. - * - * @return config object - * @see SimpleConfig - */ - public SimpleConfig request() { - return new SimpleConfig(this); - } - - private String getConfig() { - return provider.get(filename) + "\n"; - } - - } - } From ed9c54ad7d3854265f9351c4a1d3df585bfc6ea6 Mon Sep 17 00:00:00 2001 From: Ryu Seowoong Date: Sun, 16 Nov 2025 21:41:23 +0900 Subject: [PATCH 5/5] remove repo --- build.gradle | 5 +---- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 9484d59..e1e61ea 100644 --- a/build.gradle +++ b/build.gradle @@ -82,9 +82,6 @@ publishing { // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. repositories { - maven { - name = "local" - url = uri(localMvnRepo) - } + } } diff --git a/gradle.properties b/gradle.properties index b255d7a..e5d05b9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.parallel=true minecraft_version=1.20.4 loader_version=0.16.3 # Mod Properties -mod_version=1.20.4-Fabric-3.2.0.0 +mod_version=1.20.4-Fabric-2.2.0.0 maven_group=com.modularmods.mcgltf archives_base_name=MCglTF # Dependencies