From fd49e0db5c90bf7386692bf42410692f69deb061 Mon Sep 17 00:00:00 2001 From: iSergio Date: Fri, 19 Nov 2021 13:42:04 +0300 Subject: [PATCH] New example - Model Experimental 3D Models --- .../showcase/config/InjectorModule.java | 1 + .../examples/ModelExperimental3DModels.java | 109 +++++++ .../BoxInstanced/glTF/box-instanced.gltf | 289 ++++++++++++++++++ .../GltfLoader/BoxInstanced/glTF/geometry.bin | Bin 0 -> 648 bytes .../BoxInstanced/glTF/instances.bin | Bin 0 -> 176 bytes .../GltfLoader/BoxInstanced/glTF/metadata.bin | Bin 0 -> 104 bytes .../Data/Models/PBR/BoxUnlit/BoxUnlit.gltf | 151 +++++++++ .../examples/Model Experimental 3D Models.jpg | Bin 0 -> 11306 bytes .../examples/ModelExperimental3DModels.txt | 93 ++++++ 9 files changed, 643 insertions(+) create mode 100644 cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/examples/ModelExperimental3DModels.java create mode 100644 cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/box-instanced.gltf create mode 100644 cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/geometry.bin create mode 100644 cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/instances.bin create mode 100644 cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/metadata.bin create mode 100644 cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/PBR/BoxUnlit/BoxUnlit.gltf create mode 100644 cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/Model Experimental 3D Models.jpg create mode 100644 cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/ModelExperimental3DModels.txt diff --git a/cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/config/InjectorModule.java b/cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/config/InjectorModule.java index 8146c88f..0adc756c 100644 --- a/cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/config/InjectorModule.java +++ b/cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/config/InjectorModule.java @@ -122,5 +122,6 @@ public class InjectorModule extends AbstractGinModule { bind(CustomShadersModels.class).asEagerSingleton(); bind(Tiles3DNextCDBYemen.class).asEagerSingleton(); bind(Tiles3DNextS2Globe.class).asEagerSingleton(); + bind(ModelExperimental3DModels.class).asEagerSingleton(); } } diff --git a/cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/examples/ModelExperimental3DModels.java b/cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/examples/ModelExperimental3DModels.java new file mode 100644 index 00000000..22059757 --- /dev/null +++ b/cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/examples/ModelExperimental3DModels.java @@ -0,0 +1,109 @@ +/* + * Copyright 2021 iserge, Gis4Fun. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.cleanlogic.cesiumjs4gwt.showcase.examples; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.ui.AbsolutePanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.ListBox; +import org.cesiumjs.cs.core.*; +import org.cesiumjs.cs.core.HeadingPitchRoll; +import org.cesiumjs.cs.scene.experimental.ModelExperimental; +import org.cesiumjs.cs.scene.experimental.options.ModelExperimentalFromGltfOptions; +import org.cesiumjs.cs.widgets.Viewer; +import org.cesiumjs.cs.widgets.ViewerPanel; +import org.cleanlogic.cesiumjs4gwt.showcase.basic.AbstractExample; +import org.cleanlogic.cesiumjs4gwt.showcase.components.store.ShowcaseExampleStore; + +import javax.inject.Inject; +import java.lang.Math; + +public class ModelExperimental3DModels extends AbstractExample { + private Viewer viewer; + + private final HeadingPitchRoll hpr = new HeadingPitchRoll(Math.toRadians(180), 0, 0); + private final Transforms.LocalFrameToFixedFrame fixedFrameTransform = Transforms.localFrameToFixedFrameGenerator("north", "west"); + + @Inject + public ModelExperimental3DModels(ShowcaseExampleStore store) { + super("Model Experimental 3D Models", + "Load glTF models using Model Experimental", + new String[]{"Showcase", "Cesium", "3d", "Viewer", "experimental"}, store, "1.87.1"); + } + + @Override + public void buildPanel() { + ViewerPanel csVPanel = new ViewerPanel(); + viewer = csVPanel.getViewer(); + + csVPanel.getViewer().clock().currentTime = JulianDate.fromIso8601("2021-11-09T20:27:37.016064475348684937Z"); + + ListBox listBox = new ListBox(); + listBox.addItem("Cesium Balloon"); + listBox.addItem("Skinned Character"); + listBox.addItem("Draco Compressed Model"); + listBox.addItem("Unlit Box"); + listBox.addItem("Drone"); + listBox.addItem("Ground Vehicle"); + listBox.addItem("Instanced Box"); + listBox.addChangeHandler(event -> { + String value = ((ListBox) event.getSource()).getSelectedItemText(); + String prefix = GWT.getModuleBaseURL(); + switch (value) { + case "Cesium Balloon": selectModel(prefix + "SampleData/models/CesiumBalloon/CesiumBalloon.glb", 15); break; + case "Skinned Character": selectModel(prefix + "SampleData/models/CesiumMan/Cesium_Man.glb", 0); break; + case "Draco Compressed Model": selectModel(prefix + "SampleData/models/DracoCompressed/CesiumMilkTruck.gltf", 0); break; + case "Unlit Box": selectModel(prefix + "Specs/Data/Models/PBR/BoxUnlit/BoxUnlit.gltf", 0); break; + case "Drone": selectModel(prefix + "SampleData/models/CesiumDrone/CesiumDrone.glb", 15); break; + case "Ground Vehicle": selectModel(prefix + "SampleData/models/GroundVehicle/GroundVehicle.glb", 0); break; + case "Instanced Box": selectModel(prefix + "Specs/Data/Models/GltfLoader/BoxInstanced/glTF/box-instanced.gltf", 15); break; + default: break; + } + }); + + AbsolutePanel aPanel = new AbsolutePanel(); + aPanel.add(csVPanel); + aPanel.add(listBox, 20, 20); + + contentPanel.add(new HTML( + "

Load glTF models using Model Experimental.

")); + contentPanel.add(aPanel); + + initWidget(contentPanel); + + selectModel(GWT.getModuleBaseURL() + "SampleData/models/CesiumBalloon/CesiumBalloon.glb", 15); + } + + @Override + public String[] getSourceCodeURLs() { + String[] sourceCodeURLs = new String[1]; + sourceCodeURLs[0] = GWT.getModuleBaseURL() + "examples/" + "ModelExperimental3DModels.txt"; + return sourceCodeURLs; + } + + private void selectModel(String url, double height) { + Cartesian3 position = Cartesian3.fromDegrees(-123.0744619, 44.0503706, height); + + viewer.scene().primitives().removeAll(); + ModelExperimentalFromGltfOptions options = ModelExperimentalFromGltfOptions.create(url); + options.modelMatrix = Transforms.headingPitchRollToFixedFrame(position, hpr, Ellipsoid.WGS84(), fixedFrameTransform); + ModelExperimental model = (ModelExperimental) viewer.scene().primitives().add(ModelExperimental.fromGltf(options)); + + model.readyPromise().then(nModel -> viewer.camera.lookAt(position, + new HeadingPitchRange(Math.toRadians(45), Math.toRadians(-15), model.boundingSphere().radius * 5))); + } +} diff --git a/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/box-instanced.gltf b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/box-instanced.gltf new file mode 100644 index 00000000..4b134f5c --- /dev/null +++ b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/box-instanced.gltf @@ -0,0 +1,289 @@ +{ + "asset": { + "version": "2.0" + }, + "extensionsUsed": [ + "EXT_mesh_features", + "EXT_mesh_gpu_instancing" + ], + "extensionsRequired": [ + "EXT_mesh_gpu_instancing" + ], + "extensions": { + "EXT_mesh_features": { + "schema": { + "classes": { + "box": { + "properties": { + "name": { + "componentType": "STRING" + }, + "volume": { + "componentType": "FLOAT32" + } + } + }, + "section": { + "properties": { + "name": { + "componentType": "STRING" + }, + "id": { + "componentType": "UINT16" + } + } + } + } + }, + "propertyTables": [ + { + "name": "Box", + "class": "box", + "count": 4, + "properties": { + "name": { + "stringOffsetType": "UINT16", + "bufferView": 7, + "stringOffsetBufferView": 8 + }, + "volume": { + "bufferView": 9 + } + } + }, + { + "name": "Section", + "class": "section", + "count": 2, + "properties": { + "name": { + "stringOffsetType": "UINT16", + "bufferView": 10, + "stringOffsetBufferView": 11 + }, + "id": { + "bufferView": 12 + } + } + } + ] + } + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0, + "extensions": { + "EXT_mesh_gpu_instancing": { + "attributes": { + "TRANSLATION": 3, + "ROTATION": 4, + "SCALE": 5, + "FEATURE_ID_0": 6 + } + }, + "EXT_mesh_features": { + "propertyTables": [ + 0, + 1 + ], + "featureIds": [ + { + "offset": 0, + "repeat": 1 + }, + { + "attribute": 0 + } + ] + } + } + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "POSITION": 0, + "NORMAL": 1 + }, + "indices": 2, + "mode": 4 + } + ] + } + ], + "accessors": [ + { + "name": "Positions", + "bufferView": 0, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "name": "Normals", + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "type": "VEC3" + }, + { + "name": "Indices", + "bufferView": 2, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "type": "SCALAR" + }, + { + "name": "Instance Translations", + "bufferView": 3, + "byteOffset": 0, + "componentType": 5126, + "count": 4, + "type": "VEC3" + }, + { + "name": "Instance Rotations", + "bufferView": 4, + "byteOffset": 0, + "componentType": 5126, + "count": 4, + "type": "VEC4" + }, + { + "name": "Instance Scales", + "bufferView": 5, + "byteOffset": 0, + "componentType": 5126, + "count": 4, + "type": "VEC3" + }, + { + "name": "Instance Feature IDs", + "bufferView": 6, + "byteOffset": 0, + "componentType": 5126, + "count": 4, + "type": "SCALAR" + } + ], + "bufferViews": [ + { + "name": "Positions", + "buffer": 0, + "byteLength": 288, + "byteOffset": 0 + }, + { + "name": "Normals", + "buffer": 0, + "byteLength": 288, + "byteOffset": 288 + }, + { + "name": "Indices", + "buffer": 0, + "byteLength": 72, + "byteOffset": 576 + }, + { + "name": "Instance Translations", + "buffer": 1, + "byteLength": 48, + "byteOffset": 0 + }, + { + "name": "Instance Rotations", + "buffer": 1, + "byteLength": 64, + "byteOffset": 48 + }, + { + "name": "Instance Scales", + "buffer": 1, + "byteLength": 48, + "byteOffset": 112 + }, + { + "name": "Instance Feature IDs", + "buffer": 1, + "byteLength": 16, + "byteOffset": 160 + }, + { + "name": "Box Names", + "buffer": 2, + "byteLength": 40, + "byteOffset": 0 + }, + { + "name": "Box Name Offsets", + "buffer": 2, + "byteLength": 10, + "byteOffset": 40 + }, + { + "name": "Box Volumes", + "buffer": 2, + "byteLength": 16, + "byteOffset": 56 + }, + { + "name": "Section Name", + "buffer": 2, + "byteLength": 9, + "byteOffset": 72 + }, + { + "name": "Section Name Offsets", + "buffer": 2, + "byteLength": 6, + "byteOffset": 88 + }, + { + "name": "Section IDs", + "buffer": 2, + "byteLength": 4, + "byteOffset": 96 + } + ], + "buffers": [ + { + "name": "Geometry Buffer", + "byteLength": 648, + "uri": "geometry.bin" + }, + { + "name": "Instances Buffer", + "byteLength": 176, + "uri": "instances.bin" + }, + { + "name": "Metadata Buffer", + "byteLength": 104, + "uri": "metadata.bin" + } + ] +} diff --git a/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/geometry.bin b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/geometry.bin new file mode 100644 index 0000000000000000000000000000000000000000..999f962cf186e3dd7d49fdd4d6f3afc19de1cb85 GIT binary patch literal 648 zcmZQzVAv1E_6!URAPnMzXk?5m24cf7NDVR@oez>j7lZLZG%`k43*v(?NDYVvVGtXH zL2M9)v5{$XHaZ`q4~AiKAU=!@qhVqU5YPY;hcFq4VuSR<)Z<|jWfrpCc+7%Y$IyVJ z1|&vHI~W<57#J9s7?>H@7+4ut7}y!u7+4rM7&sZY7&sWX7`Peu7r9(YA literal 0 HcmV?d00001 diff --git a/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/instances.bin b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/instances.bin new file mode 100644 index 0000000000000000000000000000000000000000..0f4b2a8dc8f62c66aec9ea7884fa7e90505430ac GIT binary patch literal 176 zcmZQzU^u|Qz~I0D0U$OAgLoh@WHyM;AoBjO9Y_*{y|J;eJp)4n5@xVxU~sTMd&UQ3 SHi!nROG`_$2iXI`5cL2ALn+1p literal 0 HcmV?d00001 diff --git a/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/metadata.bin b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/GltfLoader/BoxInstanced/glTF/metadata.bin new file mode 100644 index 0000000000000000000000000000000000000000..1dffc7779929e4cfcd4b849927021595eb2c6f55 GIT binary patch literal 104 zcmXTPFHp!yO)E*tFDc2-MP?Rdre~CZq`?dZ1`Y;c26+Yz1_-d_x^Bn7z+gXX=1f~@ a{kwJ`GoT6~3K&=zI2jliOf|Z%fdl}MR~q5~ literal 0 HcmV?d00001 diff --git a/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/PBR/BoxUnlit/BoxUnlit.gltf b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/PBR/BoxUnlit/BoxUnlit.gltf new file mode 100644 index 00000000..f4bda300 --- /dev/null +++ b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/Specs/Data/Models/PBR/BoxUnlit/BoxUnlit.gltf @@ -0,0 +1,151 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "extensionsUsed": [ + "KHR_materials_unlit" + ], + "extensionsRequired": [ + "KHR_materials_unlit" + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.0, + 1.0, + 0.0, + 1.0 + ], + "metallicFactor": 1.0 + }, + "name": "Unlit Green", + "extensions": { + "KHR_materials_unlit": {} + } + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 576, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 648, + "uri": "data:application/octet-stream;base64,AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA" + } + ] +} diff --git a/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/Model Experimental 3D Models.jpg b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/Model Experimental 3D Models.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b67fab48ac11a3f85a334369ccb8d6f2bcdfd23c GIT binary patch literal 11306 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 literal 0 HcmV?d00001 diff --git a/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/ModelExperimental3DModels.txt b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/ModelExperimental3DModels.txt new file mode 100644 index 00000000..d8b0780d --- /dev/null +++ b/cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/ModelExperimental3DModels.txt @@ -0,0 +1,93 @@ +package org.cleanlogic.cesiumjs4gwt.showcase.examples; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.ui.AbsolutePanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.ListBox; +import org.cesiumjs.cs.core.*; +import org.cesiumjs.cs.core.HeadingPitchRoll; +import org.cesiumjs.cs.scene.experimental.ModelExperimental; +import org.cesiumjs.cs.scene.experimental.options.ModelExperimentalFromGltfOptions; +import org.cesiumjs.cs.widgets.Viewer; +import org.cesiumjs.cs.widgets.ViewerPanel; +import org.cleanlogic.cesiumjs4gwt.showcase.basic.AbstractExample; +import org.cleanlogic.cesiumjs4gwt.showcase.components.store.ShowcaseExampleStore; + +import javax.inject.Inject; +import java.lang.Math; + +public class ModelExperimental3DModels extends AbstractExample { + private Viewer viewer; + + private final HeadingPitchRoll hpr = new HeadingPitchRoll(Math.toRadians(180), 0, 0); + private final Transforms.LocalFrameToFixedFrame fixedFrameTransform = Transforms.localFrameToFixedFrameGenerator("north", "west"); + + @Inject + public ModelExperimental3DModels(ShowcaseExampleStore store) { + super("Model Experimental 3D Models", + "Load glTF models using Model Experimental", + new String[]{"Showcase", "Cesium", "3d", "Viewer", "experimental"}, store, "1.87.1"); + } + + @Override + public void buildPanel() { + ViewerPanel csVPanel = new ViewerPanel(); + viewer = csVPanel.getViewer(); + + csVPanel.getViewer().clock().currentTime = JulianDate.fromIso8601("2021-11-09T20:27:37.016064475348684937Z"); + + ListBox listBox = new ListBox(); + listBox.addItem("Cesium Balloon"); + listBox.addItem("Skinned Character"); + listBox.addItem("Draco Compressed Model"); + listBox.addItem("Unlit Box"); + listBox.addItem("Drone"); + listBox.addItem("Ground Vehicle"); + listBox.addItem("Instanced Box"); + listBox.addChangeHandler(event -> { + String value = ((ListBox) event.getSource()).getSelectedItemText(); + String prefix = GWT.getModuleBaseURL(); + switch (value) { + case "Cesium Balloon": selectModel(prefix + "SampleData/models/CesiumBalloon/CesiumBalloon.glb", 15); break; + case "Skinned Character": selectModel(prefix + "SampleData/models/CesiumMan/Cesium_Man.glb", 0); break; + case "Draco Compressed Model": selectModel(prefix + "SampleData/models/DracoCompressed/CesiumMilkTruck.gltf", 0); break; + case "Unlit Box": selectModel(prefix + "Specs/Data/Models/PBR/BoxUnlit/BoxUnlit.gltf", 0); break; + case "Drone": selectModel(prefix + "SampleData/models/CesiumDrone/CesiumDrone.glb", 15); break; + case "Ground Vehicle": selectModel(prefix + "SampleData/models/GroundVehicle/GroundVehicle.glb", 0); break; + case "Instanced Box": selectModel(prefix + "Specs/Data/Models/GltfLoader/BoxInstanced/glTF/box-instanced.gltf", 15); break; + default: break; + } + }); + + AbsolutePanel aPanel = new AbsolutePanel(); + aPanel.add(csVPanel); + aPanel.add(listBox, 20, 20); + + contentPanel.add(new HTML( + "

Load glTF models using Model Experimental.

")); + contentPanel.add(aPanel); + + initWidget(contentPanel); + + selectModel(GWT.getModuleBaseURL() + "SampleData/models/CesiumBalloon/CesiumBalloon.glb", 15); + } + + @Override + public String[] getSourceCodeURLs() { + String[] sourceCodeURLs = new String[1]; + sourceCodeURLs[0] = GWT.getModuleBaseURL() + "examples/" + "ModelExperimental3DModels.txt"; + return sourceCodeURLs; + } + + private void selectModel(String url, double height) { + Cartesian3 position = Cartesian3.fromDegrees(-123.0744619, 44.0503706, height); + + viewer.scene().primitives().removeAll(); + ModelExperimentalFromGltfOptions options = ModelExperimentalFromGltfOptions.create(url); + options.modelMatrix = Transforms.headingPitchRollToFixedFrame(position, hpr, Ellipsoid.WGS84(), fixedFrameTransform); + ModelExperimental model = (ModelExperimental) viewer.scene().primitives().add(ModelExperimental.fromGltf(options)); + + model.readyPromise().then(nModel -> viewer.camera.lookAt(position, + new HeadingPitchRange(Math.toRadians(45), Math.toRadians(-15), model.boundingSphere().radius * 5))); + } +} -- GitLab