2
0
Эх сурвалжийг харах

fixed TerrainGrid.getHeightmapHeight, fix thanks to @Makeshift

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8198 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
bre..ns 14 жил өмнө
parent
commit
a899fbc075

+ 18 - 6
engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java

@@ -67,6 +67,8 @@ public class TerrainGrid extends TerrainQuad {
     protected LRUCache<Vector3f, TerrainQuad> cache = new LRUCache<Vector3f, TerrainQuad>(16);
     protected RigidBodyControl[] quadControls;
     protected PhysicsSpace space;
+    private int cellsLoaded = 0;
+    private int[] gridOffset;
 
     protected class UpdateQuadCache implements Runnable {
 
@@ -142,14 +144,15 @@ public class TerrainGrid extends TerrainQuad {
         this.offset = offset;
         this.offsetAmount = offsetAmount;
         this.lodCalculatorFactory = lodCalculatorFactory;
+        this.gridOffset = new int[]{0,0};
         if (lodCalculatorFactory == null) {
             lodCalculatorFactory = new LodDistanceCalculatorFactory();
         }
         this.quadIndex = new Vector3f[]{
-            new Vector3f(-1, 0, 2), new Vector3f(0, 0, 2), new Vector3f(1, 0, 2), new Vector3f(2, 0, 2),
-            new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1),
-            new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 0, 0), new Vector3f(2, 0, 0),
-            new Vector3f(-1, 0, -1), new Vector3f(0, 0, -1), new Vector3f(1, 0, -1), new Vector3f(-2, 0, -1)};
+        new Vector3f(-1, 0, 2), new Vector3f(0, 0, 2), new Vector3f(1, 0, 2), new Vector3f(2, 0, 2),
+        new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1),
+        new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 0, 0), new Vector3f(2, 0, 0),
+        new Vector3f(-1, 0, -1), new Vector3f(0, 0, -1), new Vector3f(1, 0, -1), new Vector3f(-2, 0, -1)};
 
         addControl(new UpdateControl());
     }
@@ -189,13 +192,17 @@ public class TerrainGrid extends TerrainQuad {
         // 2: grids are associated with locations, and no incremental update is done, we load new grids for new locations, and unload those that are not needed anymore
         Vector3f cam = locations.get(0);
         Vector3f camCell = this.getCell(cam);
+        if(cellsLoaded>1){                  // Check if cells are updated before updating gridoffset.
+            gridOffset[0] = Math.round(camCell.x*(size/2));
+            gridOffset[1] = Math.round(camCell.z*(size/2));
+            cellsLoaded=0;
+        }
         if (camCell.x != this.currentCell.x || camCell.z != currentCell.z) {
             this.updateChildrens(camCell);
             for (TerrainGridListener l : this.listeners.values()) {
                 l.gridMoved(camCell);
             }
         }
-
         super.update(locations);
     }
 
@@ -213,8 +220,8 @@ public class TerrainGrid extends TerrainQuad {
                 l.tileDetached(getCell(this.getQuad(idx).getWorldTranslation()), this.getQuad(idx));
             }
             this.detachChild(this.getQuad(idx));
+            cellsLoaded++; // For gridoffset calc., maybe the run() method is a better location for this.
         }
