/* * JAME 6.2.1 * http://jame.sourceforge.net * * Copyright 2001, 2016 Andrea Medeghini * * This file is based on code from idx3dIII * Copyright 1999, 2000 Peter Walser * http://www.idx3d.ch/idx3d/idx3d.html * * This file is part of JAME. * * JAME is an application for creating fractals and other graphics artifacts. * * JAME 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. * * JAME 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 JAME. If not, see <http://www.gnu.org/licenses/>. * */ package net.sf.jame.core.media.g3d; import java.util.Enumeration; public class Part extends Solid { java.util.Vector<Triangle> triangles_vector = new java.util.Vector<Triangle>(); java.util.Vector<Vertex> vertices_vector = new java.util.Vector<Vertex>(); Triangle[] triangles; Vertex[] vertices; Material material; private Projector projector; private boolean dirty = false; public int id; public Part(final String name) { super(name); projector = new DefaultProjector(); material = new DefaultMaterial(); } public Part(final String name, final Material material, final Vertex[] vertices, final Triangle[] triangles, final Projector projector) { super(name); this.projector = projector; this.material = material; this.vertices = vertices; this.triangles = triangles; for (final Vertex element : vertices) { this.addVertex(element); } for (final Triangle element : triangles) { this.addTriangle(element); } } public final void addVertex(final Vertex v) { if ((v != null) && (!vertices_vector.contains(v))) { vertices_vector.addElement(v); } dirty = false; } public final void removeVertex(final Vertex v) { vertices_vector.removeElement(v); dirty = false; } public final void addTriangle(final Triangle t) { if ((t != null) && (!triangles_vector.contains(t))) { this.addVertex(t.p1); this.addVertex(t.p2); this.addVertex(t.p3); triangles_vector.addElement(t); } dirty = false; } public final void removeTriangle(final Triangle t) { triangles_vector.removeElement(t); dirty = false; } public final Triangle triangle(final int i) { return (triangles_vector.elementAt(i)); } public final Vertex vertex(final int i) { return (vertices_vector.elementAt(i)); } public final int triangles() { return (triangles_vector.size()); } public final int vertices() { return (vertices_vector.size()); } public final int indexOf(final Triangle t) { return (triangles_vector.indexOf(t)); } public final int indexOf(final Vertex v) { return (vertices_vector.indexOf(v)); } public final void addVertex(final float x, final float y, final float z, final float u, final float v) { final Vertex q = new Vertex(x, y, z, u, v); this.addVertex(q); } public final void addTriangle(final int v1, final int v2, final int v3) { this.addTriangle(vertex(v1), vertex(v2), vertex(v3)); } public final void addTriangle(final boolean single, final int v1, final int v2, final int v3) { this.addTriangle(single, vertex(v1), vertex(v2), vertex(v3)); } public final void addTriangle(final Vertex a, final Vertex b, final Vertex c) { this.addTriangle(new Triangle(a, b, c)); } public final void addTriangle(final boolean single, final Vertex a, final Vertex b, final Vertex c) { this.addTriangle(new Triangle(single, a, b, c)); } public final Vector min() { if (vertices.length == 0) { return (new Vector(0, 0, 0)); } float minx = vertices[0].p.x; float miny = vertices[0].p.y; float minz = vertices[0].p.z; for (int i = 1; i < vertices.length; i++) { if (vertices[i].p.x < minx) { minx = vertices[i].p.x; } if (vertices[i].p.y < miny) { miny = vertices[i].p.y; } if (vertices[i].p.z < minz) { minz = vertices[i].p.z; } } return (new Vector(minx, miny, minz)); } public final Vector max() { if (vertices.length == 0) { return (new Vector(0, 0, 0)); } float maxx = vertices[0].p.x; float maxy = vertices[0].p.y; float maxz = vertices[0].p.z; for (int i = 1; i < vertices.length; i++) { if (vertices[i].p.x > maxx) { maxx = vertices[i].p.x; } if (vertices[i].p.y > maxy) { maxy = vertices[i].p.y; } if (vertices[i].p.z > maxz) { maxz = vertices[i].p.z; } } return (new Vector(maxx, maxy, maxz)); } public final Vector getDimension() { final Vector min = min(); final Vector max = max(); return (new Vector(max.x - min.x, max.y - min.y, max.z - min.z)); } public final Vector getCenter() { final Vector min = min(); final Vector max = max(); return (new Vector((max.x + min.x) / 2, (max.y + min.y) / 2, (max.z + min.z) / 2)); } public final void inverti() { if (!dirty) { for (int i = 0; i < triangles(); i++) { triangle(i).inverti(); } } } @Override final void project(Matrix ml, Matrix mt, final float vx, final float vy, final float vz) { mt = Matrix.multiply(mt, mp); ml = Matrix.multiply(ml, mr); for (final Vertex element : vertices) { element.project(ml, mt, vx, vy, vz); } for (final Triangle element : triangles) { element.project(ml, mt, vx, vy, vz); } } @Override final void rebuild() { if (!dirty) { vertices = new Vertex[vertices_vector.size()]; for (int i = 0; i < vertices.length; i++) { vertices[i] = vertices_vector.elementAt(i); } triangles = new Triangle[triangles_vector.size()]; for (int i = 0; i < triangles.length; i++) { triangles[i] = triangles_vector.elementAt(i); } if (projector != null) { projector.project(this); } for (final Vertex element : vertices) { element.parent = this; element.build(); } for (final Triangle element : triangles) { element.parent = this; element.build(); } dirty = true; } } @Override public final void transform(final Matrix mt) { if (!dirty) { for (int i = 0; i < vertices(); i++) { vertex(i).transform(mt); } } } public final void detach() { if (dirty) { final Vector center = getCenter(); for (final Vertex element : vertices) { element.q.x -= center.x; element.q.y -= center.y; element.q.z -= center.z; } shift(center.x, center.y, center.z); } } @Override public String toString() { final StringBuffer s = new StringBuffer("part: " + name + "\r\n"); s.append("parent: " + ((parent != null) ? parent.name : "unknow") + "\r\n"); for (int i = 0; i < triangles(); i++) { s.append(triangle(i).toString()); } return (s.toString()); } public final void initid(final int id) { this.id = id; for (int i = 0; i < triangles(); i++) { triangle(i).id = (id << 24) | (i & 0xFFFFFF); } } public final void setMaterial(final Material material) { this.material = material; } public final void setProjector(final Projector projector) { if (!dirty) { this.projector = projector; } } public final void removeDuplicatedVertices() { final java.util.Vector<Edge> edgesToCollapse = new java.util.Vector<Edge>(); for (int i = 0; i < vertices(); i++) { for (int j = i + 1; j < vertices(); j++) { if (vertex(i).equals(vertex(j), 0.0001f)) { edgesToCollapse.addElement(new Edge(vertex(i), vertex(j))); } } } final Enumeration<Edge> edges = edgesToCollapse.elements(); while (edges.hasMoreElements()) { edgeCollapse(edges.nextElement()); } removeDegeneratedTriangles(); } public final void removeDegeneratedTriangles() { for (int i = 0; i < triangles(); i++) { if (triangle(i).degenerated()) { removeTriangle(triangle(i)); } } dirty = false; } private void edgeCollapse(final Edge edge) { final Vertex a = edge.start(); final Vertex b = edge.end(); Triangle t; for (int i = 0; i < triangles(); i++) { t = triangle(i); if (t.p1 == b) { t.p1 = a; } if (t.p2 == b) { t.p2 = a; } if (t.p3 == b) { t.p3 = a; } } removeVertex(b); } public final Part copy() { final Part s = new Part(name + " copy"); Triangle t; for (int i = 0; i < vertices(); i++) { s.addVertex(new Vertex(vertex(i))); } for (int i = 0; i < triangles(); i++) { t = triangle(i); final int p1 = this.indexOf(t.p1); final int p2 = this.indexOf(t.p2); final int p3 = this.indexOf(t.p3); s.addTriangle(t.single, p1, p2, p3); } return s; } public final void join(final Part s) { final int vertices = vertices(); Triangle t; for (int i = 0; i < s.vertices(); i++) { this.addVertex(new Vertex(s.vertex(i))); } for (int i = 0; i < s.triangles(); i++) { t = s.triangle(i); final int p1 = s.indexOf(t.p1) + vertices; final int p2 = s.indexOf(t.p2) + vertices; final int p3 = s.indexOf(t.p3) + vertices; this.addTriangle(t.single, p1, p2, p3); } } }