MCPcopy
hub / github.com/processing/p5.js / parseObj

Function parseObj

src/webgl/loading.js:540–659  ·  view source on GitHub ↗

* @private * 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, materials = {})

Source from the content-addressed store, hash-verified

538 * f 4 3 2 1
539 */
540 function parseObj(model, lines, materials = {}) {
541 // OBJ allows a face to specify an index for a vertex (in the above example),
542 // but it also allows you to specify a custom combination of vertex, UV
543 // coordinate, and vertex normal. So, "3/4/3" would mean, "use vertex 3 with
544 // UV coordinate 4 and vertex normal 3". In WebGL, every vertex with different
545 // parameters must be a different vertex, so loadedVerts is used to
546 // temporarily store the parsed vertices, normals, etc., and indexedVerts is
547 // used to map a specific combination (keyed on, for example, the string
548 // "3/4/3"), to the actual index of the newly created vertex in the final
549 // object.
550 const loadedVerts = {
551 v: [],
552 vt: [],
553 vn: []
554 };
555
556
557 // Map from source index → Map of material → destination index
558 const usedVerts = {}; // Track colored vertices
559 let currentMaterial = null;
560 let hasColoredVertices = false;
561 let hasColorlessVertices = false;
562 for (let line = 0; line < lines.length; ++line) {
563 // Each line is a separate object (vertex, face, vertex normal, etc)
564 // For each line, split it into tokens on whitespace. The first token
565 // describes the type.
566 const tokens = lines[line].trim().split(/\b\s+/);
567
568 if (tokens.length > 0) {
569 if (tokens[0] === 'usemtl') {
570 // Switch to a new material
571 currentMaterial = tokens[1];
572 } else if (tokens[0] === 'v' || tokens[0] === 'vn') {
573 // Check if this line describes a vertex or vertex normal.
574 // It will have three numeric parameters.
575 const vertex = new Vector(
576 parseFloat(tokens[1]),
577 parseFloat(tokens[2]),
578 parseFloat(tokens[3])
579 );
580 loadedVerts[tokens[0]].push(vertex);
581 } else if (tokens[0] === 'vt') {
582 // Check if this line describes a texture coordinate.
583 // It will have two numeric parameters U and V (W is omitted).
584 // Because of WebGL texture coordinates rendering behaviour, the V
585 // coordinate is inversed.
586 const texVertex = [parseFloat(tokens[1]), 1 - parseFloat(tokens[2])];
587 loadedVerts[tokens[0]].push(texVertex);
588 } else if (tokens[0] === 'f') {
589 // Check if this line describes a face.
590 // OBJ faces can have more than three points. Triangulate points.
591 for (let tri = 3; tri < tokens.length; ++tri) {
592 const face = [];
593 const vertexTokens = [1, tri - 1, tri];
594
595 for (let tokenInd = 0; tokenInd < vertexTokens.length; ++tokenInd) {
596 // Now, convert the given token into an index
597 const vertString = tokens[vertexTokens[tokenInd]];

Callers 2

cbFunction · 0.85
loadingFunction · 0.85

Calls 7

splitMethod · 0.80
trimMethod · 0.80
atMethod · 0.80
sliceMethod · 0.80
computeNormalsMethod · 0.80
pushMethod · 0.45
copyMethod · 0.45

Tested by

no test coverage detected