Massively optimise .obj loading

pull/50/head v1.17.3
James Ball 2022-02-27 23:53:35 +00:00
rodzic 431eed7004
commit 884e51f7eb
4 zmienionych plików z 43 dodań i 43 usunięć

Wyświetl plik

@ -6,7 +6,7 @@
<groupId>sh.ball</groupId> <groupId>sh.ball</groupId>
<artifactId>osci-render</artifactId> <artifactId>osci-render</artifactId>
<version>1.17.2</version> <version>1.17.3</version>
<name>osci-render</name> <name>osci-render</name>

Wyświetl plik

@ -21,6 +21,7 @@ public class Camera {
private static final double VERTEX_VALUE_THRESHOLD = 1; private static final double VERTEX_VALUE_THRESHOLD = 1;
private static final double CAMERA_MOVE_INCREMENT = -0.1; private static final double CAMERA_MOVE_INCREMENT = -0.1;
private static final int SAMPLE_RENDER_SAMPLES = 50; private static final int SAMPLE_RENDER_SAMPLES = 50;
private static final int VERTEX_SAMPLES = 1000;
private double focalLength; private double focalLength;
private Vector3 pos; private Vector3 pos;
@ -35,17 +36,7 @@ public class Camera {
} }
public List<Shape> draw(WorldObject worldObject) { public List<Shape> draw(WorldObject worldObject) {
return getFrame(getProjectedVertices(worldObject), worldObject.getVertexPath()); return getFrame(worldObject.getVertexPath());
}
public Map<Vector3, Vector2> getProjectedVertices(WorldObject worldObject) {
Map<Vector3, Vector2> projectionMap = new HashMap<>();
for (Vector3 vertex : worldObject.getVertices()) {
projectionMap.put(vertex, project(vertex));
}
return projectionMap;
} }
// Automatically finds the correct Z position to use to view the world object properly. // Automatically finds the correct Z position to use to view the world object properly.
@ -70,7 +61,9 @@ public class Camera {
List<Vector2> vertices = new ArrayList<>(); List<Vector2> vertices = new ArrayList<>();
for (int i = 0; i < SAMPLE_RENDER_SAMPLES - 1; i++) { for (int i = 0; i < SAMPLE_RENDER_SAMPLES - 1; i++) {
vertices.addAll(getProjectedVertices(clone).values()); for (int j = 0; j < Math.min(VERTEX_SAMPLES, clone.numVertices()); j++) {
vertices.add(project(clone.getVertex(j)));
}
clone.rotate(rotation); clone.rotate(rotation);
} }
@ -106,13 +99,13 @@ public class Camera {
); );
} }
public List<Shape> getFrame(Map<Vector3, Vector2> projectionMap, List<Vector3> vertexPath) { public List<Shape> getFrame(List<Vector3> vertexPath) {
List<Shape> lines = new ArrayList<>(); List<Shape> lines = new ArrayList<>();
for (int i = 0; i < vertexPath.size(); i += 2) { for (int i = 0; i < vertexPath.size(); i += 2) {
lines.add(new Line( lines.add(new Line(
projectionMap.get(vertexPath.get(i)), project(vertexPath.get(i)),
projectionMap.get(vertexPath.get(i + 1)) project(vertexPath.get(i + 1))
)); ));
} }

Wyświetl plik

@ -35,53 +35,61 @@ public final class Vector3 {
public Vector3 add(Vector3 other) { public Vector3 add(Vector3 other) {
return new Vector3( return new Vector3(
getX() + other.getX(), x + other.x,
getY() + other.getY(), y + other.y,
getZ() + other.getZ() z + other.z
); );
} }
public Vector3 scale(double factor) { public Vector3 scale(double factor) {
return new Vector3( return new Vector3(
getX() * factor, x * factor,
getY() * factor, y * factor,
getZ() * factor z * factor
); );
} }
public Vector3 rotate(Vector3 rotation) { public Vector3 rotate(Vector3 rotation) {
return rotateX(rotation.getX()) return rotateX(rotation.x)
.rotateY(rotation.getY()) .rotateY(rotation.y)
.rotateZ(rotation.getZ()); .rotateZ(rotation.z);
} }
public Vector3 rotateX(double theta) { public Vector3 rotateX(double theta) {
double cos = Math.cos(theta);
double sin = Math.sin(theta);
return new Vector3( return new Vector3(
getX(), x,
Math.cos(theta) * getY() - Math.sin(theta) * getZ(), cos * y - sin * z,
Math.sin(theta) * getY() + Math.cos(theta) * getZ() sin * y + cos * z
); );
} }
public Vector3 rotateY(double theta) { public Vector3 rotateY(double theta) {
double cos = Math.cos(theta);
double sin = Math.sin(theta);
return new Vector3( return new Vector3(
Math.cos(theta) * getX() + Math.sin(theta) * getZ(), cos * x + sin * z,
getY(), y,
-Math.sin(theta) * getX() + Math.cos(theta) * getZ() -sin * x + cos * z
); );
} }
public Vector3 rotateZ(double theta) { public Vector3 rotateZ(double theta) {
double cos = Math.cos(theta);
double sin = Math.sin(theta);
return new Vector3( return new Vector3(
Math.cos(theta) * getX() - Math.sin(theta) * getY(), cos * x - sin * y,
Math.sin(theta) * getX() + Math.cos(theta) * getY(), sin * x + cos * y,
getZ() z
); );
} }
// TODO: Is this correctly used?!
public double distance(Vector3 vector) { public double distance(Vector3 vector) {
return Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2) + Math.pow(vector.z, 2)); double xDiff = x - vector.x;
double yDiff = y - vector.y;
double zDiff = z - vector.z;
return Math.sqrt(xDiff * xDiff + yDiff * yDiff + zDiff * zDiff);
} }
public static Vector3 meanPoint(List<Vector3> points) { public static Vector3 meanPoint(List<Vector3> points) {

Wyświetl plik

@ -76,6 +76,7 @@ public class WorldObject {
// Chinese Postman can only be performed on connected graphs, so iterate over all connected // Chinese Postman can only be performed on connected graphs, so iterate over all connected
// sub-graphs. // sub-graphs.
// TODO: parallelize?
for (Set<Vector3> vertices : inspector.connectedSets()) { for (Set<Vector3> vertices : inspector.connectedSets()) {
AsSubgraph<Vector3, DefaultWeightedEdge> subgraph = new AsSubgraph<>(graph, vertices); AsSubgraph<Vector3, DefaultWeightedEdge> subgraph = new AsSubgraph<>(graph, vertices);
ChinesePostman<Vector3, DefaultWeightedEdge> cp = new ChinesePostman<>(); ChinesePostman<Vector3, DefaultWeightedEdge> cp = new ChinesePostman<>();
@ -108,14 +109,12 @@ public class WorldObject {
position = new Vector3(); position = new Vector3();
} }
public List<Vector3> getVertices() { public Vector3 getVertex(int i) {
List<Vector3> newVertices = new ArrayList<>(); return objVertices.get(i).rotate(rotation).add(position);
for (Vector3 vertex : objVertices) {
newVertices.add(vertex.rotate(rotation).add(position));
} }
return newVertices; public int numVertices() {
return objVertices.size();
} }
private Set<Line3D> loadFromInput(InputStream input) { private Set<Line3D> loadFromInput(InputStream input) {