From b9cc8e8871de73bf70406913f18b446a1fc723e8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 12 Jan 2010 13:01:59 +0100 Subject: Generate triangle data from tile heightmaps --- .gitignore | 5 ++ src/de/gamezock/metacraft/data/Map.java | 89 ++++++++++++++++++++++------ src/de/gamezock/metacraft/data/TestTile.java | 15 +++-- src/de/gamezock/metacraft/data/Tile.java | 2 +- src/de/gamezock/metacraft/data/TileData.java | 8 ++- src/de/gamezock/metacraft/data/TileType.java | 5 ++ src/de/gamezock/metacraft/data/Triangle.java | 40 +++++++++++++ src/de/gamezock/metacraft/ui/Main.java | 64 ++++++++++++-------- src/de/gamezock/metacraft/ui/Renderer.java | 73 ++++++----------------- 9 files changed, 193 insertions(+), 108 deletions(-) create mode 100644 .gitignore create mode 100644 src/de/gamezock/metacraft/data/TileType.java create mode 100644 src/de/gamezock/metacraft/data/Triangle.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f57b3b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/.classpath +/.project +/.settings +/bin + diff --git a/src/de/gamezock/metacraft/data/Map.java b/src/de/gamezock/metacraft/data/Map.java index e387628..770ffe7 100644 --- a/src/de/gamezock/metacraft/data/Map.java +++ b/src/de/gamezock/metacraft/data/Map.java @@ -1,41 +1,96 @@ package de.gamezock.metacraft.data; +import java.util.List; +import java.util.Vector; + +import javax.vecmath.Point3f; + public class Map { - private Tile[][] tiles; - private float[][] heightmap; - - private int width, height; - private int tileSize; - + private List triangleData; + private float[][] heightmap; + + public Map() { - width = height = 1; + int width = 5; + int height = 5; - heightmap = new float[width][height]; - heightmap[0][0] = 0; + float[][] tileHeightmap = new float[width][height]; + Tile[][] tiles = new Tile[width][height]; - tiles = new Tile[width][height]; - tiles[0][0] = new Tile(new TestTile()); + for(int i = 0; i < width; ++i) { + for(int j = 0; j < height; ++j) { + tileHeightmap[i][j] = ((i-2)*(i-2)+(j-2)*(j-2))*0.5f; + tiles[i][j] = new Tile(new TestTile()); + } + } - tileSize = tiles[0][0].getData().getSize(); + createMapData(tiles, tileHeightmap); } - public Tile getTile(int x, int y) { + private void createMapData(Tile[][] tiles, float[][] tileHeightmap) { + int tileSize = tiles[0][0].getData().getSize(); + + heightmap = new float[tiles.length * tileSize][tiles[0].length * tileSize]; + + for(int i = 0; i < tiles.length; ++i) { + for(int j = 0; j < tiles[i].length; ++j) { + float[][] localHeightmap = tiles[i][j].getData().getHeightmap(); + + for(int x = 0; x < tileSize; ++x) { + for(int y = 0; y < tileSize; ++y) { + heightmap[i*tileSize + x][j*tileSize + y] = tileHeightmap[i][j] + localHeightmap[x][y]; + } + } + } + } + + triangleData = new Vector(); + + for(int x = 0; x < heightmap.length-1; ++x) { + for(int y = 0; y < heightmap[x].length-1; ++y) { + float[] h = new float[4]; + h[0] = heightmap[x][y]; + h[1] = heightmap[x+1][y]; + h[2] = heightmap[x+1][y+1]; + h[3] = heightmap[x][y+1]; + + float center = (h[0] + h[1] + h[2] + h[3]) / 4; + + for(int i = 0; i < 4; ++i) { + int i_1 = (i+1)%4; + int i_2 = (i+2)%4; + + Point3f v1 = new Point3f(x + i_1/2, y + i/2, h[i]); + Point3f v2 = new Point3f(x+0.5f, y+0.5f, center); + Point3f v3 = new Point3f(x + i_2/2, y + i_1/2, h[i_1]); + + triangleData.add(new Triangle(v1, v2, v3)); + } + } + } + } + + /*public Tile getTile(int x, int y) { return tiles[x][y]; } public float getTileHeight(int x, int y) { return heightmap[x][y]; - } + }*/ public int getWidth() { - return width; + return heightmap.length; } public int getHeight() { - return height; + return heightmap[0].length; } - public int getTileSize() { + /*public int getTileSize() { return tileSize; + }*/ + + public List getTriangleData() { + return triangleData; } } diff --git a/src/de/gamezock/metacraft/data/TestTile.java b/src/de/gamezock/metacraft/data/TestTile.java index 94a2af1..229f425 100644 --- a/src/de/gamezock/metacraft/data/TestTile.java +++ b/src/de/gamezock/metacraft/data/TestTile.java @@ -1,14 +1,14 @@ package de.gamezock.metacraft.data; -public class TestTile extends TileData { +public class TestTile implements TileData { float[][] heightmap; public TestTile() { - heightmap = new float[getSize()+1][getSize()+1]; + heightmap = new float[getSize()][getSize()]; - for(int i = 0; i < getSize()+1; ++i) { - for(int j = 0; j < getSize()+1; ++j) { - heightmap[i][j] = 1 * ((i+j)%2); + for(int i = 0; i < getSize(); ++i) { + for(int j = 0; j < getSize(); ++j) { + heightmap[i][j] = 0.2f * ((i+j)%2); } } } @@ -22,4 +22,9 @@ public class TestTile extends TileData { public float[][] getHeightmap() { return heightmap; } + + @Override + public TileType getType() { + return new TileType(); + } } diff --git a/src/de/gamezock/metacraft/data/Tile.java b/src/de/gamezock/metacraft/data/Tile.java index 718c514..75c4628 100644 --- a/src/de/gamezock/metacraft/data/Tile.java +++ b/src/de/gamezock/metacraft/data/Tile.java @@ -1,7 +1,7 @@ package de.gamezock.metacraft.data; public class Tile { - TileData tileData; + private TileData tileData; public Tile(TileData tileData) { this.tileData = tileData; diff --git a/src/de/gamezock/metacraft/data/TileData.java b/src/de/gamezock/metacraft/data/TileData.java index 5a3103a..2fb48cc 100644 --- a/src/de/gamezock/metacraft/data/TileData.java +++ b/src/de/gamezock/metacraft/data/TileData.java @@ -1,7 +1,9 @@ package de.gamezock.metacraft.data; -public abstract class TileData { - public abstract int getSize(); +public interface TileData { + public int getSize(); - public abstract float[][] getHeightmap(); + public float[][] getHeightmap(); + + public TileType getType(); } diff --git a/src/de/gamezock/metacraft/data/TileType.java b/src/de/gamezock/metacraft/data/TileType.java new file mode 100644 index 0000000..35db302 --- /dev/null +++ b/src/de/gamezock/metacraft/data/TileType.java @@ -0,0 +1,5 @@ +package de.gamezock.metacraft.data; + +public class TileType { + +} diff --git a/src/de/gamezock/metacraft/data/Triangle.java b/src/de/gamezock/metacraft/data/Triangle.java new file mode 100644 index 0000000..bcfce9d --- /dev/null +++ b/src/de/gamezock/metacraft/data/Triangle.java @@ -0,0 +1,40 @@ +package de.gamezock.metacraft.data; + +import javax.vecmath.Point3f; +import javax.vecmath.Vector3f; + +public class Triangle { + private Point3f[] vertices; + private Vector3f[] normals; + + + public Triangle(Point3f v1, Point3f v2, Point3f v3) { + vertices = new Point3f[3]; + + vertices[0] = v1; + vertices[1] = v2; + vertices[2] = v3; + + normals = new Vector3f[3]; + + Vector3f edge1 = new Vector3f(), edge2 = new Vector3f(); + edge1.sub(v1, v2); + edge2.sub(v3, v2); + + Vector3f normal = new Vector3f(); + normal.cross(edge1, edge2); + normal.normalize(); + + normals[0] = new Vector3f(normal); + normals[1] = new Vector3f(normal); + normals[2] = new Vector3f(normal); + } + + public Point3f getVertex(int i) { + return vertices[i]; + } + + public Vector3f getNormal(int i) { + return normals[i]; + } +} diff --git a/src/de/gamezock/metacraft/ui/Main.java b/src/de/gamezock/metacraft/ui/Main.java index a721feb..c26e510 100644 --- a/src/de/gamezock/metacraft/ui/Main.java +++ b/src/de/gamezock/metacraft/ui/Main.java @@ -1,6 +1,8 @@ package de.gamezock.metacraft.ui; import java.awt.Frame; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; @@ -19,7 +21,7 @@ public class Main implements GLEventListener { private Renderer renderer = new Renderer(this); private Frame frame = new Frame("metacraft"); - /*private*/ GLCanvas canvas; + private GLCanvas canvas; private GLU glu = new GLU(); @@ -33,17 +35,48 @@ public class Main implements GLEventListener { canvas = new GLCanvas(caps); canvas.addGLEventListener(this); + canvas.addKeyListener(new KeyAdapter() { + + public void keyPressed(KeyEvent e) { + if(e.getKeyCode() == KeyEvent.VK_ESCAPE) { + quit(); + } + } + }); + frame.add(canvas); frame.setSize(800, 600); frame.setResizable(false); frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { quit(); } }); - + frame.setVisible(true); - + canvas.requestFocusInWindow(); + + try { + Thread.sleep(500); + } catch (InterruptedException e) { + } + + new Thread(new Runnable() { + + @Override + public void run() { + while(true) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + } + + canvas.display(); + } + } + + }).start(); } Map getCurrentMap() { @@ -75,7 +108,7 @@ public class Main implements GLEventListener { gl.glColorMaterial(GL.GL_FRONT, GL2.GL_AMBIENT_AND_DIFFUSE); gl.glMatrixMode(GL2.GL_MODELVIEW); - glu.gluLookAt(0, -10, -25, 0, 0, 0, 0, 1, 0); + glu.gluLookAt(0, -25, -10, 0, 0, 0, 0, 1, 0); gl.glEnable(GL2.GL_LIGHT0); gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, new float[] {0, 0, 0, 1}, 0); @@ -111,27 +144,6 @@ public class Main implements GLEventListener { * @param args */ public static void main(String[] args) { - final Main main = new Main(); - - try { - Thread.sleep(500); - } catch (InterruptedException e) { - } - - new Thread(new Runnable() { - - @Override - public void run() { - while(true) { - try { - Thread.sleep(10); - } catch (InterruptedException e) { - } - - main.canvas.display(); - } - } - - }).start(); + new Main(); } } diff --git a/src/de/gamezock/metacraft/ui/Renderer.java b/src/de/gamezock/metacraft/ui/Renderer.java index cea0480..3213a53 100644 --- a/src/de/gamezock/metacraft/ui/Renderer.java +++ b/src/de/gamezock/metacraft/ui/Renderer.java @@ -6,7 +6,7 @@ import javax.vecmath.Point3f; import javax.vecmath.Vector3f; import de.gamezock.metacraft.data.Map; -import de.gamezock.metacraft.data.Tile; +import de.gamezock.metacraft.data.Triangle; public class Renderer { private Main main; @@ -15,52 +15,14 @@ public class Renderer { this.main = main; } - private void renderTileQuad(GL2 gl, Tile tile, int x, int y) { - float[][] heightmap = tile.getData().getHeightmap(); - - float[] h = new float[4]; - h[0] = heightmap[x][y]; - h[1] = heightmap[x+1][y]; - h[2] = heightmap[x+1][y+1]; - h[3] = heightmap[x][y+1]; - - float center = (h[0] + h[1] + h[2] + h[3]) / 4; - - for(int i = 0; i < 4; ++i) { - int i_1 = (i+1)%4; - int i_2 = (i+2)%4; - - Point3f v1 = new Point3f(x + i_1/2, y + i/2, h[i]); - Point3f v2 = new Point3f(x+0.5f, y+0.5f, center); - Point3f v3 = new Point3f(x + i_2/2, y + i_1/2, h[i_1]); - - Vector3f edge1 = new Vector3f(), edge2 = new Vector3f(); + private void renderTriangle(GL2 gl, Triangle t) { + for(int i = 0; i < 3; ++i) { + Point3f v = t.getVertex(i); + Vector3f n = t.getNormal(i); - edge1.sub(v1, v2); - edge2.sub(v3, v2); - - Vector3f normal = new Vector3f(); - normal.cross(edge1, edge2); - normal.normalize(); - - gl.glColor3f(1, 1, 1); - gl.glNormal3f(normal.x, normal.y, normal.z); - gl.glVertex3f(v1.x, v1.y, v1.z); - gl.glVertex3f(v2.x, v2.y, v2.z); - gl.glVertex3f(v3.x, v3.y, v3.z); - } - } - - private void renderTile(GL2 gl, Tile tile) { - gl.glBegin(GL.GL_TRIANGLES); - - for(int i = 0; i < tile.getData().getSize(); ++i) { - for(int j = 0; j < tile.getData().getSize(); ++j) { - renderTileQuad(gl, tile, i, j); - } + gl.glNormal3f(n.x, n.y, n.z); + gl.glVertex3f(v.x, v.y, v.z); } - - gl.glEnd(); } public void render(GL2 gl) { @@ -69,20 +31,19 @@ public class Renderer { Map currentMap = main.getCurrentMap(); gl.glPushMatrix(); - gl.glRotatef((System.currentTimeMillis()%3600)/10.0f, 0, 0, 1); + gl.glRotatef((System.currentTimeMillis()%9000)/25.0f, 0, 0, 1); + gl.glTranslatef(-20, -20, 0); + + gl.glBegin(GL.GL_TRIANGLES); + + gl.glColor3f(1, 1, 1); - for(int i = 0; i < currentMap.getWidth(); ++i) { - for(int j = 0; j < currentMap.getHeight(); ++j) { - gl.glPushMatrix(); - gl.glTranslatef(i*currentMap.getTileSize(), j*currentMap.getTileSize(), currentMap.getTileHeight(i, j)); - - renderTile(gl, currentMap.getTile(i, j)); - - gl.glPopMatrix(); - } + for(Triangle t : currentMap.getTriangleData()) { + renderTriangle(gl, t); } + gl.glEnd(); + gl.glPopMatrix(); } - } -- cgit v1.2.3