From c2cb30808136d9f51f860aa5b6481705a6d8c1b3 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 12 Jan 2020 00:24:35 -0500 Subject: [PATCH] Object cleanup / Planet mesh class --- .../graphics/{PlanetGrid.java => Pgrid.java} | 105 ++++---- core/src/mindustry/graphics/PlanetMesh.java | 106 ++++++++ .../mindustry/graphics/PlanetRenderer.java | 244 +----------------- 3 files changed, 159 insertions(+), 296 deletions(-) rename core/src/mindustry/graphics/{PlanetGrid.java => Pgrid.java} (77%) create mode 100644 core/src/mindustry/graphics/PlanetMesh.java diff --git a/core/src/mindustry/graphics/PlanetGrid.java b/core/src/mindustry/graphics/Pgrid.java similarity index 77% rename from core/src/mindustry/graphics/PlanetGrid.java rename to core/src/mindustry/graphics/Pgrid.java index c3658952c3..44462981b4 100644 --- a/core/src/mindustry/graphics/PlanetGrid.java +++ b/core/src/mindustry/graphics/Pgrid.java @@ -4,7 +4,7 @@ import arc.math.*; import arc.math.geom.*; import arc.util.*; -public class PlanetGrid{ +class Pgrid{ private static final float x = -0.525731112119133606f; private static final float z = -0.850650808352039932f; @@ -20,7 +20,31 @@ public class PlanetGrid{ {5, 3, 10, 1, 4}, {2, 5, 4, 0, 11}, {3, 7, 6, 1, 8}, {7, 2, 9, 0, 6} }; - Grid newGrid(int size){ + int size; + Ptile[] tiles; + Corner[] corners; + Edge[] edges; + + Pgrid(int size){ + this.size = size; + + tiles = new Ptile[tileCount(size)]; + for(int i = 0; i < tiles.length; i++){ + tiles[i] = new Ptile(i, i < 12 ? 5 : 6); + } + + corners = new Corner[cornerCount(size)]; + for(int i = 0; i < corners.length; i++){ + corners[i] = new Corner(i); + } + + edges = new Edge[edgeCount(size)]; + for(int i = 0; i < edges.length; i++){ + edges[i] = new Edge(i); + } + } + + static Pgrid newGrid(int size){ if(size == 0){ return initialGrid(); }else{ @@ -28,10 +52,10 @@ public class PlanetGrid{ } } - Grid initialGrid(){ - Grid grid = new Grid(0); + static Pgrid initialGrid(){ + Pgrid grid = new Pgrid(0); - for(Tile t : grid.tiles){ + for(Ptile t : grid.tiles){ t.v = iTiles[t.id]; for(int k = 0; k < 5; k++){ t.tiles[k] = grid.tiles[iTilesP[t.id][k]]; @@ -62,7 +86,7 @@ public class PlanetGrid{ } //new edges int nextEdge = 0; - for(Tile t : grid.tiles){ + for(Ptile t : grid.tiles){ for(int k = 0; k < 5; k++){ if(t.edges[k] == null){ addEdge(nextEdge, grid, t.id, iTilesP[t.id][k]); @@ -73,8 +97,8 @@ public class PlanetGrid{ return grid; } - Grid subdividedGrid(Grid prev){ - Grid grid = new Grid(prev.size + 1); + static Pgrid subdividedGrid(Pgrid prev){ + Pgrid grid = new Pgrid(prev.size + 1); int prevTiles = prev.tiles.length; int prevCorners = prev.corners.length; @@ -97,8 +121,8 @@ public class PlanetGrid{ } //new corners int nextCorner = 0; - for(Tile n : prev.tiles){ - Tile t = grid.tiles[n.id]; + for(Ptile n : prev.tiles){ + Ptile t = grid.tiles[n.id]; for(int k = 0; k < t.edgeCount; k++){ addCorner(nextCorner, grid, t.id, t.tiles[(k + t.edgeCount - 1) % t.edgeCount].id, t.tiles[k].id); nextCorner++; @@ -112,7 +136,7 @@ public class PlanetGrid{ } //new edges int nextEdge = 0; - for(Tile t : grid.tiles){ + for(Ptile t : grid.tiles){ for(int k = 0; k < t.edgeCount; k++){ if(t.edges[k] == null){ addEdge(nextEdge, grid, t.id, t.tiles[k].id); @@ -124,9 +148,9 @@ public class PlanetGrid{ return grid; } - void addCorner(int id, Grid grid, int t1, int t2, int t3){ + static void addCorner(int id, Pgrid grid, int t1, int t2, int t3){ Corner c = grid.corners[id]; - Tile[] t = {grid.tiles[t1], grid.tiles[t2], grid.tiles[t3]}; + Ptile[] t = {grid.tiles[t1], grid.tiles[t2], grid.tiles[t3]}; c.v = Tmp.v31.set(t[0].v).add(t[1].v).add(t[2].v).cpy().nor(); for(int i = 0; i < 3; i++){ t[i].corners[pos(t[i], t[(i + 2) % 3])] = c; @@ -134,9 +158,9 @@ public class PlanetGrid{ } } - void addEdge(int id, Grid grid, int t1, int t2){ + static void addEdge(int id, Pgrid grid, int t1, int t2){ Edge e = grid.edges[id]; - Tile[] t = {grid.tiles[t1], grid.tiles[t2]}; + Ptile[] t = {grid.tiles[t1], grid.tiles[t2]}; Corner[] c = { grid.corners[t[0].corners[pos(t[0], t[1])].id], grid.corners[t[0].corners[(pos(t[0], t[1]) + 1) % t[0].edgeCount].id]}; @@ -148,28 +172,21 @@ public class PlanetGrid{ } } - int pos(Tile t, Tile n){ + static int pos(Ptile t, Ptile n){ for(int i = 0; i < t.edgeCount; i++) if(t.tiles[i] == n) return i; return -1; } - int pos(Tile t, Corner c){ + static int pos(Ptile t, Corner c){ for(int i = 0; i < t.edgeCount; i++) if(t.corners[i] == c) return i; return -1; } - int pos(Tile t, Edge e){ - for(int i = 0; i < t.edgeCount; i++) - if(t.edges[i] == e) - return i; - return -1; - } - - int pos(Corner c, Corner n){ + static int pos(Corner c, Corner n){ for(int i = 0; i < 3; i++) if(c.corners[i] == n) return i; @@ -188,19 +205,19 @@ public class PlanetGrid{ return 30 * Mathf.pow(3, size); } - static class Tile{ + static class Ptile{ int id; int edgeCount; Vec3 v = new Vec3(); - Tile[] tiles; + Ptile[] tiles; Corner[] corners; Edge[] edges; - public Tile(int id, int edgeCount){ + public Ptile(int id, int edgeCount){ this.id = id; this.edgeCount = edgeCount; - tiles = new Tile[edgeCount]; + tiles = new Ptile[edgeCount]; corners = new Corner[edgeCount]; edges = new Edge[edgeCount]; } @@ -208,7 +225,7 @@ public class PlanetGrid{ static class Corner{ int id; - Tile[] tiles = new Tile[3]; + Ptile[] tiles = new Ptile[3]; Corner[] corners = new Corner[3]; Edge[] edges = new Edge[3]; Vec3 v = new Vec3(); @@ -220,37 +237,11 @@ public class PlanetGrid{ static class Edge{ int id; - Tile[] tiles = new Tile[2]; + Ptile[] tiles = new Ptile[2]; Corner[] corners = new Corner[2]; public Edge(int id){ this.id = id; } } - - static class Grid{ - int size; - Tile[] tiles; - Corner[] corners; - Edge[] edges; - - Grid(int size){ - this.size = size; - - tiles = new Tile[tileCount(size)]; - for(int i = 0; i < tiles.length; i++){ - tiles[i] = new Tile(i, i < 12 ? 5 : 6); - } - - corners = new Corner[cornerCount(size)]; - for(int i = 0; i < corners.length; i++){ - corners[i] = new Corner(i); - } - - edges = new Edge[edgeCount(size)]; - for(int i = 0; i < edges.length; i++){ - edges[i] = new Edge(i); - } - } - } } diff --git a/core/src/mindustry/graphics/PlanetMesh.java b/core/src/mindustry/graphics/PlanetMesh.java new file mode 100644 index 0000000000..c48db28f20 --- /dev/null +++ b/core/src/mindustry/graphics/PlanetMesh.java @@ -0,0 +1,106 @@ +package mindustry.graphics; + +import arc.*; +import arc.graphics.*; +import arc.graphics.VertexAttributes.*; +import arc.graphics.gl.*; +import arc.math.geom.*; +import arc.util.*; +import mindustry.graphics.Pgrid.*; + +public class PlanetMesh{ + private float[] floats = new float[3 + 3 + 1]; + private Shader shader = new Shader(Core.files.internal("shaders/planet.vertex.glsl").readString(), Core.files.internal("shaders/planet.fragment.glsl").readString()); + private Mesh mesh; + private Pgrid grid; + + private float color; + private boolean lines; + private float length; + + public PlanetMesh(int divisions, float length, boolean lines, Color color){ + this.length = length; + this.lines = lines; + this.color = color.toFloatBits(); + this.grid = Pgrid.newGrid(divisions); + + int vertices = grid.tiles.length * 12 * (3 + 3 + 1); + + mesh = new Mesh(true, vertices, 0, + new VertexAttribute(Usage.position, 3, Shader.positionAttribute), + new VertexAttribute(Usage.normal, 3, Shader.normalAttribute), + new VertexAttribute(Usage.colorPacked, 4, Shader.colorAttribute)); + + mesh.getVerticesBuffer().limit(mesh.getMaxVertices()); + mesh.getVerticesBuffer().position(0); + + generateMesh(); + } + + public void render(Mat3D mat){ + Gl.enable(Gl.depthTest); + + shader.begin(); + shader.setUniformMatrix4("u_projModelView", mat.val); + mesh.render(shader, lines ? Gl.lines : Gl.triangles); + shader.end(); + + Gl.disable(Gl.depthTest); + } + + private void generateMesh(){ + + for(Ptile tile : grid.tiles){ + + Vec3 nor = Tmp.v31.setZero(); + Corner[] c = tile.corners; + + for(Corner corner : c){ + corner.v.setLength(length); + nor.add(corner.v); + } + nor.nor(); + + if(lines){ + nor.set(1f, 1f, 1f); + + for(int i = 0; i < c.length; i++){ + Vec3 v1 = c[i].v; + Vec3 v2 = c[(i + 1) % c.length].v; + + vert(v1, nor); + vert(v2, nor); + } + }else{ + verts(c[0].v, c[1].v, c[2].v, nor); + verts(c[0].v, c[2].v, c[3].v, nor); + verts(c[0].v, c[3].v, c[4].v, nor); + + if(c.length > 5){ + verts(c[0].v, c[4].v, c[5].v, nor); + }else{ + verts(c[0].v, c[3].v, c[4].v, nor); + } + } + } + } + + private void verts(Vec3 a, Vec3 b, Vec3 c, Vec3 normal){ + vert(a, normal); + vert(b, normal); + vert(c, normal); + } + + private void vert(Vec3 a, Vec3 normal){ + floats[0] = a.x; + floats[1] = a.y; + floats[2] = a.z; + + floats[3] = normal.x; + floats[4] = normal.y; + floats[5] = normal.z; + + floats[6] = color; + mesh.getVerticesBuffer().put(floats); + } +} diff --git a/core/src/mindustry/graphics/PlanetRenderer.java b/core/src/mindustry/graphics/PlanetRenderer.java index fcc7fbe24a..477debb913 100644 --- a/core/src/mindustry/graphics/PlanetRenderer.java +++ b/core/src/mindustry/graphics/PlanetRenderer.java @@ -2,39 +2,20 @@ package mindustry.graphics; import arc.*; import arc.graphics.*; -import arc.graphics.VertexAttributes.*; import arc.graphics.g2d.*; import arc.graphics.g3d.*; -import arc.graphics.gl.*; import arc.input.*; import arc.math.geom.*; import arc.util.*; -import arc.util.noise.*; -import mindustry.graphics.PlanetGrid.*; public class PlanetRenderer{ private Camera3D cam = new Camera3D(); - private Shader shader = new Shader(Core.files.internal("shaders/planet.vertex.glsl").readString(), Core.files.internal("shaders/planet.fragment.glsl").readString()); - private Mesh mesh; - - private int vcount = 0; - private float[] floats = new float[3 + 3 + 1]; - - private Color[] colors = {Color.royal, Color.tan, Color.forest, Color.olive, Color.lightGray, Color.white}; - private Simplex sim = new Simplex(); private float lastX, lastY; + private PlanetMesh planet = new PlanetMesh(3, 1f, false, Color.royal); + private PlanetMesh outline = new PlanetMesh(3, 1.01f, true, Pal.accent); + public PlanetRenderer(){ - int size = 500000; - - mesh = new Mesh(true, size, 0, - new VertexAttribute(Usage.position, 3, Shader.positionAttribute), - new VertexAttribute(Usage.normal, 3, Shader.normalAttribute), - new VertexAttribute(Usage.colorPacked, 4, Shader.colorAttribute)); - mesh.getVerticesBuffer().limit(size); - mesh.getVerticesBuffer().position(0); - - planet(); Tmp.v1.trns(0, 2.5f); cam.position.set(Tmp.v1.x, 0f, Tmp.v1.y); } @@ -43,7 +24,6 @@ public class PlanetRenderer{ Draw.flush(); Gl.clearColor(0, 0, 0, 1); Gl.clear(Gl.depthBufferBit | Gl.colorBufferBit); - Gl.enable(Gl.depthTest); input(); @@ -52,231 +32,17 @@ public class PlanetRenderer{ cam.lookAt(0, 0, 0); cam.update(); - shader.begin(); - shader.setUniformMatrix4("u_projModelView", cam.combined().val); - mesh.render(shader, Gl.triangles); - shader.end(); - - Gl.disable(Gl.depthTest); + planet.render(cam.combined()); + outline.render(cam.combined()); } void input(){ Vec3 v = cam.unproject(Tmp.v33.set(Core.input.mouseX(), Core.input.mouseY(), 0f)); if(Core.input.keyDown(KeyCode.MOUSE_LEFT)){ - - //dx /= Core.graphics.getWidth(); - //dy /= Core.graphics.getHeight(); cam.position.rotate(Vec3.Y, (v.x - lastX) * 100); - //cam.position.rotate(Vec3.Z, dy); } lastX = v.x; lastY = v.y; } - - void planet(){ - PlanetGrid p = new PlanetGrid(); - Grid grid = p.newGrid(2); - - for(Tile tile : grid.tiles){ - - Vec3 nor = Tmp.v31.cpy(); - Corner[] c = tile.corners; - - for(Corner corner : c){ - nor.add(corner.v); - } - nor.nor(); - - verts(c[0].v, c[1].v, c[2].v, nor); - verts(c[0].v, c[2].v, c[3].v, nor); - verts(c[0].v, c[3].v, c[4].v, nor); - - if(c.length > 5){ - verts(c[0].v, c[4].v, c[5].v, nor); - }else{ - verts(c[0].v, c[3].v, c[4].v, nor); - } - } - } - - void verts(Vec3 a, Vec3 b, Vec3 c, Vec3 normal){ - vert(a, normal); - vert(b, normal); - vert(c, normal); - } - - int vert(Vec3 a, Vec3 normal){ - floats[0] = a.x; - floats[1] = a.y; - floats[2] = a.z; - - floats[3] = normal.x; - floats[4] = normal.y; - floats[5] = normal.z; - - floats[6] = Color.royal.toFloatBits(); - - mesh.getVerticesBuffer().put(floats); - - return vcount++; - } -/* - void ico(){ - float s = 2f/Mathf.sqrt(5), c = 1f/Mathf.sqrt(5); - - Array topPoints = new Array<>(); - topPoints.add(new Vec3(0, 0, 1)); - for(int i = 0; i < 5; i++){ - topPoints.add(new Vec3(s*Mathf.cos(i*2*Mathf.pi/5f), s*Mathf.sin(i*2*Mathf.pi/5f), c)); - } - topPoints.addAll(topPoints.map(v -> v.cpy().scl(-1, 1, -1))); - Array points = topPoints; - - vertices.addAll(points.map(p -> { - Vertex v = new Vertex(); - v.pos.set(p).scl(4f); - v.normal.set(p).nor(); - v.color.set(Color.royal); - return v; - })); - - for(int i = 0; i < 5; i++){ - indices.add(0,i+1,(i+1)%5+1); - indices.add(6,i+7,(i+1)%5+7); - indices.add(i+1,(i+1)%5+1,(7-i)%5+7); - indices.add(i+1,(7-i)%5+7,(8-i)%5+7); - } - - norm(); - } - - void norm(){ - Array newVertices = new Array<>(); - IntArray newIndices = new IntArray(); - for(int i = 0; i < indices.size; i += 3){ - Vertex v1 = vertices.get(indices.get(i)); - Vertex v2 = vertices.get(indices.get(i + 1)); - Vertex v3 = vertices.get(indices.get(i + 2)); - - Vec3 nor = v1.normal.cpy().add(v2.normal).add(v3.normal).nor(); - v1 = v1.copy(); - v2 = v2.copy(); - v3 = v3.copy(); - v1.normal = v2.normal = v3.normal = nor; - newIndices.add(newVertices.size, newVertices.size + 1, newVertices.size + 2); - newVertices.add(v1, v2, v3); - } - vertices = newVertices; - indices = newIndices; - } - - void generate(float width, float height, float depth, int divisionsU, int divisionsV){ - float angleUFrom = 0, angleUTo = 360f, angleVFrom = 0, angleVTo = 180f; - final float hw = width * 0.5f; - final float hh = height * 0.5f; - final float hd = depth * 0.5f; - final float auo = Mathf.degRad * angleUFrom; - final float stepU = (Mathf.degRad * (angleUTo - angleUFrom)) / divisionsU; - final float avo = Mathf.degRad * angleVFrom; - final float stepV = (Mathf.degRad * (angleVTo - angleVFrom)) / divisionsV; - final float us = 1f / divisionsU; - final float vs = 1f / divisionsV; - float u, v, angleU, angleV; - - final int s = divisionsU + 3; - int tempOffset = 0; - - tmpIndices.clear(); - tmpIndices.ensureCapacity(divisionsU * 2); - tmpIndices.size = s; - - vertices.clear(); - indices.clear(); - - for(int iv = 0; iv <= divisionsV; iv++){ - angleV = avo + stepV * iv; - v = vs * iv; - final float t = Mathf.sin(angleV); - final float h = Mathf.cos(angleV) * hh; - for(int iu = 0; iu <= divisionsU; iu++){ - angleU = auo + stepU * iu; - u = 1f - us * iu; - Tmp.v31.set(Mathf.cos(angleU) * hw * t, h, Mathf.sin(angleU) * hd * t); - - Vertex vert = new Vertex(); - vert.normal.set(Tmp.v32.set(Tmp.v31).nor()); - vert.color.set(vert.normal.x, vert.normal.y, vert.normal.z, 1f); - vert.uv.set(u, v); - vert.pos.set(Tmp.v31); - - int index = vertices.size; - vertices.add(vert); - - tmpIndices.set(tempOffset, (short)index); - final int o = tempOffset + s; - if(iv > 0 && iu > 0){ - indices.add(tmpIndices.get(tempOffset), tmpIndices.get((o - 1) % s), tmpIndices.get((o - (divisionsU + 2)) % s), tmpIndices.get((o - (divisionsU + 1)) % s)); - //builder.rect(tmpIndices.get(tempOffset), tmpIndices.get((o - 1) % s), tmpIndices.get((o - (divisionsU + 2)) % s), tmpIndices.get((o - (divisionsU + 1)) % s)); - } - tempOffset = (tempOffset + 1) % tmpIndices.size; - } - } - - //norm(); - } - - Color color(Vec3 v){ - double value = sim.octaveNoise3D(6, 0.6, 1.0 / 10.0, v.x, v.y, v.z); - return colors[Mathf.clamp((int)(value * colors.length), 0, colors.length - 1)]; - } - - void drawTri(){ - for(int i = 0; i < indices.size; i += 3){ - Vertex v1 = vertices.get(indices.get(i)); - Vertex v2 = vertices.get(indices.get(i + 1)); - Vertex v3 = vertices.get(indices.get(i + 2)); - - v1.d(); - v2.d(); - v3.d(); - } - } - - void drawSphere(){ - for(int i = 0; i < indices.size; i += 4){ - Vertex v1 = vertices.get(indices.get(i)); - Vertex v2 = vertices.get(indices.get(i + 1)); - Vertex v3 = vertices.get(indices.get(i + 2)); - Vertex v4 = vertices.get(indices.get(i + 3)); - - v1.d(); - v2.d(); - v3.d(); - - v3.d(); - v4.d(); - v1.d(); - } - }*/ - - class Vertex{ - Color color = new Color(); - Vec3 normal = new Vec3(); - Vec2 uv = new Vec2(); - Vec3 pos = new Vec3(); - - Vertex copy(){ - Vertex v = new Vertex(); - v.color.set(color); - v.normal.set(normal); - v.uv.set(uv); - v.pos.set(pos); - return v; - } - - public String toString(){ - return pos.toString(); - } - } }