* Parse OBJ lines into model. For reference, this is what a simple model of a * square might look like: * * v -0.5 -0.5 0.5 * v -0.5 -0.5 -0.5 * v -0.5 0.5 -0.5 * v -0.5 0.5 0.5 * * f 4 3 2 1
( model, lines )
| 32108 | * f 4 3 2 1 |
| 32109 | */ |
| 32110 | function parseObj( model, lines ) { |
| 32111 | // OBJ allows a face to specify an index for a vertex (in the above example), |
| 32112 | // but it also allows you to specify a custom combination of vertex, UV |
| 32113 | // coordinate, and vertex normal. So, "3/4/3" would mean, "use vertex 3 with |
| 32114 | // UV coordinate 4 and vertex normal 3". In WebGL, every vertex with different |
| 32115 | // parameters must be a different vertex, so loadedVerts is used to |
| 32116 | // temporarily store the parsed vertices, normals, etc., and indexedVerts is |
| 32117 | // used to map a specific combination (keyed on, for example, the string |
| 32118 | // "3/4/3"), to the actual index of the newly created vertex in the final |
| 32119 | // object. |
| 32120 | var loadedVerts = {'v' : [], |
| 32121 | 'vt' : [], |
| 32122 | 'vn' : []}; |
| 32123 | var indexedVerts = {}; |
| 32124 | |
| 32125 | for (var line = 0; line < lines.length; ++line) { |
| 32126 | // Each line is a separate object (vertex, face, vertex normal, etc) |
| 32127 | // For each line, split it into tokens on whitespace. The first token |
| 32128 | // describes the type. |
| 32129 | var tokens = lines[line].trim().split(/\b\s+/); |
| 32130 | |
| 32131 | if (tokens.length > 0) { |
| 32132 | if (tokens[0] === 'v' || tokens[0] === 'vn') { |
| 32133 | // Check if this line describes a vertex or vertex normal. |
| 32134 | // It will have three numeric parameters. |
| 32135 | var vertex = new p5.Vector(parseFloat(tokens[1]), |
| 32136 | parseFloat(tokens[2]), |
| 32137 | parseFloat(tokens[3])); |
| 32138 | loadedVerts[tokens[0]].push(vertex); |
| 32139 | } else if (tokens[0] === 'vt') { |
| 32140 | // Check if this line describes a texture coordinate. |
| 32141 | // It will have two numeric parameters. |
| 32142 | var texVertex = [parseFloat(tokens[1]), parseFloat(tokens[2])]; |
| 32143 | loadedVerts[tokens[0]].push(texVertex); |
| 32144 | } else if (tokens[0] === 'f') { |
| 32145 | // Check if this line describes a face. |
| 32146 | // OBJ faces can have more than three points. Triangulate points. |
| 32147 | for (var tri = 3; tri < tokens.length; ++tri) { |
| 32148 | var face = []; |
| 32149 | |
| 32150 | var vertexTokens = [1, tri - 1, tri]; |
| 32151 | |
| 32152 | for (var tokenInd = 0; tokenInd < vertexTokens.length; ++tokenInd) { |
| 32153 | // Now, convert the given token into an index |
| 32154 | var vertString = tokens[vertexTokens[tokenInd]]; |
| 32155 | var vertIndex = 0; |
| 32156 | |
| 32157 | // TODO: Faces can technically use negative numbers to refer to the |
| 32158 | // previous nth vertex. I haven't seen this used in practice, but |
| 32159 | // it might be good to implement this in the future. |
| 32160 | |
| 32161 | if (indexedVerts[vertString] !== undefined) { |
| 32162 | vertIndex = indexedVerts[vertString]; |
| 32163 | } else { |
| 32164 | var vertParts = vertString.split('/'); |
| 32165 | for (var i = 0; i < vertParts.length; i++) { |
| 32166 | vertParts[i] = parseInt(vertParts[i]) - 1; |
| 32167 | } |