Basic terrain mesh done
This commit is contained in:
parent
85ffe136d3
commit
722fd26511
7 changed files with 78 additions and 60 deletions
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
|
@ -8,5 +8,5 @@
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK" />
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK" />
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
<module version="4">
|
||||||
<component name="FacetManager">
|
<component name="FacetManager">
|
||||||
<facet type="android-gradle" name="Android-Gradle">
|
<facet type="android-gradle" name="Android-Gradle">
|
||||||
<configuration>
|
<configuration>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import se.cookery.core.world.Block;
|
||||||
import se.cookery.core.world.gen.GrassLandWorldGenerator;
|
import se.cookery.core.world.gen.GrassLandWorldGenerator;
|
||||||
import se.cookery.gfx.character.Player;
|
import se.cookery.gfx.character.Player;
|
||||||
import se.cookery.gfx.terrain.TerrainMesh;
|
import se.cookery.gfx.terrain.TerrainMesh;
|
||||||
import se.cookery.gfx.util.GeometryUtil;
|
|
||||||
import se.cookery.gfx.util.MaterialUtil;
|
import se.cookery.gfx.util.MaterialUtil;
|
||||||
import se.cookery.gfx.util.WireFrameProcessor;
|
import se.cookery.gfx.util.WireFrameProcessor;
|
||||||
|
|
||||||
|
|
@ -22,32 +21,9 @@ public class CookeryClient extends SimpleApplication {
|
||||||
cam.setLocation(new Vector3f(0,20,-10));
|
cam.setLocation(new Vector3f(0,20,-10));
|
||||||
cam.lookAt(new Vector3f(0f,0f,0f), Vector3f.UNIT_Z);
|
cam.lookAt(new Vector3f(0f,0f,0f), Vector3f.UNIT_Z);
|
||||||
|
|
||||||
/** 3. We have prepared material and heightmap.
|
|
||||||
* Now we create the actual terrain:
|
|
||||||
* 3.1) Create a TerrainQuad and name it "my terrain".
|
|
||||||
* 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65.
|
|
||||||
* 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513.
|
|
||||||
* 3.4) As LOD step scale we supply Vector3f(1,1,1).
|
|
||||||
* 3.5) We supply the prepared heightmap itself.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Block block = new GrassLandWorldGenerator().generateBlock(0, 0);
|
Block block = new GrassLandWorldGenerator().generateBlock(0, 0);
|
||||||
/*float[] heightMap = new float[Block.BLOCK_SIZE*Block.BLOCK_SIZE];
|
|
||||||
|
|
||||||
for (int x=0; x<Block.BLOCK_SIZE; x++) {
|
Geometry terrain = new Geometry("terrain", new TerrainMesh(1, 1, Block.BLOCK_SIZE, Block.BLOCK_SIZE));
|
||||||
for (int y=0; y<Block.BLOCK_SIZE; y++) {
|
|
||||||
heightMap[Block.BLOCK_SIZE * x + y] = block.getHeight(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
heightMap[Block.BLOCK_SIZE*Block.BLOCK_SIZE/2+Block.BLOCK_SIZE/2] = 1;
|
|
||||||
terrain = new TerrainQuad("Ground", Block.BLOCK_SIZE+1, Block.BLOCK_SIZE+1, heightMap);
|
|
||||||
|
|
||||||
Material green = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
|
||||||
green.setColor("Color", ColorRGBA.Green);
|
|
||||||
terrain.setMaterial(green);
|
|
||||||
rootNode.attachChild(terrain);*/
|
|
||||||
|
|
||||||
Geometry terrain = new Geometry("terrain", new TerrainMesh(1, 1, 1, 1));
|
|
||||||
terrain.setMaterial(MaterialUtil.createMaterial(assetManager, ColorRGBA.Green));
|
terrain.setMaterial(MaterialUtil.createMaterial(assetManager, ColorRGBA.Green));
|
||||||
rootNode.attachChild(terrain);
|
rootNode.attachChild(terrain);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ public class Block {
|
||||||
/**
|
/**
|
||||||
* The size of a block in units of squares. The block is a square with size BLOCK_SIZE x BLOCK_SIZE.
|
* The size of a block in units of squares. The block is a square with size BLOCK_SIZE x BLOCK_SIZE.
|
||||||
**/
|
**/
|
||||||
public static final int BLOCK_SIZE = 64;
|
public static final int BLOCK_SIZE = 20;
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,8 @@
|
||||||
package se.cookery.gfx.terrain;
|
package se.cookery.gfx.terrain;
|
||||||
|
|
||||||
import com.jme3.export.InputCapsule;
|
|
||||||
import com.jme3.export.JmeExporter;
|
|
||||||
import com.jme3.export.JmeImporter;
|
|
||||||
import com.jme3.export.OutputCapsule;
|
|
||||||
import com.jme3.scene.Mesh;
|
import com.jme3.scene.Mesh;
|
||||||
import com.jme3.scene.VertexBuffer;
|
import com.jme3.scene.VertexBuffer;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class will generate a terrain mesh from a TerrainMap
|
* Class will generate a terrain mesh from a TerrainMap
|
||||||
|
|
@ -34,6 +25,8 @@ public class TerrainMesh extends Mesh {
|
||||||
public TerrainMesh(float width, float height, int widthCount, int heightCount){
|
public TerrainMesh(float width, float height, int widthCount, int heightCount){
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
this.widthCount = widthCount;
|
||||||
|
this.heightCount = heightCount;
|
||||||
|
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
@ -41,8 +34,8 @@ public class TerrainMesh extends Mesh {
|
||||||
protected void updateGeometry() {
|
protected void updateGeometry() {
|
||||||
setBuffer(VertexBuffer.Type.Position, 3, generateVertexBuffer());
|
setBuffer(VertexBuffer.Type.Position, 3, generateVertexBuffer());
|
||||||
setBuffer(VertexBuffer.Type.Index, 3, generateIndexBuffer());
|
setBuffer(VertexBuffer.Type.Index, 3, generateIndexBuffer());
|
||||||
setBuffer(VertexBuffer.Type.TexCoord, 2, generateTextureBuffer());
|
// setBuffer(VertexBuffer.Type.TexCoord, 2, generateTextureBuffer());
|
||||||
setBuffer(VertexBuffer.Type.Normal, 3, generateNormalBuffer());
|
// setBuffer(VertexBuffer.Type.Normal, 3, generateNormalBuffer());
|
||||||
|
|
||||||
updateBound();
|
updateBound();
|
||||||
setStatic();
|
setStatic();
|
||||||
|
|
@ -52,25 +45,49 @@ public class TerrainMesh extends Mesh {
|
||||||
* Generates a vertex buffer containing vertex xyz coordinates.
|
* Generates a vertex buffer containing vertex xyz coordinates.
|
||||||
*/
|
*/
|
||||||
protected float[] generateVertexBuffer() {
|
protected float[] generateVertexBuffer() {
|
||||||
float[] vertexBuf = new float[3 * widthCount * heightCount];
|
int vertexCountWidth = widthCount + 1;
|
||||||
|
int vertexCountHeight = heightCount + 1;
|
||||||
|
float[] vertexBuf = new float[3 * vertexCountWidth * vertexCountHeight];
|
||||||
|
|
||||||
return new float[]{
|
for (int row=0; row<vertexCountHeight; row++) {
|
||||||
// x, y, z
|
for (int col=0; col<vertexCountWidth; col++) {
|
||||||
0, 0, 0,
|
int vertexIndex = (3 * vertexCountWidth * row) + (3 * col);
|
||||||
0, 0, height,
|
vertexBuf[vertexIndex + 0] = width * col; // X
|
||||||
width, 0, height,
|
vertexBuf[vertexIndex + 1] = 0; // Y
|
||||||
width, 0, 0,
|
vertexBuf[vertexIndex + 2] = height * row; // Z
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vertexBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a index buffer containing planes for the mesh.
|
* Generates a index buffer containing planes for the mesh.
|
||||||
*/
|
*/
|
||||||
protected short[] generateIndexBuffer() {
|
protected short[] generateIndexBuffer() {
|
||||||
return new short[]{
|
int vertexCountWidth = widthCount + 1;
|
||||||
0, 1, 3,
|
int triangleCount = widthCount * heightCount * 2;
|
||||||
3, 1, 2
|
short[] indexBuf = new short[3 * triangleCount];
|
||||||
};
|
|
||||||
|
for (int row=0; row<heightCount; row++) {
|
||||||
|
for (int col = 0; col<widthCount; col++) {
|
||||||
|
int vertexTopLeft = (row * vertexCountWidth) + col;
|
||||||
|
int vertexTopRight = vertexTopLeft + 1;
|
||||||
|
int vertexBottomLeft = ((row + 1) * vertexCountWidth) + col;
|
||||||
|
int vertexBottomRight = vertexBottomLeft + 1;
|
||||||
|
int indexOffset = 3 * 2 * ((row * widthCount) + col);
|
||||||
|
|
||||||
|
indexBuf[indexOffset + 0] = (short) vertexTopLeft;
|
||||||
|
indexBuf[indexOffset + 1] = (short) vertexBottomLeft;
|
||||||
|
indexBuf[indexOffset + 2] = (short) vertexTopRight;
|
||||||
|
|
||||||
|
indexBuf[indexOffset + 3] = (short) vertexTopRight;
|
||||||
|
indexBuf[indexOffset + 4] = (short) vertexBottomLeft;
|
||||||
|
indexBuf[indexOffset + 5] = (short) vertexBottomRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return indexBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -10,27 +10,52 @@ class TerrainMeshTest {
|
||||||
public void singleSquareTerrain(){
|
public void singleSquareTerrain(){
|
||||||
TerrainMesh terrain = new TerrainMesh(1, 1, 1 ,1);
|
TerrainMesh terrain = new TerrainMesh(1, 1, 1 ,1);
|
||||||
|
|
||||||
float[] index = terrain.generateVertexBuffer();
|
float[] vertexBuffer = terrain.generateVertexBuffer();
|
||||||
assertEquals(3*4, index.length);
|
assertEquals(3 * 4, vertexBuffer.length);
|
||||||
assertArrayEquals(new float[]{
|
assertArrayEquals(new float[]{
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
|
1, 0, 0,
|
||||||
0, 0, 1,
|
0, 0, 1,
|
||||||
1, 0, 1,
|
1, 0, 1,
|
||||||
1, 0, 0,
|
}, vertexBuffer);
|
||||||
}, index);
|
|
||||||
|
short[] indexBuffer = terrain.generateIndexBuffer();
|
||||||
|
assertEquals(3 * 2, indexBuffer.length);
|
||||||
|
assertArrayEquals(new short[]{
|
||||||
|
0, 2, 1,
|
||||||
|
1, 2, 3,
|
||||||
|
}, indexBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void fourSquareTerrain(){
|
public void fourSquareTerrain(){
|
||||||
TerrainMesh terrain = new TerrainMesh(1, 1, 2 ,2);
|
TerrainMesh terrain = new TerrainMesh(1, 1, 2 ,2);
|
||||||
|
|
||||||
float[] index = terrain.generateVertexBuffer();
|
float[] vertexBuffer = terrain.generateVertexBuffer();
|
||||||
assertEquals(3*9, index.length);
|
assertEquals(3 * 9, vertexBuffer.length);
|
||||||
assertArrayEquals(new float[]{
|
assertArrayEquals(new float[]{
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
|
1, 0, 0,
|
||||||
|
2, 0, 0,
|
||||||
0, 0, 1,
|
0, 0, 1,
|
||||||
1, 0, 1,
|
1, 0, 1,
|
||||||
1, 0, 0,
|
2, 0, 1,
|
||||||
}, index);
|
0, 0, 2,
|
||||||
|
1, 0, 2,
|
||||||
|
2, 0, 2,
|
||||||
|
}, vertexBuffer);
|
||||||
|
|
||||||
|
short[] indexBuffer = terrain.generateIndexBuffer();
|
||||||
|
assertEquals(3 * 8, indexBuffer.length);
|
||||||
|
assertArrayEquals(new short[]{
|
||||||
|
0, 3, 1,
|
||||||
|
1, 3, 4,
|
||||||
|
1, 4, 2,
|
||||||
|
2, 4, 5,
|
||||||
|
3, 6, 4,
|
||||||
|
4, 6, 7,
|
||||||
|
4, 7, 5,
|
||||||
|
5, 7, 8,
|
||||||
|
}, indexBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
<module version="4">
|
||||||
<component name="FacetManager">
|
<component name="FacetManager">
|
||||||
<facet type="android-gradle" name="Android-Gradle">
|
<facet type="android-gradle" name="Android-Gradle">
|
||||||
<configuration>
|
<configuration>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue