Java tutorial
/* * Copyright 2017 iserge. * * 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.canvas.dom.client.Context2d; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.CanvasElement; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.RootPanel; import org.cesiumjs.cs.Cesium; import org.cesiumjs.cs.core.*; import org.cesiumjs.cs.core.Math; import org.cesiumjs.cs.core.options.ColorRandomOptions; import org.cesiumjs.cs.scene.Scene; import org.cesiumjs.cs.scene.emitters.SphereEmitter; import org.cesiumjs.cs.scene.particle.Particle; import org.cesiumjs.cs.scene.particle.ParticleBurst; import org.cesiumjs.cs.scene.particle.ParticleSystem; import org.cesiumjs.cs.scene.particle.options.ParticleBurstOptions; import org.cesiumjs.cs.scene.particle.options.ParticleSystemOptions; 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; import java.util.ArrayList; import java.util.List; /** * @author Serge Silaev aka iSergio <s.serge.b@gmail.com> */ public class ParticleSystemFireworks extends AbstractExample { private Matrix4 emitterModelMatrixScratch = new Matrix4(); private Cartesian3 emitterInitialLocation = new Cartesian3(0.0, 0.0, 100.0); private Matrix4 modelMatrix = Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(-75.59777, 40.03883)); private CanvasElement particleCanvas; private double minimumExplosionSize = 30.0; private double maximumExplosionSize = 100.0; private Cartesian2 particlePixelSize = new Cartesian2(7.0, 7.0); private double burstSize = 400.0; private double lifetime = 10.0; private double numberOfFireworks = 20.0; private double xMin = -100.0; private double xMax = 100.0; private double yMin = -80.0; private double yMax = 100.0; private double zMin = -50.0; private double zMax = 50.0; @Inject public ParticleSystemFireworks(ShowcaseExampleStore store) { super("Particle System Fireworks", "Particle system fireworks.", new String[] { "Showcase", "Cesium", "3d", "Viewer", "Particle" }, store); } @Override public void buildPanel() { ViewerOptions viewerOptions = new ViewerOptions(); viewerOptions.shouldAnimate = true; ViewerPanel csVPanel = new ViewerPanel(viewerOptions); csVPanel.getViewer().scene().debugShowFramesPerSecond = true; Math.setRandomNumberSeed(315); ColorRandomOptions[] colorRandomOptions = new ColorRandomOptions[4]; for (int i = 0; i < 4; i++) { colorRandomOptions[i] = new ColorRandomOptions(); } colorRandomOptions[0].minimumRed = 0.75f; colorRandomOptions[0].green = 0.0f; colorRandomOptions[0].minimumBlue = 0.8f; colorRandomOptions[0].alpha = 1.0f; colorRandomOptions[1].red = 0.0f; colorRandomOptions[1].minimumGreen = 0.75f; colorRandomOptions[1].minimumBlue = 0.8f; colorRandomOptions[1].alpha = 1.0f; colorRandomOptions[2].red = 0.0f; colorRandomOptions[2].green = 0.0f; colorRandomOptions[2].minimumBlue = 0.8f; colorRandomOptions[2].alpha = 1.0f; colorRandomOptions[3].minimumRed = 0.75f; colorRandomOptions[3].minimumGreen = 0.75f; colorRandomOptions[3].blue = 0.0f; colorRandomOptions[3].alpha = 1.0f; for (int i = 0; i < numberOfFireworks; ++i) { double x = Math.randomBetween(xMin, xMax); double y = Math.randomBetween(yMin, yMax); double z = Math.randomBetween(zMin, zMax); Cartesian3 offset = new Cartesian3(x, y, z); Color color = Color.fromRandom(colorRandomOptions[i % colorRandomOptions.length]); List<ParticleBurst> bursts = new ArrayList<>(); for (int j = 0; j < 3; ++j) { ParticleBurstOptions particleBurstOptions = new ParticleBurstOptions(); particleBurstOptions.time = Math.nextRandomNumber() * lifetime; particleBurstOptions.minimum = burstSize; particleBurstOptions.maximum = burstSize; bursts.add(new ParticleBurst(particleBurstOptions)); } createFirework(csVPanel.getViewer().scene(), offset, color, bursts.toArray(new ParticleBurst[bursts.size()])); } org.cesiumjs.cs.scene.Camera camera = csVPanel.getViewer().scene().camera(); Cartesian3 cameraOffset = new Cartesian3(-300.0, 0.0, 0.0); camera.lookAtTransform(modelMatrix, cameraOffset); camera.lookAtTransform(Matrix4.IDENTITY()); Cartesian3 toFireworks = Cartesian3.subtract(emitterInitialLocation, cameraOffset, new Cartesian3()); Cartesian3.normalize(toFireworks, toFireworks); double angle = Math.PI_OVER_TWO() - java.lang.Math.acos(Cartesian3.dot(toFireworks, Cartesian3.UNIT_Z())); camera.lookUp(angle); contentPanel.add(new HTML("<p></p>")); contentPanel.add(csVPanel); initWidget(contentPanel); } private CanvasElement getImage() { if (!Cesium.defined(particleCanvas)) { particleCanvas = RootPanel.get().getElement().getOwnerDocument().createCanvasElement(); particleCanvas.setWidth(20); particleCanvas.setHeight(20); Context2d context2d = particleCanvas.getContext2d(); context2d.beginPath(); context2d.arc(8, 8, 8, 0, Math.TWO_PI(), true); context2d.closePath(); context2d.setFillStyle("rgb(255, 255, 255)"); context2d.fill(); Cesium.log(particleCanvas); } return particleCanvas; } private void createFirework(Scene scene, Cartesian3 offset, Color color, ParticleBurst[] bursts) { Cartesian3 position = Cartesian3.add(emitterInitialLocation, offset, new Cartesian3()); Matrix4 emitterModelMatrix = Matrix4.fromTranslation(position, emitterModelMatrixScratch); Matrix4 particleToWorld = Matrix4.multiply(modelMatrix, emitterModelMatrix, new Matrix4()); final Matrix4 worldToParticle = Matrix4.inverseTransformation(particleToWorld, particleToWorld); final double size = Math.randomBetween(minimumExplosionSize, maximumExplosionSize); final Cartesian3 particlePositionScratch = new Cartesian3(); ParticleSystem.UpdateCallback updateCallback = new ParticleSystem.UpdateCallback() { @Override public void function(Particle particle, double dt) { Cartesian3 position = Matrix4.multiplyByPoint(worldToParticle, particle.position, particlePositionScratch); if (Cartesian3.magnitudeSquared(position) >= size * size) { Cartesian3.clone(Cartesian3.ZERO(), particle.velocity); } } }; double normalSize = (size - minimumExplosionSize) / (maximumExplosionSize - minimumExplosionSize); double minLife = 0.3; double maxLife = 1.0; double life = normalSize * (maxLife - minLife) + minLife; ParticleSystemOptions particleSystemOptions = new ParticleSystemOptions(); particleSystemOptions.image = getImage(); particleSystemOptions.startColor = color; particleSystemOptions.endColor = color.withAlpha(0.0f); particleSystemOptions.particleLife = life; particleSystemOptions.speed = 100.0; particleSystemOptions.imageSize = particlePixelSize; particleSystemOptions.emissionRate = 0; particleSystemOptions.emitter = new SphereEmitter(0.1); particleSystemOptions.bursts = bursts; particleSystemOptions.lifetime = lifetime; particleSystemOptions.updateCallback = updateCallback; particleSystemOptions.modelMatrix = modelMatrix; particleSystemOptions.emitterModelMatrix = emitterModelMatrix; scene.primitives().add(new ParticleSystem(particleSystemOptions)); } @Override public String[] getSourceCodeURLs() { String[] sourceCodeURLs = new String[1]; sourceCodeURLs[0] = GWT.getModuleBaseURL() + "examples/" + "ParticleSysteFireworks.txt"; return sourceCodeURLs; } }