Skip to content

Commit cba83c8

Browse files
committed
obj loading in a3d now works
1 parent 9ef9587 commit cba83c8

4 files changed

Lines changed: 80 additions & 22 deletions

File tree

android/core/src/processing/core/PApplet.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3006,13 +3006,21 @@ public void run() {
30063006

30073007
/**
30083008
* Load a geometry from a file as a PShape (either an SVG or OBJ file).
3009-
*/
3009+
*/
30103010
public PShape loadShape(String filename) {
3011+
return loadShape(filename, STATIC);
3012+
}
3013+
3014+
3015+
/**
3016+
* Load a geometry from a file as a PShape (either an SVG or OBJ file).
3017+
*/
3018+
public PShape loadShape(String filename, int mode) {
30113019
if (filename.toLowerCase().endsWith(".svg")) {
30123020
return new PShapeSVG(this, filename);
30133021
} else if (filename.toLowerCase().endsWith(".obj")) {
30143022
if (g instanceof PGraphicsAndroid3D) {
3015-
return new PShape3D(this, filename);
3023+
return new PShape3D(this, filename, mode);
30163024
} else {
30173025
throw new RuntimeException("OBJ files can be loaded only when using the A3D renderer.");
30183026
}
@@ -7299,9 +7307,10 @@ public void noLights() {
72997307
g.noLights();
73007308
}
73017309

7310+
73027311
public void resetLights() {
7303-
g.resetLights();
7304-
}
7312+
g.resetLights();
7313+
}
73057314

73067315

73077316
public void ambientLight(float red, float green, float blue) {

android/core/src/processing/core/PGraphicsAndroid3D.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@
5353
/*
5454
* Android 3D renderer implemented with pure OpenGL ES 1.0/1.1
5555
* By Andres Colubri
56-
*
56+
*
57+
* TODO: Comment A3D, PShape3D and PTexture,
58+
* TODO: Check lighting and materials, specially in PShape3D..
59+
* TODO: Revise triangulator (issues are particularly apparent when tesselating SVG shapes).
5760
*/
5861
public class PGraphicsAndroid3D extends PGraphics {
5962
public SurfaceHolder holder;
@@ -3563,6 +3566,7 @@ public void lights()
35633566

35643567
/**
35653568
* Switches off all lights, but keeps lighting enabled..
3569+
* TODO: discuss if this method is needed.
35663570
*/
35673571
public void resetLights() {
35683572
for (int i = 0; i < lightCount; i++) glLightDisable(i);

android/core/src/processing/core/PShape3D.java

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ public PShape3D(PApplet parent, int numVert) {
9696
}
9797

9898

99-
public PShape3D(PApplet parent, String filename) {
99+
// TODO: Properly debug OBJ loading. Particuarly when loading textured materials.
100+
public PShape3D(PApplet parent, String filename, int mode) {
100101
this.parent = parent;
101102
a3d = (PGraphicsAndroid3D)parent.g;
102103

@@ -118,8 +119,20 @@ public PShape3D(PApplet parent, String filename) {
118119
if (reader == null) {
119120
throw new RuntimeException("PShape3D: Cannot read source file");
120121
}
122+
123+
// Setting parameters.
124+
Parameters params = PShape3D.newParameters(TRIANGLES, mode);
125+
setParameters(params);
126+
121127
parseOBJ(reader, vertices, normals, textures, faces, materials);
122128
recordOBJ(vertices, normals, textures, faces, materials);
129+
130+
try {
131+
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
132+
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
133+
} catch (Exception e) {
134+
recreateResourceIdx = -1;
135+
}
123136
}
124137

125138

@@ -1716,9 +1729,11 @@ protected BufferedReader getBufferedReader(String filename) {
17161729
protected void parseOBJ(BufferedReader reader, ArrayList<PVector> vertices, ArrayList<PVector> normals, ArrayList<PVector> textures, ArrayList<OBJFace> faces, ArrayList<OBJMaterial> materials) {
17171730
Hashtable<String, Integer> materialsHash = new Hashtable<String, Integer>();
17181731
int mtlIdxCur = -1;
1732+
boolean readv, readvn, readvt;
17191733
try {
17201734
// Parse the line.
17211735

1736+
readv = readvn = readvt = false;
17221737
String line;
17231738
while ((line = reader.readLine()) != null) {
17241739

@@ -1748,24 +1763,27 @@ protected void parseOBJ(BufferedReader reader, ArrayList<PVector> vertices, Arra
17481763
// vertex
17491764
PVector tmpv = new PVector(Float.valueOf(elements[1]).floatValue(), Float.valueOf(elements[2]).floatValue(), Float.valueOf(elements[3]).floatValue());
17501765
vertices.add(tmpv);
1766+
readv = true;
17511767
} else if (elements[0].equals("vn")) {
17521768
// normal
17531769
PVector tmpn = new PVector(Float.valueOf(elements[1]).floatValue(), Float.valueOf(elements[2]).floatValue(), Float.valueOf(elements[3]).floatValue());
17541770
normals.add(tmpn);
1771+
readvn = true;
17551772
} else if (elements[0].equals("vt")) {
17561773
// uv
17571774
PVector tmpv = new PVector(Float.valueOf(elements[1]).floatValue(), Float.valueOf(elements[2]).floatValue());
17581775
textures.add(tmpv);
1776+
readvt = true;
17591777
} else if (elements[0].equals("o")) {
17601778
// Object name is ignored, for now.
17611779
} else if (elements[0].equals("mtllib")) {
17621780
if (elements[1] != null) {
17631781
parseMTL(getBufferedReader(elements[1]), materials, materialsHash);
17641782
}
17651783
} else if (elements[0].equals("g")) {
1766-
// Grouping is ignored, for now. Groups are automaticallty generated during recording by the triangulator.
1784+
// Grouping is ignored, for now. Groups are automatically generated during recording by the triangulator.
17671785
} else if (elements[0].equals("usemtl")) {
1768-
// Getting material index for the material set for use.
1786+
// Getting index of current active material (will be applied on all subsequent faces)..
17691787
if (elements[1] != null) {
17701788
String mtlname = elements[1];
17711789
if (materialsHash.containsKey(mtlname)) {
@@ -1787,33 +1805,42 @@ protected void parseOBJ(BufferedReader reader, ArrayList<PVector> vertices, Arra
17871805
String[] forder = seg.split("/");
17881806

17891807
if (forder.length > 2) {
1790-
if (forder[0].length() > 0) {
1808+
// Getting vertex and texture and normal indexes.
1809+
if (forder[0].length() > 0 && readv) {
17911810
face.vertIdx.add(Integer.valueOf(forder[0]));
17921811
}
17931812

1794-
if (forder[1].length() > 0) {
1813+
if (forder[1].length() > 0 && readvt) {
17951814
face.texIdx.add(Integer.valueOf(forder[1]));
17961815
}
17971816

1798-
if (forder[2].length() > 0) {
1817+
if (forder[2].length() > 0 && readvn) {
17991818
face.normIdx.add(Integer.valueOf(forder[2]));
1800-
// f.normals.add(getVertex(Integer.valueOf(forder[2])));
18011819
}
18021820
} else if (forder.length > 1) {
1803-
if (forder[0].length() > 0) {
1821+
// Getting vertex and texture/normal indexes.
1822+
if (forder[0].length() > 0 && readv) {
18041823
face.vertIdx.add(Integer.valueOf(forder[0]));
18051824
}
1806-
1825+
18071826
if (forder[1].length() > 0) {
1808-
face.texIdx.add(Integer.valueOf(forder[1]));
1827+
if (readvt) {
1828+
face.texIdx.add(Integer.valueOf(forder[1]));
1829+
} else if (readvn) {
1830+
face.normIdx.add(Integer.valueOf(forder[1]));
1831+
}
1832+
18091833
}
1834+
18101835
} else if (forder.length > 0) {
1811-
if (forder[0].length() > 0) {
1836+
// Getting vertex index only.
1837+
if (forder[0].length() > 0 && readv) {
18121838
face.vertIdx.add(Integer.valueOf(forder[0]));
18131839
}
18141840
}
18151841
} else {
1816-
if (seg.length() > 0) {
1842+
// Getting vertex index only.
1843+
if (seg.length() > 0 && readv) {
18171844
face.vertIdx.add(Integer.valueOf(seg));
18181845
}
18191846
}
@@ -1878,7 +1905,7 @@ protected void parseMTL(BufferedReader reader, ArrayList<OBJMaterial> materials,
18781905
} else if ((elements[0].equals("d") || elements[0].equals("Tr")) && elements.length > 1) {
18791906
// Reading the alpha transparency.
18801907
currentMtl.d = Float.valueOf(elements[1]).floatValue();
1881-
} else if (elements[0].equals("ns") && elements.length > 1) {
1908+
} else if (elements[0].equals("Ns") && elements.length > 1) {
18821909
// The specular component of the Phong shading model
18831910
currentMtl.ns = Float.valueOf(elements[1]).floatValue();
18841911
}
@@ -1893,10 +1920,10 @@ protected void parseMTL(BufferedReader reader, ArrayList<OBJMaterial> materials,
18931920

18941921
protected void recordOBJ(ArrayList<PVector> vertices, ArrayList<PVector> normals, ArrayList<PVector> textures, ArrayList<OBJFace> faces, ArrayList<OBJMaterial> materials) {
18951922
int mtlIdxCur = -1;
1923+
OBJMaterial mtl = null;
18961924
a3d.beginShapeRecorderImpl();
18971925
for (int i = 0; i < faces.size(); i++) {
18981926
OBJFace face = (OBJFace) faces.get(i);
1899-
OBJMaterial mtl = null;
19001927

19011928
// Getting current material.
19021929
if (mtlIdxCur != face.matIdx) {
@@ -1912,6 +1939,8 @@ protected void recordOBJ(ArrayList<PVector> vertices, ArrayList<PVector> normals
19121939
}
19131940

19141941
// Recording current face.
1942+
// TODO: when it is known the obj model only uses triangles or quads as faces,
1943+
// then use these shape types in beginShape(). This will improve triangulation.
19151944
a3d.beginShape();
19161945
for (int j = 0; j < face.vertIdx.size(); j++){
19171946
int vertIdx, normIdx;
@@ -1924,7 +1953,9 @@ protected void recordOBJ(ArrayList<PVector> vertices, ArrayList<PVector> normals
19241953

19251954
if (j < face.normIdx.size()) {
19261955
normIdx = face.normIdx.get(j).intValue() - 1;
1927-
norms = (PVector) normals.get(normIdx);
1956+
if (-1 < normIdx) {
1957+
norms = (PVector) normals.get(normIdx);
1958+
}
19281959
}
19291960

19301961
if (mtl != null && mtl.kdMap != null) {
@@ -1934,7 +1965,9 @@ protected void recordOBJ(ArrayList<PVector> vertices, ArrayList<PVector> normals
19341965

19351966
if (j < face.texIdx.size()) {
19361967
texIdx = face.texIdx.get(j).intValue() - 1;
1937-
tex = (PVector) textures.get(texIdx);
1968+
if (-1 < texIdx) {
1969+
tex = (PVector) textures.get(texIdx);
1970+
}
19381971
}
19391972

19401973
a3d.texture(mtl.kdMap);
@@ -1956,6 +1989,16 @@ protected void recordOBJ(ArrayList<PVector> vertices, ArrayList<PVector> normals
19561989
}
19571990
a3d.endShape(CLOSE);
19581991
}
1992+
1993+
// Allocate space for the geometry that the triangulator has generated from the OBJ model.
1994+
createModel(a3d.recordedVertices.size());
1995+
initGroups();
1996+
updateElement = -1;
1997+
1998+
width = height = depth = 0;
1999+
xmin = ymin = zmin = 10000;
2000+
xmax = ymax = zmax = -10000;
2001+
19592002
a3d.endShapeRecorderImpl(this);
19602003
}
19612004

android/core/src/processing/core/PTexture.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
/**
3636
* This class adds an opengl texture to a PImage object.
3737
* By Andres Colubri
38-
*
38+
* TODO: Finish integration with PImage
39+
* TODO: Revise updating mechanism (what happens when the pixels change in the PImage, etc).
40+
* TODO: Find alternative for FOBs
3941
*/
4042
@SuppressWarnings("unused")
4143
public class PTexture implements PConstants {

0 commit comments

Comments
 (0)