-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for .mtl Files with Textures #7072
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -531,8 +531,8 @@ function parseMtl(p5,mtlPath){ | |
]; | ||
|
||
}else if (tokens[0] === 'map_Kd') { | ||
//Texture path | ||
materials[currentMaterial].texturePath = tokens[1]; | ||
// Diffuse Texture path | ||
materials[currentMaterial].diffuseTexturePath = tokens[1]; | ||
} | ||
} | ||
resolve(materials); | ||
|
@@ -585,6 +585,17 @@ function parseObj(model, lines, materials= {}) { | |
if (tokens[0] === 'usemtl') { | ||
// Switch to a new material | ||
currentMaterial = tokens[1]; | ||
if( materials[currentMaterial] | ||
&& materials[currentMaterial].diffuseTexturePath | ||
) { | ||
if (!model.textures[currentMaterial]) { | ||
model.textures[currentMaterial] = {}; | ||
} | ||
model.hasTextures = true; | ||
model.textures[currentMaterial].diffuseTexture = | ||
loadImage(materials[currentMaterial].diffuseTexturePath); | ||
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. | ||
|
@@ -651,8 +662,15 @@ function parseObj(model, lines, materials= {}) { | |
face[0] !== face[2] && | ||
face[1] !== face[2] | ||
) { | ||
model.faces.push(face); | ||
//same material for all vertices in a particular face | ||
if (currentMaterial | ||
&& model.textures[currentMaterial] | ||
&& model.textures[currentMaterial].diffuseTexture | ||
) { | ||
model.textures[currentMaterial].faces.push(face); | ||
} else { | ||
model.faces.push(face); | ||
} | ||
if (currentMaterial | ||
&& materials[currentMaterial] | ||
&& materials[currentMaterial].diffuseColor) { | ||
|
@@ -1125,7 +1143,19 @@ p5.prototype.model = function(model) { | |
this._renderer.createBuffers(model.gid, model); | ||
} | ||
|
||
this._renderer.drawBuffers(model.gid); | ||
// If model has textures for each texture update index buffer and invoke draw call. | ||
if(model.hasTextures) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we can make this a little more consistent with
|
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a way for us to do this by having multiple index buffers that we swap between? In the past we've found that on some computers, the cpu-to-gpu data transfer is by far the biggest bottleneck, so we've tried to minimize the data sent back and forth. Currently, |
||
this._renderer._tex = texture.diffuseTexture; | ||
this._renderer.drawBuffers(model.gid); | ||
} | ||
} else { | ||
this._renderer.drawBuffers(model.gid); | ||
} | ||
} | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,11 @@ 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(); | ||
|
@@ -707,10 +712,18 @@ 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; | ||
|
@@ -1003,5 +1016,18 @@ p5.Geometry = class Geometry { | |
} | ||
return this; | ||
} | ||
|
||
/** | ||
* When using textures each material contains all the face indices for that texture. | ||
* this function collects all the faces mapped to different textures in a single array | ||
* @method collectFaces | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this meant to be used internally only? If so we can add the |
||
*/ | ||
collectFaces() { | ||
const faces = []; | ||
for (let materialName of Object.keys(this.textures)) { | ||
faces.push(this.textures[materialName]['faces']); | ||
} | ||
return faces.flat(); | ||
} | ||
}; | ||
export default p5.Geometry; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do we expect to happen here if this image file hasn't been uploaded along with the sketch? Maybe we can add some error handling here?