From ab8c9e120ee496affe2f20bc363eb6364a75714e Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 12:20:28 +0100 Subject: [PATCH 01/59] Initial structure for TerrainQuadTest --- .../jme3/terrain/geomipmap/TerrainQuadTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java new file mode 100644 index 0000000000..3bb019863f --- /dev/null +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -0,0 +1,14 @@ +package com.jme3.terrain.geomipmap; + +import org.junit.Test; + +public class TerrainQuadTest { + + /** + * No NPE or any exception when clear() a new Cinematic + */ + @Test + public void testSomething() { + + } +} From 7331b957a1540acd7c53ba495c9b6c0ffc6ba137 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 13:15:39 +0100 Subject: [PATCH 02/59] Added test for getQuad --- .../terrain/geomipmap/TerrainQuadTest.java | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 3bb019863f..b7ed6b1b72 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -1,14 +1,38 @@ package com.jme3.terrain.geomipmap; +import static org.junit.Assert.*; +import org.junit.Before; import org.junit.Test; public class TerrainQuadTest { - /** - * No NPE or any exception when clear() a new Cinematic - */ - @Test - public void testSomething() { + private TerrainQuad parentTerrainQuad; + private TerrainQuad[] children = new TerrainQuad[4]; + + @Before + public void init() { + for(int i = 0; i < 4; i++) { + children[i] = new TerrainQuad(); + } + + parentTerrainQuad = new TerrainQuad(); + fakeCreateQuad(parentTerrainQuad, children); + } + private void fakeCreateQuad(TerrainQuad parent, TerrainQuad[] children) { + for (int i = 0; i < children.length; i++) { + children[i].quadrant = i + 1; // Quadrant starts counting from 1 + parent.attachChild(children[i]); + } + } + + @Test + public void testGetQuad() { + assertEquals(parentTerrainQuad.getQuad(0), parentTerrainQuad); + assertEquals(parentTerrainQuad.getQuad(1), children[0]); + assertEquals(parentTerrainQuad.getQuad(2), children[1]); + assertEquals(parentTerrainQuad.getQuad(3), children[2]); + assertEquals(parentTerrainQuad.getQuad(4), children[3]); + assertEquals(parentTerrainQuad.getQuad(5), null); } } From 2f4b929654f2e77e90b3083d58042cc6d68b4ddf Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 13:55:33 +0100 Subject: [PATCH 03/59] Tests for all children of root for findRightQuad --- .../java/com/jme3/terrain/geomipmap/TerrainQuadTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index b7ed6b1b72..d3d1bbcdc3 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -35,4 +35,12 @@ public void testGetQuad() { assertEquals(parentTerrainQuad.getQuad(4), children[3]); assertEquals(parentTerrainQuad.getQuad(5), null); } + + @Test + public void testFindRightQuad() { + assertEquals(children[0].findRightQuad(), children[2]); + assertEquals(children[1].findRightQuad(), children[3]); + assertEquals(children[2].findRightQuad(), null); + assertEquals(children[3].findRightQuad(), null); + } } From 0d56f936396bfc742301bd6e226a6271ed90783c Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 14:14:23 +0100 Subject: [PATCH 04/59] Added tests for findDown, Left and Top quad --- .../terrain/geomipmap/TerrainQuadTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index d3d1bbcdc3..b0593747c2 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -43,4 +43,28 @@ public void testFindRightQuad() { assertEquals(children[2].findRightQuad(), null); assertEquals(children[3].findRightQuad(), null); } + + @Test + public void testFindDownQuad() { + assertEquals(children[0].findDownQuad(), children[1]); + assertEquals(children[1].findDownQuad(), null); + assertEquals(children[2].findDownQuad(), children[3]); + assertEquals(children[3].findDownQuad(), null); + } + + @Test + public void testFindLeftQuad() { + assertEquals(children[0].findLeftQuad(), null); + assertEquals(children[1].findLeftQuad(), null); + assertEquals(children[2].findLeftQuad(), children[0]); + assertEquals(children[3].findLeftQuad(), children[1]); + } + + @Test + public void testFindTopQuad() { + assertEquals(children[0].findTopQuad(), null); + assertEquals(children[1].findTopQuad(), children[0]); + assertEquals(children[2].findTopQuad(), null); + assertEquals(children[3].findTopQuad(), children[2]); + } } From 3f74b586da9addc8a54626c8be64d39ed61e740d Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 14:16:09 +0100 Subject: [PATCH 05/59] Added parent findQuad tests --- .../test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index b0593747c2..acce5a22ed 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -38,6 +38,7 @@ public void testGetQuad() { @Test public void testFindRightQuad() { + assertEquals(parentTerrainQuad.findRightQuad(), null); assertEquals(children[0].findRightQuad(), children[2]); assertEquals(children[1].findRightQuad(), children[3]); assertEquals(children[2].findRightQuad(), null); @@ -46,6 +47,7 @@ public void testFindRightQuad() { @Test public void testFindDownQuad() { + assertEquals(parentTerrainQuad.findDownQuad(), null); assertEquals(children[0].findDownQuad(), children[1]); assertEquals(children[1].findDownQuad(), null); assertEquals(children[2].findDownQuad(), children[3]); @@ -54,6 +56,7 @@ public void testFindDownQuad() { @Test public void testFindLeftQuad() { + assertEquals(parentTerrainQuad.findLeftQuad(), null); assertEquals(children[0].findLeftQuad(), null); assertEquals(children[1].findLeftQuad(), null); assertEquals(children[2].findLeftQuad(), children[0]); @@ -62,6 +65,7 @@ public void testFindLeftQuad() { @Test public void testFindTopQuad() { + assertEquals(parentTerrainQuad.findTopQuad(), null); assertEquals(children[0].findTopQuad(), null); assertEquals(children[1].findTopQuad(), children[0]); assertEquals(children[2].findTopQuad(), null); From 0333703e00bc34548866941d1edc7b0fdda97c2b Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 16 Mar 2016 15:18:50 +0100 Subject: [PATCH 06/59] lod test --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- .../resources/com/jme3/system/version.properties | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a0f68906bf..f76418f51d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Dec 01 20:04:11 EST 2014 +#Wed Mar 16 12:05:41 CET 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/jme3-core/src/main/resources/com/jme3/system/version.properties b/jme3-core/src/main/resources/com/jme3/system/version.properties index 98168a14e1..0aa73859a9 100644 --- a/jme3-core/src/main/resources/com/jme3/system/version.properties +++ b/jme3-core/src/main/resources/com/jme3/system/version.properties @@ -1,11 +1,12 @@ # THIS IS AN AUTO-GENERATED FILE.. # DO NOT MODIFY! -build.date=1900-01-01 -git.revision=0 -git.branch=unknown -git.hash= -git.hash.short= -git.tag= -name.full=jMonkeyEngine 3.1.0-UNKNOWN +build.date=2016-03-16 +git.revision=5475 +git.branch=refactorings +git.hash=10947e8b5096f6d7e2bf0e327faa43b275adeb34 +git.hash.short=10947e8 +git.tag=null +name.full=jMonkeyEngine 3.1-refactorings-5475 +version.full=3.1-refactorings-5475 version.number=3.1.0 version.tag=SNAPSHOT \ No newline at end of file From fbe6c8e7228317a2de401b0478959da6e37641c8 Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 16 Mar 2016 16:26:02 +0100 Subject: [PATCH 07/59] lod test --- .../src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 8cceb85bb8..2e21c7feaf 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -48,6 +48,7 @@ import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.debug.WireBox; +import com.jme3.system.SystemListener; import com.jme3.terrain.ProgressMonitor; import com.jme3.terrain.Terrain; import com.jme3.terrain.geomipmap.lodcalc.LodCalculator; @@ -369,13 +370,16 @@ protected boolean calculateLod(List location, HashMap= 0;) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { + System.out.println("hier quad"); boolean b = ((TerrainQuad) child).calculateLod(location, updates, lodCalculator); if (b) lodChanged = true; } else if (child instanceof TerrainPatch) { + System.out.println("hier patch"); boolean b = lodCalculator.calculateLod((TerrainPatch) child, location, updates); if (b) lodChanged = true; From 5980a7d06a8e663f883a750c391538c2fc5c4b5b Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 17:01:11 +0100 Subject: [PATCH 08/59] Added FakeTerrainQuad with public getQuad method --- .../jme3/terrain/geomipmap/FakeTerrainQuad.java | 8 ++++++++ .../jme3/terrain/geomipmap/TerrainQuadTest.java | 16 +++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/FakeTerrainQuad.java diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/FakeTerrainQuad.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/FakeTerrainQuad.java new file mode 100644 index 0000000000..429209d339 --- /dev/null +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/FakeTerrainQuad.java @@ -0,0 +1,8 @@ +package com.jme3.terrain.geomipmap; + +public class FakeTerrainQuad extends TerrainQuad { + + public TerrainQuad getQuad(int quad) { + return super.getQuad(quad); + } +} diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index b7ed6b1b72..a2f16887cc 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -6,26 +6,32 @@ public class TerrainQuadTest { - private TerrainQuad parentTerrainQuad; - private TerrainQuad[] children = new TerrainQuad[4]; + private FakeTerrainQuad parentTerrainQuad; + private FakeTerrainQuad[] children = new FakeTerrainQuad[4]; @Before public void init() { for(int i = 0; i < 4; i++) { - children[i] = new TerrainQuad(); + children[i] = new FakeTerrainQuad(); } - parentTerrainQuad = new TerrainQuad(); + parentTerrainQuad = new FakeTerrainQuad(); fakeCreateQuad(parentTerrainQuad, children); } - private void fakeCreateQuad(TerrainQuad parent, TerrainQuad[] children) { + private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) { for (int i = 0; i < children.length; i++) { children[i].quadrant = i + 1; // Quadrant starts counting from 1 parent.attachChild(children[i]); } } + @Test + public void testFakeTerrainQuad() { + FakeTerrainQuad fake = new FakeTerrainQuad(); + assertEquals(fake, fake.getQuad(0)); + } + @Test public void testGetQuad() { assertEquals(parentTerrainQuad.getQuad(0), parentTerrainQuad); From d01c559a034f9a7ee896f4a15adfd9acbf4eabd8 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 17:27:21 +0100 Subject: [PATCH 09/59] Added method to create nested quads --- .../terrain/geomipmap/TerrainQuadTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index a2f16887cc..ef81661992 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -1,6 +1,8 @@ package com.jme3.terrain.geomipmap; import static org.junit.Assert.*; + +import com.jme3.scene.Spatial; import org.junit.Before; import org.junit.Test; @@ -26,12 +28,60 @@ private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) } } + /** + * Used to recursively create a nested structure of {@link Spatial}s. + * If nesting level is > 1, root element will be a {@link TerrainQuad}. + * Leafs (nesting level 0) are {@link TerrainPatch}es. + * @param nestLevel Nest level to be created. + * @return Nested structure of {@link Spatial}s + */ + private Spatial createNestedQuad(int nestLevel) { + if (nestLevel == 0) { + return new TerrainPatch(); + } + + FakeTerrainQuad parent = new FakeTerrainQuad(); + for(int i = 0; i < 4; i++) { + Spatial child = createNestedQuad(nestLevel - 1); + + if (child instanceof TerrainPatch) { + TerrainPatch patchChild = (TerrainPatch) child; + patchChild.quadrant = (short) (i + 1); + parent.attachChild(patchChild); + } else if (child instanceof TerrainQuad) { + FakeTerrainQuad quadChild = (FakeTerrainQuad) child; + quadChild.quadrant = i + 1; + parent.attachChild(quadChild); + } + } + + return parent; + } + @Test public void testFakeTerrainQuad() { FakeTerrainQuad fake = new FakeTerrainQuad(); assertEquals(fake, fake.getQuad(0)); } + @Test + public void testNestStructure() { + Spatial leaf = createNestedQuad(0); + assertTrue(leaf instanceof TerrainPatch); + + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); + assertEquals(root.getChildren().size(), 4); + for(int i = 0; i < 4; i++) { + assertTrue(root.getChild(i) instanceof TerrainPatch); // Ensure children of root are leafs + } + + root = (FakeTerrainQuad) createNestedQuad(2); + assertEquals(root.getChildren().size(), 4); + for(int i = 0; i < 4; i++) { + assertTrue(root.getChild(i) instanceof TerrainQuad); // Ensure children of root are not leafs + } + } + @Test public void testGetQuad() { assertEquals(parentTerrainQuad.getQuad(0), parentTerrainQuad); From e5f5b41daa3f622d38e7da923b97b5e355e0e544 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 13:55:33 +0100 Subject: [PATCH 10/59] Tests for all children of root for findRightQuad --- .../java/com/jme3/terrain/geomipmap/TerrainQuadTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index ef81661992..5125b92757 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -91,4 +91,12 @@ public void testGetQuad() { assertEquals(parentTerrainQuad.getQuad(4), children[3]); assertEquals(parentTerrainQuad.getQuad(5), null); } + + @Test + public void testFindRightQuad() { + assertEquals(children[0].findRightQuad(), children[2]); + assertEquals(children[1].findRightQuad(), children[3]); + assertEquals(children[2].findRightQuad(), null); + assertEquals(children[3].findRightQuad(), null); + } } From a4ef98f8d7892bceddd49244031f1096a6eb45cb Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 14:14:23 +0100 Subject: [PATCH 11/59] Added tests for findDown, Left and Top quad --- .../terrain/geomipmap/TerrainQuadTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 5125b92757..07169557e4 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -99,4 +99,28 @@ public void testFindRightQuad() { assertEquals(children[2].findRightQuad(), null); assertEquals(children[3].findRightQuad(), null); } + + @Test + public void testFindDownQuad() { + assertEquals(children[0].findDownQuad(), children[1]); + assertEquals(children[1].findDownQuad(), null); + assertEquals(children[2].findDownQuad(), children[3]); + assertEquals(children[3].findDownQuad(), null); + } + + @Test + public void testFindLeftQuad() { + assertEquals(children[0].findLeftQuad(), null); + assertEquals(children[1].findLeftQuad(), null); + assertEquals(children[2].findLeftQuad(), children[0]); + assertEquals(children[3].findLeftQuad(), children[1]); + } + + @Test + public void testFindTopQuad() { + assertEquals(children[0].findTopQuad(), null); + assertEquals(children[1].findTopQuad(), children[0]); + assertEquals(children[2].findTopQuad(), null); + assertEquals(children[3].findTopQuad(), children[2]); + } } From c37003a6b45444eb5b2967b654790d878276bf5c Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 14:16:09 +0100 Subject: [PATCH 12/59] Added parent findQuad tests --- .../test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 07169557e4..c9efe91c0e 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -94,6 +94,7 @@ public void testGetQuad() { @Test public void testFindRightQuad() { + assertEquals(parentTerrainQuad.findRightQuad(), null); assertEquals(children[0].findRightQuad(), children[2]); assertEquals(children[1].findRightQuad(), children[3]); assertEquals(children[2].findRightQuad(), null); @@ -102,6 +103,7 @@ public void testFindRightQuad() { @Test public void testFindDownQuad() { + assertEquals(parentTerrainQuad.findDownQuad(), null); assertEquals(children[0].findDownQuad(), children[1]); assertEquals(children[1].findDownQuad(), null); assertEquals(children[2].findDownQuad(), children[3]); @@ -110,6 +112,7 @@ public void testFindDownQuad() { @Test public void testFindLeftQuad() { + assertEquals(parentTerrainQuad.findLeftQuad(), null); assertEquals(children[0].findLeftQuad(), null); assertEquals(children[1].findLeftQuad(), null); assertEquals(children[2].findLeftQuad(), children[0]); @@ -118,6 +121,7 @@ public void testFindLeftQuad() { @Test public void testFindTopQuad() { + assertEquals(parentTerrainQuad.findTopQuad(), null); assertEquals(children[0].findTopQuad(), null); assertEquals(children[1].findTopQuad(), children[0]); assertEquals(children[2].findTopQuad(), null); From 0ae84d8d8555e214cedb277ae4c6e3094e044e7b Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 16 Mar 2016 15:18:50 +0100 Subject: [PATCH 13/59] lod test --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- .../resources/com/jme3/system/version.properties | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a0f68906bf..f76418f51d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Dec 01 20:04:11 EST 2014 +#Wed Mar 16 12:05:41 CET 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/jme3-core/src/main/resources/com/jme3/system/version.properties b/jme3-core/src/main/resources/com/jme3/system/version.properties index 98168a14e1..0aa73859a9 100644 --- a/jme3-core/src/main/resources/com/jme3/system/version.properties +++ b/jme3-core/src/main/resources/com/jme3/system/version.properties @@ -1,11 +1,12 @@ # THIS IS AN AUTO-GENERATED FILE.. # DO NOT MODIFY! -build.date=1900-01-01 -git.revision=0 -git.branch=unknown -git.hash= -git.hash.short= -git.tag= -name.full=jMonkeyEngine 3.1.0-UNKNOWN +build.date=2016-03-16 +git.revision=5475 +git.branch=refactorings +git.hash=10947e8b5096f6d7e2bf0e327faa43b275adeb34 +git.hash.short=10947e8 +git.tag=null +name.full=jMonkeyEngine 3.1-refactorings-5475 +version.full=3.1-refactorings-5475 version.number=3.1.0 version.tag=SNAPSHOT \ No newline at end of file From aab659e6cb36e0983e2c0daf0a33aacdb9273536 Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 16 Mar 2016 16:26:02 +0100 Subject: [PATCH 14/59] lod test --- .../src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 8cceb85bb8..2e21c7feaf 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -48,6 +48,7 @@ import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.debug.WireBox; +import com.jme3.system.SystemListener; import com.jme3.terrain.ProgressMonitor; import com.jme3.terrain.Terrain; import com.jme3.terrain.geomipmap.lodcalc.LodCalculator; @@ -369,13 +370,16 @@ protected boolean calculateLod(List location, HashMap= 0;) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { + System.out.println("hier quad"); boolean b = ((TerrainQuad) child).calculateLod(location, updates, lodCalculator); if (b) lodChanged = true; } else if (child instanceof TerrainPatch) { + System.out.println("hier patch"); boolean b = lodCalculator.calculateLod((TerrainPatch) child, location, updates); if (b) lodChanged = true; From 4b2538a748049f0e362d3adab69e45042b955d37 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 16 Mar 2016 18:21:57 +0100 Subject: [PATCH 15/59] Changed tests to cover everything except useFinder lines --- .../terrain/geomipmap/TerrainQuadTest.java | 84 ++++++++++++++----- 1 file changed, 64 insertions(+), 20 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index c9efe91c0e..c87e1323c4 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -94,37 +94,81 @@ public void testGetQuad() { @Test public void testFindRightQuad() { - assertEquals(parentTerrainQuad.findRightQuad(), null); - assertEquals(children[0].findRightQuad(), children[2]); - assertEquals(children[1].findRightQuad(), children[3]); - assertEquals(children[2].findRightQuad(), null); - assertEquals(children[3].findRightQuad(), null); + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); + FakeTerrainQuad topRight = (FakeTerrainQuad)root.getQuad(3); + + assertEquals(root.findRightQuad(), null); + assertEquals(topLeftChild.findRightQuad(), topRight); // Confirm position of two parent quads + + // Check quad children of parent + assertEquals(topLeftChild.getQuad(1).findRightQuad(), topLeftChild.getQuad(3)); + assertEquals(topLeftChild.getQuad(2).findRightQuad(), topLeftChild.getQuad(4)); + assertEquals(topLeftChild.getQuad(3).findRightQuad(), topRight.getQuad(1)); + assertEquals(topLeftChild.getQuad(4).findRightQuad(), topRight.getQuad(2)); + + // Check non-existing neighbour quads + assertEquals(topRight.getQuad(3).findRightQuad(), null); + assertEquals(topRight.getQuad(4).findRightQuad(), null); } @Test public void testFindDownQuad() { - assertEquals(parentTerrainQuad.findDownQuad(), null); - assertEquals(children[0].findDownQuad(), children[1]); - assertEquals(children[1].findDownQuad(), null); - assertEquals(children[2].findDownQuad(), children[3]); - assertEquals(children[3].findDownQuad(), null); + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); + FakeTerrainQuad downLeftChild = (FakeTerrainQuad)root.getQuad(2); + + assertEquals(root.findDownQuad(), null); + assertEquals(topLeftChild.findDownQuad(), downLeftChild); // Confirm position of two parent quads + + // Check quad children of parent + assertEquals(topLeftChild.getQuad(1).findDownQuad(), topLeftChild.getQuad(2)); + assertEquals(topLeftChild.getQuad(2).findDownQuad(), downLeftChild.getQuad(1)); + assertEquals(topLeftChild.getQuad(3).findDownQuad(), topLeftChild.getQuad(4)); + assertEquals(topLeftChild.getQuad(4).findDownQuad(), downLeftChild.getQuad(3)); + + // Check non-existing neighbour quads + assertEquals(downLeftChild.getQuad(2).findDownQuad(), null); + assertEquals(downLeftChild.getQuad(4).findDownQuad(), null); } @Test public void testFindLeftQuad() { - assertEquals(parentTerrainQuad.findLeftQuad(), null); - assertEquals(children[0].findLeftQuad(), null); - assertEquals(children[1].findLeftQuad(), null); - assertEquals(children[2].findLeftQuad(), children[0]); - assertEquals(children[3].findLeftQuad(), children[1]); + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); + FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); + + assertEquals(root.findLeftQuad(), null); + assertEquals(topRightChild.findLeftQuad(), topLeftChild); // Confirm position of two parent quads + + // Check quad children of parent + assertEquals(topRightChild.getQuad(1).findLeftQuad(), topLeftChild.getQuad(3)); + assertEquals(topRightChild.getQuad(2).findLeftQuad(), topLeftChild.getQuad(4)); + assertEquals(topRightChild.getQuad(3).findLeftQuad(), topRightChild.getQuad(1)); + assertEquals(topRightChild.getQuad(4).findLeftQuad(), topRightChild.getQuad(2)); + + // Check non-existing neighbour quads + assertEquals(topLeftChild.getQuad(1).findLeftQuad(), null); + assertEquals(topLeftChild.getQuad(2).findLeftQuad(), null); } @Test public void testFindTopQuad() { - assertEquals(parentTerrainQuad.findTopQuad(), null); - assertEquals(children[0].findTopQuad(), null); - assertEquals(children[1].findTopQuad(), children[0]); - assertEquals(children[2].findTopQuad(), null); - assertEquals(children[3].findTopQuad(), children[2]); + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); + FakeTerrainQuad downLeftChild = (FakeTerrainQuad)root.getQuad(2); + + assertEquals(root.findTopQuad(), null); + assertEquals(downLeftChild.findTopQuad(), topLeftChild); // Confirm position of two parent quads + + // Check quad children of parent + assertEquals(downLeftChild.getQuad(1).findTopQuad(), topLeftChild.getQuad(2)); + assertEquals(downLeftChild.getQuad(2).findTopQuad(), downLeftChild.getQuad(1)); + assertEquals(downLeftChild.getQuad(3).findTopQuad(), topLeftChild.getQuad(4)); + assertEquals(downLeftChild.getQuad(4).findTopQuad(), downLeftChild.getQuad(3)); + + // Check non-existing neighbour quads + assertEquals(topLeftChild.getQuad(1).findTopQuad(), null); + assertEquals(topLeftChild.getQuad(3).findTopQuad(), null); } } From ea54662e4c233edcd6187ba8606864384902f95f Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Fri, 18 Mar 2016 12:32:47 +0100 Subject: [PATCH 16/59] Added test for getPatch --- .../terrain/geomipmap/TerrainQuadTest.java | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index c87e1323c4..51fb7d6912 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -13,7 +13,7 @@ public class TerrainQuadTest { @Before public void init() { - for(int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { children[i] = new FakeTerrainQuad(); } @@ -32,6 +32,7 @@ private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) * Used to recursively create a nested structure of {@link Spatial}s. * If nesting level is > 1, root element will be a {@link TerrainQuad}. * Leafs (nesting level 0) are {@link TerrainPatch}es. + * * @param nestLevel Nest level to be created. * @return Nested structure of {@link Spatial}s */ @@ -41,7 +42,7 @@ private Spatial createNestedQuad(int nestLevel) { } FakeTerrainQuad parent = new FakeTerrainQuad(); - for(int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { Spatial child = createNestedQuad(nestLevel - 1); if (child instanceof TerrainPatch) { @@ -71,13 +72,13 @@ public void testNestStructure() { FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); assertEquals(root.getChildren().size(), 4); - for(int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { assertTrue(root.getChild(i) instanceof TerrainPatch); // Ensure children of root are leafs } root = (FakeTerrainQuad) createNestedQuad(2); assertEquals(root.getChildren().size(), 4); - for(int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { assertTrue(root.getChild(i) instanceof TerrainQuad); // Ensure children of root are not leafs } } @@ -94,9 +95,9 @@ public void testGetQuad() { @Test public void testFindRightQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad topRight = (FakeTerrainQuad)root.getQuad(3); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); + FakeTerrainQuad topRight = (FakeTerrainQuad) root.getQuad(3); assertEquals(root.findRightQuad(), null); assertEquals(topLeftChild.findRightQuad(), topRight); // Confirm position of two parent quads @@ -114,9 +115,9 @@ public void testFindRightQuad() { @Test public void testFindDownQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad downLeftChild = (FakeTerrainQuad)root.getQuad(2); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); + FakeTerrainQuad downLeftChild = (FakeTerrainQuad) root.getQuad(2); assertEquals(root.findDownQuad(), null); assertEquals(topLeftChild.findDownQuad(), downLeftChild); // Confirm position of two parent quads @@ -134,9 +135,9 @@ public void testFindDownQuad() { @Test public void testFindLeftQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); + FakeTerrainQuad topRightChild = (FakeTerrainQuad) root.getQuad(3); assertEquals(root.findLeftQuad(), null); assertEquals(topRightChild.findLeftQuad(), topLeftChild); // Confirm position of two parent quads @@ -154,9 +155,9 @@ public void testFindLeftQuad() { @Test public void testFindTopQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad downLeftChild = (FakeTerrainQuad)root.getQuad(2); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); + FakeTerrainQuad downLeftChild = (FakeTerrainQuad) root.getQuad(2); assertEquals(root.findTopQuad(), null); assertEquals(downLeftChild.findTopQuad(), topLeftChild); // Confirm position of two parent quads @@ -171,4 +172,15 @@ public void testFindTopQuad() { assertEquals(topLeftChild.getQuad(1).findTopQuad(), null); assertEquals(topLeftChild.getQuad(3).findTopQuad(), null); } + + @Test + public void testGetPatch() { + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); + assertEquals(root.getPatch(0), null); + assertEquals(root.getPatch(1), root.getChild(0)); + assertEquals(root.getPatch(2), root.getChild(1)); + assertEquals(root.getPatch(3), root.getChild(2)); + assertEquals(root.getPatch(4), root.getChild(3)); + assertEquals(root.getPatch(5), null); + } } From 65929d9d12e5c9f7091efb8f54254281096305c7 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Fri, 18 Mar 2016 12:57:10 +0100 Subject: [PATCH 17/59] Added exception variable and tests for findRightPatch --- .../terrain/geomipmap/TerrainQuadTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 51fb7d6912..ace2058c68 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -4,10 +4,15 @@ import com.jme3.scene.Spatial; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class TerrainQuadTest { + @Rule + public final ExpectedException exception = ExpectedException.none(); + private FakeTerrainQuad parentTerrainQuad; private FakeTerrainQuad[] children = new FakeTerrainQuad[4]; @@ -183,4 +188,26 @@ public void testGetPatch() { assertEquals(root.getPatch(4), root.getChild(3)); assertEquals(root.getPatch(5), null); } + + @Test + public void testFindRightPatch() { + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); + FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); + + exception.expect(NullPointerException.class); + root.findRightPatch(null); + + assertEquals(topLeftChild.findRightQuad(), topRightChild); // Confirm position of two parent quads + + // Check quad children of parent + assertEquals(topLeftChild.findRightPatch(topLeftChild.getPatch(1)), topLeftChild.getPatch(3)); + assertEquals(topLeftChild.findRightPatch(topLeftChild.getPatch(2)), topLeftChild.getPatch(4)); + assertEquals(topLeftChild.findRightPatch(topLeftChild.getPatch(3)), topRightChild.getPatch(1)); + assertEquals(topLeftChild.findRightPatch(topLeftChild.getPatch(4)), topRightChild.getPatch(2)); + + // Check non-existing neighbour quads + assertEquals(topRightChild.findRightPatch(topRightChild.getPatch(3)), null); + assertEquals(topRightChild.findRightPatch(topRightChild.getPatch(4)), null); + } } From 669ec4ff1a3de7bf3cd010e92e16f93dc67bdfb3 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Fri, 18 Mar 2016 16:52:35 +0100 Subject: [PATCH 18/59] Added null checks to getPatch and findRightPatch tests --- .../terrain/geomipmap/TerrainQuadTest.java | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index ace2058c68..b4dbf5847f 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -181,11 +181,12 @@ public void testFindTopQuad() { @Test public void testGetPatch() { FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); - assertEquals(root.getPatch(0), null); - assertEquals(root.getPatch(1), root.getChild(0)); - assertEquals(root.getPatch(2), root.getChild(1)); - assertEquals(root.getPatch(3), root.getChild(2)); - assertEquals(root.getPatch(4), root.getChild(3)); + assertNull(root.getPatch(0)); + for (int i = 1; i <= 4; i++) { + TerrainPatch child = root.getPatch(i); + assertNotNull(child); + assertEquals(root.getChild(i - 1), child); + } assertEquals(root.getPatch(5), null); } @@ -201,10 +202,23 @@ public void testFindRightPatch() { assertEquals(topLeftChild.findRightQuad(), topRightChild); // Confirm position of two parent quads // Check quad children of parent - assertEquals(topLeftChild.findRightPatch(topLeftChild.getPatch(1)), topLeftChild.getPatch(3)); - assertEquals(topLeftChild.findRightPatch(topLeftChild.getPatch(2)), topLeftChild.getPatch(4)); - assertEquals(topLeftChild.findRightPatch(topLeftChild.getPatch(3)), topRightChild.getPatch(1)); - assertEquals(topLeftChild.findRightPatch(topLeftChild.getPatch(4)), topRightChild.getPatch(2)); + TerrainPatch child1 = topLeftChild.findRightPatch(topLeftChild.getPatch(2)); + assertNotNull(child1); + assertEquals(child1, topLeftChild.getPatch(3)); + + TerrainPatch child2 = topLeftChild.findRightPatch(topLeftChild.getPatch(2)); + assertNotNull(child1); + assertEquals(child2, topLeftChild.getPatch(4)); + + + TerrainPatch child3 = topLeftChild.findRightPatch(topLeftChild.getPatch(3)); + assertNotNull(child3); + assertEquals(child3, topRightChild.getPatch(1)); + + + TerrainPatch child4 = topLeftChild.findRightPatch(topLeftChild.getPatch(4)); + assertNotNull(child4); + assertEquals(child4, topRightChild.getPatch(2)); // Check non-existing neighbour quads assertEquals(topRightChild.findRightPatch(topRightChild.getPatch(3)), null); From 2f74803724908b7bebbbc9ac5e8ae98f38005ff3 Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 23 Mar 2016 12:20:39 +0100 Subject: [PATCH 19/59] Refactoring and Testing of createQuadPatch method in TerrainQuad. --- .../jme3/terrain/geomipmap/TerrainPatch.java | 485 +++++++------- .../jme3/terrain/geomipmap/TerrainQuad.java | 628 ++++++++++-------- .../geomipmap/FakeDistanceLodCalculator.java | 15 + .../terrain/geomipmap/FakeTerrainPatch.java | 8 + 4 files changed, 616 insertions(+), 520 deletions(-) create mode 100644 jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/FakeDistanceLodCalculator.java create mode 100644 jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/FakeTerrainPatch.java diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java index 4ac811e9fc..556bb6882b 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java @@ -50,6 +50,7 @@ import com.jme3.terrain.geomipmap.TerrainQuad.LocationHeight; import com.jme3.terrain.geomipmap.lodcalc.util.EntropyComputeUtil; import com.jme3.util.BufferUtils; + import java.io.IOException; import java.nio.Buffer; import java.nio.FloatBuffer; @@ -65,18 +66,18 @@ * That uses a geo-mipmapping algorithm to change the index buffer of the mesh. * The mesh is a triangle strip. In wireframe mode you might notice some strange lines, these are degenerate * triangles generated by the geoMipMap algorithm and can be ignored. The video card removes them at almost no cost. - * + *

* Each patch needs to know its neighbour's LOD so it can seam its edges with them, in case the neighbour has a different * LOD. If this doesn't happen, you will see gaps. - * + *

* The LOD value is most detailed at zero. It gets less detailed the higher the LOD value until you reach maxLod, which * is a mathematical limit on the number of times the 'size' of the patch can be divided by two. However there is a -1 to that * for now until I add in a custom index buffer calculation for that max level, the current algorithm does not go that far. - * - * You can supply a LodThresholdCalculator for use in determining when the LOD should change. It's API will no doubt change - * in the near future. Right now it defaults to just changing LOD every two patch sizes. So if a patch has a size of 65, + *

+ * You can supply a LodThresholdCalculator for use in determining when the LOD should change. It's API will no doubt change + * in the near future. Right now it defaults to just changing LOD every two patch sizes. So if a patch has a size of 65, * then the LOD changes every 130 units away. - * + * * @author Brent Owens */ public class TerrainPatch extends Geometry { @@ -118,14 +119,14 @@ public TerrainPatch() { super("TerrainPatch"); setBatchHint(BatchHint.Never); } - + public TerrainPatch(String name) { super(name); setBatchHint(BatchHint.Never); } public TerrainPatch(String name, int size) { - this(name, size, new Vector3f(1,1,1), null, new Vector3f(0,0,0)); + this(name, size, new Vector3f(1, 1, 1), null, new Vector3f(0, 0, 0)); } /** @@ -133,19 +134,14 @@ public TerrainPatch(String name, int size) { * parameters and heightmap data are then processed to generate a * TriMesh object for rendering. * - * @param name - * the name of the terrain patch. - * @param size - * the size of the heightmap. - * @param stepScale - * the scale for the axes. - * @param heightMap - * the height data. - * @param origin - * the origin offset of the patch. + * @param name the name of the terrain patch. + * @param size the size of the heightmap. + * @param stepScale the scale for the axes. + * @param heightMap the height data. + * @param origin the origin offset of the patch. */ public TerrainPatch(String name, int size, Vector3f stepScale, - float[] heightMap, Vector3f origin) { + float[] heightMap, Vector3f origin) { this(name, size, stepScale, heightMap, origin, size, new Vector2f(), 0); } @@ -154,27 +150,19 @@ public TerrainPatch(String name, int size, Vector3f stepScale, * parameters and heightmap data are then processed to generate a * TriMesh object for renderering. * - * @param name - * the name of the terrain patch. - * @param size - * the size of the patch. - * @param stepScale - * the scale for the axes. - * @param heightMap - * the height data. - * @param origin - * the origin offset of the patch. - * @param totalSize - * the total size of the terrain. (Higher if the patch is part of - * a TerrainQuad tree. - * @param offset - * the offset for texture coordinates. - * @param offsetAmount - * the total offset amount. Used for texture coordinates. + * @param name the name of the terrain patch. + * @param size the size of the patch. + * @param stepScale the scale for the axes. + * @param heightMap the height data. + * @param origin the origin offset of the patch. + * @param totalSize the total size of the terrain. (Higher if the patch is part of + * a TerrainQuad tree. + * @param offset the offset for texture coordinates. + * @param offsetAmount the total offset amount. Used for texture coordinates. */ public TerrainPatch(String name, int size, Vector3f stepScale, - float[] heightMap, Vector3f origin, int totalSize, - Vector2f offset, float offsetAmount) { + float[] heightMap, Vector3f origin, int totalSize, + Vector2f offset, float offsetAmount) { super(name); setBatchHint(BatchHint.Never); this.size = size; @@ -186,7 +174,7 @@ public TerrainPatch(String name, int size, Vector3f stepScale, setLocalTranslation(origin); geomap = new LODGeomap(size, heightMap); - Mesh m = geomap.createMesh(stepScale, new Vector2f(1,1), offset, offsetAmount, totalSize, false); + Mesh m = geomap.createMesh(stepScale, new Vector2f(1, 1), offset, offsetAmount, totalSize, false); setMesh(m); } @@ -195,23 +183,23 @@ public TerrainPatch(String name, int size, Vector3f stepScale, * This calculation is slow, so don't use it often. */ public void generateLodEntropies() { - float[] entropies = new float[getMaxLod()+1]; - for (int i = 0; i <= getMaxLod(); i++){ + float[] entropies = new float[getMaxLod() + 1]; + for (int i = 0; i <= getMaxLod(); i++) { int curLod = (int) Math.pow(2, i); IndexBuffer idxB = geomap.writeIndexArrayLodDiff(curLod, false, false, false, false, totalSize); Buffer ib; if (idxB.getBuffer() instanceof IntBuffer) - ib = (IntBuffer)idxB.getBuffer(); + ib = (IntBuffer) idxB.getBuffer(); else - ib = (ShortBuffer)idxB.getBuffer(); + ib = (ShortBuffer) idxB.getBuffer(); entropies[i] = EntropyComputeUtil.computeLodEntropy(mesh, ib); } lodEntropy = entropies; } - public float[] getLodEntropies(){ - if (lodEntropy == null){ + public float[] getLodEntropies() { + if (lodEntropy == null) { generateLodEntropies(); } return lodEntropy; @@ -221,7 +209,7 @@ public float[] getLodEntropies(){ public FloatBuffer getHeightmap() { return BufferUtils.createFloatBuffer(geomap.getHeightArray()); } - + public float[] getHeightMap() { return geomap.getHeightArray(); } @@ -231,20 +219,21 @@ public float[] getHeightMap() { * If the patch size is 32 then the returned value would be log2(32)-2 = 3 * You can then use that value, 3, to see how many times you can divide 32 by 2 * before the terrain gets too un-detailed (can't stitch it any further). + * * @return the maximum LOD */ public int getMaxLod() { if (maxLod < 0) - maxLod = Math.max(1, (int) (FastMath.log(size-1)/FastMath.log(2)) -1); // -1 forces our minimum of 4 triangles wide + maxLod = Math.max(1, (int) (FastMath.log(size - 1) / FastMath.log(2)) - 1); // -1 forces our minimum of 4 triangles wide return maxLod; } - protected void reIndexGeometry(HashMap updated, boolean useVariableLod) { + protected void reIndexGeometry(HashMap updated, boolean useVariableLod) { UpdatedTerrainPatch utp = updated.get(getName()); - if (utp != null && utp.isReIndexNeeded() ) { + if (utp != null && utp.isReIndexNeeded()) { int pow = (int) Math.pow(2, utp.getNewLod()); boolean left = utp.getLeftLod() > utp.getNewLod(); boolean top = utp.getTopLod() > utp.getNewLod(); @@ -256,12 +245,12 @@ protected void reIndexGeometry(HashMap updated, bool idxB = geomap.writeIndexArrayLodVariable(pow, (int) Math.pow(2, utp.getRightLod()), (int) Math.pow(2, utp.getTopLod()), (int) Math.pow(2, utp.getLeftLod()), (int) Math.pow(2, utp.getBottomLod()), totalSize); else idxB = geomap.writeIndexArrayLodDiff(pow, right, top, left, bottom, totalSize); - + Buffer b; if (idxB.getBuffer() instanceof IntBuffer) - b = (IntBuffer)idxB.getBuffer(); + b = (IntBuffer) idxB.getBuffer(); else - b = (ShortBuffer)idxB.getBuffer(); + b = (ShortBuffer) idxB.getBuffer(); utp.setNewIndexBuffer(b); } @@ -274,39 +263,41 @@ public Vector2f getTex(float x, float z, Vector2f store) { return store; } int idx = (int) (z * size + x); - return store.set(getMesh().getFloatBuffer(Type.TexCoord).get(idx*2), - getMesh().getFloatBuffer(Type.TexCoord).get(idx*2+1) ); + return store.set(getMesh().getFloatBuffer(Type.TexCoord).get(idx * 2), + getMesh().getFloatBuffer(Type.TexCoord).get(idx * 2 + 1)); } - + public float getHeightmapHeight(float x, float z) { if (x < 0 || z < 0 || x >= size || z >= size) return 0; int idx = (int) (z * size + x); - return getMesh().getFloatBuffer(Type.Position).get(idx*3+1); // 3 floats per entry (x,y,z), the +1 is to get the Y + return getMesh().getFloatBuffer(Type.Position).get(idx * 3 + 1); // 3 floats per entry (x,y,z), the +1 is to get the Y } - + /** * Get the triangle of this geometry at the specified local coordinate. + * * @param x local to the terrain patch * @param z local to the terrain patch * @return the triangle in world coordinates, or null if the point does intersect this patch on the XZ axis */ public Triangle getTriangle(float x, float z) { - return geomap.getTriangleAtPoint(x, z, getWorldScale() , getWorldTranslation()); + return geomap.getTriangleAtPoint(x, z, getWorldScale(), getWorldTranslation()); } /** * Get the triangles at the specified grid point. Probably only 2 triangles + * * @param x local to the terrain patch * @param z local to the terrain patch * @return the triangles in world coordinates, or null if the point does intersect this patch on the XZ axis */ public Triangle[] getGridTriangles(float x, float z) { - return geomap.getGridTrianglesAtPoint(x, z, getWorldScale() , getWorldTranslation()); + return geomap.getGridTrianglesAtPoint(x, z, getWorldScale(), getWorldTranslation()); } protected void setHeight(List locationHeights, boolean overrideHeight) { - + for (LocationHeight lh : locationHeights) { if (lh.x < 0 || lh.z < 0 || lh.x >= size || lh.z >= size) continue; @@ -314,10 +305,10 @@ protected void setHeight(List locationHeights, boolean overrideH if (overrideHeight) { geomap.getHeightArray()[idx] = lh.h; } else { - float h = getMesh().getFloatBuffer(Type.Position).get(idx*3+1); - geomap.getHeightArray()[idx] = h+lh.h; + float h = getMesh().getFloatBuffer(Type.Position).get(idx * 3 + 1); + geomap.getHeightArray()[idx] = h + lh.h; } - + } FloatBuffer newVertexBuffer = geomap.writeVertexArray(null, stepScale, false); @@ -333,7 +324,7 @@ protected void updateNormals() { getMesh().getBuffer(Type.Normal).updateData(newNormalBuffer); FloatBuffer newTangentBuffer = null; FloatBuffer newBinormalBuffer = null; - FloatBuffer[] tb = geomap.writeTangentArray(newNormalBuffer, newTangentBuffer, newBinormalBuffer, (FloatBuffer)getMesh().getBuffer(Type.TexCoord).getData(), getWorldScale()); + FloatBuffer[] tb = geomap.writeTangentArray(newNormalBuffer, newTangentBuffer, newBinormalBuffer, (FloatBuffer) getMesh().getBuffer(Type.TexCoord).getData(), getWorldScale()); newTangentBuffer = tb[0]; newBinormalBuffer = tb[1]; getMesh().getBuffer(Type.Tangent).updateData(newTangentBuffer); @@ -344,39 +335,38 @@ private void setInBuffer(Mesh mesh, int index, Vector3f normal, Vector3f tangent VertexBuffer NB = mesh.getBuffer(Type.Normal); VertexBuffer TB = mesh.getBuffer(Type.Tangent); VertexBuffer BB = mesh.getBuffer(Type.Binormal); - BufferUtils.setInBuffer(normal, (FloatBuffer)NB.getData(), index); - BufferUtils.setInBuffer(tangent, (FloatBuffer)TB.getData(), index); - BufferUtils.setInBuffer(binormal, (FloatBuffer)BB.getData(), index); + BufferUtils.setInBuffer(normal, (FloatBuffer) NB.getData(), index); + BufferUtils.setInBuffer(tangent, (FloatBuffer) TB.getData(), index); + BufferUtils.setInBuffer(binormal, (FloatBuffer) BB.getData(), index); NB.setUpdateNeeded(); TB.setUpdateNeeded(); BB.setUpdateNeeded(); } - + /** * Matches the normals along the edge of the patch with the neighbours. * Computes the normals for the right, bottom, left, and top edges of the * patch, and saves those normals in the neighbour's edges too. - * + *

* Takes 4 points (if has neighbour on that side) for each * point on the edge of the patch: - * * - * | - * *---x---* - * | - * * - * It works across the right side of the patch, from the top down to + * * + * | + * *---x---* + * | + * * + * It works across the right side of the patch, from the top down to * the bottom. Then it works on the bottom side of the patch, from the * left to the right. */ protected void fixNormalEdges(TerrainPatch right, - TerrainPatch bottom, - TerrainPatch top, - TerrainPatch left, - TerrainPatch bottomRight, - TerrainPatch bottomLeft, - TerrainPatch topRight, - TerrainPatch topLeft) - { + TerrainPatch bottom, + TerrainPatch top, + TerrainPatch left, + TerrainPatch bottomRight, + TerrainPatch bottomLeft, + TerrainPatch topRight, + TerrainPatch topLeft) { Vector3f rootPoint = new Vector3f(); Vector3f rightPoint = new Vector3f(); Vector3f leftPoint = new Vector3f(); @@ -388,228 +378,269 @@ protected void fixNormalEdges(TerrainPatch right, Vector3f binormal = new Vector3f(); Vector3f normal = new Vector3f(); - - int s = this.getSize()-1; - + + int s = this.getSize() - 1; + if (right != null) { // right side, works its way down - for (int i=0; i= size || z >= size) return null; // out of range - - int index = (z*size+x)*3; - FloatBuffer nb = (FloatBuffer)this.getMesh().getBuffer(Type.Normal).getData(); + + int index = (z * size + x) * 3; + FloatBuffer nb = (FloatBuffer) this.getMesh().getBuffer(Type.Normal).getData(); Vector3f normal = new Vector3f(); normal.x = nb.get(index); - normal.y = nb.get(index+1); - normal.z = nb.get(index+2); + normal.y = nb.get(index + 1); + normal.z = nb.get(index + 2); return normal; } + protected TerrainPatch createQuadPatch(int patchNumber, float[] heightMap, int split, int halfSize, int quarterSize) { + float[] heightBlock; + Vector3f origin; + Vector2f tempOffset = new Vector2f(); + tempOffset.x = offset.x; + tempOffset.y = offset.y; + + TerrainQuad test = new TerrainQuad(); + + if (patchNumber == 1) { + heightBlock = test.createHeightSubBlock(heightMap, 0, 0, split); + origin = new Vector3f(-halfSize * stepScale.x, 0, -halfSize + * stepScale.z); + tempOffset.x += origin.x / 2; + tempOffset.y += origin.z / 2; + } else if (patchNumber == 2) { + heightBlock = test.createHeightSubBlock(heightMap, 0, split - 1, split); + origin = new Vector3f(-halfSize * stepScale.x, 0, 0); + tempOffset.x += origin.x / 2; + tempOffset.y += quarterSize * stepScale.z; + + } else if (patchNumber == 3) { + heightBlock = test.createHeightSubBlock(heightMap, split - 1, 0, split); + origin = new Vector3f(0, 0, -halfSize * stepScale.z); + tempOffset.x += quarterSize * stepScale.x; + tempOffset.y += origin.z / 2; + } else { + heightBlock = test.createHeightSubBlock(heightMap, split - 1, + split - 1, split); + origin = new Vector3f(0, 0, 0); + tempOffset.x += quarterSize * stepScale.x; + tempOffset.y += quarterSize * stepScale.z; + } + + + return new TerrainPatch(getName() + "Patch" + patchNumber, split, + stepScale, heightBlock, origin, totalSize, tempOffset, + offsetAmount); + + } + + protected float getHeight(int x, int z, float xm, float zm) { - return geomap.getHeight(x,z,xm,zm); + return geomap.getHeight(x, z, xm, zm); } - + /** * Locks the mesh (sets it static) to improve performance. * But it it not editable then. Set unlock to make it editable. @@ -626,7 +657,7 @@ public void lockMesh() { public void unlockMesh() { getMesh().setDynamic(); } - + /** * Returns the offset amount this terrain patch uses for textures. * @@ -678,8 +709,7 @@ public Vector2f getOffset() { * coordinates. Note that this does NOT rebuild the terrain at all. * This is mostly used for outside constructors of terrain patches. * - * @param offset - * The new texture offset. + * @param offset The new texture offset. */ public void setOffset(Vector2f offset) { this.offset = offset; @@ -690,8 +720,7 @@ public void setOffset(Vector2f offset) { * rebuild the terrain at all. This is mostly used for outside constructors * of terrain patches. * - * @param size - * The new size. + * @param size The new size. */ public void setSize(int size) { this.size = size; @@ -704,8 +733,7 @@ public void setSize(int size) { * rebuild the terrain at all. This is mostly used for outside constructors * of terrain patches. * - * @param totalSize - * The new total size. + * @param totalSize The new total size. */ public void setTotalSize(int totalSize) { this.totalSize = totalSize; @@ -716,8 +744,7 @@ public void setTotalSize(int totalSize) { * does NOT rebuild the terrain at all. This is mostly used for * outside constructors of terrain patches. * - * @param stepScale - * The new step scale. + * @param stepScale The new step scale. */ public void setStepScale(Vector3f stepScale) { this.stepScale = stepScale; @@ -728,8 +755,7 @@ public void setStepScale(Vector3f stepScale) { * rebuild the terrain at all. This is mostly used for outside * constructors of terrain patches. * - * @param offsetAmount - * The new texture offset. + * @param offsetAmount The new texture offset. */ public void setOffsetAmount(float offsetAmount) { this.offsetAmount = offsetAmount; @@ -743,8 +769,7 @@ public short getQuadrant() { } /** - * @param quadrant - * The quadrant to set. + * @param quadrant The quadrant to set. */ public void setQuadrant(short quadrant) { this.quadrant = quadrant; @@ -807,18 +832,18 @@ protected void setLodBottom(int lodBottom) { public int collideWith(Collidable other, CollisionResults results) throws UnsupportedCollisionException { if (refreshFlags != 0) throw new IllegalStateException("Scene graph must be updated" + - " before checking collision"); + " before checking collision"); if (other instanceof BoundingVolume) - if (!getWorldBound().intersects((BoundingVolume)other)) + if (!getWorldBound().intersects((BoundingVolume) other)) return 0; - - if(other instanceof Ray) - return collideWithRay((Ray)other, results); + + if (other instanceof Ray) + return collideWithRay((Ray) other, results); else if (other instanceof BoundingVolume) - return collideWithBoundingVolume((BoundingVolume)other, results); + return collideWithBoundingVolume((BoundingVolume) other, results); else { - throw new UnsupportedCollisionException("TerrainPatch cannnot collide with "+other.getClass().getName()); + throw new UnsupportedCollisionException("TerrainPatch cannnot collide with " + other.getClass().getName()); } } @@ -830,12 +855,12 @@ private int collideWithRay(Ray ray, CollisionResults results) { private int collideWithBoundingVolume(BoundingVolume boundingVolume, CollisionResults results) { if (boundingVolume instanceof BoundingBox) - return collideWithBoundingBox((BoundingBox)boundingVolume, results); - else if(boundingVolume instanceof BoundingSphere) { + return collideWithBoundingBox((BoundingBox) boundingVolume, results); + else if (boundingVolume instanceof BoundingSphere) { BoundingSphere sphere = (BoundingSphere) boundingVolume; BoundingBox bbox = new BoundingBox(boundingVolume.getCenter().clone(), sphere.getRadius(), - sphere.getRadius(), - sphere.getRadius()); + sphere.getRadius(), + sphere.getRadius()); return collideWithBoundingBox(bbox, results); } return 0; @@ -843,9 +868,9 @@ else if(boundingVolume instanceof BoundingSphere) { protected Vector3f worldCoordinateToLocal(Vector3f loc) { Vector3f translated = new Vector3f(); - translated.x = loc.x/getWorldScale().x - getWorldTranslation().x; - translated.y = loc.y/getWorldScale().y - getWorldTranslation().y; - translated.z = loc.z/getWorldScale().z - getWorldTranslation().z; + translated.x = loc.x / getWorldScale().x - getWorldTranslation().x; + translated.y = loc.y / getWorldScale().y - getWorldTranslation().y; + translated.z = loc.z / getWorldScale().z - getWorldTranslation().z; return translated; } @@ -853,12 +878,12 @@ protected Vector3f worldCoordinateToLocal(Vector3f loc) { * This most definitely is not optimized. */ private int collideWithBoundingBox(BoundingBox bbox, CollisionResults results) { - + // test the four corners, for cases where the bbox dimensions are less than the terrain grid size, which is probably most of the time - Vector3f topLeft = worldCoordinateToLocal(new Vector3f(bbox.getCenter().x-bbox.getXExtent(), 0, bbox.getCenter().z-bbox.getZExtent())); - Vector3f topRight = worldCoordinateToLocal(new Vector3f(bbox.getCenter().x+bbox.getXExtent(), 0, bbox.getCenter().z-bbox.getZExtent())); - Vector3f bottomLeft = worldCoordinateToLocal(new Vector3f(bbox.getCenter().x-bbox.getXExtent(), 0, bbox.getCenter().z+bbox.getZExtent())); - Vector3f bottomRight = worldCoordinateToLocal(new Vector3f(bbox.getCenter().x+bbox.getXExtent(), 0, bbox.getCenter().z+bbox.getZExtent())); + Vector3f topLeft = worldCoordinateToLocal(new Vector3f(bbox.getCenter().x - bbox.getXExtent(), 0, bbox.getCenter().z - bbox.getZExtent())); + Vector3f topRight = worldCoordinateToLocal(new Vector3f(bbox.getCenter().x + bbox.getXExtent(), 0, bbox.getCenter().z - bbox.getZExtent())); + Vector3f bottomLeft = worldCoordinateToLocal(new Vector3f(bbox.getCenter().x - bbox.getXExtent(), 0, bbox.getCenter().z + bbox.getZExtent())); + Vector3f bottomRight = worldCoordinateToLocal(new Vector3f(bbox.getCenter().x + bbox.getXExtent(), 0, bbox.getCenter().z + bbox.getZExtent())); Triangle t = getTriangle(topLeft.x, topLeft.z); if (t != null && bbox.collideWith(t, results) > 0) @@ -872,14 +897,14 @@ private int collideWithBoundingBox(BoundingBox bbox, CollisionResults results) { t = getTriangle(bottomRight.x, bottomRight.z); if (t != null && bbox.collideWith(t, results) > 0) return 1; - + // box is larger than the points on the terrain, so test against the points - for (float z=topLeft.z; z= size || z >= size) continue; - t = getTriangle(x,z); + t = getTriangle(x, z); if (t != null && bbox.collideWith(t, results) > 0) return 1; } @@ -895,12 +920,12 @@ public void write(JmeExporter ex) throws IOException { // this reduces the save size to 10% by not saving the mesh Mesh temp = getMesh(); mesh = null; - + super.write(ex); OutputCapsule oc = ex.getCapsule(this); oc.write(size, "size", 16); oc.write(totalSize, "totalSize", 16); - oc.write(quadrant, "quadrant", (short)0); + oc.write(quadrant, "quadrant", (short) 0); oc.write(stepScale, "stepScale", Vector3f.UNIT_XYZ); oc.write(offset, "offset", Vector3f.UNIT_XYZ); oc.write(offsetAmount, "offsetAmount", 0); @@ -908,7 +933,7 @@ public void write(JmeExporter ex) throws IOException { //oc.write(lodCalculatorFactory, "lodCalculatorFactory", null); oc.write(lodEntropy, "lodEntropy", null); oc.write(geomap, "geomap", null); - + setMesh(temp); } @@ -918,7 +943,7 @@ public void read(JmeImporter im) throws IOException { InputCapsule ic = im.getCapsule(this); size = ic.readInt("size", 16); totalSize = ic.readInt("totalSize", 16); - quadrant = ic.readShort("quadrant", (short)0); + quadrant = ic.readShort("quadrant", (short) 0); stepScale = (Vector3f) ic.readSavable("stepScale", Vector3f.UNIT_XYZ); offset = (Vector2f) ic.readSavable("offset", Vector3f.UNIT_XYZ); offsetAmount = ic.readFloat("offsetAmount", 0); @@ -927,8 +952,8 @@ public void read(JmeImporter im) throws IOException { //lodCalculatorFactory = (LodCalculatorFactory) ic.readSavable("lodCalculatorFactory", null); lodEntropy = ic.readFloatArray("lodEntropy", null); geomap = (LODGeomap) ic.readSavable("geomap", null); - - Mesh regen = geomap.createMesh(stepScale, new Vector2f(1,1), offset, offsetAmount, totalSize, false); + + Mesh regen = geomap.createMesh(stepScale, new Vector2f(1, 1), offset, offsetAmount, totalSize, false); setMesh(regen); //TangentBinormalGenerator.generate(this); // note that this will be removed ensurePositiveVolumeBBox(); @@ -957,9 +982,9 @@ public TerrainPatch clone() { protected void ensurePositiveVolumeBBox() { if (getModelBound() instanceof BoundingBox) { - if (((BoundingBox)getModelBound()).getYExtent() < 0.001f) { + if (((BoundingBox) getModelBound()).getYExtent() < 0.001f) { // a correction so the box always has a volume - ((BoundingBox)getModelBound()).setYExtent(0.001f); + ((BoundingBox) getModelBound()).setYExtent(0.001f); updateWorldBound(); } } diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 2e21c7feaf..47087f7dcb 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -48,7 +48,6 @@ import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.debug.WireBox; -import com.jme3.system.SystemListener; import com.jme3.terrain.ProgressMonitor; import com.jme3.terrain.Terrain; import com.jme3.terrain.geomipmap.lodcalc.LodCalculator; @@ -56,6 +55,7 @@ import com.jme3.terrain.geomipmap.picking.TerrainPickData; import com.jme3.terrain.geomipmap.picking.TerrainPicker; import com.jme3.util.TangentBinormalGenerator; + import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -104,6 +104,7 @@ * +---------> +z * (world coordinates) * + * * @author Brent Owens */ public class TerrainQuad extends Node implements Terrain { @@ -127,7 +128,7 @@ public class TerrainQuad extends Node implements Terrain { private Vector3f lastScale = Vector3f.UNIT_XYZ; protected NeighbourFinder neighbourFinder; - + public TerrainQuad() { super("Terrain"); } @@ -143,33 +144,33 @@ public TerrainQuad() { * A TerrainQuad of totalSize 513x513 will be 513 units wide and 513 units long. * PatchSize is just used to subdivide the terrain into tiles that can be culled. *

- * @param name the name of the scene element. This is required for - * identification and comparison purposes. - * @param patchSize size of the individual patches (geometry). Power of 2 plus 1, - * must be smaller than totalSize. (eg. 33, 65...) - * @param totalSize the size of this entire terrain (on one side). Power of 2 plus 1 - * (eg. 513, 1025, 2049...) + * + * @param name the name of the scene element. This is required for + * identification and comparison purposes. + * @param patchSize size of the individual patches (geometry). Power of 2 plus 1, + * must be smaller than totalSize. (eg. 33, 65...) + * @param totalSize the size of this entire terrain (on one side). Power of 2 plus 1 + * (eg. 513, 1025, 2049...) * @param heightMap The height map to generate the terrain from (a flat - * height map will be generated if this is null). The size of one side of the heightmap - * must match the totalSize. So a 513x513 heightmap is needed for a terrain with totalSize of 513. + * height map will be generated if this is null). The size of one side of the heightmap + * must match the totalSize. So a 513x513 heightmap is needed for a terrain with totalSize of 513. */ public TerrainQuad(String name, int patchSize, int totalSize, float[] heightMap) { this(name, patchSize, totalSize, Vector3f.UNIT_XYZ, heightMap); - - affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size*2, Float.MAX_VALUE, size*2); + + affectedAreaBBox = new BoundingBox(new Vector3f(0, 0, 0), size * 2, Float.MAX_VALUE, size * 2); fixNormalEdges(affectedAreaBBox); addControl(new NormalRecalcControl(this)); } - + /** - * - * @param name the name of the scene element. This is required for - * identification and comparison purposes. + * @param name the name of the scene element. This is required for + * identification and comparison purposes. * @param patchSize size of the individual patches * @param quadSize * @param totalSize the size of this entire terrain tree (on one side) * @param heightMap The height map to generate the terrain from (a flat - * height map will be generated if this is null) + * height map will be generated if this is null) */ @Deprecated public TerrainQuad(String name, int patchSize, int quadSize, int totalSize, float[] heightMap) { @@ -177,14 +178,13 @@ public TerrainQuad(String name, int patchSize, int quadSize, int totalSize, floa } /** - * - * @param name the name of the scene element. This is required for - * identification and comparison purposes. + * @param name the name of the scene element. This is required for + * identification and comparison purposes. * @param patchSize size of the individual patches - * @param size size of this quad, can be between totalSize and patchSize + * @param size size of this quad, can be between totalSize and patchSize * @param scale * @param heightMap The height map to generate the terrain from (a flat - * height map will be generated if this is null) + * height map will be generated if this is null) */ @Deprecated public TerrainQuad(String name, int patchSize, int size, Vector3f scale, float[] heightMap) { @@ -193,17 +193,16 @@ public TerrainQuad(String name, int patchSize, int size, Vector3f scale, float[] //fixNormalEdges(affectedAreaBBox); //addControl(new NormalRecalcControl(this)); } - + /** - * - * @param name the name of the scene element. This is required for - * identification and comparison purposes. + * @param name the name of the scene element. This is required for + * identification and comparison purposes. * @param patchSize size of the individual patches * @param totalSize the size of this entire terrain tree (on one side) * @param quadSize * @param scale * @param heightMap The height map to generate the terrain from (a flat - * height map will be generated if this is null) + * height map will be generated if this is null) */ @Deprecated public TerrainQuad(String name, int patchSize, int totalSize, int quadSize, Vector3f scale, float[] heightMap) { @@ -214,21 +213,20 @@ public TerrainQuad(String name, int patchSize, int totalSize, int quadSize, Vect } protected TerrainQuad(String name, int patchSize, int quadSize, - Vector3f scale, float[] heightMap, int totalSize, - Vector2f offset, float offsetAmount) - { + Vector3f scale, float[] heightMap, int totalSize, + Vector2f offset, float offsetAmount) { super(name); - + if (heightMap == null) heightMap = generateDefaultHeightMap(quadSize); - + if (!FastMath.isPowerOfTwo(quadSize - 1)) { throw new RuntimeException("size given: " + quadSize + " Terrain quad sizes may only be (2^N + 1)"); } if (FastMath.sqrt(heightMap.length) > quadSize) { Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Heightmap size is larger than the terrain size. Make sure your heightmap image is the same size as the terrain!"); } - + this.offset = offset; this.offsetAmount = offsetAmount; this.totalSize = totalSize; @@ -247,14 +245,14 @@ public void setNeighbourFinder(NeighbourFinder neighbourFinder) { * Forces the recalculation of all normals on the terrain. */ public void recalculateAllNormals() { - affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), totalSize*2, Float.MAX_VALUE, totalSize*2); + affectedAreaBBox = new BoundingBox(new Vector3f(0, 0, 0), totalSize * 2, Float.MAX_VALUE, totalSize * 2); } - + /** * Create just a flat heightmap */ private float[] generateDefaultHeightMap(int size) { - float[] heightMap = new float[size*size]; + float[] heightMap = new float[size * size]; return heightMap; } @@ -268,17 +266,17 @@ protected void updateNormals() { //TODO background-thread this if it ends up being expensive fixNormals(affectedAreaBBox); // the affected patches fixNormalEdges(affectedAreaBBox); // the edges between the patches - + setNormalRecalcNeeded(null); // set to false } } - + /** * Caches the transforms (except rotation) so the LOD calculator, * which runs on a separate thread, can access them safely. */ protected void cacheTerrainTransforms() { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).cacheTerrainTransforms(); @@ -308,21 +306,22 @@ private int collideWithRay(Ray ray, CollisionResults results) { /** * Generate the entropy values for the terrain for the "perspective" LOD * calculator. This routine can take a long time to run! + * * @param progressMonitor optional */ public void generateEntropy(ProgressMonitor progressMonitor) { // only check this on the root quad if (isRootQuad()) if (progressMonitor != null) { - int numCalc = (totalSize-1)/(patchSize-1); // make it an even number - progressMonitor.setMonitorMax(numCalc*numCalc); + int numCalc = (totalSize - 1) / (patchSize - 1); // make it an even number + progressMonitor.setMonitorMax(numCalc * numCalc); } if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { - ((TerrainQuad) child).generateEntropy(progressMonitor); + ((TerrainQuad) child).generateEntropy(progressMonitor); } else if (child instanceof TerrainPatch) { ((TerrainPatch) child).generateLodEntropies(); if (progressMonitor != null) @@ -338,22 +337,22 @@ public void generateEntropy(ProgressMonitor progressMonitor) { } protected boolean isRootQuad() { - return (getParent() != null && !(getParent() instanceof TerrainQuad) ); + return (getParent() != null && !(getParent() instanceof TerrainQuad)); } public Material getMaterial() { return getMaterial(null); } - + public Material getMaterial(Vector3f worldLocation) { // get the material from one of the children. They all share the same material if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { - return ((TerrainQuad)child).getMaterial(worldLocation); + return ((TerrainQuad) child).getMaterial(worldLocation); } else if (child instanceof TerrainPatch) { - return ((TerrainPatch)child).getMaterial(); + return ((TerrainPatch) child).getMaterial(); } } } @@ -363,23 +362,21 @@ public Material getMaterial(Vector3f worldLocation) { public int getNumMajorSubdivisions() { return 1; } - - protected boolean calculateLod(List location, HashMap updates, LodCalculator lodCalculator) { + + protected boolean calculateLod(List location, HashMap updates, LodCalculator lodCalculator) { boolean lodChanged = false; if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { - System.out.println("hier quad"); boolean b = ((TerrainQuad) child).calculateLod(location, updates, lodCalculator); if (b) lodChanged = true; } else if (child instanceof TerrainPatch) { - System.out.println("hier patch"); boolean b = lodCalculator.calculateLod((TerrainPatch) child, location, updates); if (b) lodChanged = true; @@ -390,9 +387,9 @@ protected boolean calculateLod(List location, HashMap updated) { + protected synchronized void findNeighboursLod(HashMap updated) { if (children != null) { - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { ((TerrainQuad) child).findNeighboursLod(updated); @@ -438,7 +435,7 @@ protected synchronized void findNeighboursLod(HashMap= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { ((TerrainQuad) child).resetCachedNeighbours(); @@ -482,14 +479,14 @@ public void resetCachedNeighbours() { } } } - + /** * Find any neighbours that should have their edges seamed because another neighbour * changed its LOD to a greater value (less detailed) */ - protected synchronized void fixEdges(HashMap updated) { + protected synchronized void fixEdges(HashMap updated) { if (children != null) { - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { ((TerrainQuad) child).fixEdges(updated); @@ -497,7 +494,7 @@ protected synchronized void fixEdges(HashMap updated TerrainPatch patch = (TerrainPatch) child; UpdatedTerrainPatch utp = updated.get(patch.getName()); - if(utp != null && utp.lodChanged()) { + if (utp != null && utp.lodChanged()) { if (!patch.searchedForNeighboursAlready) { // set the references to the neighbours patch.rightNeighbour = findRightPatch(patch); @@ -530,7 +527,7 @@ protected synchronized void fixEdges(HashMap updated utpD.setTopLod(utp.getNewLod()); utpD.setFixEdges(true); } - if (top != null){ + if (top != null) { UpdatedTerrainPatch utpT = updated.get(top.getName()); if (utpT == null) { utpT = new UpdatedTerrainPatch(top); @@ -540,7 +537,7 @@ protected synchronized void fixEdges(HashMap updated utpT.setBottomLod(utp.getNewLod()); utpT.setFixEdges(true); } - if (left != null){ + if (left != null) { UpdatedTerrainPatch utpL = updated.get(left.getName()); if (utpL == null) { utpL = new UpdatedTerrainPatch(left); @@ -556,9 +553,9 @@ protected synchronized void fixEdges(HashMap updated } } - protected synchronized void reIndexPages(HashMap updated, boolean usesVariableLod) { + protected synchronized void reIndexPages(HashMap updated, boolean usesVariableLod) { if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).reIndexPages(updated, usesVariableLod); @@ -575,10 +572,8 @@ protected synchronized void reIndexPages(HashMap upd * children. If the child's size is less than or equal to the set block * size, then patches are created, otherwise, quads are created. * - * @param blockSize - * the blocks size to test against. - * @param heightMap - * the height data. + * @param blockSize the blocks size to test against. + * @param heightMap the height data. */ protected void split(int blockSize, float[] heightMap) { if ((size >> 1) + 1 <= blockSize) { @@ -591,14 +586,14 @@ protected void split(int blockSize, float[] heightMap) { /** * Quadrants, world coordinates, and heightmap coordinates (Y-up): - * - * -z - * -u | - * -v 1|3 - * -x ----+---- x - * 2|4 u - * | v - * z + *

+ * -z + * -u | + * -v 1|3 + * -x ----+---- x + * 2|4 u + * | v + * z * createQuad generates four new quads from this quad. * The heightmap's top left (0,0) coordinate is at the bottom, -x,-z * coordinate of the terrain, so it grows in the positive x.z direction. @@ -619,7 +614,7 @@ protected void createQuad(int blockSize, float[] heightMap) { float[] heightBlock1 = createHeightSubBlock(heightMap, 0, 0, split); Vector3f origin1 = new Vector3f(-quarterSize * stepScale.x, 0, - -quarterSize * stepScale.z); + -quarterSize * stepScale.z); tempOffset.x = offset.x; tempOffset.y = offset.y; @@ -627,18 +622,18 @@ protected void createQuad(int blockSize, float[] heightMap) { tempOffset.y += origin1.z; TerrainQuad quad1 = new TerrainQuad(getName() + "Quad1", blockSize, - split, stepScale, heightBlock1, totalSize, tempOffset, - offsetAmount); + split, stepScale, heightBlock1, totalSize, tempOffset, + offsetAmount); quad1.setLocalTranslation(origin1); quad1.quadrant = 1; this.attachChild(quad1); // 2 lower left of heightmap, lower left quad float[] heightBlock2 = createHeightSubBlock(heightMap, 0, split - 1, - split); + split); Vector3f origin2 = new Vector3f(-quarterSize * stepScale.x, 0, - quarterSize * stepScale.z); + quarterSize * stepScale.z); tempOffset = new Vector2f(); tempOffset.x = offset.x; @@ -647,18 +642,18 @@ protected void createQuad(int blockSize, float[] heightMap) { tempOffset.y += origin2.z; TerrainQuad quad2 = new TerrainQuad(getName() + "Quad2", blockSize, - split, stepScale, heightBlock2, totalSize, tempOffset, - offsetAmount); + split, stepScale, heightBlock2, totalSize, tempOffset, + offsetAmount); quad2.setLocalTranslation(origin2); quad2.quadrant = 2; this.attachChild(quad2); // 3 upper right of heightmap, upper right quad float[] heightBlock3 = createHeightSubBlock(heightMap, split - 1, 0, - split); + split); Vector3f origin3 = new Vector3f(quarterSize * stepScale.x, 0, - -quarterSize * stepScale.z); + -quarterSize * stepScale.z); tempOffset = new Vector2f(); tempOffset.x = offset.x; @@ -667,18 +662,18 @@ protected void createQuad(int blockSize, float[] heightMap) { tempOffset.y += origin3.z; TerrainQuad quad3 = new TerrainQuad(getName() + "Quad3", blockSize, - split, stepScale, heightBlock3, totalSize, tempOffset, - offsetAmount); + split, stepScale, heightBlock3, totalSize, tempOffset, + offsetAmount); quad3.setLocalTranslation(origin3); quad3.quadrant = 3; this.attachChild(quad3); - + // 4 lower right of heightmap, lower right quad float[] heightBlock4 = createHeightSubBlock(heightMap, split - 1, - split - 1, split); + split - 1, split); Vector3f origin4 = new Vector3f(quarterSize * stepScale.x, 0, - quarterSize * stepScale.z); + quarterSize * stepScale.z); tempOffset = new Vector2f(); tempOffset.x = offset.x; @@ -687,8 +682,8 @@ protected void createQuad(int blockSize, float[] heightMap) { tempOffset.y += origin4.z; TerrainQuad quad4 = new TerrainQuad(getName() + "Quad4", blockSize, - split, stepScale, heightBlock4, totalSize, tempOffset, - offsetAmount); + split, stepScale, heightBlock4, totalSize, tempOffset, + offsetAmount); quad4.setLocalTranslation(origin4); quad4.quadrant = 4; this.attachChild(quad4); @@ -696,13 +691,13 @@ protected void createQuad(int blockSize, float[] heightMap) { } public void generateDebugTangents(Material mat) { - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { - ((TerrainQuad)child).generateDebugTangents(mat); + ((TerrainQuad) child).generateDebugTangents(mat); } else if (child instanceof TerrainPatch) { - Geometry debug = new Geometry( "Debug " + name, - TangentBinormalGenerator.genTbnLines( ((TerrainPatch)child).getMesh(), 0.8f)); + Geometry debug = new Geometry("Debug " + name, + TangentBinormalGenerator.genTbnLines(((TerrainPatch) child).getMesh(), 0.8f)); attachChild(debug); debug.setLocalTranslation(child.getLocalTranslation()); debug.setCullHint(CullHint.Never); @@ -711,111 +706,161 @@ public void generateDebugTangents(Material mat) { } } + protected void createQuadPatch(int patchNumber, float[] heightMap, int split, int halfSize, int quarterSize) { + float[] heightBlock; + Vector3f origin; + Vector2f tempOffset = new Vector2f(); + tempOffset.x = offset.x; + tempOffset.y = offset.y; + + if (patchNumber == 1) { + heightBlock = createHeightSubBlock(heightMap, 0, 0, split); + origin = new Vector3f(-halfSize * stepScale.x, 0, -halfSize + * stepScale.z); + tempOffset.x += origin.x / 2; + tempOffset.y += origin.z / 2; + } else if (patchNumber == 2) { + heightBlock = createHeightSubBlock(heightMap, 0, split - 1, split); + origin = new Vector3f(-halfSize * stepScale.x, 0, 0); + tempOffset.x += origin.x / 2; + tempOffset.y += quarterSize * stepScale.z; + + } else if (patchNumber == 3) { + heightBlock = createHeightSubBlock(heightMap, split - 1, 0, split); + origin = new Vector3f(0, 0, -halfSize * stepScale.z); + tempOffset.x += quarterSize * stepScale.x; + tempOffset.y += origin.z / 2; + } else { + heightBlock = createHeightSubBlock(heightMap, split - 1, + split - 1, split); + origin = new Vector3f(0, 0, 0); + tempOffset.x += quarterSize * stepScale.x; + tempOffset.y += quarterSize * stepScale.z; + } + + + TerrainPatch patch = new TerrainPatch(getName() + "Patch" + patchNumber, split, + stepScale, heightBlock, origin, totalSize, tempOffset, + offsetAmount); + patch.setQuadrant((short) patchNumber); + this.attachChild(patch); + patch.setModelBound(new BoundingBox()); + patch.updateModelBound(); + } + /** * createQuadPatch creates four child patches from this quad. */ protected void createQuadPatch(float[] heightMap) { + + TerrainPatch test = new TerrainPatch(); // create 4 terrain patches int quarterSize = size >> 2; int halfSize = size >> 1; int split = (size + 1) >> 1; - //if (lodCalculator == null) - // lodCalculator = createDefaultLodCalculator(); // set a default one - offsetAmount += quarterSize; - // 1 lower left - float[] heightBlock1 = createHeightSubBlock(heightMap, 0, 0, split); - - Vector3f origin1 = new Vector3f(-halfSize * stepScale.x, 0, -halfSize - * stepScale.z); - - Vector2f tempOffset1 = new Vector2f(); - tempOffset1.x = offset.x; - tempOffset1.y = offset.y; - tempOffset1.x += origin1.x / 2; - tempOffset1.y += origin1.z / 2; - - TerrainPatch patch1 = new TerrainPatch(getName() + "Patch1", split, - stepScale, heightBlock1, origin1, totalSize, tempOffset1, - offsetAmount); - patch1.setQuadrant((short) 1); - this.attachChild(patch1); - patch1.setModelBound(new BoundingBox()); - patch1.updateModelBound(); - //patch1.setLodCalculator(lodCalculator); - //TangentBinormalGenerator.generate(patch1); - - // 2 upper left - float[] heightBlock2 = createHeightSubBlock(heightMap, 0, split - 1, - split); - - Vector3f origin2 = new Vector3f(-halfSize * stepScale.x, 0, 0); - - Vector2f tempOffset2 = new Vector2f(); - tempOffset2.x = offset.x; - tempOffset2.y = offset.y; - tempOffset2.x += origin1.x / 2; - tempOffset2.y += quarterSize * stepScale.z; - - TerrainPatch patch2 = new TerrainPatch(getName() + "Patch2", split, - stepScale, heightBlock2, origin2, totalSize, tempOffset2, - offsetAmount); - patch2.setQuadrant((short) 2); - this.attachChild(patch2); - patch2.setModelBound(new BoundingBox()); - patch2.updateModelBound(); - //patch2.setLodCalculator(lodCalculator); - //TangentBinormalGenerator.generate(patch2); - - // 3 lower right - float[] heightBlock3 = createHeightSubBlock(heightMap, split - 1, 0, - split); - - Vector3f origin3 = new Vector3f(0, 0, -halfSize * stepScale.z); - - Vector2f tempOffset3 = new Vector2f(); - tempOffset3.x = offset.x; - tempOffset3.y = offset.y; - tempOffset3.x += quarterSize * stepScale.x; - tempOffset3.y += origin3.z / 2; - - TerrainPatch patch3 = new TerrainPatch(getName() + "Patch3", split, - stepScale, heightBlock3, origin3, totalSize, tempOffset3, - offsetAmount); - patch3.setQuadrant((short) 3); - this.attachChild(patch3); - patch3.setModelBound(new BoundingBox()); - patch3.updateModelBound(); - //patch3.setLodCalculator(lodCalculator); - //TangentBinormalGenerator.generate(patch3); - - // 4 upper right - float[] heightBlock4 = createHeightSubBlock(heightMap, split - 1, - split - 1, split); - Vector3f origin4 = new Vector3f(0, 0, 0); - - Vector2f tempOffset4 = new Vector2f(); - tempOffset4.x = offset.x; - tempOffset4.y = offset.y; - tempOffset4.x += quarterSize * stepScale.x; - tempOffset4.y += quarterSize * stepScale.z; + for (int i = 1; i < 5; i++) { + //TerrainPatch patch = test.createQuadPatch(i, heightMap, split, halfSize, quarterSize); + createQuadPatch(i, heightMap, split, halfSize, quarterSize); +// patch.setQuadrant((short) i); +// this.attachChild(patch); +// patch.setModelBound(new BoundingBox()); +// patch.updateModelBound(); + } - TerrainPatch patch4 = new TerrainPatch(getName() + "Patch4", split, - stepScale, heightBlock4, origin4, totalSize, tempOffset4, - offsetAmount); - patch4.setQuadrant((short) 4); - this.attachChild(patch4); - patch4.setModelBound(new BoundingBox()); - patch4.updateModelBound(); - //patch4.setLodCalculator(lodCalculator); - //TangentBinormalGenerator.generate(patch4); + // 1 lower left +// float[] heightBlock1 = createHeightSubBlock(heightMap, 0, 0, split); +// +// Vector3f origin1 = new Vector3f(-halfSize * stepScale.x, 0, -halfSize +// * stepScale.z); +// +// Vector2f tempOffset1 = new Vector2f(); +// tempOffset1.x = offset.x; +// tempOffset1.y = offset.y; +// tempOffset1.x += origin1.x / 2; +// tempOffset1.y += origin1.z / 2; +// +// TerrainPatch patch1 = new TerrainPatch(getName() + "Patch1", split, +// stepScale, heightBlock1, origin1, totalSize, tempOffset1, +// offsetAmount); +// patch1.setQuadrant((short) 1); +// this.attachChild(patch1); +// patch1.setModelBound(new BoundingBox()); +// patch1.updateModelBound(); +// +// // 2 upper left +// float[] heightBlock2 = createHeightSubBlock(heightMap, 0, split - 1, +// split); +// +// Vector3f origin2 = new Vector3f(-halfSize * stepScale.x, 0, 0); +// +// Vector2f tempOffset2 = new Vector2f(); +// tempOffset2.x = offset.x; +// tempOffset2.y = offset.y; +// //tempOffset2.x += origin1.x / 2; +// tempOffset2.y += quarterSize * stepScale.z; +// +// TerrainPatch patch2 = new TerrainPatch(getName() + "Patch2", split, +// stepScale, heightBlock2, origin2, totalSize, tempOffset2, +// offsetAmount); +// patch2.setQuadrant((short) 2); +// this.attachChild(patch2); +// patch2.setModelBound(new BoundingBox()); +// patch2.updateModelBound(); +// //patch2.setLodCalculator(lodCalculator); +// //TangentBinormalGenerator.generate(patch2); +// +// // 3 lower right +// float[] heightBlock3 = createHeightSubBlock(heightMap, split - 1, 0, +// split); +// +// Vector3f origin3 = new Vector3f(0, 0, -halfSize * stepScale.z); +// +// Vector2f tempOffset3 = new Vector2f(); +// tempOffset3.x = offset.x; +// tempOffset3.y = offset.y; +// tempOffset3.x += quarterSize * stepScale.x; +// tempOffset3.y += origin3.z / 2; +// +// TerrainPatch patch3 = new TerrainPatch(getName() + "Patch3", split, +// stepScale, heightBlock3, origin3, totalSize, tempOffset3, +// offsetAmount); +// patch3.setQuadrant((short) 3); +// this.attachChild(patch3); +// patch3.setModelBound(new BoundingBox()); +// patch3.updateModelBound(); +// //patch3.setLodCalculator(lodCalculator); +// //TangentBinormalGenerator.generate(patch3); +// +// // 4 upper right +// float[] heightBlock4 = createHeightSubBlock(heightMap, split - 1, +// split - 1, split); +// +// Vector3f origin4 = new Vector3f(0, 0, 0); +// +// Vector2f tempOffset4 = new Vector2f(); +// tempOffset4.x = offset.x; +// tempOffset4.y = offset.y; +// tempOffset4.x += quarterSize * stepScale.x; +// tempOffset4.y += quarterSize * stepScale.z; +// +// TerrainPatch patch4 = new TerrainPatch(getName() + "Patch4", split, +// stepScale, heightBlock4, origin4, totalSize, tempOffset4, +// offsetAmount); +// patch4.setQuadrant((short) 4); +// this.attachChild(patch4); +// patch4.setModelBound(new BoundingBox()); +// patch4.updateModelBound(); +// //patch4.setLodCalculator(lodCalculator); +// //TangentBinormalGenerator.generate(patch4); } + public float[] createHeightSubBlock(float[] heightMap, int x, - int y, int side) { + int y, int side) { float[] rVal = new float[side * side]; int bsize = (int) FastMath.sqrt(heightMap.length); int count = 0; @@ -843,13 +888,13 @@ public void attachBoundChildren(Node parent) { } else if (this.getChild(i) instanceof TerrainPatch) { BoundingVolume bv = getChild(i).getWorldBound(); if (bv instanceof BoundingBox) { - attachBoundingBox((BoundingBox)bv, parent); + attachBoundingBox((BoundingBox) bv, parent); } } } BoundingVolume bv = getWorldBound(); if (bv instanceof BoundingBox) { - attachBoundingBox((BoundingBox)bv, parent); + attachBoundingBox((BoundingBox) bv, parent); } } @@ -896,7 +941,7 @@ protected boolean needToRecalculateNormals() { } return false; } - + /** * This will cause all normals for this terrain quad to be recalculated */ @@ -923,7 +968,7 @@ protected float getHeightmapHeight(int x, int z) { int quad = findQuadrant(x, z); int split = (size + 1) >> 1; if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial spat = children.get(i); int col = x; int row = z; @@ -968,7 +1013,7 @@ protected Vector3f getMeshNormal(int x, int z) { int quad = findQuadrant(x, z); int split = (size + 1) >> 1; if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial spat = children.get(i); int col = x; int row = z; @@ -1011,6 +1056,7 @@ protected Vector3f getMeshNormal(int x, int z) { /** * is the 2d point inside the terrain? + * * @param x local coordinate * @param z local coordinate */ @@ -1028,19 +1074,19 @@ private class QuadrantChild { int col; int row; Spatial child; - + QuadrantChild(int col, int row, Spatial child) { this.col = col; this.row = row; this.child = child; } } - + private QuadrantChild findMatchingChild(int x, int z) { int quad = findQuadrant(x, z); int split = (size + 1) >> 1; if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial spat = children.get(i); int col = x; int row = z; @@ -1073,19 +1119,20 @@ private QuadrantChild findMatchingChild(int x, int z) { } return null; } - + /** * Get the interpolated height of the terrain at the specified point. + * * @param xz the location to get the height for * @return Float.NAN if the value does not exist, or the coordinates are outside of the terrain */ public float getHeight(Vector2f xz) { // offset - float x = (float)(((xz.x - getWorldTranslation().x) / getWorldScale().x) + (float)(totalSize-1) / 2f); - float z = (float)(((xz.y - getWorldTranslation().z) / getWorldScale().z) + (float)(totalSize-1) / 2f); - if (!isInside((int)x, (int)z)) + float x = (float) (((xz.x - getWorldTranslation().x) / getWorldScale().x) + (float) (totalSize - 1) / 2f); + float z = (float) (((xz.y - getWorldTranslation().z) / getWorldScale().z) + (float) (totalSize - 1) / 2f); + if (!isInside((int) x, (int) z)) return Float.NaN; - float height = getHeight((int)x, (int)z, (x%1f), (z%1f)); + float height = getHeight((int) x, (int) z, (x % 1f), (z % 1f)); height *= getWorldScale().y; return height; } @@ -1094,8 +1141,8 @@ public float getHeight(Vector2f xz) { * gets an interpolated value at the specified point */ protected float getHeight(int x, int z, float xm, float zm) { - - QuadrantChild match = findMatchingChild(x,z); + + QuadrantChild match = findMatchingChild(x, z); if (match != null) { if (match.child instanceof TerrainQuad) { return ((TerrainQuad) match.child).getHeight(match.col, match.row, xm, zm); @@ -1108,20 +1155,20 @@ protected float getHeight(int x, int z, float xm, float zm) { public Vector3f getNormal(Vector2f xz) { // offset - float x = (float)(((xz.x - getWorldTranslation().x) / getWorldScale().x) + (float)(totalSize-1) / 2f); - float z = (float)(((xz.y - getWorldTranslation().z) / getWorldScale().z) + (float)(totalSize-1) / 2f); + float x = (float) (((xz.x - getWorldTranslation().x) / getWorldScale().x) + (float) (totalSize - 1) / 2f); + float z = (float) (((xz.y - getWorldTranslation().z) / getWorldScale().z) + (float) (totalSize - 1) / 2f); Vector3f normal = getNormal(x, z, xz); - + return normal; } - + protected Vector3f getNormal(float x, float z, Vector2f xz) { - x-=0.5f; - z-=0.5f; + x -= 0.5f; + z -= 0.5f; float col = FastMath.floor(x); float row = FastMath.floor(z); boolean onX = false; - if(1 - (x - col)-(z - row) < 0) // what triangle to interpolate on + if (1 - (x - col) - (z - row) < 0) // what triangle to interpolate on onX = true; // v1--v2 ^ // | / | | @@ -1134,10 +1181,10 @@ protected Vector3f getNormal(float x, float z, Vector2f xz) { Vector3f n2 = getMeshNormal((int) FastMath.floor(x), (int) FastMath.ceil(z)); Vector3f n3 = getMeshNormal((int) FastMath.ceil(x), (int) FastMath.floor(z)); Vector3f n4 = getMeshNormal((int) FastMath.floor(x), (int) FastMath.floor(z)); - + return n1.add(n2).add(n3).add(n4).normalize(); } - + public void setHeight(Vector2f xz, float height) { List coord = new ArrayList(); coord.add(xz); @@ -1173,19 +1220,19 @@ protected void setHeight(List xz, List height, boolean override List locations = new ArrayList(); // offset - for (int i=0; i locations, boolean overrideHeight) Spatial quad4 = null; // get the child quadrants - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial spat = children.get(i); int childQuadrant = 0; if (spat instanceof TerrainQuad) { @@ -1264,30 +1312,30 @@ else if (childQuadrant == 4) // send the locations to the children if (!quadLH1.isEmpty()) { if (quad1 instanceof TerrainQuad) - ((TerrainQuad)quad1).setHeight(quadLH1, overrideHeight); - else if(quad1 instanceof TerrainPatch) - ((TerrainPatch)quad1).setHeight(quadLH1, overrideHeight); + ((TerrainQuad) quad1).setHeight(quadLH1, overrideHeight); + else if (quad1 instanceof TerrainPatch) + ((TerrainPatch) quad1).setHeight(quadLH1, overrideHeight); } if (!quadLH2.isEmpty()) { if (quad2 instanceof TerrainQuad) - ((TerrainQuad)quad2).setHeight(quadLH2, overrideHeight); - else if(quad2 instanceof TerrainPatch) - ((TerrainPatch)quad2).setHeight(quadLH2, overrideHeight); + ((TerrainQuad) quad2).setHeight(quadLH2, overrideHeight); + else if (quad2 instanceof TerrainPatch) + ((TerrainPatch) quad2).setHeight(quadLH2, overrideHeight); } if (!quadLH3.isEmpty()) { if (quad3 instanceof TerrainQuad) - ((TerrainQuad)quad3).setHeight(quadLH3, overrideHeight); - else if(quad3 instanceof TerrainPatch) - ((TerrainPatch)quad3).setHeight(quadLH3, overrideHeight); + ((TerrainQuad) quad3).setHeight(quadLH3, overrideHeight); + else if (quad3 instanceof TerrainPatch) + ((TerrainPatch) quad3).setHeight(quadLH3, overrideHeight); } if (!quadLH4.isEmpty()) { if (quad4 instanceof TerrainQuad) - ((TerrainQuad)quad4).setHeight(quadLH4, overrideHeight); - else if(quad4 instanceof TerrainPatch) - ((TerrainPatch)quad4).setHeight(quadLH4, overrideHeight); + ((TerrainQuad) quad4).setHeight(quadLH4, overrideHeight); + else if (quad4 instanceof TerrainPatch) + ((TerrainPatch) quad4).setHeight(quadLH4, overrideHeight); } } @@ -1295,7 +1343,7 @@ protected boolean isPointOnTerrain(int x, int z) { return (x >= 0 && x <= totalSize && z >= 0 && z <= totalSize); } - + public int getTerrainSize() { return totalSize; } @@ -1319,6 +1367,7 @@ private int findQuadrant(int x, int y) { /** * lock or unlock the meshes of this terrain. * Locked meshes are uneditable but have better performance. + * * @param locked or unlocked */ public void setLocked(boolean locked) { @@ -1346,7 +1395,7 @@ public void setQuadrant(short quadrant) { protected TerrainPatch getPatch(int quad) { if (children != null) - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainPatch) { TerrainPatch tb = (TerrainPatch) child; @@ -1361,7 +1410,7 @@ protected TerrainQuad getQuad(int quad) { if (quad == 0) return this; if (children != null) - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { TerrainQuad tq = (TerrainQuad) child; @@ -1604,13 +1653,13 @@ protected void fixNormals(BoundingBox affectedArea) { // go through the children and see if they collide with the affectedAreaBBox // if they do, then update their normals - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { - if (affectedArea != null && affectedArea.intersects(((TerrainQuad) child).getWorldBound()) ) + if (affectedArea != null && affectedArea.intersects(((TerrainQuad) child).getWorldBound())) ((TerrainQuad) child).fixNormals(affectedArea); } else if (child instanceof TerrainPatch) { - if (affectedArea != null && affectedArea.intersects(((TerrainPatch) child).getWorldBound()) ) + if (affectedArea != null && affectedArea.intersects(((TerrainPatch) child).getWorldBound())) ((TerrainPatch) child).updateNormals(); // recalculate the patch's normals } } @@ -1623,13 +1672,13 @@ protected void fixNormalEdges(BoundingBox affectedArea) { if (children == null) return; - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { - if (affectedArea != null && affectedArea.intersects(((TerrainQuad) child).getWorldBound()) ) + if (affectedArea != null && affectedArea.intersects(((TerrainQuad) child).getWorldBound())) ((TerrainQuad) child).fixNormalEdges(affectedArea); } else if (child instanceof TerrainPatch) { - if (affectedArea != null && !affectedArea.intersects(((TerrainPatch) child).getWorldBound()) ) // if doesn't intersect, continue + if (affectedArea != null && !affectedArea.intersects(((TerrainPatch) child).getWorldBound())) // if doesn't intersect, continue continue; TerrainPatch tp = (TerrainPatch) child; @@ -1658,20 +1707,19 @@ protected void fixNormalEdges(BoundingBox affectedArea) { } - @Override - public int collideWith(Collidable other, CollisionResults results){ + public int collideWith(Collidable other, CollisionResults results) { int total = 0; if (other instanceof Ray) - return collideWithRay((Ray)other, results); + return collideWithRay((Ray) other, results); // if it didn't collide with this bbox, return if (other instanceof BoundingVolume) - if (!this.getWorldBound().intersects((BoundingVolume)other)) + if (!this.getWorldBound().intersects((BoundingVolume) other)) return total; - for (Spatial child : children){ + for (Spatial child : children) { total += child.collideWith(other, results); } return total; @@ -1680,6 +1728,7 @@ public int collideWith(Collidable other, CollisionResults results){ /** * Gather the terrain patches that intersect the given ray (toTest). * This only tests the bounding boxes + * * @param toTest * @param results */ @@ -1700,8 +1749,7 @@ public void findPick(Ray toTest, List results) { results.add(new TerrainPickData(tp, cr.getClosestCollision())); } } - } - else if (children.get(i) instanceof TerrainQuad) { + } else if (children.get(i) instanceof TerrainQuad) { ((TerrainQuad) children.get(i)).findPick(toTest, results); } } @@ -1713,30 +1761,31 @@ else if (children.get(i) instanceof TerrainQuad) { /** * Retrieve all Terrain Patches from all children and store them * in the 'holder' list + * * @param holder must not be null, will be populated when returns */ public void getAllTerrainPatches(List holder) { if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).getAllTerrainPatches(holder); } else if (child instanceof TerrainPatch) { - holder.add((TerrainPatch)child); + holder.add((TerrainPatch) child); } } } } - public void getAllTerrainPatchesWithTranslation(Map holder, Vector3f translation) { + public void getAllTerrainPatchesWithTranslation(Map holder, Vector3f translation) { if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).getAllTerrainPatchesWithTranslation(holder, translation.clone().add(child.getLocalTranslation())); } else if (child instanceof TerrainPatch) { //if (holder.size() < 4) - holder.put((TerrainPatch)child, translation.clone().add(child.getLocalTranslation())); + holder.put((TerrainPatch) child, translation.clone().add(child.getLocalTranslation())); } } } @@ -1748,14 +1797,14 @@ public void read(JmeImporter e) throws IOException { InputCapsule c = e.getCapsule(this); size = c.readInt("size", 0); stepScale = (Vector3f) c.readSavable("stepScale", null); - offset = (Vector2f) c.readSavable("offset", new Vector2f(0,0)); + offset = (Vector2f) c.readSavable("offset", new Vector2f(0, 0)); offsetAmount = c.readFloat("offsetAmount", 0); quadrant = c.readInt("quadrant", 0); totalSize = c.readInt("totalSize", 0); //lodCalculator = (LodCalculator) c.readSavable("lodCalculator", createDefaultLodCalculator()); //lodCalculatorFactory = (LodCalculatorFactory) c.readSavable("lodCalculatorFactory", null); - - if ( !(getParent() instanceof TerrainQuad) ) { + + if (!(getParent() instanceof TerrainQuad)) { BoundingBox all = new BoundingBox(getWorldTranslation(), totalSize, totalSize, totalSize); affectedAreaBBox = all; updateNormals(); @@ -1769,7 +1818,7 @@ public void write(JmeExporter e) throws IOException { c.write(size, "size", 0); c.write(totalSize, "totalSize", 0); c.write(stepScale, "stepScale", null); - c.write(offset, "offset", new Vector2f(0,0)); + c.write(offset, "offset", new Vector2f(0, 0)); c.write(offsetAmount, "offsetAmount", 0); c.write(quadrant, "quadrant", 0); //c.write(lodCalculatorFactory, "lodCalculatorFactory", null); @@ -1781,7 +1830,7 @@ public TerrainQuad clone() { return this.clone(true); } - @Override + @Override public TerrainQuad clone(boolean cloneMaterials) { TerrainQuad quadClone = (TerrainQuad) super.clone(cloneMaterials); quadClone.name = name.toString(); @@ -1797,10 +1846,10 @@ public TerrainQuad clone(boolean cloneMaterials) { quadClone.quadrant = quadrant; //quadClone.lodCalculatorFactory = lodCalculatorFactory.clone(); //quadClone.lodCalculator = lodCalculator.clone(); - + TerrainLodControl lodControlCloned = this.getControl(TerrainLodControl.class); TerrainLodControl lodControl = quadClone.getControl(TerrainLodControl.class); - + if (lodControlCloned != null && !(getParent() instanceof TerrainQuad)) { //lodControlCloned.setLodCalculator(lodControl.getLodCalculator().clone()); } @@ -1810,7 +1859,7 @@ public TerrainQuad clone(boolean cloneMaterials) { return quadClone; } - + @Override protected void setParent(Node parent) { super.setParent(parent); @@ -1819,7 +1868,7 @@ protected void setParent(Node parent) { clearCaches(); } } - + /** * Removes any cached references this terrain is holding, in particular * the TerrainPatch's neighbour references. @@ -1828,7 +1877,7 @@ protected void setParent(Node parent) { */ public void clearCaches() { if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).clearCaches(); @@ -1838,10 +1887,10 @@ public void clearCaches() { } } } - + public int getMaxLod() { if (maxLod < 0) - maxLod = Math.max(1, (int) (FastMath.log(size-1)/FastMath.log(2)) -1); // -1 forces our minimum of 4 triangles wide + maxLod = Math.max(1, (int) (FastMath.log(size - 1) / FastMath.log(2)) - 1); // -1 forces our minimum of 4 triangles wide return maxLod; } @@ -1857,26 +1906,25 @@ public int getTotalSize() { public float[] getHeightMap() { float[] hm = null; - int length = ((size-1)/2)+1; - int area = size*size; + int length = ((size - 1) / 2) + 1; + int area = size * size; hm = new float[area]; if (getChildren() != null && !getChildren().isEmpty()) { - float[] ul=null, ur=null, bl=null, br=null; + float[] ul = null, ur = null, bl = null, br = null; // get the child heightmaps if (getChild(0) instanceof TerrainPatch) { for (Spatial s : getChildren()) { - if ( ((TerrainPatch)s).getQuadrant() == 1) - ul = ((TerrainPatch)s).getHeightMap(); - else if(((TerrainPatch) s).getQuadrant() == 2) - bl = ((TerrainPatch)s).getHeightMap(); - else if(((TerrainPatch) s).getQuadrant() == 3) - ur = ((TerrainPatch)s).getHeightMap(); - else if(((TerrainPatch) s).getQuadrant() == 4) - br = ((TerrainPatch)s).getHeightMap(); + if (((TerrainPatch) s).getQuadrant() == 1) + ul = ((TerrainPatch) s).getHeightMap(); + else if (((TerrainPatch) s).getQuadrant() == 2) + bl = ((TerrainPatch) s).getHeightMap(); + else if (((TerrainPatch) s).getQuadrant() == 3) + ur = ((TerrainPatch) s).getHeightMap(); + else if (((TerrainPatch) s).getQuadrant() == 4) + br = ((TerrainPatch) s).getHeightMap(); } - } - else { + } else { ul = getQuad(1).getHeightMap(); bl = getQuad(2).getHeightMap(); ur = getQuad(3).getHeightMap(); @@ -1887,26 +1935,26 @@ else if(((TerrainPatch) s).getQuadrant() == 4) // first upper blocks - for (int y=0; y locations, HashMap updates){return true;} + +} diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/FakeTerrainPatch.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/FakeTerrainPatch.java new file mode 100644 index 0000000000..52de1995f8 --- /dev/null +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/FakeTerrainPatch.java @@ -0,0 +1,8 @@ +package com.jme3.terrain.geomipmap; + +import com.jme3.math.Vector3f; + +public class FakeTerrainPatch extends TerrainPatch { + + public Vector3f worldTranslationCached = super.worldTranslationCached; +} From 7515a9726ab81cc610acc173c7717fac5c301738 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 23 Mar 2016 12:42:47 +0100 Subject: [PATCH 20/59] Fixed exception assertion in patch tests --- .../terrain/geomipmap/TerrainQuadTest.java | 47 +++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index b4dbf5847f..7dc07c0007 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -196,13 +196,16 @@ public void testFindRightPatch() { FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); - exception.expect(NullPointerException.class); - root.findRightPatch(null); + try { + root.findRightPatch(null); + } catch (RuntimeException e) { + assertEquals(e.getClass(), NullPointerException.class); + } assertEquals(topLeftChild.findRightQuad(), topRightChild); // Confirm position of two parent quads // Check quad children of parent - TerrainPatch child1 = topLeftChild.findRightPatch(topLeftChild.getPatch(2)); + TerrainPatch child1 = topLeftChild.findRightPatch(topLeftChild.getPatch(1)); assertNotNull(child1); assertEquals(child1, topLeftChild.getPatch(3)); @@ -224,4 +227,42 @@ public void testFindRightPatch() { assertEquals(topRightChild.findRightPatch(topRightChild.getPatch(3)), null); assertEquals(topRightChild.findRightPatch(topRightChild.getPatch(4)), null); } + + @Test + public void testFindDownPatch() { + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); + FakeTerrainQuad bottomLeftChild = (FakeTerrainQuad)root.getQuad(2); + + try { + root.findDownPatch(null); + } catch (RuntimeException e) { + assertEquals(e.getClass(), NullPointerException.class); + } + + assertEquals(topLeftChild.findDownQuad(), bottomLeftChild); // Confirm position of two parent quads + + // Check quad children of parent + TerrainPatch child1 = topLeftChild.findDownPatch(topLeftChild.getPatch(1)); + assertNotNull(child1); + assertEquals(child1, topLeftChild.getPatch(2)); + + TerrainPatch child2 = topLeftChild.findDownPatch(topLeftChild.getPatch(2)); + assertNotNull(child1); + assertEquals(child2, bottomLeftChild.getPatch(1)); + + + TerrainPatch child3 = topLeftChild.findDownPatch(topLeftChild.getPatch(3)); + assertNotNull(child3); + assertEquals(child3, topLeftChild.getPatch(4)); + + + TerrainPatch child4 = topLeftChild.findDownPatch(topLeftChild.getPatch(4)); + assertNotNull(child4); + assertEquals(child4, bottomLeftChild.getPatch(3)); + + // Check non-existing neighbour quads + assertEquals(bottomLeftChild.findDownPatch(bottomLeftChild.getPatch(2)), null); + assertEquals(bottomLeftChild.findDownPatch(bottomLeftChild.getPatch(4)), null); + } } From 7214fae8425b489402f97902ee003750c1cdbda5 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 23 Mar 2016 12:52:46 +0100 Subject: [PATCH 21/59] Added final patch tests --- .../terrain/geomipmap/TerrainQuadTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 7dc07c0007..00ffb977ab 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -265,4 +265,80 @@ public void testFindDownPatch() { assertEquals(bottomLeftChild.findDownPatch(bottomLeftChild.getPatch(2)), null); assertEquals(bottomLeftChild.findDownPatch(bottomLeftChild.getPatch(4)), null); } + + @Test + public void testFindLeftPatch() { + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); + FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); + + try { + root.findLeftPatch(null); + } catch (RuntimeException e) { + assertEquals(e.getClass(), NullPointerException.class); + } + + assertEquals(topRightChild.findLeftQuad(), topLeftChild); // Confirm position of two parent quads + + // Check quad children of parent + TerrainPatch child1 = topRightChild.findLeftPatch(topRightChild.getPatch(1)); + assertNotNull(child1); + assertEquals(child1, topLeftChild.getPatch(3)); + + TerrainPatch child2 = topRightChild.findLeftPatch(topRightChild.getPatch(2)); + assertNotNull(child1); + assertEquals(child2, topLeftChild.getPatch(4)); + + + TerrainPatch child3 = topRightChild.findLeftPatch(topRightChild.getPatch(3)); + assertNotNull(child3); + assertEquals(child3, topRightChild.getPatch(1)); + + + TerrainPatch child4 = topRightChild.findLeftPatch(topRightChild.getPatch(4)); + assertNotNull(child4); + assertEquals(child4, topRightChild.getPatch(2)); + + // Check non-existing neighbour quads + assertEquals(topLeftChild.findLeftPatch(topLeftChild.getPatch(1)), null); + assertEquals(topLeftChild.findLeftPatch(topLeftChild.getPatch(2)), null); + } + + @Test + public void testFindTopPatch() { + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); + FakeTerrainQuad bottomRightChild = (FakeTerrainQuad)root.getQuad(4); + + try { + root.findTopPatch(null); + } catch (RuntimeException e) { + assertEquals(e.getClass(), NullPointerException.class); + } + + assertEquals(bottomRightChild.findTopQuad(), topRightChild); // Confirm position of two parent quads + + // Check quad children of parent + TerrainPatch child1 = bottomRightChild.findTopPatch(bottomRightChild.getPatch(1)); + assertNotNull(child1); + assertEquals(child1, topRightChild.getPatch(2)); + + TerrainPatch child2 = bottomRightChild.findTopPatch(bottomRightChild.getPatch(2)); + assertNotNull(child1); + assertEquals(child2, bottomRightChild.getPatch(1)); + + + TerrainPatch child3 = bottomRightChild.findTopPatch(bottomRightChild.getPatch(3)); + assertNotNull(child3); + assertEquals(child3, topRightChild.getPatch(4)); + + + TerrainPatch child4 = bottomRightChild.findTopPatch(bottomRightChild.getPatch(4)); + assertNotNull(child4); + assertEquals(child4, bottomRightChild.getPatch(3)); + + // Check non-existing neighbour quads + assertEquals(topRightChild.findTopPatch(topRightChild.getPatch(1)), null); + assertEquals(topRightChild.findTopPatch(topRightChild.getPatch(3)), null); + } } From e22dd1678bab22dab3beab003640ec14c52c6525 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 23 Mar 2016 15:22:03 +0100 Subject: [PATCH 22/59] First step of refactoring findQuad --- .../jme3/terrain/geomipmap/TerrainQuad.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 8cceb85bb8..21a74c73a9 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -1446,6 +1446,87 @@ else if (tp.getQuadrant() == 1) { return null; } + protected TerrainQuad findQuad(int direction) { + final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; + + boolean useFinder = false; + if (getParent() == null || !(getParent() instanceof TerrainQuad)) { + if (neighbourFinder == null) + return null; + else + useFinder = true; + } + + TerrainQuad pQuad = null; + if (!useFinder) + pQuad = (TerrainQuad) getParent(); + + TerrainQuad neighbourQuad; + switch (direction) { + case DIR_RIGHT: + switch (quadrant) { + case 1: return pQuad.getQuad(3); + case 2: return pQuad.getQuad(4); + case 3: + neighbourQuad = pQuad.findQuad(DIR_RIGHT); + if (neighbourQuad != null) + return neighbourQuad.getQuad(1); + break; + case 4: case DIR_RIGHT: + neighbourQuad = pQuad.findQuad(DIR_RIGHT); + if (neighbourQuad != null) + return neighbourQuad.getQuad(2); + break; + } + case DIR_DOWN: + switch (quadrant) { + case 1: return pQuad.getQuad(2); + case 2: neighbourQuad = pQuad.findQuad(DIR_DOWN); + if (neighbourQuad != null) + return neighbourQuad.getQuad(1); + break; + case 3: return pQuad.getQuad(4); + case 4: + neighbourQuad = pQuad.findQuad(DIR_DOWN); + if (neighbourQuad != null) + return neighbourQuad.getQuad(3); + break; + } + case DIR_LEFT: + switch (quadrant) { + case 1: + neighbourQuad = pQuad.findQuad(DIR_LEFT); + if (neighbourQuad != null) + return neighbourQuad.getQuad(3); + break; + case 2: + neighbourQuad = pQuad.findQuad(DIR_LEFT); + if (neighbourQuad != null) + return neighbourQuad.getQuad(4); + break; + case 3: return pQuad.getQuad(1); + case 4: return pQuad.getQuad(2); + } + case DIR_TOP: + switch (quadrant) { + case 1: + neighbourQuad = pQuad.findQuad(DIR_TOP); + if (neighbourQuad != null) + return neighbourQuad.getQuad(2); + break; + case 2: return pQuad.getQuad(1); + case 3: + neighbourQuad = pQuad.findQuad(DIR_TOP); + if (neighbourQuad != null) + return neighbourQuad.getQuad(4); + break; + case 4: pQuad.getQuad(3); + } + } + + return null; + } + protected TerrainQuad findRightQuad() { boolean useFinder = false; if (getParent() == null || !(getParent() instanceof TerrainQuad)) { From 6fde4420c320ec5ab8a9f64a89a965786cd65cf7 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 23 Mar 2016 16:16:11 +0100 Subject: [PATCH 23/59] Improved readability of findQuad, added test to compare new methods to old findQuad methods --- .../jme3/terrain/geomipmap/TerrainQuad.java | 157 ++++++++++-------- .../terrain/geomipmap/TerrainQuadTest.java | 24 +++ 2 files changed, 116 insertions(+), 65 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 21a74c73a9..9fa0593a00 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -126,6 +126,8 @@ public class TerrainQuad extends Node implements Terrain { private Vector3f lastScale = Vector3f.UNIT_XYZ; protected NeighbourFinder neighbourFinder; + + private final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; public TerrainQuad() { super("Terrain"); @@ -1447,8 +1449,6 @@ else if (tp.getQuadrant() == 1) { } protected TerrainQuad findQuad(int direction) { - final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; - boolean useFinder = false; if (getParent() == null || !(getParent() instanceof TerrainQuad)) { if (neighbourFinder == null) @@ -1457,73 +1457,100 @@ protected TerrainQuad findQuad(int direction) { useFinder = true; } - TerrainQuad pQuad = null; - if (!useFinder) - pQuad = (TerrainQuad) getParent(); + if (quadrant == 0) { + // at the top quad + if (useFinder) { + TerrainQuad quad = neighbourFinder.getRightQuad(this); + return quad; + } + } - TerrainQuad neighbourQuad; switch (direction) { - case DIR_RIGHT: - switch (quadrant) { - case 1: return pQuad.getQuad(3); - case 2: return pQuad.getQuad(4); - case 3: - neighbourQuad = pQuad.findQuad(DIR_RIGHT); - if (neighbourQuad != null) - return neighbourQuad.getQuad(1); - break; - case 4: case DIR_RIGHT: - neighbourQuad = pQuad.findQuad(DIR_RIGHT); - if (neighbourQuad != null) - return neighbourQuad.getQuad(2); - break; - } - case DIR_DOWN: - switch (quadrant) { - case 1: return pQuad.getQuad(2); - case 2: neighbourQuad = pQuad.findQuad(DIR_DOWN); - if (neighbourQuad != null) - return neighbourQuad.getQuad(1); - break; - case 3: return pQuad.getQuad(4); - case 4: - neighbourQuad = pQuad.findQuad(DIR_DOWN); - if (neighbourQuad != null) - return neighbourQuad.getQuad(3); - break; - } - case DIR_LEFT: - switch (quadrant) { - case 1: - neighbourQuad = pQuad.findQuad(DIR_LEFT); - if (neighbourQuad != null) - return neighbourQuad.getQuad(3); - break; - case 2: - neighbourQuad = pQuad.findQuad(DIR_LEFT); - if (neighbourQuad != null) - return neighbourQuad.getQuad(4); - break; - case 3: return pQuad.getQuad(1); - case 4: return pQuad.getQuad(2); - } - case DIR_TOP: - switch (quadrant) { - case 1: - neighbourQuad = pQuad.findQuad(DIR_TOP); - if (neighbourQuad != null) - return neighbourQuad.getQuad(2); - break; - case 2: return pQuad.getQuad(1); - case 3: - neighbourQuad = pQuad.findQuad(DIR_TOP); - if (neighbourQuad != null) - return neighbourQuad.getQuad(4); - break; - case 4: pQuad.getQuad(3); - } + case DIR_RIGHT : return getRightNeighbourQuad(); + case DIR_DOWN : return getDownNeighbourQuad(); + case DIR_LEFT : return getLeftNeighbourQuad(); + case DIR_TOP : return getTopNeighbourQuad(); + } + + return null; + } + + private TerrainQuad getRightNeighbourQuad() { + TerrainQuad pQuad = (TerrainQuad) getParent(); + TerrainQuad neighbourQuad; + switch (quadrant) { + case 1: return pQuad.getQuad(3); + case 2: return pQuad.getQuad(4); + case 3: + neighbourQuad = pQuad.findQuad(DIR_RIGHT); + if (neighbourQuad != null) + return neighbourQuad.getQuad(1); + break; + case 4: case DIR_RIGHT: + neighbourQuad = pQuad.findQuad(DIR_RIGHT); + if (neighbourQuad != null) + return neighbourQuad.getQuad(2); + break; + } + return null; + } + + private TerrainQuad getDownNeighbourQuad() { + TerrainQuad pQuad = (TerrainQuad) getParent(); + TerrainQuad neighbourQuad; + switch (quadrant) { + case 1: return pQuad.getQuad(2); + case 2: neighbourQuad = pQuad.findQuad(DIR_DOWN); + if (neighbourQuad != null) + return neighbourQuad.getQuad(1); + break; + case 3: return pQuad.getQuad(4); + case 4: + neighbourQuad = pQuad.findQuad(DIR_DOWN); + if (neighbourQuad != null) + return neighbourQuad.getQuad(3); + break; } + return null; + } + private TerrainQuad getLeftNeighbourQuad() { + TerrainQuad pQuad = (TerrainQuad) getParent(); + TerrainQuad neighbourQuad; + switch (quadrant) { + case 1: + neighbourQuad = pQuad.findQuad(DIR_LEFT); + if (neighbourQuad != null) + return neighbourQuad.getQuad(3); + break; + case 2: + neighbourQuad = pQuad.findQuad(DIR_LEFT); + if (neighbourQuad != null) + return neighbourQuad.getQuad(4); + break; + case 3: return pQuad.getQuad(1); + case 4: return pQuad.getQuad(2); + } + return null; + } + + private TerrainQuad getTopNeighbourQuad() { + TerrainQuad pQuad = (TerrainQuad) getParent(); + TerrainQuad neighbourQuad; + switch (quadrant) { + case 1: + neighbourQuad = pQuad.findQuad(DIR_TOP); + if (neighbourQuad != null) + return neighbourQuad.getQuad(2); + break; + case 2: return pQuad.getQuad(1); + case 3: + neighbourQuad = pQuad.findQuad(DIR_TOP); + if (neighbourQuad != null) + return neighbourQuad.getQuad(4); + break; + case 4: pQuad.getQuad(3); + } return null; } diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 00ffb977ab..e429d29f0d 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -341,4 +341,28 @@ public void testFindTopPatch() { assertEquals(topRightChild.findTopPatch(topRightChild.getPatch(1)), null); assertEquals(topRightChild.findTopPatch(topRightChild.getPatch(3)), null); } + + @Test + public void testFindQuad() { + int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; + + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + + assertEquals(root.quadrant, 0); + + assertEquals(root.findQuad(-1), null); + + assertEquals(root.findQuad(DIR_RIGHT), root.findRightQuad()); + assertEquals(root.findQuad(DIR_DOWN), root.findDownQuad()); + assertEquals(root.findQuad(DIR_LEFT), root.findLeftQuad()); + assertEquals(root.findQuad(DIR_TOP), root.findTopQuad()); + + for(int i = 0; i < root.getChildren().size(); i++) { + FakeTerrainQuad child = (FakeTerrainQuad)root.getQuad(i); + assertEquals(child.findQuad(DIR_RIGHT), child.findRightQuad()); + assertEquals(child.findQuad(DIR_DOWN), child.findDownQuad()); + assertEquals(child.findQuad(DIR_LEFT), child.findLeftQuad()); + assertEquals(child.findQuad(DIR_TOP), child.findTopQuad()); + } + } } From 03e639af23cb1ae1b536153dda4551ed2d864842 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 23 Mar 2016 16:44:35 +0100 Subject: [PATCH 24/59] Added functionality for neighbourfinder in all directions --- .../java/com/jme3/terrain/geomipmap/TerrainQuad.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 9fa0593a00..1e3223b1e8 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -1458,10 +1458,13 @@ protected TerrainQuad findQuad(int direction) { } if (quadrant == 0) { - // at the top quad if (useFinder) { - TerrainQuad quad = neighbourFinder.getRightQuad(this); - return quad; + switch (direction) { + case DIR_RIGHT : return neighbourFinder.getRightQuad(this); + case DIR_DOWN : return neighbourFinder.getDownQuad(this); + case DIR_LEFT : return neighbourFinder.getLeftQuad(this); + case DIR_TOP : return neighbourFinder.getDownQuad(this); + } } } From e9880da11642fb79fac246519d9df85c0d44ffc5 Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 23 Mar 2016 17:29:00 +0100 Subject: [PATCH 25/59] createQuadPatch is refactored to setPatchChildren --- Test Results - TerrainQuadTest.html | 619 ++++++++++++++++++ .../jme3/terrain/geomipmap/TerrainPatch.java | 67 +- .../jme3/terrain/geomipmap/TerrainQuad.java | 169 +---- 3 files changed, 683 insertions(+), 172 deletions(-) create mode 100644 Test Results - TerrainQuadTest.html diff --git a/Test Results - TerrainQuadTest.html b/Test Results - TerrainQuadTest.html new file mode 100644 index 0000000000..b4271d9d9a --- /dev/null +++ b/Test Results - TerrainQuadTest.html @@ -0,0 +1,619 @@ + + + + +Test Results — TerrainQuadTest + + + + + + + + + +

+ +
+
    +
  • + +
    35 ms
    +
    passedTerrainQuadTest.testGetQuad
    +
  • +
  • + +
    0 ms
    +
    passedTerrainQuadTest.testNestStructure
    +
  • +
  • + +
    0 ms
    +
    passedTerrainQuadTest.testFakeTerrainQuad
    +
  • +
  • + +
    0 ms
    +
    passedTerrainQuadTest.testCalculateLod
    +
  • +
+
+
+ + + diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java index 556bb6882b..a4b520a791 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java @@ -595,45 +595,42 @@ protected Vector3f getMeshNormal(int x, int z) { return normal; } - protected TerrainPatch createQuadPatch(int patchNumber, float[] heightMap, int split, int halfSize, int quarterSize) { - float[] heightBlock; + + protected TerrainPatch createQuadPatch(TerrainQuad terrainQuad, int patchNumber, float[] heightBlock, int quarterSize, int halfSize, int split) { + Vector3f origin; Vector2f tempOffset = new Vector2f(); - tempOffset.x = offset.x; - tempOffset.y = offset.y; - - TerrainQuad test = new TerrainQuad(); - - if (patchNumber == 1) { - heightBlock = test.createHeightSubBlock(heightMap, 0, 0, split); - origin = new Vector3f(-halfSize * stepScale.x, 0, -halfSize - * stepScale.z); - tempOffset.x += origin.x / 2; - tempOffset.y += origin.z / 2; - } else if (patchNumber == 2) { - heightBlock = test.createHeightSubBlock(heightMap, 0, split - 1, split); - origin = new Vector3f(-halfSize * stepScale.x, 0, 0); - tempOffset.x += origin.x / 2; - tempOffset.y += quarterSize * stepScale.z; - - } else if (patchNumber == 3) { - heightBlock = test.createHeightSubBlock(heightMap, split - 1, 0, split); - origin = new Vector3f(0, 0, -halfSize * stepScale.z); - tempOffset.x += quarterSize * stepScale.x; - tempOffset.y += origin.z / 2; - } else { - heightBlock = test.createHeightSubBlock(heightMap, split - 1, - split - 1, split); - origin = new Vector3f(0, 0, 0); - tempOffset.x += quarterSize * stepScale.x; - tempOffset.y += quarterSize * stepScale.z; + tempOffset.x = terrainQuad.offset.x; + tempOffset.y = terrainQuad.offset.y; + + switch (patchNumber) { + case 1: + origin = new Vector3f(-halfSize * terrainQuad.stepScale.x, 0, -halfSize + * terrainQuad.stepScale.z); + tempOffset.x += origin.x / 2; + tempOffset.y += origin.z / 2; + break; + case 2: + origin = new Vector3f(-halfSize * terrainQuad.stepScale.x, 0, 0); + tempOffset.x += origin.x / 2; + tempOffset.y += quarterSize * terrainQuad.stepScale.z; + System.out.println(tempOffset); + break; + case 3: + origin = new Vector3f(0, 0, -halfSize * terrainQuad.stepScale.z); + tempOffset.x += quarterSize * terrainQuad.stepScale.x; + tempOffset.y += origin.z / 2; + break; + case 4: + origin = new Vector3f(0, 0, 0); + tempOffset.x += quarterSize * terrainQuad.stepScale.x; + tempOffset.y += quarterSize * terrainQuad.stepScale.z; + break; + default: + return null; } - - return new TerrainPatch(getName() + "Patch" + patchNumber, split, - stepScale, heightBlock, origin, totalSize, tempOffset, - offsetAmount); - + return new TerrainPatch(terrainQuad.getName() + "Patch" + patchNumber, split, terrainQuad.stepScale, heightBlock, origin, terrainQuad.totalSize, tempOffset, terrainQuad.offsetAmount); } diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 47087f7dcb..c2f879ab82 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -577,7 +577,7 @@ protected synchronized void reIndexPages(HashMap up */ protected void split(int blockSize, float[] heightMap) { if ((size >> 1) + 1 <= blockSize) { - createQuadPatch(heightMap); + setPatchChildren(heightMap); } else { createQuad(blockSize, heightMap); } @@ -706,156 +706,42 @@ public void generateDebugTangents(Material mat) { } } - protected void createQuadPatch(int patchNumber, float[] heightMap, int split, int halfSize, int quarterSize) { - float[] heightBlock; - Vector3f origin; - Vector2f tempOffset = new Vector2f(); - tempOffset.x = offset.x; - tempOffset.y = offset.y; - if (patchNumber == 1) { - heightBlock = createHeightSubBlock(heightMap, 0, 0, split); - origin = new Vector3f(-halfSize * stepScale.x, 0, -halfSize - * stepScale.z); - tempOffset.x += origin.x / 2; - tempOffset.y += origin.z / 2; - } else if (patchNumber == 2) { - heightBlock = createHeightSubBlock(heightMap, 0, split - 1, split); - origin = new Vector3f(-halfSize * stepScale.x, 0, 0); - tempOffset.x += origin.x / 2; - tempOffset.y += quarterSize * stepScale.z; - - } else if (patchNumber == 3) { - heightBlock = createHeightSubBlock(heightMap, split - 1, 0, split); - origin = new Vector3f(0, 0, -halfSize * stepScale.z); - tempOffset.x += quarterSize * stepScale.x; - tempOffset.y += origin.z / 2; - } else { - heightBlock = createHeightSubBlock(heightMap, split - 1, - split - 1, split); - origin = new Vector3f(0, 0, 0); - tempOffset.x += quarterSize * stepScale.x; - tempOffset.y += quarterSize * stepScale.z; + protected float[] createHeightBlock(int patchNumber, float[] heightMap, int split) { + switch (patchNumber) { + case 1: + return createHeightSubBlock(heightMap, 0, 0, split); + case 2: + return createHeightSubBlock(heightMap, 0, split - 1, split); + case 3: + return createHeightSubBlock(heightMap, split - 1, 0, split); + case 4: + return createHeightSubBlock(heightMap, split - 1, split - 1, split); + default: + return null; } - - - TerrainPatch patch = new TerrainPatch(getName() + "Patch" + patchNumber, split, - stepScale, heightBlock, origin, totalSize, tempOffset, - offsetAmount); - patch.setQuadrant((short) patchNumber); - this.attachChild(patch); - patch.setModelBound(new BoundingBox()); - patch.updateModelBound(); } /** - * createQuadPatch creates four child patches from this quad. + * setPatchChildren creates four child patches from this quad. */ - protected void createQuadPatch(float[] heightMap) { + protected void setPatchChildren(float[] heightMap) { + TerrainPatch terrainPatch = new TerrainPatch(); + int numberOfPatchChildren = 4; - TerrainPatch test = new TerrainPatch(); - // create 4 terrain patches int quarterSize = size >> 2; int halfSize = size >> 1; int split = (size + 1) >> 1; offsetAmount += quarterSize; - - for (int i = 1; i < 5; i++) { - //TerrainPatch patch = test.createQuadPatch(i, heightMap, split, halfSize, quarterSize); - createQuadPatch(i, heightMap, split, halfSize, quarterSize); -// patch.setQuadrant((short) i); -// this.attachChild(patch); -// patch.setModelBound(new BoundingBox()); -// patch.updateModelBound(); + for (int i = 1; i <= numberOfPatchChildren; i++) { + TerrainPatch patch = terrainPatch.createQuadPatch(this, i, createHeightBlock(i, heightMap, split), quarterSize, halfSize, split); + patch.setQuadrant((short) i); + this.attachChild(patch); + patch.setModelBound(new BoundingBox()); + patch.updateModelBound(); } - - // 1 lower left -// float[] heightBlock1 = createHeightSubBlock(heightMap, 0, 0, split); -// -// Vector3f origin1 = new Vector3f(-halfSize * stepScale.x, 0, -halfSize -// * stepScale.z); -// -// Vector2f tempOffset1 = new Vector2f(); -// tempOffset1.x = offset.x; -// tempOffset1.y = offset.y; -// tempOffset1.x += origin1.x / 2; -// tempOffset1.y += origin1.z / 2; -// -// TerrainPatch patch1 = new TerrainPatch(getName() + "Patch1", split, -// stepScale, heightBlock1, origin1, totalSize, tempOffset1, -// offsetAmount); -// patch1.setQuadrant((short) 1); -// this.attachChild(patch1); -// patch1.setModelBound(new BoundingBox()); -// patch1.updateModelBound(); -// -// // 2 upper left -// float[] heightBlock2 = createHeightSubBlock(heightMap, 0, split - 1, -// split); -// -// Vector3f origin2 = new Vector3f(-halfSize * stepScale.x, 0, 0); -// -// Vector2f tempOffset2 = new Vector2f(); -// tempOffset2.x = offset.x; -// tempOffset2.y = offset.y; -// //tempOffset2.x += origin1.x / 2; -// tempOffset2.y += quarterSize * stepScale.z; -// -// TerrainPatch patch2 = new TerrainPatch(getName() + "Patch2", split, -// stepScale, heightBlock2, origin2, totalSize, tempOffset2, -// offsetAmount); -// patch2.setQuadrant((short) 2); -// this.attachChild(patch2); -// patch2.setModelBound(new BoundingBox()); -// patch2.updateModelBound(); -// //patch2.setLodCalculator(lodCalculator); -// //TangentBinormalGenerator.generate(patch2); -// -// // 3 lower right -// float[] heightBlock3 = createHeightSubBlock(heightMap, split - 1, 0, -// split); -// -// Vector3f origin3 = new Vector3f(0, 0, -halfSize * stepScale.z); -// -// Vector2f tempOffset3 = new Vector2f(); -// tempOffset3.x = offset.x; -// tempOffset3.y = offset.y; -// tempOffset3.x += quarterSize * stepScale.x; -// tempOffset3.y += origin3.z / 2; -// -// TerrainPatch patch3 = new TerrainPatch(getName() + "Patch3", split, -// stepScale, heightBlock3, origin3, totalSize, tempOffset3, -// offsetAmount); -// patch3.setQuadrant((short) 3); -// this.attachChild(patch3); -// patch3.setModelBound(new BoundingBox()); -// patch3.updateModelBound(); -// //patch3.setLodCalculator(lodCalculator); -// //TangentBinormalGenerator.generate(patch3); -// -// // 4 upper right -// float[] heightBlock4 = createHeightSubBlock(heightMap, split - 1, -// split - 1, split); -// -// Vector3f origin4 = new Vector3f(0, 0, 0); -// -// Vector2f tempOffset4 = new Vector2f(); -// tempOffset4.x = offset.x; -// tempOffset4.y = offset.y; -// tempOffset4.x += quarterSize * stepScale.x; -// tempOffset4.y += quarterSize * stepScale.z; -// -// TerrainPatch patch4 = new TerrainPatch(getName() + "Patch4", split, -// stepScale, heightBlock4, origin4, totalSize, tempOffset4, -// offsetAmount); -// patch4.setQuadrant((short) 4); -// this.attachChild(patch4); -// patch4.setModelBound(new BoundingBox()); -// patch4.updateModelBound(); -// //patch4.setLodCalculator(lodCalculator); -// //TangentBinormalGenerator.generate(patch4); } @@ -1903,6 +1789,15 @@ public int getTotalSize() { return totalSize; } + public float getOffsetAmount() { + return offsetAmount; + } + + public void setOffsetAmount(float offsetAmount) { + this.offsetAmount = offsetAmount; + } + + public float[] getHeightMap() { float[] hm = null; From 6b62d7d332ce8b9c5c494f18e9dec120739f4737 Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 23 Mar 2016 17:39:03 +0100 Subject: [PATCH 26/59] Added Javadoc to the createQuadPatch methods. --- .../com/jme3/terrain/geomipmap/TerrainPatch.java | 11 +++++++++++ .../java/com/jme3/terrain/geomipmap/TerrainQuad.java | 12 +++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java index a4b520a791..fecf747de3 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java @@ -596,6 +596,17 @@ protected Vector3f getMeshNormal(int x, int z) { } + /** + * createQuadPatch creates a terrain patch according to the provided patchNumber. + * + * @param terrainQuad + * @param patchNumber + * @param heightBlock + * @param quarterSize + * @param halfSize + * @param split + * @return TerrainPatch object + */ protected TerrainPatch createQuadPatch(TerrainQuad terrainQuad, int patchNumber, float[] heightBlock, int quarterSize, int halfSize, int split) { Vector3f origin; diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index c2f879ab82..64be20425b 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -707,6 +707,14 @@ public void generateDebugTangents(Material mat) { } + /** + * createHeightBlock creates the heightSubBlock according to the provided patch number. + * + * @param patchNumber + * @param heightMap + * @param split + * @return HeightSubBlock array + */ protected float[] createHeightBlock(int patchNumber, float[] heightMap, int split) { switch (patchNumber) { case 1: @@ -723,7 +731,9 @@ protected float[] createHeightBlock(int patchNumber, float[] heightMap, int spli } /** - * setPatchChildren creates four child patches from this quad. + * setPatchChildren sets four child patches to this quad. + * + * @param heightMap */ protected void setPatchChildren(float[] heightMap) { TerrainPatch terrainPatch = new TerrainPatch(); From 4ae6bf20be22557dfac740bd66c8ada1ef56093c Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 23 Mar 2016 18:06:39 +0100 Subject: [PATCH 27/59] Added testclass for NeighbourFinder --- .../geomipmap/TestNeighbourFinder.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TestNeighbourFinder.java diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TestNeighbourFinder.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TestNeighbourFinder.java new file mode 100644 index 0000000000..ecbc31c0d0 --- /dev/null +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TestNeighbourFinder.java @@ -0,0 +1,61 @@ +package com.jme3.terrain.geomipmap; + +public class TestNeighbourFinder implements NeighbourFinder { + + TerrainQuad quad1, quad2, quad3, quad4; + + public TestNeighbourFinder(TerrainQuad quad1, TerrainQuad quad2, TerrainQuad quad3, TerrainQuad quad4) { + this.quad1 = quad1; + this.quad2 = quad2; + this.quad3 = quad3; + this.quad4 = quad4; + } + + @Override + public TerrainQuad getRightQuad(TerrainQuad center) { + if (center == quad1) { + return quad3; + } + if (center == quad2) { + return quad4; + } + + return null; + } + + @Override + public TerrainQuad getLeftQuad(TerrainQuad center) { + if (center == quad3) { + return quad1; + } + if (center == quad4) { + return quad2; + } + + return null; + } + + @Override + public TerrainQuad getTopQuad(TerrainQuad center) { + if (center == quad2) { + return quad1; + } + if (center == quad4) { + return quad3; + } + + return null; + } + + @Override + public TerrainQuad getDownQuad(TerrainQuad center) { + if (center == quad1) { + return quad2; + } + if (center == quad3) { + return quad4; + } + + return null; + } +} From c8ec8652e860d3bc811d2b3740142153ec1a295e Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 23 Mar 2016 18:22:50 +0100 Subject: [PATCH 28/59] Add test for using NeighbourFinder in findQuad --- .../jme3/terrain/geomipmap/TerrainQuad.java | 2 +- .../terrain/geomipmap/TerrainQuadTest.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 1e3223b1e8..a5792c48ea 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -1463,7 +1463,7 @@ protected TerrainQuad findQuad(int direction) { case DIR_RIGHT : return neighbourFinder.getRightQuad(this); case DIR_DOWN : return neighbourFinder.getDownQuad(this); case DIR_LEFT : return neighbourFinder.getLeftQuad(this); - case DIR_TOP : return neighbourFinder.getDownQuad(this); + case DIR_TOP : return neighbourFinder.getTopQuad(this); } } } diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index e429d29f0d..303149015a 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -98,6 +98,24 @@ public void testGetQuad() { assertEquals(parentTerrainQuad.getQuad(5), null); } + @Test + public void testFindQuadNeighbourFinder() { + FakeTerrainQuad[] roots = new FakeTerrainQuad[4]; + roots[0] = (FakeTerrainQuad) createNestedQuad(2); + roots[1] = (FakeTerrainQuad) createNestedQuad(2); + roots[2] = (FakeTerrainQuad) createNestedQuad(2); + roots[3] = (FakeTerrainQuad) createNestedQuad(2); + + NeighbourFinder nf = new TestNeighbourFinder(roots[0], roots[1], roots[2], roots[3]); + for (FakeTerrainQuad root : roots) { + root.setNeighbourFinder(nf); + assertEquals(root.findQuad(0), nf.getRightQuad(root)); + assertEquals(root.findQuad(1), nf.getDownQuad(root)); + assertEquals(root.findQuad(2), nf.getLeftQuad(root)); + assertEquals(root.findQuad(3), nf.getTopQuad(root)); + } + } + @Test public void testFindRightQuad() { FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3); From 6744ad45f4bcb84c0e4435c371df01d8ab45dd3b Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 23 Mar 2016 18:33:14 +0100 Subject: [PATCH 29/59] Refactored findDownQuad etc to findQuad(dir) in tests, and assured 100% coverage for findQuad(dir) --- .../jme3/terrain/geomipmap/TerrainQuad.java | 2 +- .../terrain/geomipmap/TerrainQuadTest.java | 79 ++++++++++--------- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index a5792c48ea..622e72e4d6 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -1552,7 +1552,7 @@ private TerrainQuad getTopNeighbourQuad() { if (neighbourQuad != null) return neighbourQuad.getQuad(4); break; - case 4: pQuad.getQuad(3); + case 4: return pQuad.getQuad(3); } return null; } diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 303149015a..4e7e032218 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -10,6 +10,8 @@ public class TerrainQuadTest { + final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; + @Rule public final ExpectedException exception = ExpectedException.none(); @@ -122,18 +124,18 @@ public void testFindRightQuad() { FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad topRight = (FakeTerrainQuad) root.getQuad(3); - assertEquals(root.findRightQuad(), null); - assertEquals(topLeftChild.findRightQuad(), topRight); // Confirm position of two parent quads + assertEquals(root.findQuad(DIR_RIGHT), null); + assertEquals(topLeftChild.findQuad(DIR_RIGHT), topRight); // Confirm position of two parent quads // Check quad children of parent - assertEquals(topLeftChild.getQuad(1).findRightQuad(), topLeftChild.getQuad(3)); - assertEquals(topLeftChild.getQuad(2).findRightQuad(), topLeftChild.getQuad(4)); - assertEquals(topLeftChild.getQuad(3).findRightQuad(), topRight.getQuad(1)); - assertEquals(topLeftChild.getQuad(4).findRightQuad(), topRight.getQuad(2)); + assertEquals(topLeftChild.getQuad(1).findQuad(DIR_RIGHT), topLeftChild.getQuad(3)); + assertEquals(topLeftChild.getQuad(2).findQuad(DIR_RIGHT), topLeftChild.getQuad(4)); + assertEquals(topLeftChild.getQuad(3).findQuad(DIR_RIGHT), topRight.getQuad(1)); + assertEquals(topLeftChild.getQuad(4).findQuad(DIR_RIGHT), topRight.getQuad(2)); // Check non-existing neighbour quads - assertEquals(topRight.getQuad(3).findRightQuad(), null); - assertEquals(topRight.getQuad(4).findRightQuad(), null); + assertEquals(topRight.getQuad(3).findQuad(DIR_RIGHT), null); + assertEquals(topRight.getQuad(4).findQuad(DIR_RIGHT), null); } @Test @@ -142,18 +144,18 @@ public void testFindDownQuad() { FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad downLeftChild = (FakeTerrainQuad) root.getQuad(2); - assertEquals(root.findDownQuad(), null); - assertEquals(topLeftChild.findDownQuad(), downLeftChild); // Confirm position of two parent quads + assertEquals(root.findQuad(DIR_DOWN), null); + assertEquals(topLeftChild.findQuad(DIR_DOWN), downLeftChild); // Confirm position of two parent quads // Check quad children of parent - assertEquals(topLeftChild.getQuad(1).findDownQuad(), topLeftChild.getQuad(2)); - assertEquals(topLeftChild.getQuad(2).findDownQuad(), downLeftChild.getQuad(1)); - assertEquals(topLeftChild.getQuad(3).findDownQuad(), topLeftChild.getQuad(4)); - assertEquals(topLeftChild.getQuad(4).findDownQuad(), downLeftChild.getQuad(3)); + assertEquals(topLeftChild.getQuad(1).findQuad(DIR_DOWN), topLeftChild.getQuad(2)); + assertEquals(topLeftChild.getQuad(2).findQuad(DIR_DOWN), downLeftChild.getQuad(1)); + assertEquals(topLeftChild.getQuad(3).findQuad(DIR_DOWN), topLeftChild.getQuad(4)); + assertEquals(topLeftChild.getQuad(4).findQuad(DIR_DOWN), downLeftChild.getQuad(3)); // Check non-existing neighbour quads - assertEquals(downLeftChild.getQuad(2).findDownQuad(), null); - assertEquals(downLeftChild.getQuad(4).findDownQuad(), null); + assertEquals(downLeftChild.getQuad(2).findQuad(DIR_DOWN), null); + assertEquals(downLeftChild.getQuad(4).findQuad(DIR_DOWN), null); } @Test @@ -162,18 +164,18 @@ public void testFindLeftQuad() { FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad topRightChild = (FakeTerrainQuad) root.getQuad(3); - assertEquals(root.findLeftQuad(), null); - assertEquals(topRightChild.findLeftQuad(), topLeftChild); // Confirm position of two parent quads + assertEquals(root.findQuad(DIR_LEFT), null); + assertEquals(topRightChild.findQuad(DIR_LEFT), topLeftChild); // Confirm position of two parent quads // Check quad children of parent - assertEquals(topRightChild.getQuad(1).findLeftQuad(), topLeftChild.getQuad(3)); - assertEquals(topRightChild.getQuad(2).findLeftQuad(), topLeftChild.getQuad(4)); - assertEquals(topRightChild.getQuad(3).findLeftQuad(), topRightChild.getQuad(1)); - assertEquals(topRightChild.getQuad(4).findLeftQuad(), topRightChild.getQuad(2)); + assertEquals(topRightChild.getQuad(1).findQuad(DIR_LEFT), topLeftChild.getQuad(3)); + assertEquals(topRightChild.getQuad(2).findQuad(DIR_LEFT), topLeftChild.getQuad(4)); + assertEquals(topRightChild.getQuad(3).findQuad(DIR_LEFT), topRightChild.getQuad(1)); + assertEquals(topRightChild.getQuad(4).findQuad(DIR_LEFT), topRightChild.getQuad(2)); // Check non-existing neighbour quads - assertEquals(topLeftChild.getQuad(1).findLeftQuad(), null); - assertEquals(topLeftChild.getQuad(2).findLeftQuad(), null); + assertEquals(topLeftChild.getQuad(1).findQuad(DIR_LEFT), null); + assertEquals(topLeftChild.getQuad(2).findQuad(DIR_LEFT), null); } @Test @@ -182,18 +184,18 @@ public void testFindTopQuad() { FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad downLeftChild = (FakeTerrainQuad) root.getQuad(2); - assertEquals(root.findTopQuad(), null); - assertEquals(downLeftChild.findTopQuad(), topLeftChild); // Confirm position of two parent quads + assertEquals(root.findQuad(DIR_TOP), null); + assertEquals(downLeftChild.findQuad(DIR_TOP), topLeftChild); // Confirm position of two parent quads // Check quad children of parent - assertEquals(downLeftChild.getQuad(1).findTopQuad(), topLeftChild.getQuad(2)); - assertEquals(downLeftChild.getQuad(2).findTopQuad(), downLeftChild.getQuad(1)); - assertEquals(downLeftChild.getQuad(3).findTopQuad(), topLeftChild.getQuad(4)); - assertEquals(downLeftChild.getQuad(4).findTopQuad(), downLeftChild.getQuad(3)); + assertEquals(downLeftChild.getQuad(1).findQuad(DIR_TOP), topLeftChild.getQuad(2)); + assertEquals(downLeftChild.getQuad(2).findQuad(DIR_TOP), downLeftChild.getQuad(1)); + assertEquals(downLeftChild.getQuad(3).findQuad(DIR_TOP), topLeftChild.getQuad(4)); + assertEquals(downLeftChild.getQuad(4).findQuad(DIR_TOP), downLeftChild.getQuad(3)); // Check non-existing neighbour quads - assertEquals(topLeftChild.getQuad(1).findTopQuad(), null); - assertEquals(topLeftChild.getQuad(3).findTopQuad(), null); + assertEquals(topLeftChild.getQuad(1).findQuad(DIR_TOP), null); + assertEquals(topLeftChild.getQuad(3).findQuad(DIR_TOP), null); } @Test @@ -220,7 +222,7 @@ public void testFindRightPatch() { assertEquals(e.getClass(), NullPointerException.class); } - assertEquals(topLeftChild.findRightQuad(), topRightChild); // Confirm position of two parent quads + assertEquals(topLeftChild.findQuad(DIR_RIGHT), topRightChild); // Confirm position of two parent quads // Check quad children of parent TerrainPatch child1 = topLeftChild.findRightPatch(topLeftChild.getPatch(1)); @@ -258,7 +260,7 @@ public void testFindDownPatch() { assertEquals(e.getClass(), NullPointerException.class); } - assertEquals(topLeftChild.findDownQuad(), bottomLeftChild); // Confirm position of two parent quads + assertEquals(topLeftChild.findQuad(DIR_DOWN), bottomLeftChild); // Confirm position of two parent quads // Check quad children of parent TerrainPatch child1 = topLeftChild.findDownPatch(topLeftChild.getPatch(1)); @@ -296,7 +298,7 @@ public void testFindLeftPatch() { assertEquals(e.getClass(), NullPointerException.class); } - assertEquals(topRightChild.findLeftQuad(), topLeftChild); // Confirm position of two parent quads + assertEquals(topRightChild.findQuad(DIR_LEFT), topLeftChild); // Confirm position of two parent quads // Check quad children of parent TerrainPatch child1 = topRightChild.findLeftPatch(topRightChild.getPatch(1)); @@ -334,7 +336,7 @@ public void testFindTopPatch() { assertEquals(e.getClass(), NullPointerException.class); } - assertEquals(bottomRightChild.findTopQuad(), topRightChild); // Confirm position of two parent quads + assertEquals(bottomRightChild.findQuad(DIR_TOP), topRightChild); // Confirm position of two parent quads // Check quad children of parent TerrainPatch child1 = bottomRightChild.findTopPatch(bottomRightChild.getPatch(1)); @@ -362,13 +364,12 @@ public void testFindTopPatch() { @Test public void testFindQuad() { - int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); assertEquals(root.quadrant, 0); - assertEquals(root.findQuad(-1), null); + assertNull(root.findQuad(-1)); + assertNull(root.getQuad(1).findQuad(-1)); assertEquals(root.findQuad(DIR_RIGHT), root.findRightQuad()); assertEquals(root.findQuad(DIR_DOWN), root.findDownQuad()); From c3d2bfe73c64339dad62315ac8fd403b82da1d16 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 23 Mar 2016 18:48:36 +0100 Subject: [PATCH 30/59] Deprecated all findXQuad() methods --- .../jme3/terrain/geomipmap/TerrainQuad.java | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 622e72e4d6..8f76ee6ed1 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -1377,12 +1377,12 @@ else if (tp.getQuadrant() == 2) return getPatch(4); else if (tp.getQuadrant() == 3) { // find the patch to the right and ask it for child 1. - TerrainQuad quad = findRightQuad(); + TerrainQuad quad = findQuad(DIR_RIGHT); if (quad != null) return quad.getPatch(1); } else if (tp.getQuadrant() == 4) { // find the patch to the right and ask it for child 2. - TerrainQuad quad = findRightQuad(); + TerrainQuad quad = findQuad(DIR_RIGHT); if (quad != null) return quad.getPatch(2); } @@ -1397,11 +1397,11 @@ else if (tp.getQuadrant() == 3) return getPatch(4); else if (tp.getQuadrant() == 2) { // find the patch below and ask it for child 1. - TerrainQuad quad = findDownQuad(); + TerrainQuad quad = findQuad(DIR_DOWN); if (quad != null) return quad.getPatch(1); } else if (tp.getQuadrant() == 4) { - TerrainQuad quad = findDownQuad(); + TerrainQuad quad = findQuad(DIR_DOWN); if (quad != null) return quad.getPatch(3); } @@ -1417,11 +1417,11 @@ else if (tp.getQuadrant() == 4) return getPatch(3); else if (tp.getQuadrant() == 1) { // find the patch above and ask it for child 2. - TerrainQuad quad = findTopQuad(); + TerrainQuad quad = findQuad(DIR_TOP); if (quad != null) return quad.getPatch(2); } else if (tp.getQuadrant() == 3) { - TerrainQuad quad = findTopQuad(); + TerrainQuad quad = findQuad(DIR_TOP); if (quad != null) return quad.getPatch(4); } @@ -1436,11 +1436,11 @@ else if (tp.getQuadrant() == 4) return getPatch(2); else if (tp.getQuadrant() == 1) { // find the patch above and ask it for child 3. - TerrainQuad quad = findLeftQuad(); + TerrainQuad quad = findQuad(DIR_LEFT); if (quad != null) return quad.getPatch(3); } else if (tp.getQuadrant() == 2) { - TerrainQuad quad = findLeftQuad(); + TerrainQuad quad = findQuad(DIR_LEFT); if (quad != null) return quad.getPatch(4); } @@ -1557,6 +1557,7 @@ private TerrainQuad getTopNeighbourQuad() { return null; } + @Deprecated protected TerrainQuad findRightQuad() { boolean useFinder = false; if (getParent() == null || !(getParent() instanceof TerrainQuad)) { @@ -1575,11 +1576,11 @@ protected TerrainQuad findRightQuad() { else if (quadrant == 2) return pQuad.getQuad(4); else if (quadrant == 3) { - TerrainQuad quad = pQuad.findRightQuad(); + TerrainQuad quad = pQuad.findQuad(DIR_RIGHT); if (quad != null) return quad.getQuad(1); } else if (quadrant == 4) { - TerrainQuad quad = pQuad.findRightQuad(); + TerrainQuad quad = pQuad.findQuad(DIR_RIGHT); if (quad != null) return quad.getQuad(2); } else if (quadrant == 0) { @@ -1593,6 +1594,7 @@ else if (quadrant == 3) { return null; } + @Deprecated protected TerrainQuad findDownQuad() { boolean useFinder = false; if (getParent() == null || !(getParent() instanceof TerrainQuad)) { @@ -1611,11 +1613,11 @@ protected TerrainQuad findDownQuad() { else if (quadrant == 3) return pQuad.getQuad(4); else if (quadrant == 2) { - TerrainQuad quad = pQuad.findDownQuad(); + TerrainQuad quad = pQuad.findQuad(DIR_DOWN); if (quad != null) return quad.getQuad(1); } else if (quadrant == 4) { - TerrainQuad quad = pQuad.findDownQuad(); + TerrainQuad quad = pQuad.findQuad(DIR_DOWN); if (quad != null) return quad.getQuad(3); } else if (quadrant == 0) { @@ -1629,6 +1631,7 @@ else if (quadrant == 2) { return null; } + @Deprecated protected TerrainQuad findTopQuad() { boolean useFinder = false; if (getParent() == null || !(getParent() instanceof TerrainQuad)) { @@ -1647,11 +1650,11 @@ protected TerrainQuad findTopQuad() { else if (quadrant == 4) return pQuad.getQuad(3); else if (quadrant == 1) { - TerrainQuad quad = pQuad.findTopQuad(); + TerrainQuad quad = pQuad.findQuad(DIR_TOP); if (quad != null) return quad.getQuad(2); } else if (quadrant == 3) { - TerrainQuad quad = pQuad.findTopQuad(); + TerrainQuad quad = pQuad.findQuad(DIR_TOP); if (quad != null) return quad.getQuad(4); } else if (quadrant == 0) { @@ -1665,6 +1668,7 @@ else if (quadrant == 1) { return null; } + @Deprecated protected TerrainQuad findLeftQuad() { boolean useFinder = false; if (getParent() == null || !(getParent() instanceof TerrainQuad)) { @@ -1683,11 +1687,11 @@ protected TerrainQuad findLeftQuad() { else if (quadrant == 4) return pQuad.getQuad(2); else if (quadrant == 1) { - TerrainQuad quad = pQuad.findLeftQuad(); + TerrainQuad quad = pQuad.findQuad(DIR_LEFT); if (quad != null) return quad.getQuad(3); } else if (quadrant == 2) { - TerrainQuad quad = pQuad.findLeftQuad(); + TerrainQuad quad = pQuad.findQuad(DIR_LEFT); if (quad != null) return quad.getQuad(4); } else if (quadrant == 0) { From 2e54026877f0f260c46f1bcdd2020386798cd41c Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 09:21:12 +0200 Subject: [PATCH 31/59] Refactored to findPatch methods in TerrainPatch --- .../jme3/terrain/geomipmap/TerrainPatch.java | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java index 4ac811e9fc..cc1fa5d384 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java @@ -114,6 +114,8 @@ public class TerrainPatch extends Geometry { protected float[] lodEntropy; + private final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; + public TerrainPatch() { super("TerrainPatch"); setBatchHint(BatchHint.Never); @@ -305,6 +307,105 @@ public Triangle[] getGridTriangles(float x, float z) { return geomap.getGridTrianglesAtPoint(x, z, getWorldScale() , getWorldTranslation()); } + protected TerrainPatch findPatch(int direction) { + switch (direction) { + case DIR_RIGHT : return getRightNeighbourPatch(); + case DIR_DOWN : return getDownNeighbourPatch(); + case DIR_LEFT : return getLeftNeighbourPatch(); + case DIR_TOP : return getTopNeighbourPatch(); + } + + return null; + } + + private TerrainPatch getRightNeighbourPatch() { + TerrainQuad parent = (TerrainQuad) this.getParent(); + TerrainQuad neighbourQuad; + + switch(quadrant) { + case 1: return parent.getPatch(3); + case 2: return parent.getPatch(4); + case 3: + neighbourQuad = parent.findQuad(DIR_RIGHT); + if (neighbourQuad != null) + return neighbourQuad.getPatch(1); + break; + case 4: + neighbourQuad = parent.findQuad(DIR_RIGHT); + if (neighbourQuad != null) + return neighbourQuad.getPatch(2); + break; + } + + return null; + } + + private TerrainPatch getDownNeighbourPatch() { + TerrainQuad parent = (TerrainQuad) this.getParent(); + TerrainQuad neighbourQuad; + + switch(quadrant) { + case 1: return parent.getPatch(2); + case 2: + neighbourQuad = parent.findQuad(DIR_DOWN); + if (neighbourQuad != null) + return neighbourQuad.getPatch(1); + break; + case 3: return parent.getPatch(4); + case 4: + neighbourQuad = parent.findQuad(DIR_DOWN); + if (neighbourQuad != null) + return neighbourQuad.getPatch(3); + break; + } + + return null; + } + + private TerrainPatch getLeftNeighbourPatch() { + TerrainQuad parent = (TerrainQuad) this.getParent(); + TerrainQuad neighbourQuad; + + switch(quadrant) { + case 1: + neighbourQuad = parent.findQuad(DIR_LEFT); + if (neighbourQuad != null) + return neighbourQuad.getPatch(3); + break; + case 2: + neighbourQuad = parent.findQuad(DIR_LEFT); + if (neighbourQuad != null) + return neighbourQuad.getPatch(4); + break; + case 3: return parent.getPatch(1); + case 4: return parent.getPatch(2); + } + + return null; + } + + private TerrainPatch getTopNeighbourPatch() { + TerrainQuad parent = (TerrainQuad) this.getParent(); + TerrainQuad neighbourQuad; + + switch(quadrant) { + case 1: + neighbourQuad = parent.findQuad(DIR_TOP); + if (neighbourQuad != null) + return neighbourQuad.getPatch(2); + break; + case 2: return parent.getPatch(1); + case 3: + neighbourQuad = parent.findQuad(DIR_TOP); + if (neighbourQuad != null) + return neighbourQuad.getPatch(4); + break; + case 4: return parent.getPatch(3); + } + + return null; + } + protected void setHeight(List locationHeights, boolean overrideHeight) { for (LocationHeight lh : locationHeights) { From af180509b84069d0a6d1b813cd6f3f5f2dfc0351 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 09:33:50 +0200 Subject: [PATCH 32/59] Added comparison tests between old code and refactored code --- .../terrain/geomipmap/TerrainPatchTest.java | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainPatchTest.java diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainPatchTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainPatchTest.java new file mode 100644 index 0000000000..764f3fba5a --- /dev/null +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainPatchTest.java @@ -0,0 +1,112 @@ +package com.jme3.terrain.geomipmap; + +import com.jme3.scene.Spatial; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.junit.Assert.*; + +public class TerrainPatchTest { + + final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + private FakeTerrainQuad parentTerrainQuad; + private FakeTerrainQuad[] children = new FakeTerrainQuad[4]; + + @Before + public void init() { + for (int i = 0; i < 4; i++) { + children[i] = new FakeTerrainQuad(); + } + + parentTerrainQuad = new FakeTerrainQuad(); + fakeCreateQuad(parentTerrainQuad, children); + } + + private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) { + for (int i = 0; i < children.length; i++) { + children[i].quadrant = i + 1; // Quadrant starts counting from 1 + parent.attachChild(children[i]); + } + } + + /** + * Used to recursively create a nested structure of {@link Spatial}s. + * If nesting level is > 1, root element will be a {@link TerrainQuad}. + * Leafs (nesting level 0) are {@link TerrainPatch}es. + * + * @param nestLevel Nest level to be created. + * @return Nested structure of {@link Spatial}s + */ + private Spatial createNestedQuad(int nestLevel) { + if (nestLevel == 0) { + return new TerrainPatch(); + } + + FakeTerrainQuad parent = new FakeTerrainQuad(); + for (int i = 0; i < 4; i++) { + Spatial child = createNestedQuad(nestLevel - 1); + + if (child instanceof TerrainPatch) { + TerrainPatch patchChild = (TerrainPatch) child; + patchChild.quadrant = (short) (i + 1); + parent.attachChild(patchChild); + } else if (child instanceof TerrainQuad) { + FakeTerrainQuad quadChild = (FakeTerrainQuad) child; + quadChild.quadrant = i + 1; + parent.attachChild(quadChild); + } + } + + return parent; + } + + @Test + public void testFindPatch() { + // Test for nestlevel 2 + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + + // Test for all quad children + for (int i = 1; i <= 4; i++) { + FakeTerrainQuad quadChild = (FakeTerrainQuad) root.getQuad(i); + + // Test for all patch children + for (int j = 1; j <= 4; j++) { + TerrainPatch patchChild = quadChild.getPatch(j); + + assertNotNull(patchChild); + + assertEquals(patchChild.findPatch(DIR_RIGHT), quadChild.findRightPatch(patchChild)); + assertEquals(patchChild.findPatch(DIR_DOWN),quadChild.findDownPatch(patchChild)); + assertEquals(patchChild.findPatch(DIR_LEFT),quadChild.findLeftPatch(patchChild)); + assertEquals(patchChild.findPatch(DIR_TOP), quadChild.findTopPatch(patchChild)); + + // Test nonsense direction + assertNull(patchChild.findPatch(-1)); + } + } + + // Test for nestlevel 1 + root = (FakeTerrainQuad)createNestedQuad(1); + + // Test for all patch children + for (int j = 1; j <= 4; j++) { + TerrainPatch patchChild = root.getPatch(j); + + assertNotNull(patchChild); + + assertEquals(patchChild.findPatch(DIR_RIGHT), root.findRightPatch(patchChild)); + assertEquals(patchChild.findPatch(DIR_DOWN),root.findDownPatch(patchChild)); + assertEquals(patchChild.findPatch(DIR_LEFT),root.findLeftPatch(patchChild)); + assertEquals(patchChild.findPatch(DIR_TOP), root.findTopPatch(patchChild)); + + // Test nonsense direction + assertNull(patchChild.findPatch(-1)); + } + } +} From 90dcab5443f97ee4d0104e67b0292057411db647 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 09:35:13 +0200 Subject: [PATCH 33/59] Removed dead test code --- .../terrain/geomipmap/TerrainPatchTest.java | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainPatchTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainPatchTest.java index 764f3fba5a..28f8058757 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainPatchTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainPatchTest.java @@ -1,10 +1,7 @@ package com.jme3.terrain.geomipmap; import com.jme3.scene.Spatial; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import static org.junit.Assert.*; @@ -12,29 +9,6 @@ public class TerrainPatchTest { final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; - @Rule - public final ExpectedException exception = ExpectedException.none(); - - private FakeTerrainQuad parentTerrainQuad; - private FakeTerrainQuad[] children = new FakeTerrainQuad[4]; - - @Before - public void init() { - for (int i = 0; i < 4; i++) { - children[i] = new FakeTerrainQuad(); - } - - parentTerrainQuad = new FakeTerrainQuad(); - fakeCreateQuad(parentTerrainQuad, children); - } - - private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) { - for (int i = 0; i < children.length; i++) { - children[i].quadrant = i + 1; // Quadrant starts counting from 1 - parent.attachChild(children[i]); - } - } - /** * Used to recursively create a nested structure of {@link Spatial}s. * If nesting level is > 1, root element will be a {@link TerrainQuad}. From 6df313521c16ce6870436bdd253b0fcff85add11 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 09:39:17 +0200 Subject: [PATCH 34/59] Added deprecated tags to old code --- .../main/java/com/jme3/terrain/geomipmap/TerrainQuad.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 8f76ee6ed1..9ddb035b78 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -1370,6 +1370,7 @@ protected TerrainQuad getQuad(int quad) { return null; } + @Deprecated protected TerrainPatch findRightPatch(TerrainPatch tp) { if (tp.getQuadrant() == 1) return getPatch(3); @@ -1390,6 +1391,7 @@ else if (tp.getQuadrant() == 3) { return null; } + @Deprecated protected TerrainPatch findDownPatch(TerrainPatch tp) { if (tp.getQuadrant() == 1) return getPatch(2); @@ -1409,7 +1411,7 @@ else if (tp.getQuadrant() == 2) { return null; } - + @Deprecated protected TerrainPatch findTopPatch(TerrainPatch tp) { if (tp.getQuadrant() == 2) return getPatch(1); @@ -1429,6 +1431,7 @@ else if (tp.getQuadrant() == 1) { return null; } + @Deprecated protected TerrainPatch findLeftPatch(TerrainPatch tp) { if (tp.getQuadrant() == 3) return getPatch(1); From e94b2e11a8d00bbacc1f098ac854218a9c0c8853 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 10:10:42 +0200 Subject: [PATCH 35/59] Set deprecated code back to tests and the code itself --- .../jme3/terrain/geomipmap/TerrainQuad.java | 16 ++--- .../terrain/geomipmap/TerrainQuadTest.java | 64 +++++++++---------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 9ddb035b78..873a8c54b1 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -1579,11 +1579,11 @@ protected TerrainQuad findRightQuad() { else if (quadrant == 2) return pQuad.getQuad(4); else if (quadrant == 3) { - TerrainQuad quad = pQuad.findQuad(DIR_RIGHT); + TerrainQuad quad = pQuad.findRightQuad(); if (quad != null) return quad.getQuad(1); } else if (quadrant == 4) { - TerrainQuad quad = pQuad.findQuad(DIR_RIGHT); + TerrainQuad quad = pQuad.findRightQuad(); if (quad != null) return quad.getQuad(2); } else if (quadrant == 0) { @@ -1616,11 +1616,11 @@ protected TerrainQuad findDownQuad() { else if (quadrant == 3) return pQuad.getQuad(4); else if (quadrant == 2) { - TerrainQuad quad = pQuad.findQuad(DIR_DOWN); + TerrainQuad quad = pQuad.findDownQuad(); if (quad != null) return quad.getQuad(1); } else if (quadrant == 4) { - TerrainQuad quad = pQuad.findQuad(DIR_DOWN); + TerrainQuad quad = pQuad.findDownQuad(); if (quad != null) return quad.getQuad(3); } else if (quadrant == 0) { @@ -1653,11 +1653,11 @@ protected TerrainQuad findTopQuad() { else if (quadrant == 4) return pQuad.getQuad(3); else if (quadrant == 1) { - TerrainQuad quad = pQuad.findQuad(DIR_TOP); + TerrainQuad quad = pQuad.findTopQuad(); if (quad != null) return quad.getQuad(2); } else if (quadrant == 3) { - TerrainQuad quad = pQuad.findQuad(DIR_TOP); + TerrainQuad quad = pQuad.findTopQuad(); if (quad != null) return quad.getQuad(4); } else if (quadrant == 0) { @@ -1690,11 +1690,11 @@ protected TerrainQuad findLeftQuad() { else if (quadrant == 4) return pQuad.getQuad(2); else if (quadrant == 1) { - TerrainQuad quad = pQuad.findQuad(DIR_LEFT); + TerrainQuad quad = pQuad.findLeftQuad(); if (quad != null) return quad.getQuad(3); } else if (quadrant == 2) { - TerrainQuad quad = pQuad.findQuad(DIR_LEFT); + TerrainQuad quad = pQuad.findLeftQuad(); if (quad != null) return quad.getQuad(4); } else if (quadrant == 0) { diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 4e7e032218..1fd0e3e1a3 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -124,18 +124,18 @@ public void testFindRightQuad() { FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad topRight = (FakeTerrainQuad) root.getQuad(3); - assertEquals(root.findQuad(DIR_RIGHT), null); - assertEquals(topLeftChild.findQuad(DIR_RIGHT), topRight); // Confirm position of two parent quads + assertEquals(root.findRightQuad(), null); + assertEquals(topLeftChild.findRightQuad(), topRight); // Confirm position of two parent quads // Check quad children of parent - assertEquals(topLeftChild.getQuad(1).findQuad(DIR_RIGHT), topLeftChild.getQuad(3)); - assertEquals(topLeftChild.getQuad(2).findQuad(DIR_RIGHT), topLeftChild.getQuad(4)); - assertEquals(topLeftChild.getQuad(3).findQuad(DIR_RIGHT), topRight.getQuad(1)); - assertEquals(topLeftChild.getQuad(4).findQuad(DIR_RIGHT), topRight.getQuad(2)); + assertEquals(topLeftChild.getQuad(1).findRightQuad(), topLeftChild.getQuad(3)); + assertEquals(topLeftChild.getQuad(2).findRightQuad(), topLeftChild.getQuad(4)); + assertEquals(topLeftChild.getQuad(3).findRightQuad(), topRight.getQuad(1)); + assertEquals(topLeftChild.getQuad(4).findRightQuad(), topRight.getQuad(2)); // Check non-existing neighbour quads - assertEquals(topRight.getQuad(3).findQuad(DIR_RIGHT), null); - assertEquals(topRight.getQuad(4).findQuad(DIR_RIGHT), null); + assertEquals(topRight.getQuad(3).findRightQuad(), null); + assertEquals(topRight.getQuad(4).findRightQuad(), null); } @Test @@ -144,18 +144,18 @@ public void testFindDownQuad() { FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad downLeftChild = (FakeTerrainQuad) root.getQuad(2); - assertEquals(root.findQuad(DIR_DOWN), null); - assertEquals(topLeftChild.findQuad(DIR_DOWN), downLeftChild); // Confirm position of two parent quads + assertEquals(root.findDownQuad(), null); + assertEquals(topLeftChild.findDownQuad(), downLeftChild); // Confirm position of two parent quads // Check quad children of parent - assertEquals(topLeftChild.getQuad(1).findQuad(DIR_DOWN), topLeftChild.getQuad(2)); - assertEquals(topLeftChild.getQuad(2).findQuad(DIR_DOWN), downLeftChild.getQuad(1)); - assertEquals(topLeftChild.getQuad(3).findQuad(DIR_DOWN), topLeftChild.getQuad(4)); - assertEquals(topLeftChild.getQuad(4).findQuad(DIR_DOWN), downLeftChild.getQuad(3)); + assertEquals(topLeftChild.getQuad(1).findDownQuad(), topLeftChild.getQuad(2)); + assertEquals(topLeftChild.getQuad(2).findDownQuad(), downLeftChild.getQuad(1)); + assertEquals(topLeftChild.getQuad(3).findDownQuad(), topLeftChild.getQuad(4)); + assertEquals(topLeftChild.getQuad(4).findDownQuad(), downLeftChild.getQuad(3)); // Check non-existing neighbour quads - assertEquals(downLeftChild.getQuad(2).findQuad(DIR_DOWN), null); - assertEquals(downLeftChild.getQuad(4).findQuad(DIR_DOWN), null); + assertEquals(downLeftChild.getQuad(2).findDownQuad(), null); + assertEquals(downLeftChild.getQuad(4).findDownQuad(), null); } @Test @@ -164,18 +164,18 @@ public void testFindLeftQuad() { FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad topRightChild = (FakeTerrainQuad) root.getQuad(3); - assertEquals(root.findQuad(DIR_LEFT), null); - assertEquals(topRightChild.findQuad(DIR_LEFT), topLeftChild); // Confirm position of two parent quads + assertEquals(root.findLeftQuad(), null); + assertEquals(topRightChild.findLeftQuad(), topLeftChild); // Confirm position of two parent quads // Check quad children of parent - assertEquals(topRightChild.getQuad(1).findQuad(DIR_LEFT), topLeftChild.getQuad(3)); - assertEquals(topRightChild.getQuad(2).findQuad(DIR_LEFT), topLeftChild.getQuad(4)); - assertEquals(topRightChild.getQuad(3).findQuad(DIR_LEFT), topRightChild.getQuad(1)); - assertEquals(topRightChild.getQuad(4).findQuad(DIR_LEFT), topRightChild.getQuad(2)); + assertEquals(topRightChild.getQuad(1).findLeftQuad(), topLeftChild.getQuad(3)); + assertEquals(topRightChild.getQuad(2).findLeftQuad(), topLeftChild.getQuad(4)); + assertEquals(topRightChild.getQuad(3).findLeftQuad(), topRightChild.getQuad(1)); + assertEquals(topRightChild.getQuad(4).findLeftQuad(), topRightChild.getQuad(2)); // Check non-existing neighbour quads - assertEquals(topLeftChild.getQuad(1).findQuad(DIR_LEFT), null); - assertEquals(topLeftChild.getQuad(2).findQuad(DIR_LEFT), null); + assertEquals(topLeftChild.getQuad(1).findLeftQuad(), null); + assertEquals(topLeftChild.getQuad(2).findLeftQuad(), null); } @Test @@ -184,18 +184,18 @@ public void testFindTopQuad() { FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad downLeftChild = (FakeTerrainQuad) root.getQuad(2); - assertEquals(root.findQuad(DIR_TOP), null); - assertEquals(downLeftChild.findQuad(DIR_TOP), topLeftChild); // Confirm position of two parent quads + assertEquals(root.findTopQuad(), null); + assertEquals(downLeftChild.findTopQuad(), topLeftChild); // Confirm position of two parent quads // Check quad children of parent - assertEquals(downLeftChild.getQuad(1).findQuad(DIR_TOP), topLeftChild.getQuad(2)); - assertEquals(downLeftChild.getQuad(2).findQuad(DIR_TOP), downLeftChild.getQuad(1)); - assertEquals(downLeftChild.getQuad(3).findQuad(DIR_TOP), topLeftChild.getQuad(4)); - assertEquals(downLeftChild.getQuad(4).findQuad(DIR_TOP), downLeftChild.getQuad(3)); + assertEquals(downLeftChild.getQuad(1).findTopQuad(), topLeftChild.getQuad(2)); + assertEquals(downLeftChild.getQuad(2).findTopQuad(), downLeftChild.getQuad(1)); + assertEquals(downLeftChild.getQuad(3).findTopQuad(), topLeftChild.getQuad(4)); + assertEquals(downLeftChild.getQuad(4).findTopQuad(), downLeftChild.getQuad(3)); // Check non-existing neighbour quads - assertEquals(topLeftChild.getQuad(1).findQuad(DIR_TOP), null); - assertEquals(topLeftChild.getQuad(3).findQuad(DIR_TOP), null); + assertEquals(topLeftChild.getQuad(1).findTopQuad(), null); + assertEquals(topLeftChild.getQuad(3).findTopQuad(), null); } @Test From 3837d1a3a0005cc502cd6b8b769e52551d1fce8f Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 10:52:21 +0200 Subject: [PATCH 36/59] Added test coverage for the NeighbourFinder in the legacy code --- .../jme3/terrain/geomipmap/TerrainQuadTest.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 1fd0e3e1a3..cf97937d61 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -111,10 +111,17 @@ public void testFindQuadNeighbourFinder() { NeighbourFinder nf = new TestNeighbourFinder(roots[0], roots[1], roots[2], roots[3]); for (FakeTerrainQuad root : roots) { root.setNeighbourFinder(nf); - assertEquals(root.findQuad(0), nf.getRightQuad(root)); - assertEquals(root.findQuad(1), nf.getDownQuad(root)); - assertEquals(root.findQuad(2), nf.getLeftQuad(root)); - assertEquals(root.findQuad(3), nf.getTopQuad(root)); + // Legacy code + assertEquals(root.findRightQuad(), nf.getRightQuad(root)); + assertEquals(root.findDownQuad(), nf.getDownQuad(root)); + assertEquals(root.findLeftQuad(), nf.getLeftQuad(root)); + assertEquals(root.findTopQuad(), nf.getTopQuad(root)); + + // Refactored code + assertEquals(root.findQuad(DIR_RIGHT), nf.getRightQuad(root)); + assertEquals(root.findQuad(DIR_DOWN), nf.getDownQuad(root)); + assertEquals(root.findQuad(DIR_LEFT), nf.getLeftQuad(root)); + assertEquals(root.findQuad(DIR_TOP), nf.getTopQuad(root)); } } From 3517d1c551ac34e43087d059b39d314b45c198da Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 11:00:44 +0200 Subject: [PATCH 37/59] Reversed legacy code to its original code --- .../com/jme3/terrain/geomipmap/TerrainQuad.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 873a8c54b1..4ef3292caf 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -1378,12 +1378,12 @@ else if (tp.getQuadrant() == 2) return getPatch(4); else if (tp.getQuadrant() == 3) { // find the patch to the right and ask it for child 1. - TerrainQuad quad = findQuad(DIR_RIGHT); + TerrainQuad quad = findRightQuad(); if (quad != null) return quad.getPatch(1); } else if (tp.getQuadrant() == 4) { // find the patch to the right and ask it for child 2. - TerrainQuad quad = findQuad(DIR_RIGHT); + TerrainQuad quad = findRightQuad(); if (quad != null) return quad.getPatch(2); } @@ -1399,11 +1399,11 @@ else if (tp.getQuadrant() == 3) return getPatch(4); else if (tp.getQuadrant() == 2) { // find the patch below and ask it for child 1. - TerrainQuad quad = findQuad(DIR_DOWN); + TerrainQuad quad = findDownQuad(); if (quad != null) return quad.getPatch(1); } else if (tp.getQuadrant() == 4) { - TerrainQuad quad = findQuad(DIR_DOWN); + TerrainQuad quad = findDownQuad(); if (quad != null) return quad.getPatch(3); } @@ -1419,11 +1419,11 @@ else if (tp.getQuadrant() == 4) return getPatch(3); else if (tp.getQuadrant() == 1) { // find the patch above and ask it for child 2. - TerrainQuad quad = findQuad(DIR_TOP); + TerrainQuad quad = findTopQuad(); if (quad != null) return quad.getPatch(2); } else if (tp.getQuadrant() == 3) { - TerrainQuad quad = findQuad(DIR_TOP); + TerrainQuad quad = findTopQuad(); if (quad != null) return quad.getPatch(4); } @@ -1439,11 +1439,11 @@ else if (tp.getQuadrant() == 4) return getPatch(2); else if (tp.getQuadrant() == 1) { // find the patch above and ask it for child 3. - TerrainQuad quad = findQuad(DIR_LEFT); + TerrainQuad quad = findLeftQuad(); if (quad != null) return quad.getPatch(3); } else if (tp.getQuadrant() == 2) { - TerrainQuad quad = findQuad(DIR_LEFT); + TerrainQuad quad = findLeftQuad(); if (quad != null) return quad.getPatch(4); } From 38c64ad38ddf5d6168c17e57bf7360e41086efb2 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 11:12:42 +0200 Subject: [PATCH 38/59] Changed existing code to use the new findPatch method --- .../jme3/terrain/geomipmap/TerrainQuad.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 4ef3292caf..b4a50f1136 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -399,10 +399,10 @@ protected synchronized void findNeighboursLod(HashMap updated if(utp != null && utp.lodChanged()) { if (!patch.searchedForNeighboursAlready) { // set the references to the neighbours - patch.rightNeighbour = findRightPatch(patch); - patch.bottomNeighbour = findDownPatch(patch); - patch.leftNeighbour = findLeftPatch(patch); - patch.topNeighbour = findTopPatch(patch); + patch.rightNeighbour = patch.findPatch(DIR_RIGHT); + patch.bottomNeighbour = patch.findPatch(DIR_DOWN); + patch.leftNeighbour = patch.findPatch(DIR_LEFT); + patch.topNeighbour = patch.findPatch(DIR_TOP); patch.searchedForNeighboursAlready = true; } TerrainPatch right = patch.rightNeighbour; @@ -1747,22 +1747,22 @@ protected void fixNormalEdges(BoundingBox affectedArea) { continue; TerrainPatch tp = (TerrainPatch) child; - TerrainPatch right = findRightPatch(tp); - TerrainPatch bottom = findDownPatch(tp); - TerrainPatch top = findTopPatch(tp); - TerrainPatch left = findLeftPatch(tp); + TerrainPatch right = tp.findPatch(DIR_RIGHT); + TerrainPatch bottom = tp.findPatch(DIR_DOWN); + TerrainPatch top = tp.findPatch(DIR_TOP); + TerrainPatch left = tp.findPatch(DIR_LEFT); TerrainPatch topLeft = null; if (top != null) - topLeft = findLeftPatch(top); + topLeft = top.findPatch(DIR_LEFT); TerrainPatch bottomRight = null; if (right != null) - bottomRight = findDownPatch(right); + bottomRight = right.findPatch(DIR_DOWN); TerrainPatch topRight = null; if (top != null) - topRight = findRightPatch(top); + topRight = top.findPatch(DIR_RIGHT); TerrainPatch bottomLeft = null; if (left != null) - bottomLeft = findDownPatch(left); + bottomLeft = left.findPatch(DIR_DOWN); tp.fixNormalEdges(right, bottom, top, left, bottomRight, bottomLeft, topRight, topLeft); From 6e4c6a11d0db4e05de26c0b9fd123e0e91e18d8b Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 30 Mar 2016 12:31:19 +0200 Subject: [PATCH 39/59] testGetHeightmapHeight --- .../jme3/terrain/geomipmap/TerrainPatch.java | 1 - .../jme3/terrain/geomipmap/TerrainQuad.java | 57 ++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java index fecf747de3..076ba8ef1d 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java @@ -625,7 +625,6 @@ protected TerrainPatch createQuadPatch(TerrainQuad terrainQuad, int patchNumber, origin = new Vector3f(-halfSize * terrainQuad.stepScale.x, 0, 0); tempOffset.x += origin.x / 2; tempOffset.y += quarterSize * terrainQuad.stepScale.z; - System.out.println(tempOffset); break; case 3: origin = new Vector3f(0, 0, -halfSize * terrainQuad.stepScale.z); diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 64be20425b..e874ab9a99 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -108,6 +108,10 @@ * @author Brent Owens */ public class TerrainQuad extends Node implements Terrain { + + private Vector3f meshNormal; + private float heightmapHeight; + protected Vector2f offset; protected int totalSize; // the size of this entire terrain tree (on one side) @@ -902,9 +906,59 @@ protected float getHeightmapHeight(int x, int z) { } } + + //getMatch(x, z); return Float.NaN; } +// protected void getMatch(int x, int z) { +// +// int quad = findQuadrant(x, z); +// int split = (size + 1) >> 1; +// if (children != null) { +// for (int i = children.size(); --i >= 0; ) { +// Spatial spat = children.get(i); +// int col = x; +// int row = z; +// boolean match = false; +// +// // get the childs quadrant +// int childQuadrant = 0; +// if (spat instanceof TerrainQuad) { +// childQuadrant = ((TerrainQuad) spat).getQuadrant(); +// } else if (spat instanceof TerrainPatch) { +// childQuadrant = ((TerrainPatch) spat).getQuadrant(); +// } +// +// if (childQuadrant == 1 && (quad & 1) != 0) { +// match = true; +// } else if (childQuadrant == 2 && (quad & 2) != 0) { +// row = z - split + 1; +// match = true; +// } else if (childQuadrant == 3 && (quad & 4) != 0) { +// col = x - split + 1; +// match = true; +// } else if (childQuadrant == 4 && (quad & 8) != 0) { +// col = x - split + 1; +// row = z - split + 1; +// match = true; +// } +// +// if (match) { +// if (spat instanceof TerrainQuad) { +// ((TerrainQuad) spat).getHeightmapHeight(col, row); +// } else if (spat instanceof TerrainPatch) { +// ((TerrainPatch) spat).getHeightmapHeight(col, row); +// } +// } +// +// } +// } +// heightmapHeight = Float.NaN; +// +// } + + protected Vector3f getMeshNormal(int x, int z) { int quad = findQuadrant(x, z); int split = (size + 1) >> 1; @@ -1072,7 +1126,7 @@ protected Vector3f getNormal(float x, float z, Vector2f xz) { // v3--v4 | Z // | // <-------Y - // X + // X Vector3f n1 = getMeshNormal((int) FastMath.ceil(x), (int) FastMath.ceil(z)); Vector3f n2 = getMeshNormal((int) FastMath.floor(x), (int) FastMath.ceil(z)); Vector3f n3 = getMeshNormal((int) FastMath.ceil(x), (int) FastMath.floor(z)); @@ -1144,6 +1198,7 @@ protected class LocationHeight { this.z = z; this.h = h; } + } protected void setHeight(List locations, boolean overrideHeight) { From 37bad818c42ec6bd871aa720a05981bd07e4c649 Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 30 Mar 2016 13:08:02 +0200 Subject: [PATCH 40/59] TerrainQuadTest updated --- .../terrain/geomipmap/TerrainQuadTest.java | 296 ++++++++++++++++-- 1 file changed, 266 insertions(+), 30 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index ef81661992..e5859c4016 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -1,30 +1,100 @@ package com.jme3.terrain.geomipmap; -import static org.junit.Assert.*; - +import com.jme3.asset.AssetManager; +import com.jme3.bounding.BoundingBox; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; import com.jme3.scene.Spatial; +import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.geomipmap.lodcalc.LodCalculator; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.HillHeightMap; import org.junit.Before; import org.junit.Test; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import static org.junit.Assert.assertEquals; + public class TerrainQuadTest { + private AssetManager assetManager; private FakeTerrainQuad parentTerrainQuad; + private TerrainQuad terrainQuad = new TerrainQuad(); private FakeTerrainQuad[] children = new FakeTerrainQuad[4]; + private TerrainPatch[] tpChildren = new TerrainPatch[4]; + private LodCalculator lodCalculator = new DistanceLodCalculator(); + private LodCalculator fakeLodCalculator = new FakeDistanceLodCalculator(); + private List location = new ArrayList(); + private HashMap updates = new HashMap(); + private Vector3f v3f = new Vector3f(); + private Vector2f v2f = new Vector2f(); + private BoundingBox boundingBox = new BoundingBox(); + private float[] testHeightmap; + @Before public void init() { - for(int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { children[i] = new FakeTerrainQuad(); + // children[i] = new TerrainQuad(); + tpChildren[i] = new TerrainPatch(); } - parentTerrainQuad = new FakeTerrainQuad(); - fakeCreateQuad(parentTerrainQuad, children); + // HEIGHTMAP image (for the terrain heightmap) + //Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); + // CREATE HEIGHTMAP + AbstractHeightMap heightmap = null; + try { + heightmap = new HillHeightMap(5, 1000, 50, 100, (byte) 3); + + //heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 1f); + heightmap.load(); + + } catch (Exception e) { + e.printStackTrace(); + } + + + terrainQuad = new TerrainQuad("terrain_1", 3, 5, heightmap.getHeightMap()); + + + TerrainPatch tp0 = (TerrainPatch) terrainQuad.getChild(0); + System.out.println("tp 0 heightmap: " + tp0.getHeightMap().length); + for (int i = 0; i < 9; i++) { + System.out.println("tp 0 heightmap: " + tp0.getHeightMap()[i]); + } + TerrainPatch tp1 = (TerrainPatch) terrainQuad.getChild(1); + for (int i = 0; i < 9; i++) { + System.out.println("tp 1 heightmap: " + tp1.getHeightMap()[i]); + } + TerrainPatch tp2 = (TerrainPatch) terrainQuad.getChild(2); + for (int i = 0; i < 9; i++) { + System.out.println("tp 2 heightmap: " + tp2.getHeightMap()[i]); + } + TerrainPatch tp3 = (TerrainPatch) terrainQuad.getChild(3); + for (int i = 0; i < 9; i++) { + System.out.println("tp 3 heightmap: " + tp3.getHeightMap()[i]); + } + + + testHeightmap = heightmap.getHeightMap(); + + for (int i = 0; i < testHeightmap.length; i++) { + System.out.println("heightmap values: " + testHeightmap[i]); + } + +// parentTerrainQuad = new FakeTerrainQuad(); +// fakeCreateQuad(parentTerrainQuad, children); } private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) { for (int i = 0; i < children.length; i++) { children[i].quadrant = i + 1; // Quadrant starts counting from 1 parent.attachChild(children[i]); + //parent.getQuad(i).attachChild((tpChildren[i])); } } @@ -32,6 +102,7 @@ private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) * Used to recursively create a nested structure of {@link Spatial}s. * If nesting level is > 1, root element will be a {@link TerrainQuad}. * Leafs (nesting level 0) are {@link TerrainPatch}es. + * * @param nestLevel Nest level to be created. * @return Nested structure of {@link Spatial}s */ @@ -41,7 +112,7 @@ private Spatial createNestedQuad(int nestLevel) { } FakeTerrainQuad parent = new FakeTerrainQuad(); - for(int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { Spatial child = createNestedQuad(nestLevel - 1); if (child instanceof TerrainPatch) { @@ -58,37 +129,202 @@ private Spatial createNestedQuad(int nestLevel) { return parent; } +// @Test +// public void testFakeTerrainQuad() { +// FakeTerrainQuad fake = new FakeTerrainQuad(); +// assertEquals(fake, fake.getQuad(0)); +// } +// +// @Test +// public void testNestStructure() { +// Spatial leaf = createNestedQuad(0); +// assertTrue(leaf instanceof TerrainPatch); +// +// FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); +// assertEquals(root.getChildren().size(), 4); +// for (int i = 0; i < 4; i++) { +// assertTrue(root.getChild(i) instanceof TerrainPatch); // Ensure children of root are leafs +// } +// +// root = (FakeTerrainQuad) createNestedQuad(2); +// assertEquals(root.getChildren().size(), 4); +// for (int i = 0; i < 4; i++) { +// assertTrue(root.getChild(i) instanceof TerrainQuad); // Ensure children of root are not leafs +// } +// } +// +// @Test +// public void testGetQuad() { +// assertEquals(parentTerrainQuad.getQuad(0), parentTerrainQuad); +// assertEquals(parentTerrainQuad.getQuad(1), children[0]); +// assertEquals(parentTerrainQuad.getQuad(2), children[1]); +// assertEquals(parentTerrainQuad.getQuad(3), children[2]); +// assertEquals(parentTerrainQuad.getQuad(4), children[3]); +// assertEquals(parentTerrainQuad.getQuad(5), null); +// } +// +// +// /** +// * tests the calculateLod method. +// * Came to the conclusion that the method does belong to TerrainQuad, but should be renamed +// * as it does not calculate anything. Is only retrieves values from users of the LodCalculator interface. +// * The actual lodCalculator is defined in the calculateLod method of these childs. +// */ +// @Test +// public void testCalculateLod() { +// FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); +// assertFalse(root.calculateLod(location, updates, lodCalculator)); +// assertTrue(root.calculateLod(location, updates, fakeLodCalculator)); +// +// FakeTerrainQuad leaf = (FakeTerrainQuad) createNestedQuad(1); +// leaf.attachChild(children[1]); +// assertTrue(leaf.calculateLod(location, updates, fakeLodCalculator)); +// } + +// @Test +// public void testCreateQuadPatch1() { +// String patch1 = "terrain_1Patch1"; +// +// +// boundingBox.setCenter(1.0f, 54.88082f, 1.0f); +// terrainQuad.setPatchChildren(testHeightmap); +// +// +// System.out.println(terrainQuad.getChildren()); +// +// assertTrue(terrainQuad.getChild(patch1) instanceof TerrainPatch); +// TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch1); +// +// assertEquals(patch1, p1.getName()); +// assertEquals(v2f.set(-1.0f, -1.0f), p1.getOffset()); +// assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); +// assertEquals(v3f.add(-2.0f, 0.0f, -2.0f), p1.getLocalTranslation()); +// assertEquals(9, p1.getHeightMap().length); +// assertEquals(5, p1.getTotalSize()); +// assertEquals(1, p1.getQuadrant()); +// assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); +// } +// +// @Test +// public void testCreateQuadPatch2() { +// String patch2 = "terrain_1Patch2"; +// +// boundingBox.setCenter(1.0f, 92.78813f, 1.0f); +// +// terrainQuad.setPatchChildren(testHeightmap); +// +// assertTrue(terrainQuad.getChild(patch2) instanceof TerrainPatch); +// TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch2); +// +// assertEquals(patch2, p1.getName()); +// assertEquals(v2f.set(-1.0f, 1.0f), p1.getOffset()); +// assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); +// assertEquals(v3f.add(-2.0f, 0.0f, 0.0f), p1.getLocalTranslation()); +// assertEquals(9, p1.getHeightMap().length); +// assertEquals(5, p1.getTotalSize()); +// assertEquals(2, p1.getQuadrant()); +// assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); +// } +// +// @Test +// public void testCreateQuadPatch3() { +// String patch3 = "terrain_1Patch3"; +// +// boundingBox.setCenter(1.0f, 64.86637f, 1.0f); +// +// terrainQuad.setPatchChildren(testHeightmap); +// +// assertTrue(terrainQuad.getChild(patch3) instanceof TerrainPatch); +// TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch3); +// +// assertEquals(patch3, p1.getName()); +// assertEquals(v2f.set(1.0f, -1.0f), p1.getOffset()); +// assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); +// assertEquals(v3f.add(0.0f, 0.0f, -2.0f), p1.getLocalTranslation()); +// assertEquals(9, p1.getHeightMap().length); +// assertEquals(5, p1.getTotalSize()); +// assertEquals(3, p1.getQuadrant()); +// assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); +// } +// +// @Test +// public void testCreateQuadPatch4() { +// String patch4 = "terrain_1Patch4"; +// +// boundingBox.setCenter(1.0f, 180.92175f, 1.0f); +// +// terrainQuad.setPatchChildren(testHeightmap); +// +// assertTrue(terrainQuad.getChild(patch4) instanceof TerrainPatch); +// TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch4); +// +// assertEquals(patch4, p1.getName()); +// assertEquals(v2f.set(1.0f, 1.0f), p1.getOffset()); +// assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); +// assertEquals(v3f.add(0.0f, 0.0f, 0.0f), p1.getLocalTranslation()); +// assertEquals(9, p1.getHeightMap().length); +// assertEquals(5, p1.getTotalSize()); +// assertEquals(4, p1.getQuadrant()); +// assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); +// } + @Test - public void testFakeTerrainQuad() { - FakeTerrainQuad fake = new FakeTerrainQuad(); - assertEquals(fake, fake.getQuad(0)); + public void testGetHeightmapHeight() { + assertEquals(0.0f, terrainQuad.getHeightmapHeight(6, 6), 0.0f); +// assertEquals(testHeightmap[0], terrainQuad.getHeightmapHeight(0, 0), 0.0f); +// children = new FakeTerrainQuad[3]; +// for (int i = 0; i < 3; i++) { +// children[i] = new FakeTerrainQuad(); +// } +// +// parentTerrainQuad = new FakeTerrainQuad(); +// parentTerrainQuad.size = 10; +// fakeCreateQuad(parentTerrainQuad, children); +// +// assertEquals(Float.NaN, parentTerrainQuad.getHeightmapHeight(5, 3), 0.0f); +// +// children = new FakeTerrainQuad[2]; +// for (int i = 0; i < 2; i++) { +// children[i] = new FakeTerrainQuad(); +// } +// parentTerrainQuad = new FakeTerrainQuad(); +// parentTerrainQuad.size = 50; +// fakeCreateQuad(parentTerrainQuad, children); +// +// assertEquals(Float.NaN, parentTerrainQuad.getHeightmapHeight(5, 49), 0.0f); + + } @Test - public void testNestStructure() { - Spatial leaf = createNestedQuad(0); - assertTrue(leaf instanceof TerrainPatch); - - FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); - assertEquals(root.getChildren().size(), 4); - for(int i = 0; i < 4; i++) { - assertTrue(root.getChild(i) instanceof TerrainPatch); // Ensure children of root are leafs + public void testGetMeshNormal() { + Vector3f v1 = new Vector3f(-0.7327255f, 0.043074645f, -0.67915976f); + + assertEquals(null, terrainQuad.getMeshNormal(10, 10)); + assertEquals(v1, terrainQuad.getMeshNormal(0, 0)); + children = new FakeTerrainQuad[3]; + for (int i = 0; i < 3; i++) { + children[i] = new FakeTerrainQuad(); } - root = (FakeTerrainQuad) createNestedQuad(2); - assertEquals(root.getChildren().size(), 4); - for(int i = 0; i < 4; i++) { - assertTrue(root.getChild(i) instanceof TerrainQuad); // Ensure children of root are not leafs + parentTerrainQuad = new FakeTerrainQuad(); + parentTerrainQuad.size = 10; + fakeCreateQuad(parentTerrainQuad, children); + + assertEquals(null, parentTerrainQuad.getMeshNormal(5, 3)); + + children = new FakeTerrainQuad[2]; + for (int i = 0; i < 2; i++) { + children[i] = new FakeTerrainQuad(); } - } + parentTerrainQuad = new FakeTerrainQuad(); + parentTerrainQuad.size = 50; + fakeCreateQuad(parentTerrainQuad, children); + + assertEquals(null, parentTerrainQuad.getMeshNormal(5, 49)); + - @Test - public void testGetQuad() { - assertEquals(parentTerrainQuad.getQuad(0), parentTerrainQuad); - assertEquals(parentTerrainQuad.getQuad(1), children[0]); - assertEquals(parentTerrainQuad.getQuad(2), children[1]); - assertEquals(parentTerrainQuad.getQuad(3), children[2]); - assertEquals(parentTerrainQuad.getQuad(4), children[3]); - assertEquals(parentTerrainQuad.getQuad(5), null); } + + } From 104d0938d2a617166b5d9c55976879737e34c5a5 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 13:55:05 +0200 Subject: [PATCH 41/59] Created new class QuadrantFinder to reduce duplicate code --- .../jme3/terrain/geomipmap/TerrainQuad.java | 193 ++++++++---------- .../terrain/geomipmap/TerrainQuadTest.java | 42 ++-- 2 files changed, 102 insertions(+), 133 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index e874ab9a99..382541a82a 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -48,6 +48,7 @@ import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.debug.WireBox; +import com.jme3.scene.shape.Quad; import com.jme3.terrain.ProgressMonitor; import com.jme3.terrain.Terrain; import com.jme3.terrain.geomipmap.lodcalc.LodCalculator; @@ -865,49 +866,17 @@ public float getHeightmapHeight(Vector2f xz) { * not an interpolated (actual) height value. */ protected float getHeightmapHeight(int x, int z) { - int quad = findQuadrant(x, z); - int split = (size + 1) >> 1; - if (children != null) { - for (int i = children.size(); --i >= 0; ) { - Spatial spat = children.get(i); - int col = x; - int row = z; - boolean match = false; - - // get the childs quadrant - int childQuadrant = 0; - if (spat instanceof TerrainQuad) { - childQuadrant = ((TerrainQuad) spat).getQuadrant(); - } else if (spat instanceof TerrainPatch) { - childQuadrant = ((TerrainPatch) spat).getQuadrant(); - } - - if (childQuadrant == 1 && (quad & 1) != 0) { - match = true; - } else if (childQuadrant == 2 && (quad & 2) != 0) { - row = z - split + 1; - match = true; - } else if (childQuadrant == 3 && (quad & 4) != 0) { - col = x - split + 1; - match = true; - } else if (childQuadrant == 4 && (quad & 8) != 0) { - col = x - split + 1; - row = z - split + 1; - match = true; - } - - if (match) { - if (spat instanceof TerrainQuad) { - return ((TerrainQuad) spat).getHeightmapHeight(col, row); - } else if (spat instanceof TerrainPatch) { - return ((TerrainPatch) spat).getHeightmapHeight(col, row); - } - } - + QuadrantFinder qf = new QuadrantFinder(x, z); + qf.invoke(); + + if (qf.isMatch()) { + if (qf.spat instanceof TerrainQuad) { + return ((TerrainQuad) qf.spat).getHeightmapHeight(qf.col, qf.row); + } else if (qf.spat instanceof TerrainPatch) { + return ((TerrainPatch) qf.spat).getHeightmapHeight(qf.col, qf.row); } } - //getMatch(x, z); return Float.NaN; } @@ -960,47 +929,17 @@ protected float getHeightmapHeight(int x, int z) { protected Vector3f getMeshNormal(int x, int z) { - int quad = findQuadrant(x, z); - int split = (size + 1) >> 1; - if (children != null) { - for (int i = children.size(); --i >= 0; ) { - Spatial spat = children.get(i); - int col = x; - int row = z; - boolean match = false; - - // get the childs quadrant - int childQuadrant = 0; - if (spat instanceof TerrainQuad) { - childQuadrant = ((TerrainQuad) spat).getQuadrant(); - } else if (spat instanceof TerrainPatch) { - childQuadrant = ((TerrainPatch) spat).getQuadrant(); - } - - if (childQuadrant == 1 && (quad & 1) != 0) { - match = true; - } else if (childQuadrant == 2 && (quad & 2) != 0) { - row = z - split + 1; - match = true; - } else if (childQuadrant == 3 && (quad & 4) != 0) { - col = x - split + 1; - match = true; - } else if (childQuadrant == 4 && (quad & 8) != 0) { - col = x - split + 1; - row = z - split + 1; - match = true; - } - - if (match) { - if (spat instanceof TerrainQuad) { - return ((TerrainQuad) spat).getMeshNormal(col, row); - } else if (spat instanceof TerrainPatch) { - return ((TerrainPatch) spat).getMeshNormal(col, row); - } - } - + QuadrantFinder qf = new QuadrantFinder(x, z); + qf.invoke(); + + if (qf.match) { + if (qf.spat instanceof TerrainQuad) { + return ((TerrainQuad) qf.spat).getMeshNormal(qf.col, qf.row); + } else if (qf.spat instanceof TerrainPatch) { + return ((TerrainPatch) qf.spat).getMeshNormal(qf.col, qf.row); } } + return null; } @@ -1033,40 +972,12 @@ private class QuadrantChild { } private QuadrantChild findMatchingChild(int x, int z) { - int quad = findQuadrant(x, z); - int split = (size + 1) >> 1; - if (children != null) { - for (int i = children.size(); --i >= 0; ) { - Spatial spat = children.get(i); - int col = x; - int row = z; - boolean match = false; - - // get the childs quadrant - int childQuadrant = 0; - if (spat instanceof TerrainQuad) { - childQuadrant = ((TerrainQuad) spat).getQuadrant(); - } else if (spat instanceof TerrainPatch) { - childQuadrant = ((TerrainPatch) spat).getQuadrant(); - } + QuadrantFinder qf = new QuadrantFinder(x, z); + qf.invoke(); + + if (qf.isMatch()) + return new QuadrantChild(qf.col, qf.row, qf.spat); - if (childQuadrant == 1 && (quad & 1) != 0) { - match = true; - } else if (childQuadrant == 2 && (quad & 2) != 0) { - row = z - split + 1; - match = true; - } else if (childQuadrant == 3 && (quad & 4) != 0) { - col = x - split + 1; - match = true; - } else if (childQuadrant == 4 && (quad & 8) != 0) { - col = x - split + 1; - row = z - split + 1; - match = true; - } - if (match) - return new QuadrantChild(col, row, spat); - } - } return null; } @@ -1921,5 +1832,63 @@ else if (((TerrainPatch) s).getQuadrant() == 4) return hm; } + + public class QuadrantFinder { + private int x; + private int z; + private int i; + private Spatial spat; + private int col; + private int row; + private boolean match; + + public QuadrantFinder(int x, int z) { + this.x = x; + this.z = z; + } + + public boolean isMatch() { + return this.match; + } + + public boolean invoke() { + int quad = findQuadrant(this.x, this.z); + int split = (size + 1) >> 1; + + if (children != null) { + for (int i = children.size(); --i >= 0; ) { + this.spat = children.get(i); + + // get the childs quadrant + int childQuadrant = 0; + if (this.spat instanceof TerrainQuad) { + childQuadrant = ((TerrainQuad) this.spat).getQuadrant(); + } else if (this.spat instanceof TerrainPatch) { + childQuadrant = ((TerrainPatch) this.spat).getQuadrant(); + } + + if (childQuadrant == 1 && (quad & 1) != 0) { + this.match = true; + } else if (childQuadrant == 2 && (quad & 2) != 0) { + this.row = this.z - split + 1; + this.match = true; + } else if (childQuadrant == 3 && (quad & 4) != 0) { + this.col = this.x - split + 1; + this.match = true; + } else if (childQuadrant == 4 && (quad & 8) != 0) { + this.col = this.x - split + 1; + this.row = this.z - split + 1; + this.match = true; + } + + if (this.match) { + return true; + } + } + } + + return false; + } + } } diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index e5859c4016..b8f0869391 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -271,27 +271,27 @@ private Spatial createNestedQuad(int nestLevel) { @Test public void testGetHeightmapHeight() { assertEquals(0.0f, terrainQuad.getHeightmapHeight(6, 6), 0.0f); -// assertEquals(testHeightmap[0], terrainQuad.getHeightmapHeight(0, 0), 0.0f); -// children = new FakeTerrainQuad[3]; -// for (int i = 0; i < 3; i++) { -// children[i] = new FakeTerrainQuad(); -// } -// -// parentTerrainQuad = new FakeTerrainQuad(); -// parentTerrainQuad.size = 10; -// fakeCreateQuad(parentTerrainQuad, children); -// -// assertEquals(Float.NaN, parentTerrainQuad.getHeightmapHeight(5, 3), 0.0f); -// -// children = new FakeTerrainQuad[2]; -// for (int i = 0; i < 2; i++) { -// children[i] = new FakeTerrainQuad(); -// } -// parentTerrainQuad = new FakeTerrainQuad(); -// parentTerrainQuad.size = 50; -// fakeCreateQuad(parentTerrainQuad, children); -// -// assertEquals(Float.NaN, parentTerrainQuad.getHeightmapHeight(5, 49), 0.0f); + assertEquals(testHeightmap[0], terrainQuad.getHeightmapHeight(0, 0), 0.0f); + children = new FakeTerrainQuad[3]; + for (int i = 0; i < 3; i++) { + children[i] = new FakeTerrainQuad(); + } + + parentTerrainQuad = new FakeTerrainQuad(); + parentTerrainQuad.size = 10; + fakeCreateQuad(parentTerrainQuad, children); + + assertEquals(Float.NaN, parentTerrainQuad.getHeightmapHeight(5, 3), 0.0f); + + children = new FakeTerrainQuad[2]; + for (int i = 0; i < 2; i++) { + children[i] = new FakeTerrainQuad(); + } + parentTerrainQuad = new FakeTerrainQuad(); + parentTerrainQuad.size = 50; + fakeCreateQuad(parentTerrainQuad, children); + + assertEquals(Float.NaN, parentTerrainQuad.getHeightmapHeight(5, 49), 0.0f); } From 2e1dba77b71819296ed6f116d11a564f74ba37eb Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 13:58:17 +0200 Subject: [PATCH 42/59] Removed unused field `i` from QuadrantFinder class --- .../src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 382541a82a..8f8f2f633d 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -1836,7 +1836,6 @@ else if (((TerrainPatch) s).getQuadrant() == 4) public class QuadrantFinder { private int x; private int z; - private int i; private Spatial spat; private int col; private int row; From fce1632d2a180aa0e1293c54d9f6c0187d318785 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Wed, 30 Mar 2016 15:16:20 +0200 Subject: [PATCH 43/59] Removed most duplicate code between fixEdges and findNeighboursLod --- .../jme3/terrain/geomipmap/TerrainQuad.java | 101 ++++++------------ 1 file changed, 35 insertions(+), 66 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index b4a50f1136..3df45c2660 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -395,65 +395,39 @@ protected synchronized void findNeighboursLod(HashMap updated UpdatedTerrainPatch utp = updated.get(patch.getName()); if(utp != null && utp.lodChanged()) { - if (!patch.searchedForNeighboursAlready) { - // set the references to the neighbours - patch.rightNeighbour = patch.findPatch(DIR_RIGHT); - patch.bottomNeighbour = patch.findPatch(DIR_DOWN); - patch.leftNeighbour = patch.findPatch(DIR_LEFT); - patch.topNeighbour = patch.findPatch(DIR_TOP); - patch.searchedForNeighboursAlready = true; - } + setPatchNeighbourReferences(patch); + TerrainPatch right = patch.rightNeighbour; TerrainPatch down = patch.bottomNeighbour; TerrainPatch top = patch.topNeighbour; TerrainPatch left = patch.leftNeighbour; if (right != null) { - UpdatedTerrainPatch utpR = updated.get(right.getName()); - if (utpR == null) { - utpR = new UpdatedTerrainPatch(right); - updated.put(utpR.getName(), utpR); - utpR.setNewLod(right.lod); - } + UpdatedTerrainPatch utpR = getUpdatedTerrainPatch(updated, right); utpR.setLeftLod(utp.getNewLod()); utpR.setFixEdges(true); } if (down != null) { - UpdatedTerrainPatch utpD = updated.get(down.getName()); - if (utpD == null) { - utpD = new UpdatedTerrainPatch(down); - updated.put(utpD.getName(), utpD); - utpD.setNewLod(down.lod); - } + UpdatedTerrainPatch utpD = getUpdatedTerrainPatch(updated, down); utpD.setTopLod(utp.getNewLod()); utpD.setFixEdges(true); } if (top != null){ - UpdatedTerrainPatch utpT = updated.get(top.getName()); - if (utpT == null) { - utpT = new UpdatedTerrainPatch(top); - updated.put(utpT.getName(), utpT); - utpT.setNewLod(top.lod); - } + UpdatedTerrainPatch utpT = getUpdatedTerrainPatch(updated, top); utpT.setBottomLod(utp.getNewLod()); utpT.setFixEdges(true); } if (left != null){ - UpdatedTerrainPatch utpL = updated.get(left.getName()); - if (utpL == null) { - utpL = new UpdatedTerrainPatch(left); - updated.put(utpL.getName(), utpL); - utpL.setNewLod(left.lod); - } + UpdatedTerrainPatch utpL = getUpdatedTerrainPatch(updated, left); utpL.setRightLod(utp.getNewLod()); utpL.setFixEdges(true); } @@ -554,6 +513,16 @@ protected synchronized void fixEdges(HashMap updated } } + private UpdatedTerrainPatch getUpdatedTerrainPatch(HashMap updated, TerrainPatch right) { + UpdatedTerrainPatch utpR = updated.get(right.getName()); + if (utpR == null) { + utpR = new UpdatedTerrainPatch(right); + updated.put(utpR.getName(), utpR); + utpR.setNewLod(right.lod); + } + return utpR; + } + protected synchronized void reIndexPages(HashMap updated, boolean usesVariableLod) { if (children != null) { for (int i = children.size(); --i >= 0;) { From 3c130531bc99f31c4e5a54325775633035ba20ae Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Wed, 30 Mar 2016 21:07:45 +0200 Subject: [PATCH 44/59] created getHeight test, to test the private method findMatchingChild (only place this is called is in getHeight method). --- .../jme3/terrain/geomipmap/TerrainQuad.java | 71 ++++++------------- .../terrain/geomipmap/TerrainQuadTest.java | 42 ++++------- 2 files changed, 35 insertions(+), 78 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 8f8f2f633d..b4ada5a585 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -48,7 +48,6 @@ import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.debug.WireBox; -import com.jme3.scene.shape.Quad; import com.jme3.terrain.ProgressMonitor; import com.jme3.terrain.Terrain; import com.jme3.terrain.geomipmap.lodcalc.LodCalculator; @@ -862,8 +861,12 @@ public float getHeightmapHeight(Vector2f xz) { } /** - * This will just get the heightmap value at the supplied point, - * not an interpolated (actual) height value. + * getHeightmapHeight retrieves the heightmap value based on the quadrant of the supplied coordinates, + * not and interpolated (actual) height value. + * + * @param x int x-coordinate + * @param z int z-coordinate + * @return Float heightMapHeight */ protected float getHeightmapHeight(int x, int z) { QuadrantFinder qf = new QuadrantFinder(x, z); @@ -880,54 +883,13 @@ protected float getHeightmapHeight(int x, int z) { return Float.NaN; } -// protected void getMatch(int x, int z) { -// -// int quad = findQuadrant(x, z); -// int split = (size + 1) >> 1; -// if (children != null) { -// for (int i = children.size(); --i >= 0; ) { -// Spatial spat = children.get(i); -// int col = x; -// int row = z; -// boolean match = false; -// -// // get the childs quadrant -// int childQuadrant = 0; -// if (spat instanceof TerrainQuad) { -// childQuadrant = ((TerrainQuad) spat).getQuadrant(); -// } else if (spat instanceof TerrainPatch) { -// childQuadrant = ((TerrainPatch) spat).getQuadrant(); -// } -// -// if (childQuadrant == 1 && (quad & 1) != 0) { -// match = true; -// } else if (childQuadrant == 2 && (quad & 2) != 0) { -// row = z - split + 1; -// match = true; -// } else if (childQuadrant == 3 && (quad & 4) != 0) { -// col = x - split + 1; -// match = true; -// } else if (childQuadrant == 4 && (quad & 8) != 0) { -// col = x - split + 1; -// row = z - split + 1; -// match = true; -// } -// -// if (match) { -// if (spat instanceof TerrainQuad) { -// ((TerrainQuad) spat).getHeightmapHeight(col, row); -// } else if (spat instanceof TerrainPatch) { -// ((TerrainPatch) spat).getHeightmapHeight(col, row); -// } -// } -// -// } -// } -// heightmapHeight = Float.NaN; -// -// } - - + /** + * getMeshNormal retrieves the MeshNormal value based on the quadrant of the supplied coordinates. + * + * @param x int x-coordinate + * @param z int z-coordinate + * @return Vector3f meshNormal + */ protected Vector3f getMeshNormal(int x, int z) { QuadrantFinder qf = new QuadrantFinder(x, z); qf.invoke(); @@ -971,6 +933,13 @@ private class QuadrantChild { } } + /** + * findMatchingChild returns a new QuadrantChild object based on the quadrant of the supplied coordinates. + * + * @param x int x-coordinate + * @param z int z-coordinate + * @return QuadrantChild object + */ private QuadrantChild findMatchingChild(int x, int z) { QuadrantFinder qf = new QuadrantFinder(x, z); qf.invoke(); diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index b8f0869391..e3a059e0bd 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -59,35 +59,8 @@ public void init() { terrainQuad = new TerrainQuad("terrain_1", 3, 5, heightmap.getHeightMap()); - - - TerrainPatch tp0 = (TerrainPatch) terrainQuad.getChild(0); - System.out.println("tp 0 heightmap: " + tp0.getHeightMap().length); - for (int i = 0; i < 9; i++) { - System.out.println("tp 0 heightmap: " + tp0.getHeightMap()[i]); - } - TerrainPatch tp1 = (TerrainPatch) terrainQuad.getChild(1); - for (int i = 0; i < 9; i++) { - System.out.println("tp 1 heightmap: " + tp1.getHeightMap()[i]); - } - TerrainPatch tp2 = (TerrainPatch) terrainQuad.getChild(2); - for (int i = 0; i < 9; i++) { - System.out.println("tp 2 heightmap: " + tp2.getHeightMap()[i]); - } - TerrainPatch tp3 = (TerrainPatch) terrainQuad.getChild(3); - for (int i = 0; i < 9; i++) { - System.out.println("tp 3 heightmap: " + tp3.getHeightMap()[i]); - } - - testHeightmap = heightmap.getHeightMap(); - for (int i = 0; i < testHeightmap.length; i++) { - System.out.println("heightmap values: " + testHeightmap[i]); - } - -// parentTerrainQuad = new FakeTerrainQuad(); -// fakeCreateQuad(parentTerrainQuad, children); } private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) { @@ -322,8 +295,23 @@ public void testGetMeshNormal() { fakeCreateQuad(parentTerrainQuad, children); assertEquals(null, parentTerrainQuad.getMeshNormal(5, 49)); + } + @Test + public void getHeight() { + assertEquals(Float.NaN, terrainQuad.getHeight(10, 10, 10.0f, 10.0f), 0.0f); + assertEquals(2.9181213f, terrainQuad.getHeight(0, 0, 0.0f, 0.0f), 0.0f); + + children = new FakeTerrainQuad[3]; + for (int i = 0; i < 3; i++) { + children[i] = new FakeTerrainQuad(); + } + + parentTerrainQuad = new FakeTerrainQuad(); + parentTerrainQuad.size = 10; + fakeCreateQuad(parentTerrainQuad, children); + assertEquals(Float.NaN, parentTerrainQuad.getHeight(0, 0, 0.0f, 0.0f), 0.0f); } From 18747abed567dc83e746653ce14d87c76db5c74f Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Thu, 31 Mar 2016 11:16:46 +0200 Subject: [PATCH 45/59] fixed javadoc for tests --- .../java/jme3test/terrain/TerrainTest.java | 4 +- .../geomipmap/MultiTerrainLodControl.java | 47 +-- .../terrain/geomipmap/TerrainLodControl.java | 101 +++---- .../jme3/terrain/geomipmap/TerrainQuad.java | 8 +- .../terrain/geomipmap/TerrainQuadTest.java | 278 ++++++++++-------- 5 files changed, 226 insertions(+), 212 deletions(-) diff --git a/jme3-examples/src/main/java/jme3test/terrain/TerrainTest.java b/jme3-examples/src/main/java/jme3test/terrain/TerrainTest.java index 7eff18b8f9..a0f6572351 100644 --- a/jme3-examples/src/main/java/jme3test/terrain/TerrainTest.java +++ b/jme3-examples/src/main/java/jme3test/terrain/TerrainTest.java @@ -157,13 +157,14 @@ public void simpleInitApp() { */ terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); - control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier + control.setLodCalculator(new DistanceLodCalculator(65, 2.7f)); // patch size, and a multiplier terrain.addControl(control); terrain.setMaterial(matRock); terrain.setLocalTranslation(0, -100, 0); terrain.setLocalScale(2f, 0.5f, 2f); rootNode.attachChild(terrain); + DirectionalLight light = new DirectionalLight(); light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize()); rootNode.addLight(light); @@ -187,6 +188,7 @@ private void setupKeys() { inputManager.addMapping("triPlanar", new KeyTrigger(KeyInput.KEY_P)); inputManager.addListener(actionListener, "triPlanar"); } + private ActionListener actionListener = new ActionListener() { public void onAction(String name, boolean pressed, float tpf) { diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/MultiTerrainLodControl.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/MultiTerrainLodControl.java index 995bc8f132..8733716643 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/MultiTerrainLodControl.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/MultiTerrainLodControl.java @@ -35,20 +35,21 @@ import com.jme3.renderer.Camera; import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; import com.jme3.terrain.geomipmap.lodcalc.LodCalculator; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * An extension of the TerrainLodControl that handles - * multiple terrains at once. This is to be used if you + * multiple terrains at once. This is to be used if you * have your own tiling/paging terrain system, such as * TerrainGrid. - * + * * @author Brent Owens */ public class MultiTerrainLodControl extends TerrainLodControl { - + List terrains = new ArrayList(); private List addedTerrains = new ArrayList(); private List removedTerrains = new ArrayList(); @@ -64,7 +65,7 @@ public MultiTerrainLodControl(Camera camera) { this.cameras = cams; lodCalculator = new DistanceLodCalculator(65, 2.7f); } - + /** * Add a terrain that will have its LOD handled by this control. * It will be added next update run. You should only call this from @@ -73,7 +74,7 @@ public MultiTerrainLodControl(Camera camera) { public void addTerrain(TerrainQuad tq) { addedTerrains.add(tq); } - + /** * Add a terrain that will no longer have its LOD handled by this control. * It will be removed next update run. You should only call this from @@ -82,12 +83,12 @@ public void addTerrain(TerrainQuad tq) { public void removeTerrain(TerrainQuad tq) { removedTerrains.add(tq); } - + @Override protected UpdateLOD getLodThread(List locations, LodCalculator lodCalculator) { return new UpdateMultiLOD(locations, lodCalculator); } - + @Override protected void prepareTerrain() { if (!addedTerrains.isEmpty()) { @@ -97,57 +98,57 @@ protected void prepareTerrain() { } addedTerrains.clear(); } - + if (!removedTerrains.isEmpty()) { terrains.removeAll(removedTerrains); removedTerrains.clear(); } - + for (TerrainQuad terrain : terrains) terrain.cacheTerrainTransforms();// cache the terrain's world transforms so they can be accessed on the separate thread safely } - + /** * Overrides the parent UpdateLOD runnable to process * multiple terrains. */ protected class UpdateMultiLOD extends UpdateLOD { - - + + protected UpdateMultiLOD(List camLocations, LodCalculator lodCalculator) { super(camLocations, lodCalculator); } - + @Override public HashMap call() throws Exception { - + setLodCalcRunning(true); - - HashMap updated = new HashMap(); - + + HashMap updated = new HashMap(); + for (TerrainQuad terrainQuad : terrains) { // go through each patch and calculate its LOD based on camera distance - terrainQuad.calculateLod(camLocations, updated, lodCalculator); // 'updated' gets populated here + terrainQuad.hasLodChanged(camLocations, updated, lodCalculator); // 'updated' gets populated here } - + for (TerrainQuad terrainQuad : terrains) { // then calculate the neighbour LOD values for seaming terrainQuad.findNeighboursLod(updated); } - + for (TerrainQuad terrainQuad : terrains) { // check neighbour quads that need their edges seamed terrainQuad.fixEdges(updated); } - + for (TerrainQuad terrainQuad : terrains) { // perform the edge seaming, if it requires it terrainQuad.reIndexPages(updated, lodCalculator.usesVariableLod()); } - + //setUpdateQuadLODs(updated); // set back to main ogl thread setLodCalcRunning(false); - + return updated; } } diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java index 8ad2425ada..e17b37dcfa 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java @@ -46,16 +46,12 @@ import com.jme3.terrain.Terrain; import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; import com.jme3.terrain.geomipmap.lodcalc.LodCalculator; + import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.ThreadFactory; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -68,16 +64,16 @@ * NOTE: right now it just uses the first camera passed in, * in the future it will use all of them to determine what * LOD to set. - * + *

* This control serializes, but it does not save the Camera reference. * This camera reference has to be manually added in when you load the * terrain to the scene! - * + *

* When the control or the terrain are removed from the scene, you should call * TerrainLodControl.detachAndCleanUpControl() to remove any threads it created * to handle the LOD processing. If you supply your own executor service, then * you have to handle its thread termination yourself. - * + * * @author Brent Owens */ public class TerrainLodControl extends AbstractControl { @@ -88,17 +84,17 @@ public class TerrainLodControl extends AbstractControl { protected LodCalculator lodCalculator; private boolean hasResetLod = false; // used when enabled is set to false - private HashMap updatedPatches; + private HashMap updatedPatches; private final Object updatePatchesLock = new Object(); - + protected List lastCameraLocations; // used for LOD calc private AtomicBoolean lodCalcRunning = new AtomicBoolean(false); private int lodOffCount = 0; - + protected ExecutorService executor; protected Future> indexer; private boolean forceUpdate = true; - + public TerrainLodControl() { } @@ -109,9 +105,10 @@ public TerrainLodControl(Terrain terrain, Camera camera) { this.cameras = cams; lodCalculator = new DistanceLodCalculator(65, 2.7f); // a default calculator } - + /** * Only uses the first camera right now. + * * @param terrain to act upon (must be a Spatial) * @param cameras one or more cameras to reference for LOD calc */ @@ -132,7 +129,7 @@ protected void controlRender(RenderManager rm, ViewPort vp) { public void setExecutor(ExecutorService executor) { this.executor = executor; } - + protected ExecutorService createExecutorService() { return Executors.newSingleThreadExecutor(new ThreadFactory() { public Thread newThread(Runnable r) { @@ -143,14 +140,14 @@ public Thread newThread(Runnable r) { } }); } - + @Override protected void controlUpdate(float tpf) { //list of cameras for when terrain supports multiple cameras (ie split screen) if (lodCalculator == null) return; - + if (!enabled) { if (!hasResetLod) { // this will get run once @@ -158,7 +155,7 @@ protected void controlUpdate(float tpf) { lodCalculator.turnOffLod(); } } - + if (cameras != null) { cameraLocations.clear(); for (Camera c : cameras) // populate them @@ -168,7 +165,7 @@ protected void controlUpdate(float tpf) { updateLOD(cameraLocations, lodCalculator); } } - + /** * Call this when you remove the terrain or this control from the scene. * It will clear up any threads it had. @@ -181,10 +178,10 @@ public void detachAndCleanUpControl() { // do all of the LOD calculations protected void updateLOD(List locations, LodCalculator lodCalculator) { - if(getSpatial() == null){ + if (getSpatial() == null) { return; } - + // update any existing ones that need updating updateQuadLODs(); @@ -194,17 +191,16 @@ protected void updateLOD(List locations, LodCalculator lodCalculator) return; else lodOffCount++; - } else + } else lodOffCount = 0; - + if (lastCameraLocations != null) { if (!forceUpdate && lastCameraLocationsTheSame(locations) && !lodCalculator.isLodOff()) return; // don't update if in same spot else lastCameraLocations = cloneVectorList(locations); forceUpdate = false; - } - else { + } else { lastCameraLocations = cloneVectorList(locations); return; } @@ -216,9 +212,9 @@ protected void updateLOD(List locations, LodCalculator lodCalculator) if (executor == null) executor = createExecutorService(); - + prepareTerrain(); - + UpdateLOD updateLodThread = getLodThread(locations, lodCalculator); indexer = executor.submit(updateLodThread); } @@ -230,12 +226,12 @@ protected void updateLOD(List locations, LodCalculator lodCalculator) public void forceUpdate() { this.forceUpdate = true; } - + protected void prepareTerrain() { - TerrainQuad terrain = (TerrainQuad)getSpatial(); + TerrainQuad terrain = (TerrainQuad) getSpatial(); terrain.cacheTerrainTransforms();// cache the terrain's world transforms so they can be accessed on the separate thread safely } - + protected UpdateLOD getLodThread(List locations, LodCalculator lodCalculator) { return new UpdateLOD(locations, lodCalculator); } @@ -247,7 +243,7 @@ private void updateQuadLODs() { if (indexer != null) { if (indexer.isDone()) { try { - + HashMap updated = indexer.get(); if (updated != null) { // do the actual geometry update here @@ -255,7 +251,7 @@ private void updateQuadLODs() { utp.updateAll(); } } - + } catch (InterruptedException ex) { Logger.getLogger(TerrainLodControl.class.getName()).log(Level.SEVERE, null, ex); } catch (ExecutionException ex) { @@ -266,12 +262,12 @@ private void updateQuadLODs() { } } } - + private boolean lastCameraLocationsTheSame(List locations) { boolean theSame = true; for (Vector3f l : locations) { for (Vector3f v : lastCameraLocations) { - if (!v.equals(l) ) { + if (!v.equals(l)) { theSame = false; return false; } @@ -279,7 +275,7 @@ private boolean lastCameraLocationsTheSame(List locations) { } return theSame; } - + protected synchronized boolean isLodCalcRunning() { return lodCalcRunning.get(); } @@ -290,17 +286,12 @@ protected synchronized void setLodCalcRunning(boolean running) { private List cloneVectorList(List locations) { List cloned = new ArrayList(); - for(Vector3f l : locations) + for (Vector3f l : locations) cloned.add(l.clone()); return cloned; } - - - - - - + public Control cloneForSpatial(Spatial spatial) { if (spatial instanceof Terrain) { List cameraClone = new ArrayList(); @@ -321,7 +312,7 @@ public void setCamera(Camera camera) { cams.add(camera); setCameras(cams); } - + public void setCameras(List cameras) { this.cameras = cameras; cameraLocations.clear(); @@ -349,7 +340,7 @@ public LodCalculator getLodCalculator() { public void setLodCalculator(LodCalculator lodCalculator) { this.lodCalculator = lodCalculator; } - + @Override public void setEnabled(boolean enabled) { this.enabled = enabled; @@ -361,12 +352,12 @@ public void setEnabled(boolean enabled) { lodCalculator.turnOnLod(); } } - - + + /** * Calculates the LOD of all child terrain patches. */ - protected class UpdateLOD implements Callable> { + protected class UpdateLOD implements Callable> { protected List camLocations; protected LodCalculator lodCalculator; @@ -382,19 +373,19 @@ public HashMap call() throws Exception { //} setLodCalcRunning(true); - TerrainQuad terrainQuad = (TerrainQuad)getSpatial(); - + TerrainQuad terrainQuad = (TerrainQuad) getSpatial(); + // go through each patch and calculate its LOD based on camera distance - HashMap updated = new HashMap(); - boolean lodChanged = terrainQuad.calculateLod(camLocations, updated, lodCalculator); // 'updated' gets populated here + HashMap updated = new HashMap(); + boolean lodChanged = terrainQuad.hasLodChanged(camLocations, updated, lodCalculator); // 'updated' gets populated here if (!lodChanged) { // not worth updating anything else since no one's LOD changed setLodCalcRunning(false); return null; } - - + + // then calculate its neighbour LOD values for seaming in the shader terrainQuad.findNeighboursLod(updated); @@ -405,7 +396,7 @@ public HashMap call() throws Exception { //setUpdateQuadLODs(updated); // set back to main ogl thread setLodCalcRunning(false); - + return updated; } } @@ -414,7 +405,7 @@ public HashMap call() throws Exception { public void write(JmeExporter ex) throws IOException { super.write(ex); OutputCapsule oc = ex.getCapsule(this); - oc.write((Node)terrain, "terrain", null); + oc.write((Node) terrain, "terrain", null); oc.write(lodCalculator, "lodCalculator", null); } diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index b4ada5a585..6aa2f1106e 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -368,7 +368,7 @@ public int getNumMajorSubdivisions() { } - protected boolean calculateLod(List location, HashMap updates, LodCalculator lodCalculator) { + protected boolean hasLodChanged(List location, HashMap updates, LodCalculator lodCalculator) { boolean lodChanged = false; @@ -377,7 +377,7 @@ protected boolean calculateLod(List location, HashMap= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { - boolean b = ((TerrainQuad) child).calculateLod(location, updates, lodCalculator); + boolean b = ((TerrainQuad) child).hasLodChanged(location, updates, lodCalculator); if (b) lodChanged = true; } else if (child instanceof TerrainPatch) { @@ -814,8 +814,8 @@ private void attachBoundingBox(BoundingBox bb, Node parent) { * Does this by looking at the affectedAreaBBox bounding box. If the bbox * exists already, then it will grow the box to fit the new changedPoint. * If the affectedAreaBBox is null, then it will create one of unit size. - * - * @param needToRecalculateNormals if null, will cause needToRecalculateNormals() to return false + *

+ * needToRecalculateNormals if null, will cause needToRecalculateNormals() to return false */ protected void setNormalRecalcNeeded(Vector2f changedPoint) { if (changedPoint == null) { // set needToRecalculateNormals() to false diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index e3a059e0bd..4e172fbaae 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -16,7 +16,7 @@ import java.util.HashMap; import java.util.List; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; public class TerrainQuadTest { @@ -102,30 +102,30 @@ private Spatial createNestedQuad(int nestLevel) { return parent; } -// @Test -// public void testFakeTerrainQuad() { -// FakeTerrainQuad fake = new FakeTerrainQuad(); -// assertEquals(fake, fake.getQuad(0)); -// } -// -// @Test -// public void testNestStructure() { -// Spatial leaf = createNestedQuad(0); -// assertTrue(leaf instanceof TerrainPatch); -// -// FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); -// assertEquals(root.getChildren().size(), 4); -// for (int i = 0; i < 4; i++) { -// assertTrue(root.getChild(i) instanceof TerrainPatch); // Ensure children of root are leafs -// } -// -// root = (FakeTerrainQuad) createNestedQuad(2); -// assertEquals(root.getChildren().size(), 4); -// for (int i = 0; i < 4; i++) { -// assertTrue(root.getChild(i) instanceof TerrainQuad); // Ensure children of root are not leafs -// } -// } -// + @Test + public void testFakeTerrainQuad() { + FakeTerrainQuad fake = new FakeTerrainQuad(); + assertEquals(fake, fake.getQuad(0)); + } + + @Test + public void testNestStructure() { + Spatial leaf = createNestedQuad(0); + assertTrue(leaf instanceof TerrainPatch); + + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); + assertEquals(root.getChildren().size(), 4); + for (int i = 0; i < 4; i++) { + assertTrue(root.getChild(i) instanceof TerrainPatch); // Ensure children of root are leafs + } + + root = (FakeTerrainQuad) createNestedQuad(2); + assertEquals(root.getChildren().size(), 4); + for (int i = 0; i < 4; i++) { + assertTrue(root.getChild(i) instanceof TerrainQuad); // Ensure children of root are not leafs + } + } + // @Test // public void testGetQuad() { // assertEquals(parentTerrainQuad.getQuad(0), parentTerrainQuad); @@ -135,112 +135,120 @@ private Spatial createNestedQuad(int nestLevel) { // assertEquals(parentTerrainQuad.getQuad(4), children[3]); // assertEquals(parentTerrainQuad.getQuad(5), null); // } -// -// -// /** -// * tests the calculateLod method. -// * Came to the conclusion that the method does belong to TerrainQuad, but should be renamed -// * as it does not calculate anything. Is only retrieves values from users of the LodCalculator interface. -// * The actual lodCalculator is defined in the calculateLod method of these childs. -// */ -// @Test -// public void testCalculateLod() { -// FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); -// assertFalse(root.calculateLod(location, updates, lodCalculator)); -// assertTrue(root.calculateLod(location, updates, fakeLodCalculator)); -// -// FakeTerrainQuad leaf = (FakeTerrainQuad) createNestedQuad(1); -// leaf.attachChild(children[1]); -// assertTrue(leaf.calculateLod(location, updates, fakeLodCalculator)); -// } -// @Test -// public void testCreateQuadPatch1() { -// String patch1 = "terrain_1Patch1"; -// -// -// boundingBox.setCenter(1.0f, 54.88082f, 1.0f); -// terrainQuad.setPatchChildren(testHeightmap); -// -// -// System.out.println(terrainQuad.getChildren()); -// -// assertTrue(terrainQuad.getChild(patch1) instanceof TerrainPatch); -// TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch1); -// -// assertEquals(patch1, p1.getName()); -// assertEquals(v2f.set(-1.0f, -1.0f), p1.getOffset()); -// assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); -// assertEquals(v3f.add(-2.0f, 0.0f, -2.0f), p1.getLocalTranslation()); -// assertEquals(9, p1.getHeightMap().length); -// assertEquals(5, p1.getTotalSize()); -// assertEquals(1, p1.getQuadrant()); -// assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); -// } -// -// @Test -// public void testCreateQuadPatch2() { -// String patch2 = "terrain_1Patch2"; -// -// boundingBox.setCenter(1.0f, 92.78813f, 1.0f); -// -// terrainQuad.setPatchChildren(testHeightmap); -// -// assertTrue(terrainQuad.getChild(patch2) instanceof TerrainPatch); -// TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch2); -// -// assertEquals(patch2, p1.getName()); -// assertEquals(v2f.set(-1.0f, 1.0f), p1.getOffset()); -// assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); -// assertEquals(v3f.add(-2.0f, 0.0f, 0.0f), p1.getLocalTranslation()); -// assertEquals(9, p1.getHeightMap().length); -// assertEquals(5, p1.getTotalSize()); -// assertEquals(2, p1.getQuadrant()); -// assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); -// } -// -// @Test -// public void testCreateQuadPatch3() { -// String patch3 = "terrain_1Patch3"; -// -// boundingBox.setCenter(1.0f, 64.86637f, 1.0f); -// -// terrainQuad.setPatchChildren(testHeightmap); -// -// assertTrue(terrainQuad.getChild(patch3) instanceof TerrainPatch); -// TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch3); -// -// assertEquals(patch3, p1.getName()); -// assertEquals(v2f.set(1.0f, -1.0f), p1.getOffset()); -// assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); -// assertEquals(v3f.add(0.0f, 0.0f, -2.0f), p1.getLocalTranslation()); -// assertEquals(9, p1.getHeightMap().length); -// assertEquals(5, p1.getTotalSize()); -// assertEquals(3, p1.getQuadrant()); -// assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); -// } -// -// @Test -// public void testCreateQuadPatch4() { -// String patch4 = "terrain_1Patch4"; -// -// boundingBox.setCenter(1.0f, 180.92175f, 1.0f); -// -// terrainQuad.setPatchChildren(testHeightmap); -// -// assertTrue(terrainQuad.getChild(patch4) instanceof TerrainPatch); -// TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch4); -// -// assertEquals(patch4, p1.getName()); -// assertEquals(v2f.set(1.0f, 1.0f), p1.getOffset()); -// assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); -// assertEquals(v3f.add(0.0f, 0.0f, 0.0f), p1.getLocalTranslation()); -// assertEquals(9, p1.getHeightMap().length); -// assertEquals(5, p1.getTotalSize()); -// assertEquals(4, p1.getQuadrant()); -// assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); -// } + /** + * Tests the calculateLod method, which name has been refactored to hasLodChanged. + * We came to the conclusion that the method does belong to TerrainQuad, but should be renamed + * as it does not calculate anything. Is only retrieves values from users of the LodCalculator interface. + * The actual lodCalculator is defined in the calculateLod method of these childs. + */ + @Test + public void testCalculateLod() { + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); + assertFalse(root.hasLodChanged(location, updates, lodCalculator)); + assertTrue(root.hasLodChanged(location, updates, fakeLodCalculator)); + + FakeTerrainQuad leaf = (FakeTerrainQuad) createNestedQuad(1); + leaf.attachChild(children[1]); + assertTrue(leaf.hasLodChanged(location, updates, fakeLodCalculator)); + } + + + /** + * Tests the refactored createQuadPatch method, which name is refactored to setPatchChildren. + * setPatchChildren makes use of two new methods createHeightBlock and createQuadPatch (part of TerrainPatch). + * This is the first of 4 tests, as setPatchChildren couples 4 TerrainPatches to + * a TerrainQuad. Each tests makes sure that the correct TerrainPatch child has been coupled. + */ + @Test + public void testSetPatchChildren1() { + String patch1 = "terrain_1Patch1"; + + boundingBox.setCenter(1.0f, 54.88082f, 1.0f); + terrainQuad.setPatchChildren(testHeightmap); + + assertTrue(terrainQuad.getChild(patch1) instanceof TerrainPatch); + TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch1); + + assertEquals(patch1, p1.getName()); + assertEquals(v2f.set(-1.0f, -1.0f), p1.getOffset()); + assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); + assertEquals(v3f.add(-2.0f, 0.0f, -2.0f), p1.getLocalTranslation()); + assertEquals(9, p1.getHeightMap().length); + assertEquals(5, p1.getTotalSize()); + assertEquals(1, p1.getQuadrant()); + assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); + } + + @Test + public void testSetPatchChildren2() { + String patch2 = "terrain_1Patch2"; + + boundingBox.setCenter(1.0f, 92.78813f, 1.0f); + + terrainQuad.setPatchChildren(testHeightmap); + + assertTrue(terrainQuad.getChild(patch2) instanceof TerrainPatch); + TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch2); + + assertEquals(patch2, p1.getName()); + assertEquals(v2f.set(-1.0f, 1.0f), p1.getOffset()); + assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); + assertEquals(v3f.add(-2.0f, 0.0f, 0.0f), p1.getLocalTranslation()); + assertEquals(9, p1.getHeightMap().length); + assertEquals(5, p1.getTotalSize()); + assertEquals(2, p1.getQuadrant()); + assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); + } + + @Test + public void testSetPatchChildren3() { + String patch3 = "terrain_1Patch3"; + + boundingBox.setCenter(1.0f, 64.86637f, 1.0f); + + terrainQuad.setPatchChildren(testHeightmap); + + assertTrue(terrainQuad.getChild(patch3) instanceof TerrainPatch); + TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch3); + + assertEquals(patch3, p1.getName()); + assertEquals(v2f.set(1.0f, -1.0f), p1.getOffset()); + assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); + assertEquals(v3f.add(0.0f, 0.0f, -2.0f), p1.getLocalTranslation()); + assertEquals(9, p1.getHeightMap().length); + assertEquals(5, p1.getTotalSize()); + assertEquals(3, p1.getQuadrant()); + assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); + } + + @Test + public void testSetPatchChildren4() { + String patch4 = "terrain_1Patch4"; + + boundingBox.setCenter(1.0f, 180.92175f, 1.0f); + + terrainQuad.setPatchChildren(testHeightmap); + + assertTrue(terrainQuad.getChild(patch4) instanceof TerrainPatch); + TerrainPatch p1 = (TerrainPatch) terrainQuad.getChild(patch4); + + assertEquals(patch4, p1.getName()); + assertEquals(v2f.set(1.0f, 1.0f), p1.getOffset()); + assertEquals(1.0f, p1.getOffsetAmount(), 0.0f); + assertEquals(v3f.add(0.0f, 0.0f, 0.0f), p1.getLocalTranslation()); + assertEquals(9, p1.getHeightMap().length); + assertEquals(5, p1.getTotalSize()); + assertEquals(4, p1.getQuadrant()); + assertEquals(boundingBox.getCenter(), p1.getModelBound().getCenter()); + } + + /** + * Tests the method getHeightmapHeight(int x, int z). + * An extra internal class QuadrantFinder has been created to find the + * corresponding quadrant for the given coordinates. + */ @Test public void testGetHeightmapHeight() { assertEquals(0.0f, terrainQuad.getHeightmapHeight(6, 6), 0.0f); @@ -269,6 +277,11 @@ public void testGetHeightmapHeight() { } + /** + * Tests the method getMeshNormal(int x, int z). + * An extra internal class QuadrantFinder has been created to find the + * corresponding quadrant for the given coordinates. + */ @Test public void testGetMeshNormal() { Vector3f v1 = new Vector3f(-0.7327255f, 0.043074645f, -0.67915976f); @@ -297,6 +310,13 @@ public void testGetMeshNormal() { assertEquals(null, parentTerrainQuad.getMeshNormal(5, 49)); } + /** + * Tests the method getHeight(int x, int z, float xm, float zm). + * This method is being tested to make sure the private method + * findMatchingChild(int x, int z) after its refactoring in which + * an extra internal class QuadrantFinder has been created to find the + * corresponding quadrant for the given coordinates. + */ @Test public void getHeight() { assertEquals(Float.NaN, terrainQuad.getHeight(10, 10, 10.0f, 10.0f), 0.0f); From 18147999017f684ad14aa240be140acaff7c1944 Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Thu, 31 Mar 2016 11:52:37 +0200 Subject: [PATCH 46/59] Reverted refactorings merge --- .../gen/com/jme3/android/BuildConfig.java | 8 - .../main/gen/com/jme3/android/Manifest.java | 7 - .../src/main/gen/com/jme3/android/R.java | 7 - .../gen/com/jme3/androiddemo/BuildConfig.java | 8 - .../gen/com/jme3/androiddemo/Manifest.java | 7 - .../android/gen/com/jme3/androiddemo/R.java | 7 - .../terrain/geomipmap/TerrainQuadTest.java | 106 +--- jmonkeyengine.properties | 4 - jmonkeyengine.xml | 543 ------------------ 9 files changed, 14 insertions(+), 683 deletions(-) delete mode 100644 jme3-android-examples/src/main/gen/com/jme3/android/BuildConfig.java delete mode 100644 jme3-android-examples/src/main/gen/com/jme3/android/Manifest.java delete mode 100644 jme3-android-examples/src/main/gen/com/jme3/android/R.java delete mode 100644 jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/BuildConfig.java delete mode 100644 jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/Manifest.java delete mode 100644 jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/R.java delete mode 100644 jmonkeyengine.properties delete mode 100644 jmonkeyengine.xml diff --git a/jme3-android-examples/src/main/gen/com/jme3/android/BuildConfig.java b/jme3-android-examples/src/main/gen/com/jme3/android/BuildConfig.java deleted file mode 100644 index b3c5e7a8c5..0000000000 --- a/jme3-android-examples/src/main/gen/com/jme3/android/BuildConfig.java +++ /dev/null @@ -1,8 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package com.jme3.android; - -/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ -public final class BuildConfig { - public final static boolean DEBUG = Boolean.parseBoolean(null); -} \ No newline at end of file diff --git a/jme3-android-examples/src/main/gen/com/jme3/android/Manifest.java b/jme3-android-examples/src/main/gen/com/jme3/android/Manifest.java deleted file mode 100644 index c6b0496951..0000000000 --- a/jme3-android-examples/src/main/gen/com/jme3/android/Manifest.java +++ /dev/null @@ -1,7 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package com.jme3.android; - -/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ -public final class Manifest { -} \ No newline at end of file diff --git a/jme3-android-examples/src/main/gen/com/jme3/android/R.java b/jme3-android-examples/src/main/gen/com/jme3/android/R.java deleted file mode 100644 index 5e250b921e..0000000000 --- a/jme3-android-examples/src/main/gen/com/jme3/android/R.java +++ /dev/null @@ -1,7 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package com.jme3.android; - -/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ -public final class R { -} \ No newline at end of file diff --git a/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/BuildConfig.java b/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/BuildConfig.java deleted file mode 100644 index 4ec9fe873d..0000000000 --- a/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/BuildConfig.java +++ /dev/null @@ -1,8 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package com.jme3.androiddemo; - -/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ -public final class BuildConfig { - public final static boolean DEBUG = Boolean.parseBoolean(null); -} \ No newline at end of file diff --git a/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/Manifest.java b/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/Manifest.java deleted file mode 100644 index 8f5cc81439..0000000000 --- a/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/Manifest.java +++ /dev/null @@ -1,7 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package com.jme3.androiddemo; - -/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ -public final class Manifest { -} \ No newline at end of file diff --git a/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/R.java b/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/R.java deleted file mode 100644 index b5a0338c32..0000000000 --- a/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/R.java +++ /dev/null @@ -1,7 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package com.jme3.androiddemo; - -/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ -public final class R { -} \ No newline at end of file diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index cf4a3e089e..4e172fbaae 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -1,6 +1,5 @@ package com.jme3.terrain.geomipmap; -import static org.junit.Assert.*; import com.jme3.asset.AssetManager; import com.jme3.bounding.BoundingBox; import com.jme3.math.Vector2f; @@ -40,12 +39,10 @@ public class TerrainQuadTest { public void init() { for (int i = 0; i < 4; i++) { children[i] = new FakeTerrainQuad(); + // children[i] = new TerrainQuad(); tpChildren[i] = new TerrainPatch(); } - parentTerrainQuad = new FakeTerrainQuad(); - fakeCreateQuad(parentTerrainQuad, children); - // HEIGHTMAP image (for the terrain heightmap) //Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); // CREATE HEIGHTMAP @@ -63,12 +60,14 @@ public void init() { terrainQuad = new TerrainQuad("terrain_1", 3, 5, heightmap.getHeightMap()); testHeightmap = heightmap.getHeightMap(); + } private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) { for (int i = 0; i < children.length; i++) { children[i].quadrant = i + 1; // Quadrant starts counting from 1 parent.attachChild(children[i]); + //parent.getQuad(i).attachChild((tpChildren[i])); } } @@ -127,95 +126,16 @@ public void testNestStructure() { } } - @Test - public void testGetQuad() { - assertEquals(parentTerrainQuad.getQuad(0), parentTerrainQuad); - assertEquals(parentTerrainQuad.getQuad(1), children[0]); - assertEquals(parentTerrainQuad.getQuad(2), children[1]); - assertEquals(parentTerrainQuad.getQuad(3), children[2]); - assertEquals(parentTerrainQuad.getQuad(4), children[3]); - assertEquals(parentTerrainQuad.getQuad(5), null); - } - - @Test - public void testFindRightQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad topRight = (FakeTerrainQuad)root.getQuad(3); - - assertEquals(root.findRightQuad(), null); - assertEquals(topLeftChild.findRightQuad(), topRight); // Confirm position of two parent quads - - // Check quad children of parent - assertEquals(topLeftChild.getQuad(1).findRightQuad(), topLeftChild.getQuad(3)); - assertEquals(topLeftChild.getQuad(2).findRightQuad(), topLeftChild.getQuad(4)); - assertEquals(topLeftChild.getQuad(3).findRightQuad(), topRight.getQuad(1)); - assertEquals(topLeftChild.getQuad(4).findRightQuad(), topRight.getQuad(2)); - - // Check non-existing neighbour quads - assertEquals(topRight.getQuad(3).findRightQuad(), null); - assertEquals(topRight.getQuad(4).findRightQuad(), null); - } - - @Test - public void testFindDownQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad downLeftChild = (FakeTerrainQuad)root.getQuad(2); - - assertEquals(root.findDownQuad(), null); - assertEquals(topLeftChild.findDownQuad(), downLeftChild); // Confirm position of two parent quads - - // Check quad children of parent - assertEquals(topLeftChild.getQuad(1).findDownQuad(), topLeftChild.getQuad(2)); - assertEquals(topLeftChild.getQuad(2).findDownQuad(), downLeftChild.getQuad(1)); - assertEquals(topLeftChild.getQuad(3).findDownQuad(), topLeftChild.getQuad(4)); - assertEquals(topLeftChild.getQuad(4).findDownQuad(), downLeftChild.getQuad(3)); - - // Check non-existing neighbour quads - assertEquals(downLeftChild.getQuad(2).findDownQuad(), null); - assertEquals(downLeftChild.getQuad(4).findDownQuad(), null); - } - - @Test - public void testFindLeftQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); - - assertEquals(root.findLeftQuad(), null); - assertEquals(topRightChild.findLeftQuad(), topLeftChild); // Confirm position of two parent quads - - // Check quad children of parent - assertEquals(topRightChild.getQuad(1).findLeftQuad(), topLeftChild.getQuad(3)); - assertEquals(topRightChild.getQuad(2).findLeftQuad(), topLeftChild.getQuad(4)); - assertEquals(topRightChild.getQuad(3).findLeftQuad(), topRightChild.getQuad(1)); - assertEquals(topRightChild.getQuad(4).findLeftQuad(), topRightChild.getQuad(2)); - - // Check non-existing neighbour quads - assertEquals(topLeftChild.getQuad(1).findLeftQuad(), null); - assertEquals(topLeftChild.getQuad(2).findLeftQuad(), null); - } +// @Test +// public void testGetQuad() { +// assertEquals(parentTerrainQuad.getQuad(0), parentTerrainQuad); +// assertEquals(parentTerrainQuad.getQuad(1), children[0]); +// assertEquals(parentTerrainQuad.getQuad(2), children[1]); +// assertEquals(parentTerrainQuad.getQuad(3), children[2]); +// assertEquals(parentTerrainQuad.getQuad(4), children[3]); +// assertEquals(parentTerrainQuad.getQuad(5), null); +// } - @Test - public void testFindTopQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(3); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad downLeftChild = (FakeTerrainQuad)root.getQuad(2); - - assertEquals(root.findTopQuad(), null); - assertEquals(downLeftChild.findTopQuad(), topLeftChild); // Confirm position of two parent quads - - // Check quad children of parent - assertEquals(downLeftChild.getQuad(1).findTopQuad(), topLeftChild.getQuad(2)); - assertEquals(downLeftChild.getQuad(2).findTopQuad(), downLeftChild.getQuad(1)); - assertEquals(downLeftChild.getQuad(3).findTopQuad(), topLeftChild.getQuad(4)); - assertEquals(downLeftChild.getQuad(4).findTopQuad(), downLeftChild.getQuad(3)); - - // Check non-existing neighbour quads - assertEquals(topLeftChild.getQuad(1).findTopQuad(), null); - assertEquals(topLeftChild.getQuad(3).findTopQuad(), null); - } /** * Tests the calculateLod method, which name has been refactored to hasLodChanged. @@ -413,4 +333,6 @@ public void getHeight() { assertEquals(Float.NaN, parentTerrainQuad.getHeight(0, 0, 0.0f, 0.0f), 0.0f); } + + } diff --git a/jmonkeyengine.properties b/jmonkeyengine.properties deleted file mode 100644 index e363a6d83c..0000000000 --- a/jmonkeyengine.properties +++ /dev/null @@ -1,4 +0,0 @@ -path.variable.kotlin_bundled=C\:\\Program Files (x86)\\JetBrains\\IntelliJ IDEA 145.256.33\\plugins\\Kotlin\\kotlinc -path.variable.maven_repository=C\:\\Users\\Alexander\\.m2\\repository -jdk.home.1.8=C\:/Program Files/Java/jdk1.8.0_65 -javac2.instrumentation.includeJavaRuntime=false \ No newline at end of file diff --git a/jmonkeyengine.xml b/jmonkeyengine.xml deleted file mode 100644 index 23fb02982e..0000000000 --- a/jmonkeyengine.xml +++ /dev/null @@ -1,543 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From e4415c3912d7d1502fa8e93bd0feae1f72b9059a Mon Sep 17 00:00:00 2001 From: Alexander Grooff Date: Thu, 31 Mar 2016 12:20:19 +0200 Subject: [PATCH 47/59] Fixed auto-merge issues related to test_calculateLod --- .../jme3/terrain/geomipmap/TerrainQuad.java | 761 ++++++++---------- 1 file changed, 355 insertions(+), 406 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index b4a50f1136..2eb6be86d6 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -55,6 +55,7 @@ import com.jme3.terrain.geomipmap.picking.TerrainPickData; import com.jme3.terrain.geomipmap.picking.TerrainPicker; import com.jme3.util.TangentBinormalGenerator; + import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -103,9 +104,14 @@ * +---------> +z * (world coordinates) * + * * @author Brent Owens */ public class TerrainQuad extends Node implements Terrain { + + private Vector3f meshNormal; + private float heightmapHeight; + protected Vector2f offset; protected int totalSize; // the size of this entire terrain tree (on one side) @@ -144,33 +150,33 @@ public TerrainQuad() { * A TerrainQuad of totalSize 513x513 will be 513 units wide and 513 units long. * PatchSize is just used to subdivide the terrain into tiles that can be culled. *

- * @param name the name of the scene element. This is required for - * identification and comparison purposes. - * @param patchSize size of the individual patches (geometry). Power of 2 plus 1, - * must be smaller than totalSize. (eg. 33, 65...) - * @param totalSize the size of this entire terrain (on one side). Power of 2 plus 1 - * (eg. 513, 1025, 2049...) + * + * @param name the name of the scene element. This is required for + * identification and comparison purposes. + * @param patchSize size of the individual patches (geometry). Power of 2 plus 1, + * must be smaller than totalSize. (eg. 33, 65...) + * @param totalSize the size of this entire terrain (on one side). Power of 2 plus 1 + * (eg. 513, 1025, 2049...) * @param heightMap The height map to generate the terrain from (a flat - * height map will be generated if this is null). The size of one side of the heightmap - * must match the totalSize. So a 513x513 heightmap is needed for a terrain with totalSize of 513. + * height map will be generated if this is null). The size of one side of the heightmap + * must match the totalSize. So a 513x513 heightmap is needed for a terrain with totalSize of 513. */ public TerrainQuad(String name, int patchSize, int totalSize, float[] heightMap) { this(name, patchSize, totalSize, Vector3f.UNIT_XYZ, heightMap); - - affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size*2, Float.MAX_VALUE, size*2); + + affectedAreaBBox = new BoundingBox(new Vector3f(0, 0, 0), size * 2, Float.MAX_VALUE, size * 2); fixNormalEdges(affectedAreaBBox); addControl(new NormalRecalcControl(this)); } - + /** - * - * @param name the name of the scene element. This is required for - * identification and comparison purposes. + * @param name the name of the scene element. This is required for + * identification and comparison purposes. * @param patchSize size of the individual patches * @param quadSize * @param totalSize the size of this entire terrain tree (on one side) * @param heightMap The height map to generate the terrain from (a flat - * height map will be generated if this is null) + * height map will be generated if this is null) */ @Deprecated public TerrainQuad(String name, int patchSize, int quadSize, int totalSize, float[] heightMap) { @@ -178,14 +184,13 @@ public TerrainQuad(String name, int patchSize, int quadSize, int totalSize, floa } /** - * - * @param name the name of the scene element. This is required for - * identification and comparison purposes. + * @param name the name of the scene element. This is required for + * identification and comparison purposes. * @param patchSize size of the individual patches - * @param size size of this quad, can be between totalSize and patchSize + * @param size size of this quad, can be between totalSize and patchSize * @param scale * @param heightMap The height map to generate the terrain from (a flat - * height map will be generated if this is null) + * height map will be generated if this is null) */ @Deprecated public TerrainQuad(String name, int patchSize, int size, Vector3f scale, float[] heightMap) { @@ -194,17 +199,16 @@ public TerrainQuad(String name, int patchSize, int size, Vector3f scale, float[] //fixNormalEdges(affectedAreaBBox); //addControl(new NormalRecalcControl(this)); } - + /** - * - * @param name the name of the scene element. This is required for - * identification and comparison purposes. + * @param name the name of the scene element. This is required for + * identification and comparison purposes. * @param patchSize size of the individual patches * @param totalSize the size of this entire terrain tree (on one side) * @param quadSize * @param scale * @param heightMap The height map to generate the terrain from (a flat - * height map will be generated if this is null) + * height map will be generated if this is null) */ @Deprecated public TerrainQuad(String name, int patchSize, int totalSize, int quadSize, Vector3f scale, float[] heightMap) { @@ -215,21 +219,20 @@ public TerrainQuad(String name, int patchSize, int totalSize, int quadSize, Vect } protected TerrainQuad(String name, int patchSize, int quadSize, - Vector3f scale, float[] heightMap, int totalSize, - Vector2f offset, float offsetAmount) - { + Vector3f scale, float[] heightMap, int totalSize, + Vector2f offset, float offsetAmount) { super(name); - + if (heightMap == null) heightMap = generateDefaultHeightMap(quadSize); - + if (!FastMath.isPowerOfTwo(quadSize - 1)) { throw new RuntimeException("size given: " + quadSize + " Terrain quad sizes may only be (2^N + 1)"); } if (FastMath.sqrt(heightMap.length) > quadSize) { Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Heightmap size is larger than the terrain size. Make sure your heightmap image is the same size as the terrain!"); } - + this.offset = offset; this.offsetAmount = offsetAmount; this.totalSize = totalSize; @@ -248,14 +251,14 @@ public void setNeighbourFinder(NeighbourFinder neighbourFinder) { * Forces the recalculation of all normals on the terrain. */ public void recalculateAllNormals() { - affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), totalSize*2, Float.MAX_VALUE, totalSize*2); + affectedAreaBBox = new BoundingBox(new Vector3f(0, 0, 0), totalSize * 2, Float.MAX_VALUE, totalSize * 2); } - + /** * Create just a flat heightmap */ private float[] generateDefaultHeightMap(int size) { - float[] heightMap = new float[size*size]; + float[] heightMap = new float[size * size]; return heightMap; } @@ -269,17 +272,17 @@ protected void updateNormals() { //TODO background-thread this if it ends up being expensive fixNormals(affectedAreaBBox); // the affected patches fixNormalEdges(affectedAreaBBox); // the edges between the patches - + setNormalRecalcNeeded(null); // set to false } } - + /** * Caches the transforms (except rotation) so the LOD calculator, * which runs on a separate thread, can access them safely. */ protected void cacheTerrainTransforms() { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).cacheTerrainTransforms(); @@ -309,21 +312,22 @@ private int collideWithRay(Ray ray, CollisionResults results) { /** * Generate the entropy values for the terrain for the "perspective" LOD * calculator. This routine can take a long time to run! + * * @param progressMonitor optional */ public void generateEntropy(ProgressMonitor progressMonitor) { // only check this on the root quad if (isRootQuad()) if (progressMonitor != null) { - int numCalc = (totalSize-1)/(patchSize-1); // make it an even number - progressMonitor.setMonitorMax(numCalc*numCalc); + int numCalc = (totalSize - 1) / (patchSize - 1); // make it an even number + progressMonitor.setMonitorMax(numCalc * numCalc); } if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { - ((TerrainQuad) child).generateEntropy(progressMonitor); + ((TerrainQuad) child).generateEntropy(progressMonitor); } else if (child instanceof TerrainPatch) { ((TerrainPatch) child).generateLodEntropies(); if (progressMonitor != null) @@ -339,22 +343,22 @@ public void generateEntropy(ProgressMonitor progressMonitor) { } protected boolean isRootQuad() { - return (getParent() != null && !(getParent() instanceof TerrainQuad) ); + return (getParent() != null && !(getParent() instanceof TerrainQuad)); } public Material getMaterial() { return getMaterial(null); } - + public Material getMaterial(Vector3f worldLocation) { // get the material from one of the children. They all share the same material if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { - return ((TerrainQuad)child).getMaterial(worldLocation); + return ((TerrainQuad) child).getMaterial(worldLocation); } else if (child instanceof TerrainPatch) { - return ((TerrainPatch)child).getMaterial(); + return ((TerrainPatch) child).getMaterial(); } } } @@ -364,17 +368,18 @@ public Material getMaterial(Vector3f worldLocation) { public int getNumMajorSubdivisions() { return 1; } - - protected boolean calculateLod(List location, HashMap updates, LodCalculator lodCalculator) { + + protected boolean hasLodChanged(List location, HashMap updates, LodCalculator lodCalculator) { boolean lodChanged = false; if (children != null) { - for (int i = children.size(); --i >= 0;) { + + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { - boolean b = ((TerrainQuad) child).calculateLod(location, updates, lodCalculator); + boolean b = ((TerrainQuad) child).hasLodChanged(location, updates, lodCalculator); if (b) lodChanged = true; } else if (child instanceof TerrainPatch) { @@ -388,9 +393,9 @@ protected boolean calculateLod(List location, HashMap updated) { + protected synchronized void findNeighboursLod(HashMap updated) { if (children != null) { - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { ((TerrainQuad) child).findNeighboursLod(updated); @@ -436,7 +441,7 @@ protected synchronized void findNeighboursLod(HashMap= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { ((TerrainQuad) child).resetCachedNeighbours(); @@ -480,14 +485,14 @@ public void resetCachedNeighbours() { } } } - + /** * Find any neighbours that should have their edges seamed because another neighbour * changed its LOD to a greater value (less detailed) */ - protected synchronized void fixEdges(HashMap updated) { + protected synchronized void fixEdges(HashMap updated) { if (children != null) { - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { ((TerrainQuad) child).fixEdges(updated); @@ -495,7 +500,7 @@ protected synchronized void fixEdges(HashMap updated TerrainPatch patch = (TerrainPatch) child; UpdatedTerrainPatch utp = updated.get(patch.getName()); - if(utp != null && utp.lodChanged()) { + if (utp != null && utp.lodChanged()) { if (!patch.searchedForNeighboursAlready) { // set the references to the neighbours patch.rightNeighbour = patch.findPatch(DIR_RIGHT); @@ -528,7 +533,7 @@ protected synchronized void fixEdges(HashMap updated utpD.setTopLod(utp.getNewLod()); utpD.setFixEdges(true); } - if (top != null){ + if (top != null) { UpdatedTerrainPatch utpT = updated.get(top.getName()); if (utpT == null) { utpT = new UpdatedTerrainPatch(top); @@ -538,7 +543,7 @@ protected synchronized void fixEdges(HashMap updated utpT.setBottomLod(utp.getNewLod()); utpT.setFixEdges(true); } - if (left != null){ + if (left != null) { UpdatedTerrainPatch utpL = updated.get(left.getName()); if (utpL == null) { utpL = new UpdatedTerrainPatch(left); @@ -554,9 +559,9 @@ protected synchronized void fixEdges(HashMap updated } } - protected synchronized void reIndexPages(HashMap updated, boolean usesVariableLod) { + protected synchronized void reIndexPages(HashMap updated, boolean usesVariableLod) { if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).reIndexPages(updated, usesVariableLod); @@ -573,14 +578,12 @@ protected synchronized void reIndexPages(HashMap upd * children. If the child's size is less than or equal to the set block * size, then patches are created, otherwise, quads are created. * - * @param blockSize - * the blocks size to test against. - * @param heightMap - * the height data. + * @param blockSize the blocks size to test against. + * @param heightMap the height data. */ protected void split(int blockSize, float[] heightMap) { if ((size >> 1) + 1 <= blockSize) { - createQuadPatch(heightMap); + setPatchChildren(heightMap); } else { createQuad(blockSize, heightMap); } @@ -589,14 +592,14 @@ protected void split(int blockSize, float[] heightMap) { /** * Quadrants, world coordinates, and heightmap coordinates (Y-up): - * - * -z - * -u | - * -v 1|3 - * -x ----+---- x - * 2|4 u - * | v - * z + *

+ * -z + * -u | + * -v 1|3 + * -x ----+---- x + * 2|4 u + * | v + * z * createQuad generates four new quads from this quad. * The heightmap's top left (0,0) coordinate is at the bottom, -x,-z * coordinate of the terrain, so it grows in the positive x.z direction. @@ -617,7 +620,7 @@ protected void createQuad(int blockSize, float[] heightMap) { float[] heightBlock1 = createHeightSubBlock(heightMap, 0, 0, split); Vector3f origin1 = new Vector3f(-quarterSize * stepScale.x, 0, - -quarterSize * stepScale.z); + -quarterSize * stepScale.z); tempOffset.x = offset.x; tempOffset.y = offset.y; @@ -625,18 +628,18 @@ protected void createQuad(int blockSize, float[] heightMap) { tempOffset.y += origin1.z; TerrainQuad quad1 = new TerrainQuad(getName() + "Quad1", blockSize, - split, stepScale, heightBlock1, totalSize, tempOffset, - offsetAmount); + split, stepScale, heightBlock1, totalSize, tempOffset, + offsetAmount); quad1.setLocalTranslation(origin1); quad1.quadrant = 1; this.attachChild(quad1); // 2 lower left of heightmap, lower left quad float[] heightBlock2 = createHeightSubBlock(heightMap, 0, split - 1, - split); + split); Vector3f origin2 = new Vector3f(-quarterSize * stepScale.x, 0, - quarterSize * stepScale.z); + quarterSize * stepScale.z); tempOffset = new Vector2f(); tempOffset.x = offset.x; @@ -645,18 +648,18 @@ protected void createQuad(int blockSize, float[] heightMap) { tempOffset.y += origin2.z; TerrainQuad quad2 = new TerrainQuad(getName() + "Quad2", blockSize, - split, stepScale, heightBlock2, totalSize, tempOffset, - offsetAmount); + split, stepScale, heightBlock2, totalSize, tempOffset, + offsetAmount); quad2.setLocalTranslation(origin2); quad2.quadrant = 2; this.attachChild(quad2); // 3 upper right of heightmap, upper right quad float[] heightBlock3 = createHeightSubBlock(heightMap, split - 1, 0, - split); + split); Vector3f origin3 = new Vector3f(quarterSize * stepScale.x, 0, - -quarterSize * stepScale.z); + -quarterSize * stepScale.z); tempOffset = new Vector2f(); tempOffset.x = offset.x; @@ -665,18 +668,18 @@ protected void createQuad(int blockSize, float[] heightMap) { tempOffset.y += origin3.z; TerrainQuad quad3 = new TerrainQuad(getName() + "Quad3", blockSize, - split, stepScale, heightBlock3, totalSize, tempOffset, - offsetAmount); + split, stepScale, heightBlock3, totalSize, tempOffset, + offsetAmount); quad3.setLocalTranslation(origin3); quad3.quadrant = 3; this.attachChild(quad3); - + // 4 lower right of heightmap, lower right quad float[] heightBlock4 = createHeightSubBlock(heightMap, split - 1, - split - 1, split); + split - 1, split); Vector3f origin4 = new Vector3f(quarterSize * stepScale.x, 0, - quarterSize * stepScale.z); + quarterSize * stepScale.z); tempOffset = new Vector2f(); tempOffset.x = offset.x; @@ -685,8 +688,8 @@ protected void createQuad(int blockSize, float[] heightMap) { tempOffset.y += origin4.z; TerrainQuad quad4 = new TerrainQuad(getName() + "Quad4", blockSize, - split, stepScale, heightBlock4, totalSize, tempOffset, - offsetAmount); + split, stepScale, heightBlock4, totalSize, tempOffset, + offsetAmount); quad4.setLocalTranslation(origin4); quad4.quadrant = 4; this.attachChild(quad4); @@ -694,13 +697,13 @@ protected void createQuad(int blockSize, float[] heightMap) { } public void generateDebugTangents(Material mat) { - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { - ((TerrainQuad)child).generateDebugTangents(mat); + ((TerrainQuad) child).generateDebugTangents(mat); } else if (child instanceof TerrainPatch) { - Geometry debug = new Geometry( "Debug " + name, - TangentBinormalGenerator.genTbnLines( ((TerrainPatch)child).getMesh(), 0.8f)); + Geometry debug = new Geometry("Debug " + name, + TangentBinormalGenerator.genTbnLines(((TerrainPatch) child).getMesh(), 0.8f)); attachChild(debug); debug.setLocalTranslation(child.getLocalTranslation()); debug.setCullHint(CullHint.Never); @@ -709,111 +712,57 @@ public void generateDebugTangents(Material mat) { } } + /** - * createQuadPatch creates four child patches from this quad. + * createHeightBlock creates the heightSubBlock according to the provided patch number. + * + * @param patchNumber + * @param heightMap + * @param split + * @return HeightSubBlock array */ - protected void createQuadPatch(float[] heightMap) { - // create 4 terrain patches + protected float[] createHeightBlock(int patchNumber, float[] heightMap, int split) { + switch (patchNumber) { + case 1: + return createHeightSubBlock(heightMap, 0, 0, split); + case 2: + return createHeightSubBlock(heightMap, 0, split - 1, split); + case 3: + return createHeightSubBlock(heightMap, split - 1, 0, split); + case 4: + return createHeightSubBlock(heightMap, split - 1, split - 1, split); + default: + return null; + } + } + + /** + * setPatchChildren sets four child patches to this quad. + * + * @param heightMap + */ + protected void setPatchChildren(float[] heightMap) { + TerrainPatch terrainPatch = new TerrainPatch(); + int numberOfPatchChildren = 4; + int quarterSize = size >> 2; int halfSize = size >> 1; int split = (size + 1) >> 1; - //if (lodCalculator == null) - // lodCalculator = createDefaultLodCalculator(); // set a default one - offsetAmount += quarterSize; - // 1 lower left - float[] heightBlock1 = createHeightSubBlock(heightMap, 0, 0, split); - - Vector3f origin1 = new Vector3f(-halfSize * stepScale.x, 0, -halfSize - * stepScale.z); - - Vector2f tempOffset1 = new Vector2f(); - tempOffset1.x = offset.x; - tempOffset1.y = offset.y; - tempOffset1.x += origin1.x / 2; - tempOffset1.y += origin1.z / 2; - - TerrainPatch patch1 = new TerrainPatch(getName() + "Patch1", split, - stepScale, heightBlock1, origin1, totalSize, tempOffset1, - offsetAmount); - patch1.setQuadrant((short) 1); - this.attachChild(patch1); - patch1.setModelBound(new BoundingBox()); - patch1.updateModelBound(); - //patch1.setLodCalculator(lodCalculator); - //TangentBinormalGenerator.generate(patch1); - - // 2 upper left - float[] heightBlock2 = createHeightSubBlock(heightMap, 0, split - 1, - split); - - Vector3f origin2 = new Vector3f(-halfSize * stepScale.x, 0, 0); - - Vector2f tempOffset2 = new Vector2f(); - tempOffset2.x = offset.x; - tempOffset2.y = offset.y; - tempOffset2.x += origin1.x / 2; - tempOffset2.y += quarterSize * stepScale.z; - - TerrainPatch patch2 = new TerrainPatch(getName() + "Patch2", split, - stepScale, heightBlock2, origin2, totalSize, tempOffset2, - offsetAmount); - patch2.setQuadrant((short) 2); - this.attachChild(patch2); - patch2.setModelBound(new BoundingBox()); - patch2.updateModelBound(); - //patch2.setLodCalculator(lodCalculator); - //TangentBinormalGenerator.generate(patch2); - - // 3 lower right - float[] heightBlock3 = createHeightSubBlock(heightMap, split - 1, 0, - split); - - Vector3f origin3 = new Vector3f(0, 0, -halfSize * stepScale.z); - - Vector2f tempOffset3 = new Vector2f(); - tempOffset3.x = offset.x; - tempOffset3.y = offset.y; - tempOffset3.x += quarterSize * stepScale.x; - tempOffset3.y += origin3.z / 2; - - TerrainPatch patch3 = new TerrainPatch(getName() + "Patch3", split, - stepScale, heightBlock3, origin3, totalSize, tempOffset3, - offsetAmount); - patch3.setQuadrant((short) 3); - this.attachChild(patch3); - patch3.setModelBound(new BoundingBox()); - patch3.updateModelBound(); - //patch3.setLodCalculator(lodCalculator); - //TangentBinormalGenerator.generate(patch3); - - // 4 upper right - float[] heightBlock4 = createHeightSubBlock(heightMap, split - 1, - split - 1, split); - - Vector3f origin4 = new Vector3f(0, 0, 0); - - Vector2f tempOffset4 = new Vector2f(); - tempOffset4.x = offset.x; - tempOffset4.y = offset.y; - tempOffset4.x += quarterSize * stepScale.x; - tempOffset4.y += quarterSize * stepScale.z; - - TerrainPatch patch4 = new TerrainPatch(getName() + "Patch4", split, - stepScale, heightBlock4, origin4, totalSize, tempOffset4, - offsetAmount); - patch4.setQuadrant((short) 4); - this.attachChild(patch4); - patch4.setModelBound(new BoundingBox()); - patch4.updateModelBound(); - //patch4.setLodCalculator(lodCalculator); - //TangentBinormalGenerator.generate(patch4); + for (int i = 1; i <= numberOfPatchChildren; i++) { + TerrainPatch patch = terrainPatch.createQuadPatch(this, i, createHeightBlock(i, heightMap, split), quarterSize, halfSize, split); + patch.setQuadrant((short) i); + this.attachChild(patch); + patch.setModelBound(new BoundingBox()); + patch.updateModelBound(); + } } + public float[] createHeightSubBlock(float[] heightMap, int x, - int y, int side) { + int y, int side) { float[] rVal = new float[side * side]; int bsize = (int) FastMath.sqrt(heightMap.length); int count = 0; @@ -841,13 +790,13 @@ public void attachBoundChildren(Node parent) { } else if (this.getChild(i) instanceof TerrainPatch) { BoundingVolume bv = getChild(i).getWorldBound(); if (bv instanceof BoundingBox) { - attachBoundingBox((BoundingBox)bv, parent); + attachBoundingBox((BoundingBox) bv, parent); } } } BoundingVolume bv = getWorldBound(); if (bv instanceof BoundingBox) { - attachBoundingBox((BoundingBox)bv, parent); + attachBoundingBox((BoundingBox) bv, parent); } } @@ -867,8 +816,8 @@ private void attachBoundingBox(BoundingBox bb, Node parent) { * Does this by looking at the affectedAreaBBox bounding box. If the bbox * exists already, then it will grow the box to fit the new changedPoint. * If the affectedAreaBBox is null, then it will create one of unit size. - * - * @param needToRecalculateNormals if null, will cause needToRecalculateNormals() to return false + *

+ * needToRecalculateNormals if null, will cause needToRecalculateNormals() to return false */ protected void setNormalRecalcNeeded(Vector2f changedPoint) { if (changedPoint == null) { // set needToRecalculateNormals() to false @@ -894,7 +843,7 @@ protected boolean needToRecalculateNormals() { } return false; } - + /** * This will cause all normals for this terrain quad to be recalculated */ @@ -914,101 +863,53 @@ public float getHeightmapHeight(Vector2f xz) { } /** - * This will just get the heightmap value at the supplied point, - * not an interpolated (actual) height value. + * getHeightmapHeight retrieves the heightmap value based on the quadrant of the supplied coordinates, + * not and interpolated (actual) height value. + * + * @param x int x-coordinate + * @param z int z-coordinate + * @return Float heightMapHeight */ protected float getHeightmapHeight(int x, int z) { - int quad = findQuadrant(x, z); - int split = (size + 1) >> 1; - if (children != null) { - for (int i = children.size(); --i >= 0;) { - Spatial spat = children.get(i); - int col = x; - int row = z; - boolean match = false; - - // get the childs quadrant - int childQuadrant = 0; - if (spat instanceof TerrainQuad) { - childQuadrant = ((TerrainQuad) spat).getQuadrant(); - } else if (spat instanceof TerrainPatch) { - childQuadrant = ((TerrainPatch) spat).getQuadrant(); - } - - if (childQuadrant == 1 && (quad & 1) != 0) { - match = true; - } else if (childQuadrant == 2 && (quad & 2) != 0) { - row = z - split + 1; - match = true; - } else if (childQuadrant == 3 && (quad & 4) != 0) { - col = x - split + 1; - match = true; - } else if (childQuadrant == 4 && (quad & 8) != 0) { - col = x - split + 1; - row = z - split + 1; - match = true; - } - - if (match) { - if (spat instanceof TerrainQuad) { - return ((TerrainQuad) spat).getHeightmapHeight(col, row); - } else if (spat instanceof TerrainPatch) { - return ((TerrainPatch) spat).getHeightmapHeight(col, row); - } - } - + QuadrantFinder qf = new QuadrantFinder(x, z); + qf.invoke(); + + if (qf.isMatch()) { + if (qf.spat instanceof TerrainQuad) { + return ((TerrainQuad) qf.spat).getHeightmapHeight(qf.col, qf.row); + } else if (qf.spat instanceof TerrainPatch) { + return ((TerrainPatch) qf.spat).getHeightmapHeight(qf.col, qf.row); } } + return Float.NaN; } + /** + * getMeshNormal retrieves the MeshNormal value based on the quadrant of the supplied coordinates. + * + * @param x int x-coordinate + * @param z int z-coordinate + * @return Vector3f meshNormal + */ protected Vector3f getMeshNormal(int x, int z) { - int quad = findQuadrant(x, z); - int split = (size + 1) >> 1; - if (children != null) { - for (int i = children.size(); --i >= 0;) { - Spatial spat = children.get(i); - int col = x; - int row = z; - boolean match = false; - - // get the childs quadrant - int childQuadrant = 0; - if (spat instanceof TerrainQuad) { - childQuadrant = ((TerrainQuad) spat).getQuadrant(); - } else if (spat instanceof TerrainPatch) { - childQuadrant = ((TerrainPatch) spat).getQuadrant(); - } - - if (childQuadrant == 1 && (quad & 1) != 0) { - match = true; - } else if (childQuadrant == 2 && (quad & 2) != 0) { - row = z - split + 1; - match = true; - } else if (childQuadrant == 3 && (quad & 4) != 0) { - col = x - split + 1; - match = true; - } else if (childQuadrant == 4 && (quad & 8) != 0) { - col = x - split + 1; - row = z - split + 1; - match = true; - } - - if (match) { - if (spat instanceof TerrainQuad) { - return ((TerrainQuad) spat).getMeshNormal(col, row); - } else if (spat instanceof TerrainPatch) { - return ((TerrainPatch) spat).getMeshNormal(col, row); - } - } - + QuadrantFinder qf = new QuadrantFinder(x, z); + qf.invoke(); + + if (qf.match) { + if (qf.spat instanceof TerrainQuad) { + return ((TerrainQuad) qf.spat).getMeshNormal(qf.col, qf.row); + } else if (qf.spat instanceof TerrainPatch) { + return ((TerrainPatch) qf.spat).getMeshNormal(qf.col, qf.row); } } + return null; } /** * is the 2d point inside the terrain? + * * @param x local coordinate * @param z local coordinate */ @@ -1026,64 +927,44 @@ private class QuadrantChild { int col; int row; Spatial child; - + QuadrantChild(int col, int row, Spatial child) { this.col = col; this.row = row; this.child = child; } } - + + /** + * findMatchingChild returns a new QuadrantChild object based on the quadrant of the supplied coordinates. + * + * @param x int x-coordinate + * @param z int z-coordinate + * @return QuadrantChild object + */ private QuadrantChild findMatchingChild(int x, int z) { - int quad = findQuadrant(x, z); - int split = (size + 1) >> 1; - if (children != null) { - for (int i = children.size(); --i >= 0;) { - Spatial spat = children.get(i); - int col = x; - int row = z; - boolean match = false; - - // get the childs quadrant - int childQuadrant = 0; - if (spat instanceof TerrainQuad) { - childQuadrant = ((TerrainQuad) spat).getQuadrant(); - } else if (spat instanceof TerrainPatch) { - childQuadrant = ((TerrainPatch) spat).getQuadrant(); - } + QuadrantFinder qf = new QuadrantFinder(x, z); + qf.invoke(); + + if (qf.isMatch()) + return new QuadrantChild(qf.col, qf.row, qf.spat); - if (childQuadrant == 1 && (quad & 1) != 0) { - match = true; - } else if (childQuadrant == 2 && (quad & 2) != 0) { - row = z - split + 1; - match = true; - } else if (childQuadrant == 3 && (quad & 4) != 0) { - col = x - split + 1; - match = true; - } else if (childQuadrant == 4 && (quad & 8) != 0) { - col = x - split + 1; - row = z - split + 1; - match = true; - } - if (match) - return new QuadrantChild(col, row, spat); - } - } return null; } - + /** * Get the interpolated height of the terrain at the specified point. + * * @param xz the location to get the height for * @return Float.NAN if the value does not exist, or the coordinates are outside of the terrain */ public float getHeight(Vector2f xz) { // offset - float x = (float)(((xz.x - getWorldTranslation().x) / getWorldScale().x) + (float)(totalSize-1) / 2f); - float z = (float)(((xz.y - getWorldTranslation().z) / getWorldScale().z) + (float)(totalSize-1) / 2f); - if (!isInside((int)x, (int)z)) + float x = (float) (((xz.x - getWorldTranslation().x) / getWorldScale().x) + (float) (totalSize - 1) / 2f); + float z = (float) (((xz.y - getWorldTranslation().z) / getWorldScale().z) + (float) (totalSize - 1) / 2f); + if (!isInside((int) x, (int) z)) return Float.NaN; - float height = getHeight((int)x, (int)z, (x%1f), (z%1f)); + float height = getHeight((int) x, (int) z, (x % 1f), (z % 1f)); height *= getWorldScale().y; return height; } @@ -1092,8 +973,8 @@ public float getHeight(Vector2f xz) { * gets an interpolated value at the specified point */ protected float getHeight(int x, int z, float xm, float zm) { - - QuadrantChild match = findMatchingChild(x,z); + + QuadrantChild match = findMatchingChild(x, z); if (match != null) { if (match.child instanceof TerrainQuad) { return ((TerrainQuad) match.child).getHeight(match.col, match.row, xm, zm); @@ -1106,20 +987,20 @@ protected float getHeight(int x, int z, float xm, float zm) { public Vector3f getNormal(Vector2f xz) { // offset - float x = (float)(((xz.x - getWorldTranslation().x) / getWorldScale().x) + (float)(totalSize-1) / 2f); - float z = (float)(((xz.y - getWorldTranslation().z) / getWorldScale().z) + (float)(totalSize-1) / 2f); + float x = (float) (((xz.x - getWorldTranslation().x) / getWorldScale().x) + (float) (totalSize - 1) / 2f); + float z = (float) (((xz.y - getWorldTranslation().z) / getWorldScale().z) + (float) (totalSize - 1) / 2f); Vector3f normal = getNormal(x, z, xz); - + return normal; } - + protected Vector3f getNormal(float x, float z, Vector2f xz) { - x-=0.5f; - z-=0.5f; + x -= 0.5f; + z -= 0.5f; float col = FastMath.floor(x); float row = FastMath.floor(z); boolean onX = false; - if(1 - (x - col)-(z - row) < 0) // what triangle to interpolate on + if (1 - (x - col) - (z - row) < 0) // what triangle to interpolate on onX = true; // v1--v2 ^ // | / | | @@ -1127,15 +1008,15 @@ protected Vector3f getNormal(float x, float z, Vector2f xz) { // v3--v4 | Z // | // <-------Y - // X + // X Vector3f n1 = getMeshNormal((int) FastMath.ceil(x), (int) FastMath.ceil(z)); Vector3f n2 = getMeshNormal((int) FastMath.floor(x), (int) FastMath.ceil(z)); Vector3f n3 = getMeshNormal((int) FastMath.ceil(x), (int) FastMath.floor(z)); Vector3f n4 = getMeshNormal((int) FastMath.floor(x), (int) FastMath.floor(z)); - + return n1.add(n2).add(n3).add(n4).normalize(); } - + public void setHeight(Vector2f xz, float height) { List coord = new ArrayList(); coord.add(xz); @@ -1171,19 +1052,19 @@ protected void setHeight(List xz, List height, boolean override List locations = new ArrayList(); // offset - for (int i=0; i locations, boolean overrideHeight) { @@ -1214,7 +1097,7 @@ protected void setHeight(List locations, boolean overrideHeight) Spatial quad4 = null; // get the child quadrants - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial spat = children.get(i); int childQuadrant = 0; if (spat instanceof TerrainQuad) { @@ -1262,30 +1145,30 @@ else if (childQuadrant == 4) // send the locations to the children if (!quadLH1.isEmpty()) { if (quad1 instanceof TerrainQuad) - ((TerrainQuad)quad1).setHeight(quadLH1, overrideHeight); - else if(quad1 instanceof TerrainPatch) - ((TerrainPatch)quad1).setHeight(quadLH1, overrideHeight); + ((TerrainQuad) quad1).setHeight(quadLH1, overrideHeight); + else if (quad1 instanceof TerrainPatch) + ((TerrainPatch) quad1).setHeight(quadLH1, overrideHeight); } if (!quadLH2.isEmpty()) { if (quad2 instanceof TerrainQuad) - ((TerrainQuad)quad2).setHeight(quadLH2, overrideHeight); - else if(quad2 instanceof TerrainPatch) - ((TerrainPatch)quad2).setHeight(quadLH2, overrideHeight); + ((TerrainQuad) quad2).setHeight(quadLH2, overrideHeight); + else if (quad2 instanceof TerrainPatch) + ((TerrainPatch) quad2).setHeight(quadLH2, overrideHeight); } if (!quadLH3.isEmpty()) { if (quad3 instanceof TerrainQuad) - ((TerrainQuad)quad3).setHeight(quadLH3, overrideHeight); - else if(quad3 instanceof TerrainPatch) - ((TerrainPatch)quad3).setHeight(quadLH3, overrideHeight); + ((TerrainQuad) quad3).setHeight(quadLH3, overrideHeight); + else if (quad3 instanceof TerrainPatch) + ((TerrainPatch) quad3).setHeight(quadLH3, overrideHeight); } if (!quadLH4.isEmpty()) { if (quad4 instanceof TerrainQuad) - ((TerrainQuad)quad4).setHeight(quadLH4, overrideHeight); - else if(quad4 instanceof TerrainPatch) - ((TerrainPatch)quad4).setHeight(quadLH4, overrideHeight); + ((TerrainQuad) quad4).setHeight(quadLH4, overrideHeight); + else if (quad4 instanceof TerrainPatch) + ((TerrainPatch) quad4).setHeight(quadLH4, overrideHeight); } } @@ -1293,7 +1176,7 @@ protected boolean isPointOnTerrain(int x, int z) { return (x >= 0 && x <= totalSize && z >= 0 && z <= totalSize); } - + public int getTerrainSize() { return totalSize; } @@ -1317,6 +1200,7 @@ private int findQuadrant(int x, int y) { /** * lock or unlock the meshes of this terrain. * Locked meshes are uneditable but have better performance. + * * @param locked or unlocked */ public void setLocked(boolean locked) { @@ -1344,7 +1228,7 @@ public void setQuadrant(short quadrant) { protected TerrainPatch getPatch(int quad) { if (children != null) - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainPatch) { TerrainPatch tb = (TerrainPatch) child; @@ -1359,7 +1243,7 @@ protected TerrainQuad getQuad(int quad) { if (quad == 0) return this; if (children != null) - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { TerrainQuad tq = (TerrainQuad) child; @@ -1718,13 +1602,13 @@ protected void fixNormals(BoundingBox affectedArea) { // go through the children and see if they collide with the affectedAreaBBox // if they do, then update their normals - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { - if (affectedArea != null && affectedArea.intersects(((TerrainQuad) child).getWorldBound()) ) + if (affectedArea != null && affectedArea.intersects(((TerrainQuad) child).getWorldBound())) ((TerrainQuad) child).fixNormals(affectedArea); } else if (child instanceof TerrainPatch) { - if (affectedArea != null && affectedArea.intersects(((TerrainPatch) child).getWorldBound()) ) + if (affectedArea != null && affectedArea.intersects(((TerrainPatch) child).getWorldBound())) ((TerrainPatch) child).updateNormals(); // recalculate the patch's normals } } @@ -1737,13 +1621,13 @@ protected void fixNormalEdges(BoundingBox affectedArea) { if (children == null) return; - for (int x = children.size(); --x >= 0;) { + for (int x = children.size(); --x >= 0; ) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { - if (affectedArea != null && affectedArea.intersects(((TerrainQuad) child).getWorldBound()) ) + if (affectedArea != null && affectedArea.intersects(((TerrainQuad) child).getWorldBound())) ((TerrainQuad) child).fixNormalEdges(affectedArea); } else if (child instanceof TerrainPatch) { - if (affectedArea != null && !affectedArea.intersects(((TerrainPatch) child).getWorldBound()) ) // if doesn't intersect, continue + if (affectedArea != null && !affectedArea.intersects(((TerrainPatch) child).getWorldBound())) // if doesn't intersect, continue continue; TerrainPatch tp = (TerrainPatch) child; @@ -1772,20 +1656,19 @@ protected void fixNormalEdges(BoundingBox affectedArea) { } - @Override - public int collideWith(Collidable other, CollisionResults results){ + public int collideWith(Collidable other, CollisionResults results) { int total = 0; if (other instanceof Ray) - return collideWithRay((Ray)other, results); + return collideWithRay((Ray) other, results); // if it didn't collide with this bbox, return if (other instanceof BoundingVolume) - if (!this.getWorldBound().intersects((BoundingVolume)other)) + if (!this.getWorldBound().intersects((BoundingVolume) other)) return total; - for (Spatial child : children){ + for (Spatial child : children) { total += child.collideWith(other, results); } return total; @@ -1794,6 +1677,7 @@ public int collideWith(Collidable other, CollisionResults results){ /** * Gather the terrain patches that intersect the given ray (toTest). * This only tests the bounding boxes + * * @param toTest * @param results */ @@ -1814,8 +1698,7 @@ public void findPick(Ray toTest, List results) { results.add(new TerrainPickData(tp, cr.getClosestCollision())); } } - } - else if (children.get(i) instanceof TerrainQuad) { + } else if (children.get(i) instanceof TerrainQuad) { ((TerrainQuad) children.get(i)).findPick(toTest, results); } } @@ -1827,30 +1710,31 @@ else if (children.get(i) instanceof TerrainQuad) { /** * Retrieve all Terrain Patches from all children and store them * in the 'holder' list + * * @param holder must not be null, will be populated when returns */ public void getAllTerrainPatches(List holder) { if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).getAllTerrainPatches(holder); } else if (child instanceof TerrainPatch) { - holder.add((TerrainPatch)child); + holder.add((TerrainPatch) child); } } } } - public void getAllTerrainPatchesWithTranslation(Map holder, Vector3f translation) { + public void getAllTerrainPatchesWithTranslation(Map holder, Vector3f translation) { if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).getAllTerrainPatchesWithTranslation(holder, translation.clone().add(child.getLocalTranslation())); } else if (child instanceof TerrainPatch) { //if (holder.size() < 4) - holder.put((TerrainPatch)child, translation.clone().add(child.getLocalTranslation())); + holder.put((TerrainPatch) child, translation.clone().add(child.getLocalTranslation())); } } } @@ -1862,14 +1746,14 @@ public void read(JmeImporter e) throws IOException { InputCapsule c = e.getCapsule(this); size = c.readInt("size", 0); stepScale = (Vector3f) c.readSavable("stepScale", null); - offset = (Vector2f) c.readSavable("offset", new Vector2f(0,0)); + offset = (Vector2f) c.readSavable("offset", new Vector2f(0, 0)); offsetAmount = c.readFloat("offsetAmount", 0); quadrant = c.readInt("quadrant", 0); totalSize = c.readInt("totalSize", 0); //lodCalculator = (LodCalculator) c.readSavable("lodCalculator", createDefaultLodCalculator()); //lodCalculatorFactory = (LodCalculatorFactory) c.readSavable("lodCalculatorFactory", null); - - if ( !(getParent() instanceof TerrainQuad) ) { + + if (!(getParent() instanceof TerrainQuad)) { BoundingBox all = new BoundingBox(getWorldTranslation(), totalSize, totalSize, totalSize); affectedAreaBBox = all; updateNormals(); @@ -1883,7 +1767,7 @@ public void write(JmeExporter e) throws IOException { c.write(size, "size", 0); c.write(totalSize, "totalSize", 0); c.write(stepScale, "stepScale", null); - c.write(offset, "offset", new Vector2f(0,0)); + c.write(offset, "offset", new Vector2f(0, 0)); c.write(offsetAmount, "offsetAmount", 0); c.write(quadrant, "quadrant", 0); //c.write(lodCalculatorFactory, "lodCalculatorFactory", null); @@ -1895,7 +1779,7 @@ public TerrainQuad clone() { return this.clone(true); } - @Override + @Override public TerrainQuad clone(boolean cloneMaterials) { TerrainQuad quadClone = (TerrainQuad) super.clone(cloneMaterials); quadClone.name = name.toString(); @@ -1911,10 +1795,10 @@ public TerrainQuad clone(boolean cloneMaterials) { quadClone.quadrant = quadrant; //quadClone.lodCalculatorFactory = lodCalculatorFactory.clone(); //quadClone.lodCalculator = lodCalculator.clone(); - + TerrainLodControl lodControlCloned = this.getControl(TerrainLodControl.class); TerrainLodControl lodControl = quadClone.getControl(TerrainLodControl.class); - + if (lodControlCloned != null && !(getParent() instanceof TerrainQuad)) { //lodControlCloned.setLodCalculator(lodControl.getLodCalculator().clone()); } @@ -1924,7 +1808,7 @@ public TerrainQuad clone(boolean cloneMaterials) { return quadClone; } - + @Override protected void setParent(Node parent) { super.setParent(parent); @@ -1933,7 +1817,7 @@ protected void setParent(Node parent) { clearCaches(); } } - + /** * Removes any cached references this terrain is holding, in particular * the TerrainPatch's neighbour references. @@ -1942,7 +1826,7 @@ protected void setParent(Node parent) { */ public void clearCaches() { if (children != null) { - for (int i = children.size(); --i >= 0;) { + for (int i = children.size(); --i >= 0; ) { Spatial child = children.get(i); if (child instanceof TerrainQuad) { ((TerrainQuad) child).clearCaches(); @@ -1952,10 +1836,10 @@ public void clearCaches() { } } } - + public int getMaxLod() { if (maxLod < 0) - maxLod = Math.max(1, (int) (FastMath.log(size-1)/FastMath.log(2)) -1); // -1 forces our minimum of 4 triangles wide + maxLod = Math.max(1, (int) (FastMath.log(size - 1) / FastMath.log(2)) - 1); // -1 forces our minimum of 4 triangles wide return maxLod; } @@ -1968,29 +1852,37 @@ public int getTotalSize() { return totalSize; } + public float getOffsetAmount() { + return offsetAmount; + } + + public void setOffsetAmount(float offsetAmount) { + this.offsetAmount = offsetAmount; + } + + public float[] getHeightMap() { float[] hm = null; - int length = ((size-1)/2)+1; - int area = size*size; + int length = ((size - 1) / 2) + 1; + int area = size * size; hm = new float[area]; if (getChildren() != null && !getChildren().isEmpty()) { - float[] ul=null, ur=null, bl=null, br=null; + float[] ul = null, ur = null, bl = null, br = null; // get the child heightmaps if (getChild(0) instanceof TerrainPatch) { for (Spatial s : getChildren()) { - if ( ((TerrainPatch)s).getQuadrant() == 1) - ul = ((TerrainPatch)s).getHeightMap(); - else if(((TerrainPatch) s).getQuadrant() == 2) - bl = ((TerrainPatch)s).getHeightMap(); - else if(((TerrainPatch) s).getQuadrant() == 3) - ur = ((TerrainPatch)s).getHeightMap(); - else if(((TerrainPatch) s).getQuadrant() == 4) - br = ((TerrainPatch)s).getHeightMap(); + if (((TerrainPatch) s).getQuadrant() == 1) + ul = ((TerrainPatch) s).getHeightMap(); + else if (((TerrainPatch) s).getQuadrant() == 2) + bl = ((TerrainPatch) s).getHeightMap(); + else if (((TerrainPatch) s).getQuadrant() == 3) + ur = ((TerrainPatch) s).getHeightMap(); + else if (((TerrainPatch) s).getQuadrant() == 4) + br = ((TerrainPatch) s).getHeightMap(); } - } - else { + } else { ul = getQuad(1).getHeightMap(); bl = getQuad(2).getHeightMap(); ur = getQuad(3).getHeightMap(); @@ -2001,31 +1893,88 @@ else if(((TerrainPatch) s).getQuadrant() == 4) // first upper blocks - for (int y=0; y> 1; + + if (children != null) { + for (int i = children.size(); --i >= 0; ) { + this.spat = children.get(i); + + // get the childs quadrant + int childQuadrant = 0; + if (this.spat instanceof TerrainQuad) { + childQuadrant = ((TerrainQuad) this.spat).getQuadrant(); + } else if (this.spat instanceof TerrainPatch) { + childQuadrant = ((TerrainPatch) this.spat).getQuadrant(); + } + + if (childQuadrant == 1 && (quad & 1) != 0) { + this.match = true; + } else if (childQuadrant == 2 && (quad & 2) != 0) { + this.row = this.z - split + 1; + this.match = true; + } else if (childQuadrant == 3 && (quad & 4) != 0) { + this.col = this.x - split + 1; + this.match = true; + } else if (childQuadrant == 4 && (quad & 8) != 0) { + this.col = this.x - split + 1; + this.row = this.z - split + 1; + this.match = true; + } + + if (this.match) { + return true; + } + } + } + + return false; + } + } } From a680b05dde6065d928aacfbb39761337bc52f3c0 Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Thu, 31 Mar 2016 14:41:26 +0200 Subject: [PATCH 48/59] changed name of testCalculateLod to testHasLodChanged. --- .../terrain/geomipmap/TerrainQuadTest.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index d3b79fbfa9..8c6819c6f7 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -263,9 +263,9 @@ public void testGetPatch() { @Test public void testFindRightPatch() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(2); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); + FakeTerrainQuad topRightChild = (FakeTerrainQuad) root.getQuad(3); try { root.findRightPatch(null); @@ -301,9 +301,9 @@ public void testFindRightPatch() { @Test public void testFindDownPatch() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad bottomLeftChild = (FakeTerrainQuad)root.getQuad(2); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(2); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); + FakeTerrainQuad bottomLeftChild = (FakeTerrainQuad) root.getQuad(2); try { root.findDownPatch(null); @@ -339,9 +339,9 @@ public void testFindDownPatch() { @Test public void testFindLeftPatch() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); - FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); - FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(2); + FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); + FakeTerrainQuad topRightChild = (FakeTerrainQuad) root.getQuad(3); try { root.findLeftPatch(null); @@ -377,9 +377,9 @@ public void testFindLeftPatch() { @Test public void testFindTopPatch() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); - FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); - FakeTerrainQuad bottomRightChild = (FakeTerrainQuad)root.getQuad(4); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(2); + FakeTerrainQuad topRightChild = (FakeTerrainQuad) root.getQuad(3); + FakeTerrainQuad bottomRightChild = (FakeTerrainQuad) root.getQuad(4); try { root.findTopPatch(null); @@ -415,7 +415,7 @@ public void testFindTopPatch() { @Test public void testFindQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(2); assertEquals(root.quadrant, 0); @@ -427,8 +427,8 @@ public void testFindQuad() { assertEquals(root.findQuad(DIR_LEFT), root.findLeftQuad()); assertEquals(root.findQuad(DIR_TOP), root.findTopQuad()); - for(int i = 0; i < root.getChildren().size(); i++) { - FakeTerrainQuad child = (FakeTerrainQuad)root.getQuad(i); + for (int i = 0; i < root.getChildren().size(); i++) { + FakeTerrainQuad child = (FakeTerrainQuad) root.getQuad(i); assertEquals(child.findQuad(DIR_RIGHT), child.findRightQuad()); assertEquals(child.findQuad(DIR_DOWN), child.findDownQuad()); assertEquals(child.findQuad(DIR_LEFT), child.findLeftQuad()); @@ -443,7 +443,7 @@ public void testFindQuad() { * The actual lodCalculator is defined in the calculateLod method of these childs. */ @Test - public void testCalculateLod() { + public void testHasLodChanged() { FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); assertFalse(root.hasLodChanged(location, updates, lodCalculator)); assertTrue(root.hasLodChanged(location, updates, fakeLodCalculator)); From 4d07a53323fd483fecf91bbedf361a9dcc9cabb0 Mon Sep 17 00:00:00 2001 From: Bas de Bock Date: Thu, 31 Mar 2016 15:01:49 +0200 Subject: [PATCH 49/59] hasLodChanged javadoc. --- .../jme3/terrain/geomipmap/TerrainQuad.java | 65 +++++++++++++------ .../terrain/geomipmap/TerrainQuadTest.java | 2 +- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 2eb6be86d6..6be24d7564 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -134,7 +134,7 @@ public class TerrainQuad extends Node implements Terrain { protected NeighbourFinder neighbourFinder; private final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; - + public TerrainQuad() { super("Terrain"); } @@ -370,6 +370,15 @@ public int getNumMajorSubdivisions() { } + /** + * hasLodChanged retrieves a boolean value based on the result of the calculateLod method + * in a lodCalculator subclass. + * + * @param location the Vector3f location + * @param updates HashMap with updates to the TerrainPatches + * @param lodCalculator the kind of lodCalculator + * @return + */ protected boolean hasLodChanged(List location, HashMap updates, LodCalculator lodCalculator) { boolean lodChanged = false; @@ -1347,19 +1356,27 @@ protected TerrainQuad findQuad(int direction) { if (quadrant == 0) { if (useFinder) { switch (direction) { - case DIR_RIGHT : return neighbourFinder.getRightQuad(this); - case DIR_DOWN : return neighbourFinder.getDownQuad(this); - case DIR_LEFT : return neighbourFinder.getLeftQuad(this); - case DIR_TOP : return neighbourFinder.getTopQuad(this); + case DIR_RIGHT: + return neighbourFinder.getRightQuad(this); + case DIR_DOWN: + return neighbourFinder.getDownQuad(this); + case DIR_LEFT: + return neighbourFinder.getLeftQuad(this); + case DIR_TOP: + return neighbourFinder.getTopQuad(this); } } } switch (direction) { - case DIR_RIGHT : return getRightNeighbourQuad(); - case DIR_DOWN : return getDownNeighbourQuad(); - case DIR_LEFT : return getLeftNeighbourQuad(); - case DIR_TOP : return getTopNeighbourQuad(); + case DIR_RIGHT: + return getRightNeighbourQuad(); + case DIR_DOWN: + return getDownNeighbourQuad(); + case DIR_LEFT: + return getLeftNeighbourQuad(); + case DIR_TOP: + return getTopNeighbourQuad(); } return null; @@ -1369,14 +1386,17 @@ private TerrainQuad getRightNeighbourQuad() { TerrainQuad pQuad = (TerrainQuad) getParent(); TerrainQuad neighbourQuad; switch (quadrant) { - case 1: return pQuad.getQuad(3); - case 2: return pQuad.getQuad(4); + case 1: + return pQuad.getQuad(3); + case 2: + return pQuad.getQuad(4); case 3: neighbourQuad = pQuad.findQuad(DIR_RIGHT); if (neighbourQuad != null) return neighbourQuad.getQuad(1); break; - case 4: case DIR_RIGHT: + case 4: + case DIR_RIGHT: neighbourQuad = pQuad.findQuad(DIR_RIGHT); if (neighbourQuad != null) return neighbourQuad.getQuad(2); @@ -1389,12 +1409,15 @@ private TerrainQuad getDownNeighbourQuad() { TerrainQuad pQuad = (TerrainQuad) getParent(); TerrainQuad neighbourQuad; switch (quadrant) { - case 1: return pQuad.getQuad(2); - case 2: neighbourQuad = pQuad.findQuad(DIR_DOWN); + case 1: + return pQuad.getQuad(2); + case 2: + neighbourQuad = pQuad.findQuad(DIR_DOWN); if (neighbourQuad != null) return neighbourQuad.getQuad(1); break; - case 3: return pQuad.getQuad(4); + case 3: + return pQuad.getQuad(4); case 4: neighbourQuad = pQuad.findQuad(DIR_DOWN); if (neighbourQuad != null) @@ -1418,8 +1441,10 @@ private TerrainQuad getLeftNeighbourQuad() { if (neighbourQuad != null) return neighbourQuad.getQuad(4); break; - case 3: return pQuad.getQuad(1); - case 4: return pQuad.getQuad(2); + case 3: + return pQuad.getQuad(1); + case 4: + return pQuad.getQuad(2); } return null; } @@ -1433,13 +1458,15 @@ private TerrainQuad getTopNeighbourQuad() { if (neighbourQuad != null) return neighbourQuad.getQuad(2); break; - case 2: return pQuad.getQuad(1); + case 2: + return pQuad.getQuad(1); case 3: neighbourQuad = pQuad.findQuad(DIR_TOP); if (neighbourQuad != null) return neighbourQuad.getQuad(4); break; - case 4: return pQuad.getQuad(3); + case 4: + return pQuad.getQuad(3); } return null; } diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 8c6819c6f7..d2965497d5 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -439,7 +439,7 @@ public void testFindQuad() { /** * Tests the calculateLod method, which name has been refactored to hasLodChanged. * We came to the conclusion that the method does belong to TerrainQuad, but should be renamed - * as it does not calculate anything. Is only retrieves values from users of the LodCalculator interface. + * as it does not calculate anything. Is only retrieves values from subclasses of the LodCalculator interface. * The actual lodCalculator is defined in the calculateLod method of these childs. */ @Test From 7073754cb056abe248fd1faad7f11ab3659dfc0e Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 17:33:52 +0200 Subject: [PATCH 50/59] Added names to createNestedQuad, added first test for fixEdges --- .../jme3/terrain/geomipmap/TerrainQuad.java | 8 +- .../terrain/geomipmap/TerrainQuadTest.java | 90 ++++++++++++++----- 2 files changed, 74 insertions(+), 24 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 3df45c2660..69dc331582 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -513,12 +513,12 @@ protected synchronized void fixEdges(HashMap updated } } - private UpdatedTerrainPatch getUpdatedTerrainPatch(HashMap updated, TerrainPatch right) { - UpdatedTerrainPatch utpR = updated.get(right.getName()); + private UpdatedTerrainPatch getUpdatedTerrainPatch(HashMap updated, TerrainPatch tp) { + UpdatedTerrainPatch utpR = updated.get(tp.getName()); if (utpR == null) { - utpR = new UpdatedTerrainPatch(right); + utpR = new UpdatedTerrainPatch(tp); updated.put(utpR.getName(), utpR); - utpR.setNewLod(right.lod); + utpR.setNewLod(tp.lod); } return utpR; } diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index cf97937d61..fd2d609b3b 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -3,11 +3,17 @@ import static org.junit.Assert.*; import com.jme3.scene.Spatial; +import com.jme3.scene.control.UpdateControl; +import com.jme3.terrain.Terrain; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + public class TerrainQuadTest { final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; @@ -43,14 +49,17 @@ private void fakeCreateQuad(FakeTerrainQuad parent, FakeTerrainQuad[] children) * @param nestLevel Nest level to be created. * @return Nested structure of {@link Spatial}s */ - private Spatial createNestedQuad(int nestLevel) { + private Spatial createNestedQuad(int nestLevel, String index) { if (nestLevel == 0) { - return new TerrainPatch(); + TerrainPatch tp = new TerrainPatch(); + tp.setName(index); + return tp; } FakeTerrainQuad parent = new FakeTerrainQuad(); + parent.setName(index); for (int i = 0; i < 4; i++) { - Spatial child = createNestedQuad(nestLevel - 1); + Spatial child = createNestedQuad(nestLevel - 1, index + (i + 1)); if (child instanceof TerrainPatch) { TerrainPatch patchChild = (TerrainPatch) child; @@ -74,16 +83,16 @@ public void testFakeTerrainQuad() { @Test public void testNestStructure() { - Spatial leaf = createNestedQuad(0); + Spatial leaf = createNestedQuad(0, ""); assertTrue(leaf instanceof TerrainPatch); - FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1, ""); assertEquals(root.getChildren().size(), 4); for (int i = 0; i < 4; i++) { assertTrue(root.getChild(i) instanceof TerrainPatch); // Ensure children of root are leafs } - root = (FakeTerrainQuad) createNestedQuad(2); + root = (FakeTerrainQuad) createNestedQuad(2, ""); assertEquals(root.getChildren().size(), 4); for (int i = 0; i < 4; i++) { assertTrue(root.getChild(i) instanceof TerrainQuad); // Ensure children of root are not leafs @@ -103,10 +112,10 @@ public void testGetQuad() { @Test public void testFindQuadNeighbourFinder() { FakeTerrainQuad[] roots = new FakeTerrainQuad[4]; - roots[0] = (FakeTerrainQuad) createNestedQuad(2); - roots[1] = (FakeTerrainQuad) createNestedQuad(2); - roots[2] = (FakeTerrainQuad) createNestedQuad(2); - roots[3] = (FakeTerrainQuad) createNestedQuad(2); + roots[0] = (FakeTerrainQuad) createNestedQuad(2, ""); + roots[1] = (FakeTerrainQuad) createNestedQuad(2, ""); + roots[2] = (FakeTerrainQuad) createNestedQuad(2, ""); + roots[3] = (FakeTerrainQuad) createNestedQuad(2, ""); NeighbourFinder nf = new TestNeighbourFinder(roots[0], roots[1], roots[2], roots[3]); for (FakeTerrainQuad root : roots) { @@ -127,7 +136,7 @@ public void testFindQuadNeighbourFinder() { @Test public void testFindRightQuad() { - FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3, ""); FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad topRight = (FakeTerrainQuad) root.getQuad(3); @@ -147,7 +156,7 @@ public void testFindRightQuad() { @Test public void testFindDownQuad() { - FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3, ""); FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad downLeftChild = (FakeTerrainQuad) root.getQuad(2); @@ -167,7 +176,7 @@ public void testFindDownQuad() { @Test public void testFindLeftQuad() { - FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3, ""); FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad topRightChild = (FakeTerrainQuad) root.getQuad(3); @@ -187,7 +196,7 @@ public void testFindLeftQuad() { @Test public void testFindTopQuad() { - FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(3, ""); FakeTerrainQuad topLeftChild = (FakeTerrainQuad) root.getQuad(1); FakeTerrainQuad downLeftChild = (FakeTerrainQuad) root.getQuad(2); @@ -207,7 +216,7 @@ public void testFindTopQuad() { @Test public void testGetPatch() { - FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1, ""); assertNull(root.getPatch(0)); for (int i = 1; i <= 4; i++) { TerrainPatch child = root.getPatch(i); @@ -219,7 +228,7 @@ public void testGetPatch() { @Test public void testFindRightPatch() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2, ""); FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); @@ -257,7 +266,7 @@ public void testFindRightPatch() { @Test public void testFindDownPatch() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2, ""); FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); FakeTerrainQuad bottomLeftChild = (FakeTerrainQuad)root.getQuad(2); @@ -295,7 +304,7 @@ public void testFindDownPatch() { @Test public void testFindLeftPatch() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2, ""); FakeTerrainQuad topLeftChild = (FakeTerrainQuad)root.getQuad(1); FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); @@ -333,7 +342,7 @@ public void testFindLeftPatch() { @Test public void testFindTopPatch() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2, ""); FakeTerrainQuad topRightChild = (FakeTerrainQuad)root.getQuad(3); FakeTerrainQuad bottomRightChild = (FakeTerrainQuad)root.getQuad(4); @@ -371,7 +380,7 @@ public void testFindTopPatch() { @Test public void testFindQuad() { - FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2); + FakeTerrainQuad root = (FakeTerrainQuad)createNestedQuad(2, ""); assertEquals(root.quadrant, 0); @@ -391,4 +400,45 @@ public void testFindQuad() { assertEquals(child.findQuad(DIR_TOP), child.findTopQuad()); } } + + @Test + public void testFixEdges() { + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(2, ""); + HashMap updated = new HashMap<>(); + + assertNotNull(root.getChildren()); + + for (int i = 1; i <= root.getQuad(1).getChildren().size(); i++) { + System.out.println("Adding child " + i + " with name " + root.getQuad(1).getPatch(i).getName()); + + UpdatedTerrainPatch utp = new UpdatedTerrainPatch(root.getQuad(1).getPatch(i)); + updated.put(root.getQuad(1).getPatch(i).getName(), utp); + } + + // Set changed LOD for all patches in quad 1. + for (int i = root.getQuad(1).getChildren().size(); i > 0; i--) { + System.out.println("Update LOD of patch " + i); + + UpdatedTerrainPatch utp = updated.get(root.getQuad(1).getPatch(i).getName()); + utp.setPreviousLod(1); // Dummy value + utp.setNewLod(2); // Dummy value + } + + // Copy keys + Set unfixedKeyset = new HashSet<>(); + for (String s : updated.keySet()) { + unfixedKeyset.add(s); + } + + root.fixEdges(updated); + + // Extract newly updated keys + updated.keySet().removeAll(unfixedKeyset); + + // Assert new keys + assertTrue(updated.keySet().contains("21")); + assertTrue(updated.keySet().contains("23")); + assertTrue(updated.keySet().contains("31")); + assertTrue(updated.keySet().contains("32")); + } } From 8cd31b065ed8aa5e5c8e4c34d63266439e7802a9 Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 21:42:21 +0200 Subject: [PATCH 51/59] Improved testFixEdges --- .../terrain/geomipmap/TerrainQuadTest.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index fd2d609b3b..dd398ac2ec 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -408,32 +408,42 @@ public void testFixEdges() { assertNotNull(root.getChildren()); + // Create UTPs and add it to the updated var for (int i = 1; i <= root.getQuad(1).getChildren().size(); i++) { - System.out.println("Adding child " + i + " with name " + root.getQuad(1).getPatch(i).getName()); - UpdatedTerrainPatch utp = new UpdatedTerrainPatch(root.getQuad(1).getPatch(i)); updated.put(root.getQuad(1).getPatch(i).getName(), utp); } - // Set changed LOD for all patches in quad 1. - for (int i = root.getQuad(1).getChildren().size(); i > 0; i--) { - System.out.println("Update LOD of patch " + i); + // Copy keys + Set oldKeyset = new HashSet<>(); + for (String s : updated.keySet()) { + oldKeyset.add(s); + } + // Without any changes in LOD, keyset should remain the same + root.fixEdges(updated); + assertTrue(updated.keySet().equals(oldKeyset)); + + // Change LOD for all patches in quad 1. + for (int i = root.getQuad(1).getChildren().size(); i > 0; i--) { UpdatedTerrainPatch utp = updated.get(root.getQuad(1).getPatch(i).getName()); utp.setPreviousLod(1); // Dummy value utp.setNewLod(2); // Dummy value } // Copy keys - Set unfixedKeyset = new HashSet<>(); + oldKeyset.clear(); for (String s : updated.keySet()) { - unfixedKeyset.add(s); + oldKeyset.add(s); } root.fixEdges(updated); + // Make sure new keyset is different + assertFalse(updated.keySet().equals(oldKeyset)); + // Extract newly updated keys - updated.keySet().removeAll(unfixedKeyset); + updated.keySet().removeAll(oldKeyset); // Assert new keys assertTrue(updated.keySet().contains("21")); From 844a034b70b7e6ac4e3091e3cbc1d14a9f87b196 Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 22:29:55 +0200 Subject: [PATCH 52/59] Added test for findNeighboursLod --- .../terrain/geomipmap/TerrainQuadTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index dd398ac2ec..c065020548 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -401,6 +401,11 @@ public void testFindQuad() { } } + /** + * Test for TerrainQuads fixEdges method. + * Both situations of updated and non-updated LODs are covered. + * A typical situation is covered with assertions. + */ @Test public void testFixEdges() { FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(2, ""); @@ -451,4 +456,75 @@ public void testFixEdges() { assertTrue(updated.keySet().contains("31")); assertTrue(updated.keySet().contains("32")); } + + /** + * Test for TerrainQuads deprecated findNeighboursLod method. + * It tests for both an empty UpdatedTerrainPatch set and a full one. + * Assertions are made to verify that the LODs are set correctly. + */ + @Test + public void testFindNeighboursLod() { + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(2, ""); + HashMap updated = new HashMap<>(); + + assertNotNull(root.getChildren()); + + // Call method with empty setof UTPs + root.findNeighboursLod(updated); + + // Check if all patches are updated + for (int i = 1; i <= root.getChildren().size(); i++) { + for (int j = 1; j <= root.getQuad(i).getChildren().size(); j++) { + TerrainPatch tp = root.getQuad(i).getPatch(j); + assertTrue(updated.containsKey(tp.getName())); + } + } + + // Set random LOD to ensure proper assertions. + for (int i = 1; i <= root.getChildren().size(); i++) { + for (int j = 1; j <= root.getQuad(i).getChildren().size(); j++) { + UpdatedTerrainPatch utp = updated.get(root.getQuad(i).getPatch(j).getName()); + utp.setPreviousLod((int)(Math.random() * 100)); // Dummy value + utp.setNewLod((int)(Math.random() * 100)); // Dummy value + } + } + + root.findNeighboursLod(updated); + + // Check if all patches are updated. + for (int i = 1; i <= root.getChildren().size(); i++) { + for (int j = 1; j <= root.getQuad(i).getChildren().size(); j++) { + TerrainPatch tp = root.getQuad(i).getPatch(j); + UpdatedTerrainPatch utp = updated.get(tp.getName()); + + TerrainPatch left = tp.findPatch(DIR_LEFT); + if (left != null) { + UpdatedTerrainPatch leftUtp = updated.get(left.getName()); + assertEquals(utp.getLeftLod(), leftUtp.getNewLod()); + assertEquals(leftUtp.getRightLod(), utp.getNewLod()); + } + + TerrainPatch right = tp.findPatch(DIR_RIGHT); + if (right != null) { + UpdatedTerrainPatch rightUtp = updated.get(right.getName()); + assertEquals(utp.getRightLod(), rightUtp.getNewLod()); + assertEquals(rightUtp.getLeftLod(), utp.getNewLod()); + } + + TerrainPatch top = tp.findPatch(DIR_TOP); + if (top != null) { + UpdatedTerrainPatch topUtp = updated.get(top.getName()); + assertEquals(utp.getTopLod(), topUtp.getNewLod()); + assertEquals(topUtp.getBottomLod(), utp.getNewLod()); + } + + TerrainPatch down = tp.findPatch(DIR_DOWN); + if (down != null) { + UpdatedTerrainPatch downUtp = updated.get(down.getName()); + assertEquals(utp.getBottomLod(), downUtp.getNewLod()); + assertEquals(downUtp.getTopLod(), utp.getNewLod()); + } + } + } + } } From 33a27580970910e0ba3332fe421c7326cfd3d1a8 Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 22:37:28 +0200 Subject: [PATCH 53/59] Added test for all setLod methods in UTP --- .../geomipmap/UpdatedTerrainPatchTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatchTest.java diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatchTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatchTest.java new file mode 100644 index 0000000000..62edb21e13 --- /dev/null +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatchTest.java @@ -0,0 +1,39 @@ +package com.jme3.terrain.geomipmap; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class UpdatedTerrainPatchTest { + @Test + public void testSetLeftLod() { + TerrainPatch tp = new TerrainPatch(); + UpdatedTerrainPatch utp = new UpdatedTerrainPatch(tp); + utp.setLeftLod(1); + assertEquals(utp.getLeftLod(), 1); + } + + @Test + public void testSetTopLod() { + TerrainPatch tp = new TerrainPatch(); + UpdatedTerrainPatch utp = new UpdatedTerrainPatch(tp); + utp.setTopLod(1); + assertEquals(utp.getTopLod(), 1); + } + + @Test + public void testSetRightLod() { + TerrainPatch tp = new TerrainPatch(); + UpdatedTerrainPatch utp = new UpdatedTerrainPatch(tp); + utp.setRightLod(1); + assertEquals(utp.getRightLod(), 1); + } + + @Test + public void testSetBottomLod() { + TerrainPatch tp = new TerrainPatch(); + UpdatedTerrainPatch utp = new UpdatedTerrainPatch(tp); + utp.setBottomLod(1); + assertEquals(utp.getBottomLod(), 1); + } +} From 925a09fa0b19fca021640f3197f343f0529eb44a Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 22:42:45 +0200 Subject: [PATCH 54/59] Added setLod with test --- .../geomipmap/UpdatedTerrainPatch.java | 14 +++++++++++++ .../geomipmap/UpdatedTerrainPatchTest.java | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java index f6d370b238..594e500505 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java @@ -53,6 +53,8 @@ public class UpdatedTerrainPatch { //private boolean reIndexNeeded = false; private boolean fixEdges = false; + private final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; + public UpdatedTerrainPatch(TerrainPatch updatedPatch) { this.updatedPatch = updatedPatch; } @@ -99,12 +101,21 @@ protected void setNewIndexBuffer(Buffer newIndexBuffer) { this.newIndexBuffer = newIndexBuffer; } + protected void setLod(int lod, int dir) { + switch (dir) { + case DIR_LEFT: this.leftLod = lod; break; + case DIR_TOP: this.topLod = lod; break; + case DIR_RIGHT: this.rightLod = lod; break; + case DIR_DOWN: this.bottomLod = lod; break; + } + } protected int getRightLod() { return rightLod; } + @Deprecated protected void setRightLod(int rightLod) { this.rightLod = rightLod; } @@ -115,6 +126,7 @@ protected int getTopLod() { } + @Deprecated protected void setTopLod(int topLod) { this.topLod = topLod; } @@ -125,6 +137,7 @@ protected int getLeftLod() { } + @Deprecated protected void setLeftLod(int leftLod) { this.leftLod = leftLod; } @@ -135,6 +148,7 @@ protected int getBottomLod() { } + @Deprecated protected void setBottomLod(int bottomLod) { this.bottomLod = bottomLod; } diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatchTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatchTest.java index 62edb21e13..eca8a53c5b 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatchTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/UpdatedTerrainPatchTest.java @@ -5,6 +5,8 @@ import static org.junit.Assert.assertEquals; public class UpdatedTerrainPatchTest { + private final int DIR_RIGHT = 0, DIR_DOWN = 1, DIR_LEFT = 2, DIR_TOP = 3; + @Test public void testSetLeftLod() { TerrainPatch tp = new TerrainPatch(); @@ -36,4 +38,22 @@ public void testSetBottomLod() { utp.setBottomLod(1); assertEquals(utp.getBottomLod(), 1); } + + @Test + public void testSetLod() { + TerrainPatch tp = new TerrainPatch(); + UpdatedTerrainPatch utp = new UpdatedTerrainPatch(tp); + + utp.setLod(1, DIR_DOWN); + assertEquals(utp.getBottomLod(), 1); + + utp.setLod(2, DIR_LEFT); + assertEquals(utp.getLeftLod(), 2); + + utp.setLod(3, DIR_RIGHT); + assertEquals(utp.getRightLod(), 3); + + utp.setLod(4, DIR_TOP); + assertEquals(utp.getTopLod(), 4); + } } From bb4d9b6d0fb620e8db3de189f97d6f2ef3fbdf29 Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 22:54:29 +0200 Subject: [PATCH 55/59] Added getNeighbours to TerrainPatch and refactored fixEdges --- .../jme3/terrain/geomipmap/TerrainPatch.java | 9 ++++++ .../jme3/terrain/geomipmap/TerrainQuad.java | 32 ++++++------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java index cc1fa5d384..c987dc9cdc 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java @@ -707,6 +707,15 @@ protected Vector3f getMeshNormal(int x, int z) { return normal; } + public TerrainPatch[] getNeighbours() { + TerrainPatch[] neighbours = new TerrainPatch[4]; + neighbours[DIR_RIGHT] = this.rightNeighbour; + neighbours[DIR_DOWN] = this.bottomNeighbour; + neighbours[DIR_TOP] = this.topNeighbour; + neighbours[DIR_LEFT] = this.leftNeighbour; + return neighbours; + } + protected float getHeight(int x, int z, float xm, float zm) { return geomap.getHeight(x,z,xm,zm); } diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 69dc331582..e86c6e1418 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -483,29 +483,15 @@ protected synchronized void fixEdges(HashMap updated if(utp != null && utp.lodChanged()) { setPatchNeighbourReferences(patch); - TerrainPatch right = patch.rightNeighbour; - TerrainPatch down = patch.bottomNeighbour; - TerrainPatch top = patch.topNeighbour; - TerrainPatch left = patch.leftNeighbour; - if (right != null) { - UpdatedTerrainPatch utpR = getUpdatedTerrainPatch(updated, right); - utpR.setLeftLod(utp.getNewLod()); - utpR.setFixEdges(true); - } - if (down != null) { - UpdatedTerrainPatch utpD = getUpdatedTerrainPatch(updated, down); - utpD.setTopLod(utp.getNewLod()); - utpD.setFixEdges(true); - } - if (top != null){ - UpdatedTerrainPatch utpT = getUpdatedTerrainPatch(updated, top); - utpT.setBottomLod(utp.getNewLod()); - utpT.setFixEdges(true); - } - if (left != null){ - UpdatedTerrainPatch utpL = getUpdatedTerrainPatch(updated, left); - utpL.setRightLod(utp.getNewLod()); - utpL.setFixEdges(true); + TerrainPatch[] neighbours = patch.getNeighbours(); + + for (int direction = 0; direction < 4; direction++) { + int oppositeDirection = (direction + 2) > 4 ? 4 - (direction + 2) : direction + 2; + if (neighbours[direction] != null) { + UpdatedTerrainPatch utpR = getUpdatedTerrainPatch(updated, neighbours[direction]); + utpR.setLod(utp.getNewLod(), oppositeDirection); + utpR.setFixEdges(true); + } } } } From e33dba81771249073cf44db29fa8cfdbb0e27bd2 Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 23:00:12 +0200 Subject: [PATCH 56/59] Refactored findNeighboursLod --- .../jme3/terrain/geomipmap/TerrainQuad.java | 43 ++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index e86c6e1418..8172192c2b 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -398,38 +398,22 @@ protected synchronized void findNeighboursLod(HashMap 4 ? 4 - (direction + 2) : direction + 2; + + UpdatedTerrainPatch neighbourUtp = getUpdatedTerrainPatch(updated, neighbours[direction]); + utp.setLod(neighbourUtp.getNewLod(), direction); + neighbourUtp.setLod(utp.getNewLod(), oppositeDirection); + } } } } @@ -486,11 +470,12 @@ protected synchronized void fixEdges(HashMap updated TerrainPatch[] neighbours = patch.getNeighbours(); for (int direction = 0; direction < 4; direction++) { - int oppositeDirection = (direction + 2) > 4 ? 4 - (direction + 2) : direction + 2; if (neighbours[direction] != null) { - UpdatedTerrainPatch utpR = getUpdatedTerrainPatch(updated, neighbours[direction]); - utpR.setLod(utp.getNewLod(), oppositeDirection); - utpR.setFixEdges(true); + int oppositeDirection = (direction + 2) > 4 ? 4 - (direction + 2) : direction + 2; + + UpdatedTerrainPatch neighbourUtp = getUpdatedTerrainPatch(updated, neighbours[direction]); + neighbourUtp.setLod(utp.getNewLod(), oppositeDirection); + neighbourUtp.setFixEdges(true); } } } From dbf0ba883576016b9eda52a93043ec7007db18c9 Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 23:03:31 +0200 Subject: [PATCH 57/59] Updated JavaDoc --- .../main/java/com/jme3/terrain/geomipmap/TerrainQuad.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java index 8172192c2b..b6a83f866c 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -388,6 +388,11 @@ protected boolean calculateLod(List location, HashMap updated) { if (children != null) { for (int x = children.size(); --x >= 0;) { @@ -453,6 +458,7 @@ public void resetCachedNeighbours() { /** * Find any neighbours that should have their edges seamed because another neighbour * changed its LOD to a greater value (less detailed) + * @param updated TerrainPatches that have an updated LOD. */ protected synchronized void fixEdges(HashMap updated) { if (children != null) { From 12da5b1a07c0399fc09c2fa6844f57c0ab46eaa4 Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 23:30:12 +0200 Subject: [PATCH 58/59] Fixed createNestedQuad update --- .../com/jme3/terrain/geomipmap/TerrainQuadTest.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 215e474201..189a9693ae 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -9,17 +9,12 @@ import com.jme3.terrain.geomipmap.lodcalc.LodCalculator; import com.jme3.terrain.heightmap.AbstractHeightMap; import com.jme3.terrain.heightmap.HillHeightMap; -import com.jme3.scene.control.UpdateControl; -import com.jme3.terrain.Terrain; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; +import java.util.*; import static org.junit.Assert.*; @@ -449,11 +444,11 @@ public void testFindQuad() { */ @Test public void testCalculateLod() { - FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1, ""); assertFalse(root.hasLodChanged(location, updates, lodCalculator)); assertTrue(root.hasLodChanged(location, updates, fakeLodCalculator)); - FakeTerrainQuad leaf = (FakeTerrainQuad) createNestedQuad(1); + FakeTerrainQuad leaf = (FakeTerrainQuad) createNestedQuad(1, ""); leaf.attachChild(children[1]); assertTrue(leaf.hasLodChanged(location, updates, fakeLodCalculator)); } From 9977cd0c34f69d533f3a113d8ec58d0c77e986ee Mon Sep 17 00:00:00 2001 From: AlexanderGrooff Date: Sat, 9 Apr 2016 23:45:40 +0200 Subject: [PATCH 59/59] Small bugfix --- .../test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java index 297ad2aec0..26e90c4880 100644 --- a/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java +++ b/jme3-terrain/src/test/java/com/jme3/terrain/geomipmap/TerrainQuadTest.java @@ -444,7 +444,7 @@ public void testFindQuad() { */ @Test public void testHasLodChanged() { - FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1); + FakeTerrainQuad root = (FakeTerrainQuad) createNestedQuad(1, ""); assertFalse(root.hasLodChanged(location, updates, lodCalculator)); assertTrue(root.hasLodChanged(location, updates, fakeLodCalculator));