Skip to content

Commit

Permalink
Textures support to mtl files
Browse files Browse the repository at this point in the history
  • Loading branch information
diyaayay committed Aug 15, 2024
1 parent 21d7c8c commit 8537607
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 37 deletions.
66 changes: 52 additions & 14 deletions src/webgl/loading.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,15 +410,6 @@ p5.prototype.loadModel = function(path,options) {
}
}


async function fileExists(url) {
try {
const response = await fetch(url, { method: 'HEAD' });
return response.ok;
} catch (error) {
return false;
}
}
if (fileType.match(/\.stl$/i)) {
this.httpDo(
path,
Expand Down Expand Up @@ -495,6 +486,15 @@ p5.prototype.loadModel = function(path,options) {
return model;
};

async function fileExists(url) {
try {
const response = await fetch(url, { method: 'HEAD' });
return response.ok;
} catch (error) {
return false;
}
}

function parseMtl(p5,mtlPath){
return new Promise((resolve, reject)=>{
let currentMaterial = null;
Expand Down Expand Up @@ -532,7 +532,7 @@ function parseMtl(p5,mtlPath){

}else if (tokens[0] === 'map_Kd') {
//Texture path
materials[currentMaterial].texturePath = tokens[1];
materials[currentMaterial].diffuseTexturePath = tokens[1];
}
}
resolve(materials);
Expand Down Expand Up @@ -583,8 +583,28 @@ function parseObj(model, lines, materials= {}) {

if (tokens.length > 0) {
if (tokens[0] === 'usemtl') {
// Switch to a new material
currentMaterial = tokens[1];
if (materials[currentMaterial] &&
materials[currentMaterial].diffuseTexturePath) {
if (!model.textures) {
model.textures = {};
}
if (!model.textures[currentMaterial]) {
model.textures[currentMaterial] = {};
}
model.hasTextures = true;
model.textures[currentMaterial].diffuseTexture =
model.textures[currentMaterial].diffuseTexture = loadImage(
materials[currentMaterial].diffuseTexturePath,
img => {
//skip
},
err => {
console.warn(`Error loading textures file: ${tokens[1]}, proceeding without textures:`);
}
);
model.textures[currentMaterial].faces = [];
}
}else if (tokens[0] === 'v' || tokens[0] === 'vn') {
// Check if this line describes a vertex or vertex normal.
// It will have three numeric parameters.
Expand Down Expand Up @@ -651,7 +671,15 @@ function parseObj(model, lines, materials= {}) {
face[0] !== face[2] &&
face[1] !== face[2]
) {
model.faces.push(face);
// model.faces.push(face);
if (currentMaterial
&& model.textures[currentMaterial]
&& model.textures[currentMaterial].diffuseTexture
) {
model.textures[currentMaterial].faces.push(face);
} else {
model.faces.push(face);
}
//same material for all vertices in a particular face
if (currentMaterial
&& materials[currentMaterial]
Expand Down Expand Up @@ -1124,8 +1152,18 @@ p5.prototype.model = function(model) {
model._edgesToVertices();
this._renderer.createBuffers(model.gid, model);
}

this._renderer.drawBuffers(model.gid);
if(model.hasTextures) {
this._renderer.updateIndexBuffer(model.gid, model.faces);
this._renderer.drawBuffers(model.gid);
for (let material of Object.keys(model.textures)) {
const texture = model.textures[material];
this._renderer.updateIndexBuffer(model.gid, texture.faces);
this._renderer._tex = texture.diffuseTexture;
this._renderer.drawBuffers(model.gid);
}
} else{
this._renderer.drawBuffers(model.gid);
}
}
};

Expand Down
25 changes: 22 additions & 3 deletions src/webgl/p5.Geometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,10 @@ p5.Geometry = class Geometry {
// One color per vertex representing the stroke color at that vertex
this.vertexStrokeColors = [];

// Map storing the textures and faces for each texture
this.textures = {};
this.hasTextures = false;

// One color per line vertex, generated automatically based on
// vertexStrokeColors in _edgesToVertices()
this.lineVertexColors = new p5.DataArray();
Expand Down Expand Up @@ -925,6 +929,11 @@ p5.Geometry = class Geometry {
return this;
}

clearTextures() {
this.textures = {};
return this;
}

/**
* The `saveObj()` function exports `p5.Geometry` objects as
* 3D models in the Wavefront .obj file format.
Expand Down Expand Up @@ -1955,12 +1964,21 @@ p5.Geometry = class Geometry {
_makeTriangleEdges() {
this.edges.length = 0;

const _addEdge = face => {
this.edges.push([face[0], face[1]]);
this.edges.push([face[1], face[2]]);
this.edges.push([face[2], face[0]]);
};

for (let j = 0; j < this.faces.length; j++) {
this.edges.push([this.faces[j][0], this.faces[j][1]]);
this.edges.push([this.faces[j][1], this.faces[j][2]]);
this.edges.push([this.faces[j][2], this.faces[j][0]]);
_addEdge(this.faces[j]);
}

for (let material of Object.keys(this.textures)) {
this.textures[material].faces.map(face => _addEdge(face));
}


return this;
}

Expand Down Expand Up @@ -2299,6 +2317,7 @@ p5.Geometry = class Geometry {
}
return this;
}

};
export default p5.Geometry;

45 changes: 25 additions & 20 deletions src/webgl/p5.RendererGL.Retained.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,30 @@ p5.RendererGL.prototype._freeBuffers = function(gId) {
freeBuffers(this.retainedMode.buffers.fill);
};

p5.RendererGL.prototype.updateIndexBuffer = function(gId, faces) {
const gl = this.GL;
const buffers = this.retainedMode.geometry[gId];
let indexBuffer = buffers.indexBuffer;

if (!indexBuffer) indexBuffer = buffers.indexBuffer = gl.createBuffer();
const vals = p5.RendererGL.prototype._flatten(faces);

// If any face references a vertex with an index greater than the maximum
// un-singed 16 bit integer, then we need to use a Uint32Array instead of a
// Uint16Array

const hasVertexIndicesOverMaxUInt16 = vals.some(v => v > 65535);
let type = hasVertexIndicesOverMaxUInt16 ? Uint32Array : Uint16Array;
this._bindBuffer(indexBuffer, gl.ELEMENT_ARRAY_BUFFER, vals, type);
buffers.indexBufferType = hasVertexIndicesOverMaxUInt16
? gl.UNSIGNED_INT
: gl.UNSIGNED_SHORT;

// the vertex count is based on the number of faces
buffers.vertexCount = faces.length * 3;
};


/**
* creates a buffers object that holds the WebGL render buffers
* for a geometry.
Expand All @@ -80,26 +104,7 @@ p5.RendererGL.prototype.createBuffers = function(gId, model) {
let indexBuffer = buffers.indexBuffer;

if (model.faces.length) {
// allocate space for faces
if (!indexBuffer) indexBuffer = buffers.indexBuffer = gl.createBuffer();
const vals = p5.RendererGL.prototype._flatten(model.faces);

// If any face references a vertex with an index greater than the maximum
// un-singed 16 bit integer, then we need to use a Uint32Array instead of a
// Uint16Array
const hasVertexIndicesOverMaxUInt16 = vals.some(v => v > 65535);
let type = hasVertexIndicesOverMaxUInt16 ? Uint32Array : Uint16Array;
this._bindBuffer(indexBuffer, gl.ELEMENT_ARRAY_BUFFER, vals, type);

// If we're using a Uint32Array for our indexBuffer we will need to pass a
// different enum value to WebGL draw triangles. This happens in
// the _drawElements function.
buffers.indexBufferType = hasVertexIndicesOverMaxUInt16
? gl.UNSIGNED_INT
: gl.UNSIGNED_SHORT;

// the vertex count is based on the number of faces
buffers.vertexCount = model.faces.length * 3;
this.updateIndexBuffer(gId, model.faces);
} else {
// the index buffer is unused, remove it
if (indexBuffer) {
Expand Down

0 comments on commit 8537607

Please sign in to comment.