Loading cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/config/InjectorModule.java +1 −0 Original line number Diff line number Diff line Loading @@ -121,5 +121,6 @@ public class InjectorModule extends AbstractGinModule { bind(CustomShaders3DTiles.class).asEagerSingleton(); bind(CustomShadersModels.class).asEagerSingleton(); bind(Tiles3DNextCDBYemen.class).asEagerSingleton(); bind(Tiles3DNextS2Globe.class).asEagerSingleton(); } } cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/examples/Tiles3DNextS2Globe.java 0 → 100644 +228 −0 Original line number Diff line number Diff line /* * 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.dom.client.DivElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.ui.*; import org.cesiumjs.cs.Cesium; import org.cesiumjs.cs.core.*; import org.cesiumjs.cs.core.enums.ScreenSpaceEventType; import org.cesiumjs.cs.core.events.MouseMoveEvent; import org.cesiumjs.cs.js.JsObject; import org.cesiumjs.cs.scene.Cesium3DTileFeature; import org.cesiumjs.cs.scene.Cesium3DTileStyle; import org.cesiumjs.cs.scene.Cesium3DTileset; import org.cesiumjs.cs.scene.Scene; import org.cesiumjs.cs.scene.experimental.CustomShader; import org.cesiumjs.cs.scene.experimental.enums.UniformType; import org.cesiumjs.cs.scene.experimental.options.CustomShaderOptions; import org.cesiumjs.cs.scene.options.CameraFlyToOptions; import org.cesiumjs.cs.widgets.Viewer; import org.cesiumjs.cs.widgets.ViewerPanel; import org.cesiumjs.cs.widgets.options.ViewerOptions; import org.cleanlogic.cesiumjs4gwt.showcase.basic.AbstractExample; import org.cleanlogic.cesiumjs4gwt.showcase.components.store.ShowcaseExampleStore; import javax.inject.Inject; public class Tiles3DNextS2Globe extends AbstractExample { private Viewer viewer; private boolean enablePicking = true; @Inject public Tiles3DNextS2Globe(ShowcaseExampleStore store) { super("3D Tiles Next S2 Globe", "Load a global scale 3D Tiles Next tileset that uses 3DTILES_bounding_volume_S2", new String[]{"Showcase", "Cesium", "3d", "Viewer"}, store, "1.87.1"); } @Override public void buildPanel() { // One World Terrain Base Globe provided by Maxar Cesium.ExperimentalFeatures.enableModelExperimental = true; ViewerOptions options = new ViewerOptions(); options.enableGlobe = false; ViewerPanel csVPanel = new ViewerPanel(options); viewer = csVPanel.getViewer(); Scene scene = csVPanel.getViewer().scene(); viewer.camera.flyTo(new CameraFlyToOptions() .setDuration(0) .setDestination(new Cartesian3(762079.3157173397, -28363749.882652905, 19814354.842565004)) .setOrientation(new Cartesian3(-0.022007098944236157, 0.819079900508189, -0.5732571885110), new Cartesian3(-0.015396759850986286, 0.5730503851893346, 0.8193754913471885)) .setEasingFunction(EasingFunction.QUADRATIC_IN_OUT())); // MAXAR OWT WFF 1.2 Base Globe Cesium3DTileset tileset = (Cesium3DTileset) scene.primitives().add(Cesium3DTileset.create(IonResource.fromAssetId(666330))); tileset.maximumScreenSpaceError = 4; // --- Style --- JsObject jsStyle = JsObject.create(); jsStyle.setProperty("defines", JsObject.create()); jsStyle.getJsObject("defines").setProperty("LandCoverColor", "rgb(${color}[0], ${color}[1], ${color}[2])"); jsStyle.setProperty("color", "${LandCoverColor} === vec4(1.0) ? rgb(254, 254, 254) : ${LandCoverColor}"); Cesium3DTileStyle style = new Cesium3DTileStyle(jsStyle); Cesium.log(style); // --- Custom Shader --- CustomShader customShader = new CustomShader(new CustomShaderOptions() .addUniform("u_time", UniformType.FLOAT(), 0) .setFragmentShaderText(String.join("\n", new String[] { "void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)", "{", " // NOTE: this is exposing internal details of the shader.", " float featureId = floor(texture2D(FEATURE_ID_TEXTURE, FEATURE_ID_TEXCOORD).FEATURE_ID_CHANNEL * 255.0 + 0.5);", " // Use cartesian coordinates but scale to be roughly [-1, 1]", " vec3 positionWC = fsInput.attributes.positionWC / 6.3e6;", " if (featureId == 60.0)", " {", " // Something like FM synthesis to make irregularly spaced waves", " float wave = sin(14.0 * positionWC.z - u_time);", " wave = 0.5 + 0.5 * sin(10.0 * wave * positionWC.z - u_time);", " // mix in an over-saturated version of the diffuse to make shimmering bands of color", " material.diffuse = mix(material.diffuse, material.diffuse * 3.0, wave);", " }", "}", }))); final double startTime = performanceNow(); scene.postUpdate().addEventListener((Event.Listener) o -> customShaderUpdate(customShader, startTime)); // --- Picking --- ScreenSpaceEventHandler handler = new ScreenSpaceEventHandler(scene.canvas()); DivElement metadataOverlay = RootPanel.get().getElement().getOwnerDocument().createDivElement(); metadataOverlay.addClassName("backdrop"); metadataOverlay.getStyle().setDisplay(Style.Display.NONE); metadataOverlay.getStyle().setPosition(Style.Position.ABSOLUTE); metadataOverlay.getStyle().setBottom(0., Style.Unit.PX); metadataOverlay.getStyle().setLeft(0., Style.Unit.PX); // metadataOverlay.style["pointer-events"] = "none"; metadataOverlay.getStyle().setPadding(4.0, Style.Unit.PX); metadataOverlay.getStyle().setBackgroundColor("#303030"); metadataOverlay.getStyle().setWhiteSpace(Style.WhiteSpace.PRE_LINE); metadataOverlay.getStyle().setFontSize(16., Style.Unit.PX); csVPanel.getViewer().container().appendChild(metadataOverlay); handler.setInputAction(event -> { MouseMoveEvent movement = (MouseMoveEvent) event; if (enablePicking) { PickedObject feature = scene.pick(movement.endPosition); if (feature instanceof Cesium3DTileFeature) { metadataOverlay.getStyle().setDisplay(Style.Display.BLOCK); metadataOverlay.getStyle().setBottom(viewer.canvas().getClientHeight() - movement.endPosition.y, Style.Unit.PX); metadataOverlay.getStyle().setLeft(movement.endPosition.x, Style.Unit.PX); StringBuilder tableHtmlScratch = new StringBuilder("<table><thead><tr><th><tt>Property</tt></th><th><tt>Value</tt></th></tr></thead><tbody>"); String[] propertyNames = ((Cesium3DTileFeature) feature).getPropertyNames(); int length = propertyNames.length; for (String propertyName : propertyNames) { JsObject propertyValue = ((Cesium3DTileFeature) feature).getProperty(propertyName); tableHtmlScratch.append("<tr><td><tt>").append(propertyName).append("</tt></td><td><tt>").append(propertyValue).append("</tt></td></tr>"); } tableHtmlScratch.append("</tbody></table>"); metadataOverlay.setInnerHTML(tableHtmlScratch.toString()); } else { metadataOverlay.getStyle().setDisplay(Style.Display.NONE); } } }, ScreenSpaceEventType.MOUSE_MOVE()); ListBox listBox = new ListBox(); listBox.addItem("Globe View"); listBox.addItem("Show S2 Bounding Volumes"); listBox.addItem("Apply Style"); listBox.addItem("Apply Custom Shader"); listBox.addChangeHandler(event -> { String value = ((ListBox) event.getSource()).getSelectedItemText(); switch (value) { case "Globe View": { tileset.customShader = null; tileset.debugShowBoundingVolume = false; tileset.style = null; break; } case "Show S2 Bounding Volumes": { tileset.customShader = null; tileset.debugShowBoundingVolume = true; tileset.style = null; break; } case "Apply Style": { tileset.customShader = null; tileset.debugShowBoundingVolume = false; tileset.style = style; break; } case "Apply Custom Shader": { tileset.customShader = customShader; tileset.debugShowBoundingVolume = false; tileset.style = null; break; } default: break; } }); CheckBox enablePickingCBox = new CheckBox("Enable picking"); enablePickingCBox.getElement().getStyle().setColor("white"); enablePickingCBox.setWidth("100px"); enablePickingCBox.setValue(this.enablePicking); enablePickingCBox.addValueChangeHandler(event -> { metadataOverlay.getStyle().setDisplay(Style.Display.NONE); enablePicking = event.getValue(); }); HorizontalPanel hPanel = new HorizontalPanel(); hPanel.add(listBox); hPanel.add(enablePickingCBox); AbsolutePanel aPanel = new AbsolutePanel(); aPanel.add(csVPanel); aPanel.add(hPanel, 20, 20); contentPanel.add(new HTML( "<p>Load a global scale 3D Tiles Next tileset that uses 3DTILES_bounding_volume_S2..</p>")); contentPanel.add(aPanel); initWidget(contentPanel); } @Override public String[] getSourceCodeURLs() { String[] sourceCodeURLs = new String[1]; sourceCodeURLs[0] = GWT.getModuleBaseURL() + "examples/" + "Tiles3DNextS2Globe.txt"; return sourceCodeURLs; } private native double performanceNow() /*-{ return performance.now(); }-*/; private void customShaderUpdate(CustomShader customShader, double startTime) { double elapsedTimeSeconds = (performanceNow() - startTime) / 1000.; customShader.setUniform("u_time", elapsedTimeSeconds); } } cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/3D Tiles Next S2 Globe.jpg 0 → 100644 +10.6 KiB Loading image diff... cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/Tiles3DNextCDBYemen.txt +367 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/Tiles3DNextS2Globe.txt 0 → 100644 +212 −0 Original line number Diff line number Diff line package org.cleanlogic.cesiumjs4gwt.showcase.examples; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.ui.*; import org.cesiumjs.cs.Cesium; import org.cesiumjs.cs.core.*; import org.cesiumjs.cs.core.enums.ScreenSpaceEventType; import org.cesiumjs.cs.core.events.MouseMoveEvent; import org.cesiumjs.cs.js.JsObject; import org.cesiumjs.cs.scene.Cesium3DTileFeature; import org.cesiumjs.cs.scene.Cesium3DTileStyle; import org.cesiumjs.cs.scene.Cesium3DTileset; import org.cesiumjs.cs.scene.Scene; import org.cesiumjs.cs.scene.experimental.CustomShader; import org.cesiumjs.cs.scene.experimental.enums.UniformType; import org.cesiumjs.cs.scene.experimental.options.CustomShaderOptions; import org.cesiumjs.cs.scene.options.CameraFlyToOptions; import org.cesiumjs.cs.widgets.Viewer; import org.cesiumjs.cs.widgets.ViewerPanel; import org.cesiumjs.cs.widgets.options.ViewerOptions; import org.cleanlogic.cesiumjs4gwt.showcase.basic.AbstractExample; import org.cleanlogic.cesiumjs4gwt.showcase.components.store.ShowcaseExampleStore; import javax.inject.Inject; public class Tiles3DNextS2Globe extends AbstractExample { private Viewer viewer; private boolean enablePicking = true; @Inject public Tiles3DNextS2Globe(ShowcaseExampleStore store) { super("3D Tiles Next S2 Globe", "Load a global scale 3D Tiles Next tileset that uses 3DTILES_bounding_volume_S2", new String[]{"Showcase", "Cesium", "3d", "Viewer"}, store, "1.87.1"); } @Override public void buildPanel() { // One World Terrain Base Globe provided by Maxar Cesium.ExperimentalFeatures.enableModelExperimental = true; ViewerOptions options = new ViewerOptions(); options.enableGlobe = false; ViewerPanel csVPanel = new ViewerPanel(options); viewer = csVPanel.getViewer(); Scene scene = csVPanel.getViewer().scene(); viewer.camera.flyTo(new CameraFlyToOptions() .setDuration(0) .setDestination(new Cartesian3(762079.3157173397, -28363749.882652905, 19814354.842565004)) .setOrientation(new Cartesian3(-0.022007098944236157, 0.819079900508189, -0.5732571885110), new Cartesian3(-0.015396759850986286, 0.5730503851893346, 0.8193754913471885)) .setEasingFunction(EasingFunction.QUADRATIC_IN_OUT())); // MAXAR OWT WFF 1.2 Base Globe Cesium3DTileset tileset = (Cesium3DTileset) scene.primitives().add(Cesium3DTileset.create(IonResource.fromAssetId(666330))); tileset.maximumScreenSpaceError = 4; // --- Style --- JsObject jsStyle = JsObject.create(); jsStyle.setProperty("defines", JsObject.create()); jsStyle.getJsObject("defines").setProperty("LandCoverColor", "rgb(${color}[0], ${color}[1], ${color}[2])"); jsStyle.setProperty("color", "${LandCoverColor} === vec4(1.0) ? rgb(254, 254, 254) : ${LandCoverColor}"); Cesium3DTileStyle style = new Cesium3DTileStyle(jsStyle); Cesium.log(style); // --- Custom Shader --- CustomShader customShader = new CustomShader(new CustomShaderOptions() .addUniform("u_time", UniformType.FLOAT(), 0) .setFragmentShaderText(String.join("\n", new String[] { "void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)", "{", " // NOTE: this is exposing internal details of the shader.", " float featureId = floor(texture2D(FEATURE_ID_TEXTURE, FEATURE_ID_TEXCOORD).FEATURE_ID_CHANNEL * 255.0 + 0.5);", " // Use cartesian coordinates but scale to be roughly [-1, 1]", " vec3 positionWC = fsInput.attributes.positionWC / 6.3e6;", " if (featureId == 60.0)", " {", " // Something like FM synthesis to make irregularly spaced waves", " float wave = sin(14.0 * positionWC.z - u_time);", " wave = 0.5 + 0.5 * sin(10.0 * wave * positionWC.z - u_time);", " // mix in an over-saturated version of the diffuse to make shimmering bands of color", " material.diffuse = mix(material.diffuse, material.diffuse * 3.0, wave);", " }", "}", }))); final double startTime = performanceNow(); scene.postUpdate().addEventListener((Event.Listener) o -> customShaderUpdate(customShader, startTime)); // --- Picking --- ScreenSpaceEventHandler handler = new ScreenSpaceEventHandler(scene.canvas()); DivElement metadataOverlay = RootPanel.get().getElement().getOwnerDocument().createDivElement(); metadataOverlay.addClassName("backdrop"); metadataOverlay.getStyle().setDisplay(Style.Display.NONE); metadataOverlay.getStyle().setPosition(Style.Position.ABSOLUTE); metadataOverlay.getStyle().setBottom(0., Style.Unit.PX); metadataOverlay.getStyle().setLeft(0., Style.Unit.PX); // metadataOverlay.style["pointer-events"] = "none"; metadataOverlay.getStyle().setPadding(4.0, Style.Unit.PX); metadataOverlay.getStyle().setBackgroundColor("#303030"); metadataOverlay.getStyle().setWhiteSpace(Style.WhiteSpace.PRE_LINE); metadataOverlay.getStyle().setFontSize(16., Style.Unit.PX); csVPanel.getViewer().container().appendChild(metadataOverlay); handler.setInputAction(event -> { MouseMoveEvent movement = (MouseMoveEvent) event; if (enablePicking) { PickedObject feature = scene.pick(movement.endPosition); if (feature instanceof Cesium3DTileFeature) { metadataOverlay.getStyle().setDisplay(Style.Display.BLOCK); metadataOverlay.getStyle().setBottom(viewer.canvas().getClientHeight() - movement.endPosition.y, Style.Unit.PX); metadataOverlay.getStyle().setLeft(movement.endPosition.x, Style.Unit.PX); StringBuilder tableHtmlScratch = new StringBuilder("<table><thead><tr><th><tt>Property</tt></th><th><tt>Value</tt></th></tr></thead><tbody>"); String[] propertyNames = ((Cesium3DTileFeature) feature).getPropertyNames(); int length = propertyNames.length; for (String propertyName : propertyNames) { JsObject propertyValue = ((Cesium3DTileFeature) feature).getProperty(propertyName); tableHtmlScratch.append("<tr><td><tt>").append(propertyName).append("</tt></td><td><tt>").append(propertyValue).append("</tt></td></tr>"); } tableHtmlScratch.append("</tbody></table>"); metadataOverlay.setInnerHTML(tableHtmlScratch.toString()); } else { metadataOverlay.getStyle().setDisplay(Style.Display.NONE); } } }, ScreenSpaceEventType.MOUSE_MOVE()); ListBox listBox = new ListBox(); listBox.addItem("Globe View"); listBox.addItem("Show S2 Bounding Volumes"); listBox.addItem("Apply Style"); listBox.addItem("Apply Custom Shader"); listBox.addChangeHandler(event -> { String value = ((ListBox) event.getSource()).getSelectedItemText(); switch (value) { case "Globe View": { tileset.customShader = null; tileset.debugShowBoundingVolume = false; tileset.style = null; break; } case "Show S2 Bounding Volumes": { tileset.customShader = null; tileset.debugShowBoundingVolume = true; tileset.style = null; break; } case "Apply Style": { tileset.customShader = null; tileset.debugShowBoundingVolume = false; tileset.style = style; break; } case "Apply Custom Shader": { tileset.customShader = customShader; tileset.debugShowBoundingVolume = false; tileset.style = null; break; } default: break; } }); CheckBox enablePickingCBox = new CheckBox("Enable picking"); enablePickingCBox.getElement().getStyle().setColor("white"); enablePickingCBox.setWidth("100px"); enablePickingCBox.setValue(this.enablePicking); enablePickingCBox.addValueChangeHandler(event -> { metadataOverlay.getStyle().setDisplay(Style.Display.NONE); enablePicking = event.getValue(); }); HorizontalPanel hPanel = new HorizontalPanel(); hPanel.add(listBox); hPanel.add(enablePickingCBox); AbsolutePanel aPanel = new AbsolutePanel(); aPanel.add(csVPanel); aPanel.add(hPanel, 20, 20); contentPanel.add(new HTML( "<p>Load a global scale 3D Tiles Next tileset that uses 3DTILES_bounding_volume_S2..</p>")); contentPanel.add(aPanel); initWidget(contentPanel); } @Override public String[] getSourceCodeURLs() { String[] sourceCodeURLs = new String[1]; sourceCodeURLs[0] = GWT.getModuleBaseURL() + "examples/" + "Tiles3DNextS2Globe.txt"; return sourceCodeURLs; } private native double performanceNow() /*-{ return performance.now(); }-*/; private void customShaderUpdate(CustomShader customShader, double startTime) { double elapsedTimeSeconds = (performanceNow() - startTime) / 1000.; customShader.setUniform("u_time", elapsedTimeSeconds); } } Loading
cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/config/InjectorModule.java +1 −0 Original line number Diff line number Diff line Loading @@ -121,5 +121,6 @@ public class InjectorModule extends AbstractGinModule { bind(CustomShaders3DTiles.class).asEagerSingleton(); bind(CustomShadersModels.class).asEagerSingleton(); bind(Tiles3DNextCDBYemen.class).asEagerSingleton(); bind(Tiles3DNextS2Globe.class).asEagerSingleton(); } }
cesiumjs4gwt-showcase/src/main/java/org/cleanlogic/cesiumjs4gwt/showcase/examples/Tiles3DNextS2Globe.java 0 → 100644 +228 −0 Original line number Diff line number Diff line /* * 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.dom.client.DivElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.ui.*; import org.cesiumjs.cs.Cesium; import org.cesiumjs.cs.core.*; import org.cesiumjs.cs.core.enums.ScreenSpaceEventType; import org.cesiumjs.cs.core.events.MouseMoveEvent; import org.cesiumjs.cs.js.JsObject; import org.cesiumjs.cs.scene.Cesium3DTileFeature; import org.cesiumjs.cs.scene.Cesium3DTileStyle; import org.cesiumjs.cs.scene.Cesium3DTileset; import org.cesiumjs.cs.scene.Scene; import org.cesiumjs.cs.scene.experimental.CustomShader; import org.cesiumjs.cs.scene.experimental.enums.UniformType; import org.cesiumjs.cs.scene.experimental.options.CustomShaderOptions; import org.cesiumjs.cs.scene.options.CameraFlyToOptions; import org.cesiumjs.cs.widgets.Viewer; import org.cesiumjs.cs.widgets.ViewerPanel; import org.cesiumjs.cs.widgets.options.ViewerOptions; import org.cleanlogic.cesiumjs4gwt.showcase.basic.AbstractExample; import org.cleanlogic.cesiumjs4gwt.showcase.components.store.ShowcaseExampleStore; import javax.inject.Inject; public class Tiles3DNextS2Globe extends AbstractExample { private Viewer viewer; private boolean enablePicking = true; @Inject public Tiles3DNextS2Globe(ShowcaseExampleStore store) { super("3D Tiles Next S2 Globe", "Load a global scale 3D Tiles Next tileset that uses 3DTILES_bounding_volume_S2", new String[]{"Showcase", "Cesium", "3d", "Viewer"}, store, "1.87.1"); } @Override public void buildPanel() { // One World Terrain Base Globe provided by Maxar Cesium.ExperimentalFeatures.enableModelExperimental = true; ViewerOptions options = new ViewerOptions(); options.enableGlobe = false; ViewerPanel csVPanel = new ViewerPanel(options); viewer = csVPanel.getViewer(); Scene scene = csVPanel.getViewer().scene(); viewer.camera.flyTo(new CameraFlyToOptions() .setDuration(0) .setDestination(new Cartesian3(762079.3157173397, -28363749.882652905, 19814354.842565004)) .setOrientation(new Cartesian3(-0.022007098944236157, 0.819079900508189, -0.5732571885110), new Cartesian3(-0.015396759850986286, 0.5730503851893346, 0.8193754913471885)) .setEasingFunction(EasingFunction.QUADRATIC_IN_OUT())); // MAXAR OWT WFF 1.2 Base Globe Cesium3DTileset tileset = (Cesium3DTileset) scene.primitives().add(Cesium3DTileset.create(IonResource.fromAssetId(666330))); tileset.maximumScreenSpaceError = 4; // --- Style --- JsObject jsStyle = JsObject.create(); jsStyle.setProperty("defines", JsObject.create()); jsStyle.getJsObject("defines").setProperty("LandCoverColor", "rgb(${color}[0], ${color}[1], ${color}[2])"); jsStyle.setProperty("color", "${LandCoverColor} === vec4(1.0) ? rgb(254, 254, 254) : ${LandCoverColor}"); Cesium3DTileStyle style = new Cesium3DTileStyle(jsStyle); Cesium.log(style); // --- Custom Shader --- CustomShader customShader = new CustomShader(new CustomShaderOptions() .addUniform("u_time", UniformType.FLOAT(), 0) .setFragmentShaderText(String.join("\n", new String[] { "void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)", "{", " // NOTE: this is exposing internal details of the shader.", " float featureId = floor(texture2D(FEATURE_ID_TEXTURE, FEATURE_ID_TEXCOORD).FEATURE_ID_CHANNEL * 255.0 + 0.5);", " // Use cartesian coordinates but scale to be roughly [-1, 1]", " vec3 positionWC = fsInput.attributes.positionWC / 6.3e6;", " if (featureId == 60.0)", " {", " // Something like FM synthesis to make irregularly spaced waves", " float wave = sin(14.0 * positionWC.z - u_time);", " wave = 0.5 + 0.5 * sin(10.0 * wave * positionWC.z - u_time);", " // mix in an over-saturated version of the diffuse to make shimmering bands of color", " material.diffuse = mix(material.diffuse, material.diffuse * 3.0, wave);", " }", "}", }))); final double startTime = performanceNow(); scene.postUpdate().addEventListener((Event.Listener) o -> customShaderUpdate(customShader, startTime)); // --- Picking --- ScreenSpaceEventHandler handler = new ScreenSpaceEventHandler(scene.canvas()); DivElement metadataOverlay = RootPanel.get().getElement().getOwnerDocument().createDivElement(); metadataOverlay.addClassName("backdrop"); metadataOverlay.getStyle().setDisplay(Style.Display.NONE); metadataOverlay.getStyle().setPosition(Style.Position.ABSOLUTE); metadataOverlay.getStyle().setBottom(0., Style.Unit.PX); metadataOverlay.getStyle().setLeft(0., Style.Unit.PX); // metadataOverlay.style["pointer-events"] = "none"; metadataOverlay.getStyle().setPadding(4.0, Style.Unit.PX); metadataOverlay.getStyle().setBackgroundColor("#303030"); metadataOverlay.getStyle().setWhiteSpace(Style.WhiteSpace.PRE_LINE); metadataOverlay.getStyle().setFontSize(16., Style.Unit.PX); csVPanel.getViewer().container().appendChild(metadataOverlay); handler.setInputAction(event -> { MouseMoveEvent movement = (MouseMoveEvent) event; if (enablePicking) { PickedObject feature = scene.pick(movement.endPosition); if (feature instanceof Cesium3DTileFeature) { metadataOverlay.getStyle().setDisplay(Style.Display.BLOCK); metadataOverlay.getStyle().setBottom(viewer.canvas().getClientHeight() - movement.endPosition.y, Style.Unit.PX); metadataOverlay.getStyle().setLeft(movement.endPosition.x, Style.Unit.PX); StringBuilder tableHtmlScratch = new StringBuilder("<table><thead><tr><th><tt>Property</tt></th><th><tt>Value</tt></th></tr></thead><tbody>"); String[] propertyNames = ((Cesium3DTileFeature) feature).getPropertyNames(); int length = propertyNames.length; for (String propertyName : propertyNames) { JsObject propertyValue = ((Cesium3DTileFeature) feature).getProperty(propertyName); tableHtmlScratch.append("<tr><td><tt>").append(propertyName).append("</tt></td><td><tt>").append(propertyValue).append("</tt></td></tr>"); } tableHtmlScratch.append("</tbody></table>"); metadataOverlay.setInnerHTML(tableHtmlScratch.toString()); } else { metadataOverlay.getStyle().setDisplay(Style.Display.NONE); } } }, ScreenSpaceEventType.MOUSE_MOVE()); ListBox listBox = new ListBox(); listBox.addItem("Globe View"); listBox.addItem("Show S2 Bounding Volumes"); listBox.addItem("Apply Style"); listBox.addItem("Apply Custom Shader"); listBox.addChangeHandler(event -> { String value = ((ListBox) event.getSource()).getSelectedItemText(); switch (value) { case "Globe View": { tileset.customShader = null; tileset.debugShowBoundingVolume = false; tileset.style = null; break; } case "Show S2 Bounding Volumes": { tileset.customShader = null; tileset.debugShowBoundingVolume = true; tileset.style = null; break; } case "Apply Style": { tileset.customShader = null; tileset.debugShowBoundingVolume = false; tileset.style = style; break; } case "Apply Custom Shader": { tileset.customShader = customShader; tileset.debugShowBoundingVolume = false; tileset.style = null; break; } default: break; } }); CheckBox enablePickingCBox = new CheckBox("Enable picking"); enablePickingCBox.getElement().getStyle().setColor("white"); enablePickingCBox.setWidth("100px"); enablePickingCBox.setValue(this.enablePicking); enablePickingCBox.addValueChangeHandler(event -> { metadataOverlay.getStyle().setDisplay(Style.Display.NONE); enablePicking = event.getValue(); }); HorizontalPanel hPanel = new HorizontalPanel(); hPanel.add(listBox); hPanel.add(enablePickingCBox); AbsolutePanel aPanel = new AbsolutePanel(); aPanel.add(csVPanel); aPanel.add(hPanel, 20, 20); contentPanel.add(new HTML( "<p>Load a global scale 3D Tiles Next tileset that uses 3DTILES_bounding_volume_S2..</p>")); contentPanel.add(aPanel); initWidget(contentPanel); } @Override public String[] getSourceCodeURLs() { String[] sourceCodeURLs = new String[1]; sourceCodeURLs[0] = GWT.getModuleBaseURL() + "examples/" + "Tiles3DNextS2Globe.txt"; return sourceCodeURLs; } private native double performanceNow() /*-{ return performance.now(); }-*/; private void customShaderUpdate(CustomShader customShader, double startTime) { double elapsedTimeSeconds = (performanceNow() - startTime) / 1000.; customShader.setUniform("u_time", elapsedTimeSeconds); } }
cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/3D Tiles Next S2 Globe.jpg 0 → 100644 +10.6 KiB Loading image diff...
cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/Tiles3DNextCDBYemen.txt +367 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes
cesiumjs4gwt-showcase/src/main/resources/org/cleanlogic/cesiumjs4gwt/public/examples/Tiles3DNextS2Globe.txt 0 → 100644 +212 −0 Original line number Diff line number Diff line package org.cleanlogic.cesiumjs4gwt.showcase.examples; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.ui.*; import org.cesiumjs.cs.Cesium; import org.cesiumjs.cs.core.*; import org.cesiumjs.cs.core.enums.ScreenSpaceEventType; import org.cesiumjs.cs.core.events.MouseMoveEvent; import org.cesiumjs.cs.js.JsObject; import org.cesiumjs.cs.scene.Cesium3DTileFeature; import org.cesiumjs.cs.scene.Cesium3DTileStyle; import org.cesiumjs.cs.scene.Cesium3DTileset; import org.cesiumjs.cs.scene.Scene; import org.cesiumjs.cs.scene.experimental.CustomShader; import org.cesiumjs.cs.scene.experimental.enums.UniformType; import org.cesiumjs.cs.scene.experimental.options.CustomShaderOptions; import org.cesiumjs.cs.scene.options.CameraFlyToOptions; import org.cesiumjs.cs.widgets.Viewer; import org.cesiumjs.cs.widgets.ViewerPanel; import org.cesiumjs.cs.widgets.options.ViewerOptions; import org.cleanlogic.cesiumjs4gwt.showcase.basic.AbstractExample; import org.cleanlogic.cesiumjs4gwt.showcase.components.store.ShowcaseExampleStore; import javax.inject.Inject; public class Tiles3DNextS2Globe extends AbstractExample { private Viewer viewer; private boolean enablePicking = true; @Inject public Tiles3DNextS2Globe(ShowcaseExampleStore store) { super("3D Tiles Next S2 Globe", "Load a global scale 3D Tiles Next tileset that uses 3DTILES_bounding_volume_S2", new String[]{"Showcase", "Cesium", "3d", "Viewer"}, store, "1.87.1"); } @Override public void buildPanel() { // One World Terrain Base Globe provided by Maxar Cesium.ExperimentalFeatures.enableModelExperimental = true; ViewerOptions options = new ViewerOptions(); options.enableGlobe = false; ViewerPanel csVPanel = new ViewerPanel(options); viewer = csVPanel.getViewer(); Scene scene = csVPanel.getViewer().scene(); viewer.camera.flyTo(new CameraFlyToOptions() .setDuration(0) .setDestination(new Cartesian3(762079.3157173397, -28363749.882652905, 19814354.842565004)) .setOrientation(new Cartesian3(-0.022007098944236157, 0.819079900508189, -0.5732571885110), new Cartesian3(-0.015396759850986286, 0.5730503851893346, 0.8193754913471885)) .setEasingFunction(EasingFunction.QUADRATIC_IN_OUT())); // MAXAR OWT WFF 1.2 Base Globe Cesium3DTileset tileset = (Cesium3DTileset) scene.primitives().add(Cesium3DTileset.create(IonResource.fromAssetId(666330))); tileset.maximumScreenSpaceError = 4; // --- Style --- JsObject jsStyle = JsObject.create(); jsStyle.setProperty("defines", JsObject.create()); jsStyle.getJsObject("defines").setProperty("LandCoverColor", "rgb(${color}[0], ${color}[1], ${color}[2])"); jsStyle.setProperty("color", "${LandCoverColor} === vec4(1.0) ? rgb(254, 254, 254) : ${LandCoverColor}"); Cesium3DTileStyle style = new Cesium3DTileStyle(jsStyle); Cesium.log(style); // --- Custom Shader --- CustomShader customShader = new CustomShader(new CustomShaderOptions() .addUniform("u_time", UniformType.FLOAT(), 0) .setFragmentShaderText(String.join("\n", new String[] { "void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)", "{", " // NOTE: this is exposing internal details of the shader.", " float featureId = floor(texture2D(FEATURE_ID_TEXTURE, FEATURE_ID_TEXCOORD).FEATURE_ID_CHANNEL * 255.0 + 0.5);", " // Use cartesian coordinates but scale to be roughly [-1, 1]", " vec3 positionWC = fsInput.attributes.positionWC / 6.3e6;", " if (featureId == 60.0)", " {", " // Something like FM synthesis to make irregularly spaced waves", " float wave = sin(14.0 * positionWC.z - u_time);", " wave = 0.5 + 0.5 * sin(10.0 * wave * positionWC.z - u_time);", " // mix in an over-saturated version of the diffuse to make shimmering bands of color", " material.diffuse = mix(material.diffuse, material.diffuse * 3.0, wave);", " }", "}", }))); final double startTime = performanceNow(); scene.postUpdate().addEventListener((Event.Listener) o -> customShaderUpdate(customShader, startTime)); // --- Picking --- ScreenSpaceEventHandler handler = new ScreenSpaceEventHandler(scene.canvas()); DivElement metadataOverlay = RootPanel.get().getElement().getOwnerDocument().createDivElement(); metadataOverlay.addClassName("backdrop"); metadataOverlay.getStyle().setDisplay(Style.Display.NONE); metadataOverlay.getStyle().setPosition(Style.Position.ABSOLUTE); metadataOverlay.getStyle().setBottom(0., Style.Unit.PX); metadataOverlay.getStyle().setLeft(0., Style.Unit.PX); // metadataOverlay.style["pointer-events"] = "none"; metadataOverlay.getStyle().setPadding(4.0, Style.Unit.PX); metadataOverlay.getStyle().setBackgroundColor("#303030"); metadataOverlay.getStyle().setWhiteSpace(Style.WhiteSpace.PRE_LINE); metadataOverlay.getStyle().setFontSize(16., Style.Unit.PX); csVPanel.getViewer().container().appendChild(metadataOverlay); handler.setInputAction(event -> { MouseMoveEvent movement = (MouseMoveEvent) event; if (enablePicking) { PickedObject feature = scene.pick(movement.endPosition); if (feature instanceof Cesium3DTileFeature) { metadataOverlay.getStyle().setDisplay(Style.Display.BLOCK); metadataOverlay.getStyle().setBottom(viewer.canvas().getClientHeight() - movement.endPosition.y, Style.Unit.PX); metadataOverlay.getStyle().setLeft(movement.endPosition.x, Style.Unit.PX); StringBuilder tableHtmlScratch = new StringBuilder("<table><thead><tr><th><tt>Property</tt></th><th><tt>Value</tt></th></tr></thead><tbody>"); String[] propertyNames = ((Cesium3DTileFeature) feature).getPropertyNames(); int length = propertyNames.length; for (String propertyName : propertyNames) { JsObject propertyValue = ((Cesium3DTileFeature) feature).getProperty(propertyName); tableHtmlScratch.append("<tr><td><tt>").append(propertyName).append("</tt></td><td><tt>").append(propertyValue).append("</tt></td></tr>"); } tableHtmlScratch.append("</tbody></table>"); metadataOverlay.setInnerHTML(tableHtmlScratch.toString()); } else { metadataOverlay.getStyle().setDisplay(Style.Display.NONE); } } }, ScreenSpaceEventType.MOUSE_MOVE()); ListBox listBox = new ListBox(); listBox.addItem("Globe View"); listBox.addItem("Show S2 Bounding Volumes"); listBox.addItem("Apply Style"); listBox.addItem("Apply Custom Shader"); listBox.addChangeHandler(event -> { String value = ((ListBox) event.getSource()).getSelectedItemText(); switch (value) { case "Globe View": { tileset.customShader = null; tileset.debugShowBoundingVolume = false; tileset.style = null; break; } case "Show S2 Bounding Volumes": { tileset.customShader = null; tileset.debugShowBoundingVolume = true; tileset.style = null; break; } case "Apply Style": { tileset.customShader = null; tileset.debugShowBoundingVolume = false; tileset.style = style; break; } case "Apply Custom Shader": { tileset.customShader = customShader; tileset.debugShowBoundingVolume = false; tileset.style = null; break; } default: break; } }); CheckBox enablePickingCBox = new CheckBox("Enable picking"); enablePickingCBox.getElement().getStyle().setColor("white"); enablePickingCBox.setWidth("100px"); enablePickingCBox.setValue(this.enablePicking); enablePickingCBox.addValueChangeHandler(event -> { metadataOverlay.getStyle().setDisplay(Style.Display.NONE); enablePicking = event.getValue(); }); HorizontalPanel hPanel = new HorizontalPanel(); hPanel.add(listBox); hPanel.add(enablePickingCBox); AbsolutePanel aPanel = new AbsolutePanel(); aPanel.add(csVPanel); aPanel.add(hPanel, 20, 20); contentPanel.add(new HTML( "<p>Load a global scale 3D Tiles Next tileset that uses 3DTILES_bounding_volume_S2..</p>")); contentPanel.add(aPanel); initWidget(contentPanel); } @Override public String[] getSourceCodeURLs() { String[] sourceCodeURLs = new String[1]; sourceCodeURLs[0] = GWT.getModuleBaseURL() + "examples/" + "Tiles3DNextS2Globe.txt"; return sourceCodeURLs; } private native double performanceNow() /*-{ return performance.now(); }-*/; private void customShaderUpdate(CustomShader customShader, double startTime) { double elapsedTimeSeconds = (performanceNow() - startTime) / 1000.; customShader.setUniform("u_time", elapsedTimeSeconds); } }