/* * Copyright 2016 Nathan Howard * * This file is part of OpenGrave * * OpenGrave is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenGrave is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenGrave. If not, see <http://www.gnu.org/licenses/>. */ package com.opengrave.og.terrain; import java.util.ArrayList; import com.opengrave.common.pathing.*; import com.opengrave.common.world.CommonLocation; import com.opengrave.og.Util; import com.opengrave.og.base.*; import com.opengrave.og.engine.Location; import com.opengrave.og.engine.Node; import com.opengrave.og.light.Shadow; import com.opengrave.og.resources.RenderStyle; import com.opengrave.og.util.Matrix4f; public class TerrainPolygonMesh extends Node { Location l = new Location(); RenderablePoints points = new RenderablePoints(); RenderableLines lines = new RenderableLines(); Renderable3DStatic tris = new Renderable3DStatic(); private PathingArea lastMouseOver = null; private NavigationMesh lastMesh; private Path lastPath; private TerrainWorld world; @Override public Matrix4f getMatrix() { return Util.createMatrixFor(l, null, null, context); } public void setFrom(NavigationMesh mesh, TerrainWorld world) { this.world = world; if (mesh == lastMesh) { if (!mesh.changed) { return; } } lastMesh = mesh; points.clearPoints(); lines.clearLines(); tris.clearMesh(); for (PathingArea pgon : mesh.polygonList) { addPolygonMesh(pgon, 0f, 1f, 0f, 1f); for (Polygon minigon : pgon.getAllInnerPoly()) { addPolygonMesh(minigon, 1f, 1f, 0f, 1f); } } for (PathingEdge edge : mesh.joins) { for (Line line : edge.getInnerLines()) { addPoint(line.getPoint(0), 1f, 0f, 0f, 1f); addPoint(line.getPoint(1), 1f, 0f, 0f, 1f); } } for (Point p : mesh.pointList) { addPoint(p, 0f, 0f, 1f, 1f); } if (lastMouseOver != null) { addPolygon(lastMouseOver, 0f, 1f, 0f, 0.7f); for (PathingEdge edge : mesh.getEdges(lastMouseOver)) { addLine(edge.getLine(), 1f, 0f, 0f, 0.5f); addPolygon(edge.getNeighbour(lastMouseOver), 1f, 1f, 0f, 0.7f); } } if (lastPath != null) { for (Line line : lastPath.getLines()) { addLine(line, 0f, 0f, 1f, 1f); } } mesh.changed = false; world = null; } private float getZFor(Point p) { return world.getHeightAt(locationFor(p, p.getZ())); } private Location locationFor(Point p, int layer) { Location l = new Location(); l.setFullX((float) p.getX()); l.setFullY((float) p.getY()); l.setLayer(layer); return l; } private void addPoint(Point p, float r, float g, float b, float a) { points.addVertex(new VertexPoint((float) p.getX(), (float) p.getY(), getZFor(p), r, g, b, a, 3f, 0)); } private void addPolygonMesh(Polygon pgon, float f, float g, float h, float i) { for (Line line : pgon.getLines()) { addLine(line, f, g, h, i); } } private void addPolygon(PathingArea pgon, float r, float g, float b, float a) { ArrayList<Point> points = pgon.getPoints(); for (int i = 1; i < points.size() - 1; i++) { addTriPoint(points.get(0), r, g, b, a, pgon.getLayer()); addTriPoint(points.get(i), r, g, b, a, pgon.getLayer()); addTriPoint(points.get(i + 1), r, g, b, a, pgon.getLayer()); } } private void addTriPoint(Point point, float r, float g, float b, float a, int layer) { Vertex3D v = new Vertex3D(); v.x = (float) point.getX(); v.y = (float) point.getY(); v.z = getZFor(point); // v.r = r; // v.g = g; // v.b = b; // v.a = a; tris.addVertex(v); } public void addLine(Line line, float r, float g, float b, float a) { Point p1 = line.getPoint(0); Point p2 = line.getPoint(1); VertexPoint vp1 = new VertexPoint((float) p1.getX(), (float) p1.getY(), getZFor(p1), r, g, b, a, 3f, 0); VertexPoint vp2 = new VertexPoint((float) p2.getX(), (float) p2.getY(), getZFor(p2), r, g, b, a, 3f, 0); lines.addVertex(vp1); lines.addVertex(vp2); } @Override public void doUpdate(float delta) { lines.setContext(context); points.setContext(context); tris.setContext(context); } @Override public void doRender(Matrix4f parent) { points.render(parent, RenderStyle.NORMAL); lines.render(parent, RenderStyle.NORMAL); } @Override public void doRenderShadows(Matrix4f parent, Shadow shadow) { } @Override public void doRenderForPicking(Matrix4f parent) { } @Override public void doRenderSemiTransparent(Matrix4f parent) { tris.render(parent, RenderStyle.NORMAL); } public void hide(boolean b) { points.visible = !b; lines.visible = !b; tris.visible = !b; } public void setMouseLocation(CommonLocation location) { if (lastMesh != null) { if (location == null) { lastMouseOver = null; lastMesh.changed = true; return; } double x = location.getTileX() + location.getMinorX(); double y = location.getTileY() + location.getMinorY(); Point p = new Point(x, y, location.getLayer()); ArrayList<PathingArea> list = lastMesh.getPolygonsAt(p); if (list.size() > 0) { lastMouseOver = list.get(0); lastMesh.changed = true; } else { lastMouseOver = null; } } } public void addPath(Path path) { lastPath = path; } }