@@ -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
0 commit comments