mirror of
https://github.com/processing/processing4.git
synced 2026-02-03 13:49:18 +01:00
OBJ-loading code moved into PShapeOBJ, removed PShape2D and PShap3D
This commit is contained in:
@@ -22,16 +22,14 @@
|
||||
|
||||
package processing.opengl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PConstants;
|
||||
import processing.core.PGraphics;
|
||||
import processing.core.PImage;
|
||||
import processing.core.PShape;
|
||||
import processing.core.PVector;
|
||||
import processing.core.PShapeOBJ;
|
||||
|
||||
public class PGraphics3D extends PGraphicsOpenGL {
|
||||
|
||||
@@ -111,119 +109,34 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
|
||||
|
||||
static protected PShape loadShapeImpl(PGraphics pg, String filename,
|
||||
String ext) {
|
||||
ArrayList<PVector> vertices = new ArrayList<PVector>();
|
||||
ArrayList<PVector> normals = new ArrayList<PVector>();
|
||||
ArrayList<PVector> textures = new ArrayList<PVector>();
|
||||
ArrayList<OBJFace> faces = new ArrayList<OBJFace>();
|
||||
ArrayList<OBJMaterial> materials = new ArrayList<OBJMaterial>();
|
||||
String extension) {
|
||||
PShapeOBJ obj = null;
|
||||
|
||||
BufferedReader reader = pg.parent.createReader(filename);
|
||||
parseOBJ(pg.parent, reader, vertices, normals, textures, faces, materials);
|
||||
if (extension.equals("obj")) {
|
||||
obj = new PShapeOBJ(pg.parent, filename);
|
||||
|
||||
int prevColorMode = pg.colorMode;
|
||||
float prevColorModeX = pg.colorModeX;
|
||||
float prevColorModeY = pg.colorModeY;
|
||||
float prevColorModeZ = pg.colorModeZ;
|
||||
float prevColorModeA = pg.colorModeA;
|
||||
boolean prevStroke = pg.stroke;
|
||||
int prevTextureMode = pg.textureMode;
|
||||
pg.colorMode(RGB, 1);
|
||||
pg.stroke = false;
|
||||
pg.textureMode = NORMAL;
|
||||
|
||||
// The OBJ geometry is stored in a group shape,
|
||||
// with each face in a separate child geometry
|
||||
// shape.
|
||||
PShape root = createShapeImpl(pg.parent, GROUP);
|
||||
|
||||
int mtlIdxCur = -1;
|
||||
OBJMaterial mtl = null;
|
||||
for (int i = 0; i < faces.size(); i++) {
|
||||
OBJFace face = faces.get(i);
|
||||
|
||||
// Getting current material.
|
||||
if (mtlIdxCur != face.matIdx) {
|
||||
mtlIdxCur = PApplet.max(0, face.matIdx); // To make sure that at least we get the default material.
|
||||
mtl = materials.get(mtlIdxCur);
|
||||
} else if (extension.equals("objz")) {
|
||||
try {
|
||||
InputStream input =
|
||||
new GZIPInputStream(pg.parent.createInput(filename));
|
||||
obj = new PShapeOBJ(pg.parent, PApplet.createReader(input));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Creating child shape for current face.
|
||||
PShape child;
|
||||
if (face.vertIdx.size() == 3) {
|
||||
child = createShapeImpl(pg.parent, TRIANGLES); // Face is a triangle, so using appropriate shape kind.
|
||||
} else if (face.vertIdx.size() == 4) {
|
||||
child = createShapeImpl(pg.parent, QUADS); // Face is a quad, so using appropriate shape kind.
|
||||
} else {
|
||||
child = createShapeImpl(pg.parent, POLYGON); // Face is a general polygon
|
||||
}
|
||||
|
||||
// Setting material properties for the new face
|
||||
child.fill(mtl.kd.x, mtl.kd.y, mtl.kd.z);
|
||||
child.ambient(mtl.ka.x, mtl.ka.y, mtl.ka.z);
|
||||
child.specular(mtl.ks.x, mtl.ks.y, mtl.ks.z);
|
||||
child.shininess(mtl.ns);
|
||||
if (mtl.kdMap != null) {
|
||||
// If current material is textured, then tinting the texture using the diffuse color.
|
||||
child.tint(mtl.kd.x, mtl.kd.y, mtl.kd.z, mtl.d);
|
||||
}
|
||||
|
||||
for (int j = 0; j < face.vertIdx.size(); j++){
|
||||
int vertIdx, normIdx;
|
||||
PVector vert, norms;
|
||||
|
||||
vert = norms = null;
|
||||
|
||||
vertIdx = face.vertIdx.get(j).intValue() - 1;
|
||||
vert = vertices.get(vertIdx);
|
||||
|
||||
if (j < face.normIdx.size()) {
|
||||
normIdx = face.normIdx.get(j).intValue() - 1;
|
||||
if (-1 < normIdx) {
|
||||
norms = normals.get(normIdx);
|
||||
}
|
||||
}
|
||||
|
||||
if (mtl != null && mtl.kdMap != null) {
|
||||
// This face is textured.
|
||||
int texIdx;
|
||||
PVector tex = null;
|
||||
|
||||
if (j < face.texIdx.size()) {
|
||||
texIdx = face.texIdx.get(j).intValue() - 1;
|
||||
if (-1 < texIdx) {
|
||||
tex = textures.get(texIdx);
|
||||
}
|
||||
}
|
||||
|
||||
child.texture(mtl.kdMap);
|
||||
if (norms != null) {
|
||||
child.normal(norms.x, norms.y, norms.z);
|
||||
}
|
||||
if (tex != null) {
|
||||
child.vertex(vert.x, vert.y, vert.z, tex.x, tex.y);
|
||||
} else {
|
||||
child.vertex(vert.x, vert.y, vert.z);
|
||||
}
|
||||
} else {
|
||||
// This face is not textured.
|
||||
if (norms != null) {
|
||||
child.normal(norms.x, norms.y, norms.z);
|
||||
}
|
||||
child.vertex(vert.x, vert.y, vert.z);
|
||||
}
|
||||
}
|
||||
|
||||
child.end(CLOSE);
|
||||
root.addChild(child);
|
||||
}
|
||||
|
||||
pg.colorMode(prevColorMode, prevColorModeX, prevColorModeY, prevColorModeZ,
|
||||
prevColorModeA);
|
||||
pg.stroke = prevStroke;
|
||||
pg.textureMode = prevTextureMode;
|
||||
|
||||
return root;
|
||||
if (obj != null) {
|
||||
boolean prevStroke = pg.stroke;
|
||||
int prevTextureMode = pg.textureMode;
|
||||
pg.stroke = false;
|
||||
pg.textureMode = NORMAL;
|
||||
PShapeOpenGL p3d = PShapeOpenGL.createShape3D(pg.parent, obj);
|
||||
pg.stroke = prevStroke;
|
||||
pg.textureMode = prevTextureMode;
|
||||
return p3d;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -234,7 +147,7 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
|
||||
@Override
|
||||
public PShape createShape(PShape source) {
|
||||
return PShape3D.createShape(parent, source);
|
||||
return PShapeOpenGL.createShape3D(parent, source);
|
||||
}
|
||||
|
||||
|
||||
@@ -256,43 +169,45 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
}
|
||||
|
||||
|
||||
static protected PShape3D createShapeImpl(PApplet parent, int type) {
|
||||
PShape3D shape = null;
|
||||
static protected PShapeOpenGL createShapeImpl(PApplet parent, int type) {
|
||||
PShapeOpenGL shape = null;
|
||||
if (type == PConstants.GROUP) {
|
||||
shape = new PShape3D(parent, PConstants.GROUP);
|
||||
shape = new PShapeOpenGL(parent, PConstants.GROUP);
|
||||
} else if (type == PShape.PATH) {
|
||||
shape = new PShape3D(parent, PShape.PATH);
|
||||
shape = new PShapeOpenGL(parent, PShape.PATH);
|
||||
} else if (type == POINTS) {
|
||||
shape = new PShape3D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(POINTS);
|
||||
} else if (type == LINES) {
|
||||
shape = new PShape3D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(LINES);
|
||||
} else if (type == TRIANGLE || type == TRIANGLES) {
|
||||
shape = new PShape3D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(TRIANGLES);
|
||||
} else if (type == TRIANGLE_FAN) {
|
||||
shape = new PShape3D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(TRIANGLE_FAN);
|
||||
} else if (type == TRIANGLE_STRIP) {
|
||||
shape = new PShape3D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(TRIANGLE_STRIP);
|
||||
} else if (type == QUAD || type == QUADS) {
|
||||
shape = new PShape3D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(QUADS);
|
||||
} else if (type == QUAD_STRIP) {
|
||||
shape = new PShape3D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(QUAD_STRIP);
|
||||
} else if (type == POLYGON) {
|
||||
shape = new PShape3D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(POLYGON);
|
||||
}
|
||||
shape.is3D(true);
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
static protected PShape3D createShapeImpl(PApplet parent, int kind, float... p) {
|
||||
PShape3D shape = null;
|
||||
static protected PShapeOpenGL createShapeImpl(PApplet parent,
|
||||
int kind, float... p) {
|
||||
PShapeOpenGL shape = null;
|
||||
int len = p.length;
|
||||
|
||||
if (kind == POINT) {
|
||||
@@ -300,63 +215,63 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape3D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(POINT);
|
||||
} else if (kind == LINE) {
|
||||
if (len != 4 && len != 6) {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape3D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(LINE);
|
||||
} else if (kind == TRIANGLE) {
|
||||
if (len != 6) {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape3D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(TRIANGLE);
|
||||
} else if (kind == QUAD) {
|
||||
if (len != 8) {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape3D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(QUAD);
|
||||
} else if (kind == RECT) {
|
||||
if (len != 4 && len != 5 && len != 8) {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape3D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(RECT);
|
||||
} else if (kind == ELLIPSE) {
|
||||
if (len != 4) {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape3D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(ELLIPSE);
|
||||
} else if (kind == ARC) {
|
||||
if (len != 6) {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape3D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(ARC);
|
||||
} else if (kind == BOX) {
|
||||
if (len != 1 && len != 3) {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape3D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(BOX);
|
||||
} else if (kind == SPHERE) {
|
||||
if (len != 1) {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape3D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(SPHERE);
|
||||
} else {
|
||||
showWarning("Unrecognized primitive type");
|
||||
@@ -366,267 +281,7 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
shape.setParams(p);
|
||||
}
|
||||
|
||||
shape.is3D(true);
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// OBJ LOADING
|
||||
|
||||
|
||||
static protected void parseOBJ(PApplet parent,
|
||||
BufferedReader reader,
|
||||
ArrayList<PVector> vertices,
|
||||
ArrayList<PVector> normals,
|
||||
ArrayList<PVector> textures,
|
||||
ArrayList<OBJFace> faces,
|
||||
ArrayList<OBJMaterial> materials) {
|
||||
Hashtable<String, Integer> mtlTable = new Hashtable<String, Integer>();
|
||||
int mtlIdxCur = -1;
|
||||
boolean readv, readvn, readvt;
|
||||
try {
|
||||
|
||||
readv = readvn = readvt = false;
|
||||
String line;
|
||||
String gname = "object";
|
||||
while ((line = reader.readLine()) != null) {
|
||||
// Parse the line.
|
||||
|
||||
// The below patch/hack comes from Carlos Tomas Marti and is a
|
||||
// fix for single backslashes in Rhino obj files
|
||||
|
||||
// BEGINNING OF RHINO OBJ FILES HACK
|
||||
// Statements can be broken in multiple lines using '\' at the
|
||||
// end of a line.
|
||||
// In regular expressions, the backslash is also an escape
|
||||
// character.
|
||||
// The regular expression \\ matches a single backslash. This
|
||||
// regular expression as a Java string, becomes "\\\\".
|
||||
// That's right: 4 backslashes to match a single one.
|
||||
while (line.contains("\\")) {
|
||||
line = line.split("\\\\")[0];
|
||||
final String s = reader.readLine();
|
||||
if (s != null)
|
||||
line += s;
|
||||
}
|
||||
// END OF RHINO OBJ FILES HACK
|
||||
|
||||
String[] elements = line.split("\\s+");
|
||||
// if not a blank line, process the line.
|
||||
if (elements.length > 0) {
|
||||
if (elements[0].equals("v")) {
|
||||
// vertex
|
||||
PVector tempv = new PVector(Float.valueOf(elements[1]).floatValue(),
|
||||
Float.valueOf(elements[2]).floatValue(),
|
||||
Float.valueOf(elements[3]).floatValue());
|
||||
vertices.add(tempv);
|
||||
readv = true;
|
||||
} else if (elements[0].equals("vn")) {
|
||||
// normal
|
||||
PVector tempn = new PVector(Float.valueOf(elements[1]).floatValue(),
|
||||
Float.valueOf(elements[2]).floatValue(),
|
||||
Float.valueOf(elements[3]).floatValue());
|
||||
normals.add(tempn);
|
||||
readvn = true;
|
||||
} else if (elements[0].equals("vt")) {
|
||||
// uv, inverting v to take into account Processing's invertex Y axis
|
||||
// with respect to OpenGL.
|
||||
PVector tempv = new PVector(Float.valueOf(elements[1]).floatValue(),
|
||||
1 - Float.valueOf(elements[2]).
|
||||
floatValue());
|
||||
textures.add(tempv);
|
||||
readvt = true;
|
||||
} else if (elements[0].equals("o")) {
|
||||
// Object name is ignored, for now.
|
||||
} else if (elements[0].equals("mtllib")) {
|
||||
if (elements[1] != null) {
|
||||
BufferedReader mreader = parent.createReader(elements[1]);
|
||||
if (mreader != null) {
|
||||
parseMTL(parent, mreader, materials, mtlTable);
|
||||
}
|
||||
}
|
||||
} else if (elements[0].equals("g")) {
|
||||
gname = 1 < elements.length ? elements[1] : "";
|
||||
} else if (elements[0].equals("usemtl")) {
|
||||
// Getting index of current active material (will be applied on all subsequent faces).
|
||||
if (elements[1] != null) {
|
||||
String mtlname = elements[1];
|
||||
if (mtlTable.containsKey(mtlname)) {
|
||||
Integer tempInt = mtlTable.get(mtlname);
|
||||
mtlIdxCur = tempInt.intValue();
|
||||
} else {
|
||||
mtlIdxCur = -1;
|
||||
}
|
||||
}
|
||||
} else if (elements[0].equals("f")) {
|
||||
// Face setting
|
||||
OBJFace face = new OBJFace();
|
||||
face.matIdx = mtlIdxCur;
|
||||
face.name = gname;
|
||||
|
||||
for (int i = 1; i < elements.length; i++) {
|
||||
String seg = elements[i];
|
||||
|
||||
if (seg.indexOf("/") > 0) {
|
||||
String[] forder = seg.split("/");
|
||||
|
||||
if (forder.length > 2) {
|
||||
// Getting vertex and texture and normal indexes.
|
||||
if (forder[0].length() > 0 && readv) {
|
||||
face.vertIdx.add(Integer.valueOf(forder[0]));
|
||||
}
|
||||
|
||||
if (forder[1].length() > 0 && readvt) {
|
||||
face.texIdx.add(Integer.valueOf(forder[1]));
|
||||
}
|
||||
|
||||
if (forder[2].length() > 0 && readvn) {
|
||||
face.normIdx.add(Integer.valueOf(forder[2]));
|
||||
}
|
||||
} else if (forder.length > 1) {
|
||||
// Getting vertex and texture/normal indexes.
|
||||
if (forder[0].length() > 0 && readv) {
|
||||
face.vertIdx.add(Integer.valueOf(forder[0]));
|
||||
}
|
||||
|
||||
if (forder[1].length() > 0) {
|
||||
if (readvt) {
|
||||
face.texIdx.add(Integer.valueOf(forder[1]));
|
||||
} else if (readvn) {
|
||||
face.normIdx.add(Integer.valueOf(forder[1]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if (forder.length > 0) {
|
||||
// Getting vertex index only.
|
||||
if (forder[0].length() > 0 && readv) {
|
||||
face.vertIdx.add(Integer.valueOf(forder[0]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Getting vertex index only.
|
||||
if (seg.length() > 0 && readv) {
|
||||
face.vertIdx.add(Integer.valueOf(seg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
faces.add(face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (materials.size() == 0) {
|
||||
// No materials definition so far. Adding one default material.
|
||||
OBJMaterial defMtl = new OBJMaterial();
|
||||
materials.add(defMtl);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static protected void parseMTL(PApplet parent,
|
||||
BufferedReader reader,
|
||||
ArrayList<OBJMaterial> materials,
|
||||
Hashtable<String, Integer> materialsHash) {
|
||||
try {
|
||||
String line;
|
||||
OBJMaterial currentMtl = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
// Parse the line
|
||||
line = line.trim();
|
||||
|
||||
String elements[] = line.split("\\s+");
|
||||
|
||||
if (elements.length > 0) {
|
||||
// Extract the material data.
|
||||
|
||||
if (elements[0].equals("newmtl")) {
|
||||
// Starting new material.
|
||||
String mtlname = elements[1];
|
||||
currentMtl = new OBJMaterial(mtlname);
|
||||
materialsHash.put(mtlname, new Integer(materials.size()));
|
||||
materials.add(currentMtl);
|
||||
} else if (elements[0].equals("map_Kd") && elements.length > 1) {
|
||||
// Loading texture map.
|
||||
String texname = elements[1];
|
||||
currentMtl.kdMap = parent.loadImage(texname);
|
||||
} else if (elements[0].equals("Ka") && elements.length > 3) {
|
||||
// The ambient color of the material
|
||||
currentMtl.ka.x = Float.valueOf(elements[1]).floatValue();
|
||||
currentMtl.ka.y = Float.valueOf(elements[2]).floatValue();
|
||||
currentMtl.ka.z = Float.valueOf(elements[3]).floatValue();
|
||||
} else if (elements[0].equals("Kd") && elements.length > 3) {
|
||||
// The diffuse color of the material
|
||||
currentMtl.kd.x = Float.valueOf(elements[1]).floatValue();
|
||||
currentMtl.kd.y = Float.valueOf(elements[2]).floatValue();
|
||||
currentMtl.kd.z = Float.valueOf(elements[3]).floatValue();
|
||||
} else if (elements[0].equals("Ks") && elements.length > 3) {
|
||||
// The specular color weighted by the specular coefficient
|
||||
currentMtl.ks.x = Float.valueOf(elements[1]).floatValue();
|
||||
currentMtl.ks.y = Float.valueOf(elements[2]).floatValue();
|
||||
currentMtl.ks.z = Float.valueOf(elements[3]).floatValue();
|
||||
} else if ((elements[0].equals("d") ||
|
||||
elements[0].equals("Tr")) && elements.length > 1) {
|
||||
// Reading the alpha transparency.
|
||||
currentMtl.d = Float.valueOf(elements[1]).floatValue();
|
||||
} else if (elements[0].equals("Ns") && elements.length > 1) {
|
||||
// The specular component of the Phong shading model
|
||||
currentMtl.ns = Float.valueOf(elements[1]).floatValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Stores a face from an OBJ file
|
||||
static protected class OBJFace {
|
||||
ArrayList<Integer> vertIdx;
|
||||
ArrayList<Integer> texIdx;
|
||||
ArrayList<Integer> normIdx;
|
||||
int matIdx;
|
||||
String name;
|
||||
|
||||
OBJFace() {
|
||||
vertIdx = new ArrayList<Integer>();
|
||||
texIdx = new ArrayList<Integer>();
|
||||
normIdx = new ArrayList<Integer>();
|
||||
matIdx = -1;
|
||||
name = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Stores a material defined in an MTL file.
|
||||
static protected class OBJMaterial {
|
||||
String name;
|
||||
PVector ka;
|
||||
PVector kd;
|
||||
PVector ks;
|
||||
float d;
|
||||
float ns;
|
||||
PImage kdMap;
|
||||
|
||||
OBJMaterial() {
|
||||
this("default");
|
||||
}
|
||||
|
||||
OBJMaterial(String name) {
|
||||
this.name = name;
|
||||
ka = new PVector(0.5f, 0.5f, 0.5f);
|
||||
kd = new PVector(0.5f, 0.5f, 0.5f);
|
||||
ks = new PVector(0.5f, 0.5f, 0.5f);
|
||||
d = 1.0f;
|
||||
ns = 0.0f;
|
||||
kdMap = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user