public void run() { for (final Geometry geometry : listGeoms) { LodGenerator lODGenerator = new LodGenerator(geometry); final VertexBuffer[] lods = lODGenerator.computeLods(method, value); enqueue(new Callable<Void>() { public Void call() throws Exception { geometry.getMesh().setLodLevels(lods); lodLevel = 0; if (geometry.getMesh().getNumLodLevels() > ll) { lodLevel = ll; } geometry.setLodLevel(lodLevel); hudText.setText(computeNbTri() + " tris"); return null; } }); } } });
private void replaceVertexID(Triangle triangle, int oldID, int newID, Vertex dst) { dst.triangles.add(triangle); // NOTE: triangle is not removed from src. This is implementation specific optimization. // Its up to the compiler to unroll everything. for (int i = 0; i < 3; i++) { if (triangle.vertexId[i] == oldID) { for (int n = 0; n < 3; n++) { if (i != n) { // This is implementation specific optimization to remove following line. //removeEdge(triangle.vertex[i], new Edge(triangle.vertex[n])); removeEdge(triangle.vertex[n], new Edge(triangle.vertex[i])); addEdge(triangle.vertex[n], new Edge(dst)); addEdge(dst, new Edge(triangle.vertex[n])); } } triangle.vertex[i] = dst; triangle.vertexId[i] = newID; return; } } // assert (false); }
private boolean assertValidMesh() { // Allows to find bugs in collapsing. for (Vertex vertex : collapseCostSet) { assertValidVertex(vertex); } return true; }
private void build() { BoundingSphere bs = new BoundingSphere(); bs.computeFromPoints(mesh.getFloatBuffer(VertexBuffer.Type.Position)); meshBoundingSphereRadius = bs.getRadius(); List<Vertex> vertexLookup = new ArrayList<Vertex>(); initialize(); gatherVertexData(mesh, vertexLookup); gatherIndexData(mesh, vertexLookup); computeCosts(); // assert (assertValidMesh()); }
private void addTriangleToEdges(Triangle tri) { if (bestQuality) { Triangle duplicate = getDuplicate(tri); if (duplicate != null) { if (!tri.isRemoved) { tri.isRemoved = true; indexCount -= 3; logger.log(Level.FINE, "duplicate triangle found{0}{1} It will be excluded from Lod level calculations.", new Object[]{tri, duplicate}); } } } for (int i = 0; i < 3; i++) { tri.vertex[i].triangles.add(tri); } for (int i = 0; i < 3; i++) { for (int n = 0; n < 3; n++) { if (i != n) { addEdge(tri.vertex[i], new Edge(tri.vertex[n])); } } } }
lods[0] = mesh.getBuffer(VertexBuffer.Type.Index); for (int curLod = 0; curLod < lodCount; curLod++) { int neededTriCount = calcLodTriCount(reductionMethod, reductionValues[curLod]); while (neededTriCount < tricount) { Collections.sort(collapseCostSet, collapseComparator); Vertex v = it.next(); if (v.collapseCost < collapseCostLimit) { if (!collapse(v)) { logger.log(Level.FINE, "Couldn''t collapse vertex{0}", v.index); if (!outSkipped) { lastBakeVertexCount = tricount; lods[curLod + 1] = makeLod(mesh); numBakedLods++;
/** * Computes the lods and bake them into the mesh<br> * * This method must be fed with the reduction method * {@link TriangleReductionMethod} and a list of reduction values.<br> for * each value a lod will be generated. <p> <strong>Important note :</strong> * some meshes cannot be decimated, so the result of this method can vary * depending of the given mesh. Also the reduction values are indicative and * the produces mesh will not always meet the required reduction. * * @param reductionMethod the reduction method to use * @param reductionValues the reduction value to use for each lod level. */ public void bakeLods(TriangleReductionMethod reductionMethod, float... reductionValues) { mesh.setLodLevels(computeLods(reductionMethod, reductionValues)); }
/** * Construct a LodGenerator for the given mesh * * @param mesh the mesh to consider to generate de Lods. */ public LodGenerator(Mesh mesh) { this.mesh = mesh; build(); }
private void computeVertexCollapseCost(Vertex vertex) { vertex.collapseCost = UNINITIALIZED_COLLAPSE_COST; // assert (!vertex.edges.isEmpty()); for (Edge edge : vertex.edges) { edge.collapseCost = computeEdgeCollapseCost(vertex, edge); // assert (edge.collapseCost != UNINITIALIZED_COLLAPSE_COST); if (vertex.collapseCost > edge.collapseCost) { vertex.collapseCost = edge.collapseCost; vertex.collapseTo = edge.destination; } } // assert (vertex.collapseCost != UNINITIALIZED_COLLAPSE_COST); collapseCostSet.add(vertex); }
private void computeCosts() { collapseCostSet.clear(); for (Vertex vertex : vertexList) { if (!vertex.edges.isEmpty()) { computeVertexCollapseCost(vertex); } else { logger.log(Level.FINE, "Found isolated vertex {0} It will be excluded from Lod level calculations.", vertex); } } // assert (vertexList.size() == collapseCostSet.size()); // assert (checkCosts()); }
private void build() { BoundingSphere bs = new BoundingSphere(); bs.computeFromPoints(mesh.getFloatBuffer(VertexBuffer.Type.Position)); meshBoundingSphereRadius = bs.getRadius(); List<Vertex> vertexLookup = new ArrayList<Vertex>(); initialize(); gatherVertexData(mesh, vertexLookup); gatherIndexData(mesh, vertexLookup); computeCosts(); // assert (assertValidMesh()); }
lods[0] = mesh.getBuffer(VertexBuffer.Type.Index); for (int curLod = 0; curLod < lodCount; curLod++) { int neededTriCount = calcLodTriCount(reductionMethod, reductionValues[curLod]); while (neededTriCount < tricount) { Collections.sort(collapseCostSet, collapseComparator); Vertex v = it.next(); if (v.collapseCost < collapseCostLimit) { if (!collapse(v)) { logger.log(Level.FINE, "Couldn''t collapse vertex{0}", v.index); if (!outSkipped) { lastBakeVertexCount = tricount; lods[curLod + 1] = makeLod(mesh); numBakedLods++;
private void addTriangleToEdges(Triangle tri) { if (bestQuality) { Triangle duplicate = getDuplicate(tri); if (duplicate != null) { if (!tri.isRemoved) { tri.isRemoved = true; indexCount -= 3; logger.log(Level.FINE, "duplicate triangle found{0}{1} It will be excluded from Lod level calculations.", new Object[]{tri, duplicate}); } } } for (int i = 0; i < 3; i++) { tri.vertex[i].triangles.add(tri); } for (int i = 0; i < 3; i++) { for (int n = 0; n < 3; n++) { if (i != n) { addEdge(tri.vertex[i], new Edge(tri.vertex[n])); } } } }
/** * Computes the lods and bake them into the mesh<br> * * This method must be fed with the reduction method * {@link TriangleReductionMethod} and a list of reduction values.<br> for * each value a lod will be generated. <p> <strong>Important note :</strong> * some meshes cannot be decimated, so the result of this method can vary * depending of the given mesh. Also the reduction values are indicative and * the produces mesh will not always meet the required reduction. * * @param reductionMethod the reduction method to use * @param reductionValues the reduction value to use for each lod level. */ public void bakeLods(TriangleReductionMethod reductionMethod, float... reductionValues) { mesh.setLodLevels(computeLods(reductionMethod, reductionValues)); }
/** * Construct a LodGenerator for the given geometry * * @param geom the geometry to consider to generate de Lods. */ public LodGenerator(Geometry geom) { mesh = geom.getMesh(); build(); }
private void updateVertexCollapseCost(Vertex vertex) { float collapseCost = UNINITIALIZED_COLLAPSE_COST; Vertex collapseTo = null; for (Edge edge : vertex.edges) { edge.collapseCost = computeEdgeCollapseCost(vertex, edge); // assert (edge.collapseCost != UNINITIALIZED_COLLAPSE_COST); if (collapseCost > edge.collapseCost) { collapseCost = edge.collapseCost; collapseTo = edge.destination; } } if (collapseCost != vertex.collapseCost || vertex.collapseTo != collapseTo) { // assert (vertex.collapseTo != null); // assert (find(collapseCostSet, vertex)); collapseCostSet.remove(vertex); if (collapseCost != UNINITIALIZED_COLLAPSE_COST) { vertex.collapseCost = collapseCost; vertex.collapseTo = collapseTo; collapseCostSet.add(vertex); } } // assert (vertex.collapseCost != UNINITIALIZED_COLLAPSE_COST); }
private void computeCosts() { collapseCostSet.clear(); for (Vertex vertex : vertexList) { if (!vertex.edges.isEmpty()) { computeVertexCollapseCost(vertex); } else { logger.log(Level.FINE, "Found isolated vertex {0} It will be excluded from Lod level calculations.", vertex); } } // assert (vertexList.size() == collapseCostSet.size()); // assert (checkCosts()); }
private void replaceVertexID(Triangle triangle, int oldID, int newID, Vertex dst) { dst.triangles.add(triangle); // NOTE: triangle is not removed from src. This is implementation specific optimization. // Its up to the compiler to unroll everything. for (int i = 0; i < 3; i++) { if (triangle.vertexId[i] == oldID) { for (int n = 0; n < 3; n++) { if (i != n) { // This is implementation specific optimization to remove following line. //removeEdge(triangle.vertex[i], new Edge(triangle.vertex[n])); removeEdge(triangle.vertex[n], new Edge(triangle.vertex[i])); addEdge(triangle.vertex[n], new Edge(dst)); addEdge(dst, new Edge(triangle.vertex[n])); } } triangle.vertex[i] = dst; triangle.vertexId[i] = newID; return; } } // assert (false); }