+package org.simantics.g3d.jme.test;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.part.ViewPart;\r
+import org.simantics.g3d.jme.system.SWTCanvas;\r
+import org.simantics.g3d.jme.system.SimpleSWTApplication;\r
+\r
+import com.jme3.audio.AudioNode;\r
+import com.jme3.audio.LowPassFilter;\r
+import com.jme3.effect.ParticleEmitter;\r
+import com.jme3.effect.ParticleMesh;\r
+import com.jme3.input.controls.ActionListener;\r
+import com.jme3.input.controls.KeyTrigger;\r
+import com.jme3.light.DirectionalLight;\r
+import com.jme3.light.PointLight;\r
+import com.jme3.material.Material;\r
+import com.jme3.material.RenderState.BlendMode;\r
+import com.jme3.math.ColorRGBA;\r
+import com.jme3.math.FastMath;\r
+import com.jme3.math.Quaternion;\r
+import com.jme3.math.Vector3f;\r
+import com.jme3.post.FilterPostProcessor;\r
+import com.jme3.post.filters.BloomFilter;\r
+import com.jme3.post.filters.DepthOfFieldFilter;\r
+import com.jme3.post.filters.LightScatteringFilter;\r
+import com.jme3.renderer.Camera;\r
+import com.jme3.renderer.queue.RenderQueue.Bucket;\r
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;\r
+import com.jme3.scene.Geometry;\r
+import com.jme3.scene.Node;\r
+import com.jme3.scene.Spatial;\r
+import com.jme3.scene.shape.Box;\r
+import com.jme3.scene.shape.Sphere;\r
+import com.jme3.terrain.geomipmap.TerrainQuad;\r
+import com.jme3.terrain.heightmap.AbstractHeightMap;\r
+import com.jme3.terrain.heightmap.ImageBasedHeightMap;\r
+import com.jme3.texture.Texture;\r
+import com.jme3.texture.Texture.WrapMode;\r
+import com.jme3.texture.Texture2D;\r
+import com.jme3.util.SkyFactory;\r
+import com.jme3.water.WaterFilter;\r
+\r
+public class JMETestViewPart extends ViewPart {\r
+ \r
+ \r
+ protected SWTCanvas canvas;\r
+ \r
+ \r
+ \r
+ @Override\r
+ public void createPartControl(Composite parent) {\r
+ \r
+ canvas = new SWTCanvas(parent);\r
+ \r
+ \r
+ parent.addDisposeListener(new DisposeListener() {\r
+ \r
+ @Override\r
+ public void widgetDisposed(DisposeEvent arg0) {\r
+ canvas.dispose();\r
+ }\r
+ });\r
+ \r
+ TestApp app = new TestApp(canvas);\r
+ //TestPostWater app = new TestPostWater(canvas);\r
+ //app.createCanvas();\r
+ app.start();\r
+ \r
+ \r
+ }\r
+ \r
+ \r
+ \r
+ \r
+ @Override\r
+ public void setFocus() {\r
+ canvas.setFocus();\r
+ \r
+ }\r
+\r
+ public class TestApp extends SimpleSWTApplication {\r
+ \r
+ public TestApp(SWTCanvas canvas) {\r
+ super(canvas);\r
+ \r
+ }\r
+\r
+ float angle;\r
+ PointLight pl;\r
+ Spatial lightMdl;\r
+ \r
+ @Override\r
+ public void simpleInitApp() {\r
+ viewPort.setBackgroundColor(ColorRGBA.DarkGray);\r
+\r
+ Spatial bumpy = (Spatial) assetManager.loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml");\r
+ rootNode.attachChild(bumpy);\r
+\r
+ lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f));\r
+ lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m"));\r
+ rootNode.attachChild(lightMdl);\r
+\r
+ // flourescent main light\r
+ pl = new PointLight();\r
+ pl.setColor(new ColorRGBA(0.88f, 0.92f, 0.95f, 1.0f));\r
+ rootNode.addLight(pl);\r
+\r
+ // sunset light\r
+ DirectionalLight dl = new DirectionalLight();\r
+ dl.setDirection(new Vector3f(-0.1f,-0.7f,1).normalizeLocal());\r
+ dl.setColor(new ColorRGBA(0.44f, 0.30f, 0.20f, 1.0f));\r
+ rootNode.addLight(dl);\r
+\r
+ // skylight\r
+ dl = new DirectionalLight();\r
+ dl.setDirection(new Vector3f(-0.6f,-1,-0.6f).normalizeLocal());\r
+ dl.setColor(new ColorRGBA(0.10f, 0.22f, 0.44f, 1.0f));\r
+ rootNode.addLight(dl);\r
+\r
+ // white ambient light\r
+ dl = new DirectionalLight();\r
+ dl.setDirection(new Vector3f(1, -0.5f,-0.1f).normalizeLocal());\r
+ dl.setColor(new ColorRGBA(0.50f, 0.40f, 0.50f, 1.0f));\r
+ rootNode.addLight(dl);\r
+ }\r
+\r
+ @Override\r
+ public void simpleUpdate(float tpf){\r
+ angle += tpf * 0.25f;\r
+ angle %= FastMath.TWO_PI;\r
+\r
+ pl.setPosition(new Vector3f(FastMath.cos(angle) * 6f, 3f, FastMath.sin(angle) * 6f));\r
+ lightMdl.setLocalTranslation(pl.getPosition());\r
+ }\r
+ }\r
+ \r
+ \r
+ public class TestPostWater extends SimpleSWTApplication {\r
+\r
+ public TestPostWater(SWTCanvas canvas) {\r
+ super(canvas);\r
+ }\r
+ \r
+ private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f);\r
+ private WaterFilter water;\r
+ TerrainQuad terrain;\r
+ Material matRock;\r
+ AudioNode waves;\r
+ LowPassFilter underWaterAudioFilter = new LowPassFilter(0.5f, 0.1f);\r
+ LowPassFilter underWaterReverbFilter = new LowPassFilter(0.5f, 0.1f);\r
+ LowPassFilter aboveWaterAudioFilter = new LowPassFilter(1, 1);\r
+\r
+\r
+\r
+ @Override\r
+ public void simpleInitApp() {\r
+\r
+ setDisplayFps(false);\r
+ setDisplayStatView(false);\r
+\r
+ Node mainScene = new Node("Main Scene");\r
+ rootNode.attachChild(mainScene);\r
+\r
+ createTerrain(mainScene);\r
+ DirectionalLight sun = new DirectionalLight();\r
+ sun.setDirection(lightDir);\r
+ sun.setColor(ColorRGBA.White.clone().multLocal(1.7f));\r
+ mainScene.addLight(sun);\r
+\r
+ DirectionalLight l = new DirectionalLight();\r
+ l.setDirection(Vector3f.UNIT_Y.mult(-1));\r
+ l.setColor(ColorRGBA.White.clone().multLocal(0.3f));\r
+// mainScene.addLight(l);\r
+\r
+ flyCam.setMoveSpeed(50);\r
+\r
+ //cam.setLocation(new Vector3f(-700, 100, 300));\r
+ //cam.setRotation(new Quaternion().fromAngleAxis(0.5f, Vector3f.UNIT_Z));\r
+ cam.setLocation(new Vector3f(-327.21957f, 61.6459f, 126.884346f));\r
+ cam.setRotation(new Quaternion(0.052168474f, 0.9443102f, -0.18395276f, 0.2678024f));\r
+\r
+ \r
+ cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0}));\r
+\r
+\r
+ Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);\r
+ sky.setLocalScale(350);\r
+ \r
+ mainScene.attachChild(sky);\r
+ cam.setFrustumFar(4000);\r
+ //cam.setFrustumNear(100);\r
+ \r
+ \r
+\r
+ //private FilterPostProcessor fpp;\r
+\r
+\r
+ water = new WaterFilter(rootNode, lightDir);\r
+\r
+ FilterPostProcessor fpp = new FilterPostProcessor(assetManager);\r
+ \r
+ fpp.addFilter(water);\r
+ BloomFilter bloom=new BloomFilter();\r
+ //bloom.getE\r
+ bloom.setExposurePower(55);\r
+ bloom.setBloomIntensity(1.0f);\r
+ fpp.addFilter(bloom);\r
+ LightScatteringFilter lsf = new LightScatteringFilter(lightDir.mult(-300));\r
+ lsf.setLightDensity(1.0f);\r
+ fpp.addFilter(lsf);\r
+ DepthOfFieldFilter dof=new DepthOfFieldFilter();\r
+ dof.setFocusDistance(0);\r
+ dof.setFocusRange(100); \r
+ fpp.addFilter(dof);\r
+// \r
+ \r
+ // fpp.addFilter(new TranslucentBucketFilter());\r
+ // \r
+ \r
+ // fpp.setNumSamples(4);\r
+\r
+\r
+ water.setWaveScale(0.003f);\r
+ water.setMaxAmplitude(2f);\r
+ water.setFoamExistence(new Vector3f(1f, 4, 0.5f));\r
+ water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));\r
+ //water.setNormalScale(0.5f);\r
+\r
+ //water.setRefractionConstant(0.25f);\r
+ water.setRefractionStrength(0.2f);\r
+ //water.setFoamHardness(0.6f);\r
+\r
+ water.setWaterHeight(initialWaterHeight);\r
+ uw=cam.getLocation().y<waterHeight; \r
+ \r
+ waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg", false);\r
+ waves.setLooping(true);\r
+ waves.setReverbEnabled(true);\r
+ if(uw){\r
+ waves.setDryFilter(new LowPassFilter(0.5f, 0.1f));\r
+ }else{\r
+ waves.setDryFilter(aboveWaterAudioFilter); \r
+ }\r
+ audioRenderer.playSource(waves);\r
+ // \r
+ viewPort.addProcessor(fpp);\r
+\r
+ inputManager.addListener(new ActionListener() {\r
+\r
+ public void onAction(String name, boolean isPressed, float tpf) {\r
+ if (isPressed) {\r
+ if (name.equals("foam1")) {\r
+ water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg"));\r
+ }\r
+ if (name.equals("foam2")) {\r
+ water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));\r
+ }\r
+ if (name.equals("foam3")) {\r
+ water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam3.jpg"));\r
+ }\r
+ }\r
+ }\r
+ }, "foam1", "foam2", "foam3");\r
+ inputManager.addMapping("foam1", new KeyTrigger(keyInput.KEY_1));\r
+ inputManager.addMapping("foam2", new KeyTrigger(keyInput.KEY_2));\r
+ inputManager.addMapping("foam3", new KeyTrigger(keyInput.KEY_3));\r
+// createBox();\r
+ // createFire();\r
+ }\r
+ Geometry box;\r
+\r
+ private void createBox() {\r
+ //creating a transluscent box\r
+ box = new Geometry("box", new Box(new Vector3f(0, 0, 0), 50, 50, 50));\r
+ Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");\r
+ mat.setColor("Color", new ColorRGBA(1.0f, 0, 0, 0.3f));\r
+ mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);\r
+ //mat.getAdditionalRenderState().setDepthWrite(false);\r
+ //mat.getAdditionalRenderState().setDepthTest(false);\r
+ box.setMaterial(mat);\r
+ box.setQueueBucket(Bucket.Translucent);\r
+\r
+\r
+ //creating a post view port\r
+// ViewPort post=renderManager.createPostView("transpPost", cam);\r
+// post.setClearFlags(false, true, true);\r
+\r
+\r
+ box.setLocalTranslation(-600, 0, 300);\r
+\r
+ //attaching the box to the post viewport\r
+ //Don't forget to updateGeometricState() the box in the simpleUpdate\r
+ // post.attachScene(box);\r
+\r
+ rootNode.attachChild(box);\r
+ }\r
+\r
+ private void createFire() {\r
+ /** Uses Texture from jme3-test-data library! */\r
+ ParticleEmitter fire = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);\r
+ Material mat_red = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");\r
+ mat_red.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));\r
+\r
+ fire.setMaterial(mat_red);\r
+ fire.setImagesX(2);\r
+ fire.setImagesY(2); // 2x2 texture animation\r
+ fire.setEndColor(new ColorRGBA(1f, 0f, 0f, 1f)); // red\r
+ fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow\r
+ fire.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 2, 0));\r
+ fire.setStartSize(10f);\r
+ fire.setEndSize(1f);\r
+ fire.setGravity(0, 0, 0);\r
+ fire.setLowLife(0.5f);\r
+ fire.setHighLife(1.5f);\r
+ fire.getParticleInfluencer().setVelocityVariation(0.3f);\r
+ fire.setLocalTranslation(-350, 40, 430);\r
+\r
+ fire.setQueueBucket(Bucket.Transparent);\r
+ rootNode.attachChild(fire);\r
+ }\r
+\r
+ private void createTerrain(Node rootNode) {\r
+ matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");\r
+ matRock.setBoolean("useTriPlanarMapping", false);\r
+ matRock.setBoolean("WardIso", true);\r
+ matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));\r
+ Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");\r
+ Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");\r
+ grass.setWrap(WrapMode.Repeat);\r
+ matRock.setTexture("DiffuseMap", grass);\r
+ matRock.setFloat("DiffuseMap_0_scale", 64);\r
+ Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");\r
+ dirt.setWrap(WrapMode.Repeat);\r
+ matRock.setTexture("DiffuseMap_1", dirt);\r
+ matRock.setFloat("DiffuseMap_1_scale", 16);\r
+ Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");\r
+ rock.setWrap(WrapMode.Repeat);\r
+ matRock.setTexture("DiffuseMap_2", rock);\r
+ matRock.setFloat("DiffuseMap_2_scale", 128);\r
+ Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg");\r
+ normalMap0.setWrap(WrapMode.Repeat);\r
+ Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png");\r
+ normalMap1.setWrap(WrapMode.Repeat);\r
+ Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png");\r
+ normalMap2.setWrap(WrapMode.Repeat);\r
+ matRock.setTexture("NormalMap", normalMap0);\r
+ matRock.setTexture("NormalMap_1", normalMap2);\r
+ matRock.setTexture("NormalMap_2", normalMap2);\r
+\r
+ AbstractHeightMap heightmap = null;\r
+ try {\r
+ heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f);\r
+ heightmap.load();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());\r
+ List<Camera> cameras = new ArrayList<Camera>();\r
+ cameras.add(getCamera());\r
+ terrain.setMaterial(matRock);\r
+ terrain.setLocalScale(new Vector3f(5, 5, 5));\r
+ terrain.setLocalTranslation(new Vector3f(0, -30, 0));\r
+ terrain.setLocked(false); // unlock it so we can edit the height\r
+\r
+ terrain.setShadowMode(ShadowMode.Receive);\r
+ rootNode.attachChild(terrain);\r
+\r
+ }\r
+ //This part is to emulate tides, slightly varrying the height of the water plane\r
+ private float time = 0.0f;\r
+ private float waterHeight = 0.0f;\r
+ private float initialWaterHeight = 0.8f;\r
+ private boolean uw=false;\r
+ @Override\r
+ public void simpleUpdate(float tpf) {\r
+ super.simpleUpdate(tpf);\r
+ // box.updateGeometricState();\r
+ time += tpf;\r
+ waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f;\r
+ water.setWaterHeight(initialWaterHeight + waterHeight);\r
+ if(water.isUnderWater() && !uw){\r
+ \r
+ waves.setDryFilter(new LowPassFilter(0.5f, 0.1f));\r
+ uw=true;\r
+ }\r
+ if(!water.isUnderWater() && uw){\r
+ uw=false;\r
+ //waves.setReverbEnabled(false);\r
+ waves.setDryFilter(new LowPassFilter(1, 1f));\r
+ //waves.setDryFilter(new LowPassFilter(1,1f));\r
+ \r
+ } \r
+ }\r
+ }\r
+ \r
+ \r
+ \r
+}\r