-
     }
 
     /**
@@ -313,6 +320,11 @@ public class TerrainGrid extends TerrainQuad {
         }
         super.adjustHeight(xz, height);
     }
+    
+    @Override
+    protected float getHeightmapHeight(int x, int z) {
+        return super.getHeightmapHeight(x-gridOffset[0], z-gridOffset[1]);
+    }
 
     @Override
     protected TerrainQuad findDownQuad() {

+ 62 - 7
engine/src/test/jme3test/terrain/TerrainTestModifyHeight.java

@@ -32,8 +32,12 @@
 package jme3test.terrain;
 
 import com.jme3.app.SimpleApplication;
+import com.jme3.bounding.BoundingBox;
 import com.jme3.collision.CollisionResult;
 import com.jme3.collision.CollisionResults;
+import com.jme3.export.Savable;
+import com.jme3.export.binary.BinaryExporter;
+import com.jme3.export.binary.BinaryImporter;
 import com.jme3.font.BitmapText;
 import com.jme3.input.KeyInput;
 import com.jme3.input.MouseInput;
@@ -43,18 +47,34 @@ import com.jme3.input.controls.MouseButtonTrigger;
 import com.jme3.light.AmbientLight;
 import com.jme3.light.DirectionalLight;
 import com.jme3.material.Material;
+import com.jme3.material.RenderState.BlendMode;
 import com.jme3.math.ColorRGBA;
 import com.jme3.math.Ray;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
+import com.jme3.renderer.queue.RenderQueue.Bucket;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.shape.Sphere;
 import com.jme3.terrain.geomipmap.TerrainGrid;
 import com.jme3.terrain.geomipmap.TerrainLodControl;
 import com.jme3.terrain.geomipmap.TerrainQuad;
+import com.jme3.terrain.heightmap.AbstractHeightMap;
 import com.jme3.terrain.heightmap.FractalHeightMapGrid;
+import com.jme3.terrain.heightmap.ImageBasedHeightMap;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture.WrapMode;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import jme3tools.converters.ImageToAwt;
 import org.novyon.noise.ShaderUtils;
 import org.novyon.noise.basis.FilteredBasis;
 import org.novyon.noise.filter.IterativeFilter;
@@ -84,6 +104,8 @@ public class TerrainTestModifyHeight extends SimpleApplication {
     
     private boolean raiseTerrain = false;
     private boolean lowerTerrain = false;
+    
+    private Geometry marker;
 
     public static void main(String[] args) {
         TerrainTestModifyHeight app = new TerrainTestModifyHeight();
@@ -105,6 +127,12 @@ public class TerrainTestModifyHeight extends SimpleApplication {
                 adjustHeight(intersection, 64, -tpf * 60);
             }
         }
+        
+        if (terrain != null && intersection != null) {
+            float h = terrain.getHeight(new Vector2f(intersection.x, intersection.z));
+            Vector3f tl = terrain.getWorldTranslation();
+            marker.setLocalTranslation(tl.add(new Vector3f(intersection.x, h, intersection.z)) );
+        }
     }
     
     @Override
@@ -112,6 +140,8 @@ public class TerrainTestModifyHeight extends SimpleApplication {
         loadHintText();
         initCrossHairs();
         setupKeys();
+        
+        createMarker();
 
         // WIREFRAME material
         matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
@@ -120,7 +150,7 @@ public class TerrainTestModifyHeight extends SimpleApplication {
         
         //createTerrain();
         createTerrainGrid();
-
+        
         DirectionalLight light = new DirectionalLight();
         light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize());
         rootNode.addLight(light);
@@ -130,9 +160,9 @@ public class TerrainTestModifyHeight extends SimpleApplication {
         rootNode.addLight(ambLight);
 
         cam.setLocation(new Vector3f(0, 256, 0));
-        cam.lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y);
+        cam.lookAtDirection(new Vector3f(0, -1f, 0).normalizeLocal(), Vector3f.UNIT_X);
     }
-
+    
     public void loadHintText() {
         hintText = new BitmapText(guiFont, false);
         hintText.setLocalTranslation(0, getCamera().getHeight(), 0);
@@ -162,7 +192,6 @@ public class TerrainTestModifyHeight extends SimpleApplication {
 
     private void setupKeys() {
         flyCam.setMoveSpeed(100);
-        
         inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
         inputManager.addListener(actionListener, "wireframe");
         inputManager.addMapping("Raise", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
@@ -281,13 +310,25 @@ public class TerrainTestModifyHeight extends SimpleApplication {
         matTerrain.setTexture("DiffuseMap_2", rock);
         matTerrain.setFloat("DiffuseMap_2_scale", rockScale);
 
+        // HEIGHTMAP image (for the terrain heightmap)
+        Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
+        AbstractHeightMap heightmap = null;
+        try {
+            heightmap = new ImageBasedHeightMap(ImageToAwt.convert(heightMapImage.getImage(), false, true, 0), 0.5f);
+            heightmap.load();
+            heightmap.smooth(0.9f, 1);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        
         // CREATE THE TERRAIN
-        terrain = new TerrainQuad("terrain", 65, 513, null);
+        terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
         TerrainLodControl control = new TerrainLodControl(terrain, getCamera());
         terrain.addControl(control);
         terrain.setMaterial(matTerrain);
         terrain.setLocalTranslation(0, -100, 0);
-        terrain.setLocalScale(2f, 1f, 2f);
+        terrain.setLocalScale(2.5f, 0.5f, 2.5f);
         rootNode.attachChild(terrain);
     }
 
@@ -370,7 +411,7 @@ public class TerrainTestModifyHeight extends SimpleApplication {
         this.terrain = new TerrainGrid("terrain", 65, 257, new FractalHeightMapGrid(ground, null, 256f));
 
 
-        terrain.setMaterial(matWire);
+        terrain.setMaterial(matTerrain);
         terrain.setLocalTranslation(0, 0, 0);
         terrain.setLocalScale(2f, 1f, 2f);
         ((TerrainGrid)terrain).initialize(Vector3f.ZERO);
@@ -379,4 +420,18 @@ public class TerrainTestModifyHeight extends SimpleApplication {
         TerrainLodControl control = new TerrainLodControl(this.terrain, getCamera());
         this.terrain.addControl(control);
     }
+
+    private void createMarker() {
+        Sphere sphere = new Sphere(8, 8, 0.5f);
+        marker = new Geometry("Marker");
+        marker.setMesh(sphere);
+        
+        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        mat.setColor("Color", new ColorRGBA(251f/255f, 130f/255f, 0f, 0.6f));
+        mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
+        
+        marker.setMaterial(mat);
+        rootNode.attachChild(marker);
+        
+    }
 }