1+ package model ;
2+
3+ import java .io .BufferedReader ;
4+ import java .io .FileReader ;
5+ import java .util .ArrayList ;
6+ import java .util .List ;
7+
8+ public class Model {
9+ private final ArrayList <float []> vertexCoords ;
10+ private final ArrayList <float []> normalCoords ;
11+ private final ArrayList <float []> texCoords ;
12+ private final List <Integer > vertexIndices ;
13+ private final List <Integer > textureIndices ;
14+ private final List <Integer > normalIndices ;
15+ private final ArrayList <int []> Vindices ;
16+ private final ArrayList <int []> Nindices ;
17+ private final ArrayList <int []> Tindices ;
18+ private final String filePath ;
19+ public float minCoord = Float .MAX_VALUE ;
20+ public float maxCoord = -Float .MAX_VALUE ;
21+
22+ public Model (String filePath ) {
23+ this .filePath = filePath ;
24+ normalIndices = new ArrayList <>();
25+ textureIndices = new ArrayList <>();
26+ vertexIndices = new ArrayList <>();
27+ texCoords = new ArrayList <>();
28+ normalCoords = new ArrayList <>();
29+ vertexCoords = new ArrayList <>();
30+ // load data AFTER instantiating the fields
31+ loadData ();
32+ Vindices = new ArrayList <>();
33+ Nindices = new ArrayList <>();
34+ Tindices = new ArrayList <>();
35+ organizeIndices ();
36+ }
37+
38+ public void printFaces () {
39+ for (int i = 0 ; i < Vindices .size (); i ++) {
40+ for (int j = 0 ; j < 3 ; j ++) {
41+ System .out .print (Vindices .get (i )[j ]);
42+ if (!Tindices .isEmpty ())
43+ System .out .print ("/" + Tindices .get (i )[j ]);
44+ if (!Nindices .isEmpty ())
45+ System .out .print ("/" + Nindices .get (i )[j ]);
46+ System .out .print (" " );
47+ }
48+ System .out .println ();
49+ }
50+ }
51+
52+ private void organizeIndices () { // inserting data into arrays of 3 rather than having everything in one array
53+ if (vertexIndices .size () % 3 == 0 ) {
54+ for (int i = 0 ; i < vertexIndices .size (); i ++) {
55+ Vindices .add (new int [] { vertexIndices .get (i ++), vertexIndices .get (i ++), vertexIndices .get (i ) });
56+ if (!normalIndices .isEmpty ())
57+ Nindices .add (
58+ new int [] { normalIndices .get (i - 2 ), normalIndices .get (i - 1 ), normalIndices .get (i ) });
59+ if (!textureIndices .isEmpty ())
60+ Tindices .add (
61+ new int [] { textureIndices .get (i - 2 ), textureIndices .get (i - 1 ), textureIndices .get (i ) });
62+ }
63+ } else {
64+ System .out .println ("Critical error : faces not divisible by 3" );
65+ }
66+ }
67+
68+ public boolean hasTextureCoords () {
69+ return !Tindices .isEmpty ();
70+ }
71+
72+ public boolean hasNormalCoords () {
73+ return !Nindices .isEmpty ();
74+ }
75+
76+ public float [] getVertexCoords (int idx ) {
77+ return vertexCoords .get (idx );
78+ }
79+
80+ public float [] getTexCoords (int idx ) {
81+ return texCoords .get (idx );
82+ }
83+
84+ public float [] getNormalCoords (int idx ) {
85+ return normalCoords .get (idx );
86+ }
87+
88+ public int [] getVertexIndices (int idx ) {
89+ return Vindices .get (idx );
90+ }
91+
92+ public int [] getNormalIndices (int idx ) {
93+ return Nindices .get (idx );
94+ }
95+
96+ public int [] getTextureIndices (int idx ) {
97+ return Tindices .get (idx );
98+ }
99+
100+ public int nVerts () {
101+ return vertexCoords .size ();
102+ }
103+
104+ public int nNormals () {
105+ return normalCoords .size ();
106+ }
107+
108+ public int nTextures () {
109+ return texCoords .size ();
110+ }
111+
112+ public int nFaces () {
113+ return Vindices .size ();
114+ }
115+
116+ private void loadData () {
117+ try {
118+ FileReader f = new FileReader (filePath );
119+ BufferedReader reader = new BufferedReader (f );
120+ String Line ;
121+ String [] P ;
122+ while ((Line = reader .readLine ()) != null ) {
123+ P = Line .split ("\\ s+" );
124+
125+ if (P .length == 0 ) {
126+ continue ;
127+ }
128+
129+ if (P [0 ].equals ("v" )) {
130+ float x = Float .parseFloat (P [1 ]);
131+ float y = Float .parseFloat (P [2 ]);
132+ float z = Float .parseFloat (P [3 ]);
133+ float minCandidate = Math .min (x , Math .min (y , z ));
134+ minCoord = Math .min (minCoord , minCandidate );
135+ float maxCandidate = Math .max (x , Math .max (y , z ));
136+ maxCoord = Math .max (maxCoord , maxCandidate );
137+ vertexCoords .add (new float [] { x , y , z });
138+ }
139+ if (P [0 ].equals ("vn" )) {
140+ float x = Float .parseFloat (P [1 ]);
141+ float y = Float .parseFloat (P [2 ]);
142+ float z = Float .parseFloat (P [3 ]);
143+ float [] Vs = { x , y , z };
144+ normalCoords .add (Vs );
145+ }
146+ if (P [0 ].equals ("vt" )) {
147+ float x = Float .parseFloat (P [1 ]);
148+ float y = Float .parseFloat (P [2 ]);
149+ float z = Float .parseFloat (P [3 ]);
150+ float [] Vs = { x , y , z };
151+ texCoords .add (Vs );
152+ }
153+ String [] parts ;
154+
155+ if (P [0 ].equals ("f" )) {
156+ // TODO bug fixing : as far as I'm aware this condition is unnecessary,
157+ // and can miss faces in some formats. Check with team.
158+ if (true ) // previous condition : P[1].contains("/")
159+ {
160+ for (int i = 1 ; i < P .length ; i ++) {
161+ int coordCounter = 0 ;
162+ parts = P [i ].split ("/" ); // '1 1 1'
163+ // -1 because indices in .obj format start from 1
164+ vertexIndices .add (Integer .parseInt (parts [coordCounter ++]) - 1 );
165+ if (!texCoords .isEmpty ())
166+ textureIndices .add (Integer .parseInt (parts [coordCounter ++]) - 1 );
167+ if (!normalCoords .isEmpty ())
168+ normalIndices .add (Integer .parseInt (parts [coordCounter ++]) - 1 );
169+ }
170+ }
171+ }
172+
173+ }
174+ reader .close ();
175+ } catch (Exception e ) {
176+ System .out .println (e );
177+ }
178+
179+ }
180+ }
0 commit comments