mirror of
https://github.com/processing/processing4.git
synced 2026-02-02 05:11:12 +01:00
OBJ-loading code moved into PShapeOBJ, removed PShape2D and PShap3D
This commit is contained in:
@@ -205,6 +205,8 @@ public class PShape implements PConstants {
|
||||
/** True if colorMode(RGB, 255) */
|
||||
boolean colorModeDefault; // = true;
|
||||
|
||||
/** True if contains 3D data */
|
||||
protected boolean is3D = false;
|
||||
|
||||
// should this be called vertices (consistent with PGraphics internals)
|
||||
// or does that hurt flexibility?
|
||||
@@ -430,7 +432,7 @@ public class PShape implements PConstants {
|
||||
* Return true if this shape is 2D. Defaults to true.
|
||||
*/
|
||||
public boolean is2D() {
|
||||
return true;
|
||||
return !is3D;
|
||||
}
|
||||
|
||||
|
||||
@@ -438,7 +440,12 @@ public class PShape implements PConstants {
|
||||
* Return true if this shape is 3D. Defaults to false.
|
||||
*/
|
||||
public boolean is3D() {
|
||||
return false;
|
||||
return is3D;
|
||||
}
|
||||
|
||||
|
||||
public void is3D(boolean val) {
|
||||
is3D = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -840,9 +847,13 @@ public class PShape implements PConstants {
|
||||
// s.emissive(vert[ER] * 255, vert[EG] * 255, vert[EB] * 255);
|
||||
// s.shininess(vert[SHINE]);
|
||||
|
||||
dest.normal(vert[PGraphics.NX],
|
||||
vert[PGraphics.NY],
|
||||
vert[PGraphics.NZ]);
|
||||
if (0 < PApplet.dist(vert[PGraphics.NX],
|
||||
vert[PGraphics.NY],
|
||||
vert[PGraphics.NZ], 0, 0, 0)) {
|
||||
dest.normal(vert[PGraphics.NX],
|
||||
vert[PGraphics.NY],
|
||||
vert[PGraphics.NZ]);
|
||||
}
|
||||
dest.vertex(vert[X], vert[Y], vert[Z],
|
||||
vert[PGraphics.U],
|
||||
vert[PGraphics.V]);
|
||||
|
||||
409
core/src/processing/core/PShapeOBJ.java
Normal file
409
core/src/processing/core/PShapeOBJ.java
Normal file
@@ -0,0 +1,409 @@
|
||||
package processing.core;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* OBJ loading implemented using code from Saito's OBJLoader library:
|
||||
* http://code.google.com/p/saitoobjloader/
|
||||
* and OBJReader from Ahmet Kizilay
|
||||
* http://www.openprocessing.org/visuals/?visualID=191
|
||||
*
|
||||
*/
|
||||
public class PShapeOBJ extends PShape {
|
||||
|
||||
/**
|
||||
* Initializes a new OBJ Object with the given filename.
|
||||
*/
|
||||
public PShapeOBJ(PApplet parent, String filename) {
|
||||
this(parent, parent.createReader(filename));
|
||||
}
|
||||
|
||||
|
||||
public PShapeOBJ(PApplet parent, BufferedReader reader) {
|
||||
ArrayList<OBJFace> faces = new ArrayList<OBJFace>();
|
||||
ArrayList<OBJMaterial> materials = new ArrayList<OBJMaterial>();
|
||||
ArrayList<PVector> coords = new ArrayList<PVector>();
|
||||
ArrayList<PVector> normals = new ArrayList<PVector>();
|
||||
ArrayList<PVector> texcoords = new ArrayList<PVector>();
|
||||
parseOBJ(parent, reader, faces, materials, coords, normals, texcoords);
|
||||
|
||||
// The OBJ geometry is stored with each face in a separate child shape.
|
||||
parent = null;
|
||||
family = GROUP;
|
||||
addChildren(faces, materials, coords, normals, texcoords);
|
||||
}
|
||||
|
||||
|
||||
protected PShapeOBJ(OBJFace face, OBJMaterial mtl,
|
||||
ArrayList<PVector> coords,
|
||||
ArrayList<PVector> normals,
|
||||
ArrayList<PVector> texcoords) {
|
||||
family = GEOMETRY;
|
||||
if (face.vertIdx.size() == 3) {
|
||||
kind = TRIANGLES;
|
||||
} else if (face.vertIdx.size() == 4) {
|
||||
kind = QUADS;
|
||||
} else {
|
||||
kind = POLYGON;
|
||||
}
|
||||
|
||||
// Setting material properties for the new face
|
||||
fillColor = rgbaValue(mtl.kd);
|
||||
ambientColor = rgbaValue(mtl.ka);
|
||||
specularColor = rgbaValue(mtl.ks);
|
||||
shininess = mtl.ns;
|
||||
if (mtl.kdMap != null) {
|
||||
// If current material is textured, then tinting the texture using the
|
||||
// diffuse color.
|
||||
tintColor = rgbaValue(mtl.kd, mtl.d);
|
||||
}
|
||||
|
||||
vertexCount = face.vertIdx.size();
|
||||
vertices = new float[vertexCount][12];
|
||||
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 = coords.get(vertIdx);
|
||||
|
||||
if (j < face.normIdx.size()) {
|
||||
normIdx = face.normIdx.get(j).intValue() - 1;
|
||||
if (-1 < normIdx) {
|
||||
norms = normals.get(normIdx);
|
||||
}
|
||||
}
|
||||
|
||||
vertices[j][X] = vert.x;
|
||||
vertices[j][Y] = vert.y;
|
||||
vertices[j][Z] = vert.z;
|
||||
|
||||
vertices[j][PGraphics.R] = mtl.kd.x;
|
||||
vertices[j][PGraphics.B] = mtl.kd.y;
|
||||
vertices[j][PGraphics.G] = mtl.kd.z;
|
||||
vertices[j][PGraphics.A] = 1;
|
||||
|
||||
if (norms != null) {
|
||||
vertices[j][PGraphics.NX] = norms.x;
|
||||
vertices[j][PGraphics.NY] = norms.y;
|
||||
vertices[j][PGraphics.NZ] = norms.z;
|
||||
}
|
||||
|
||||
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 = texcoords.get(texIdx);
|
||||
}
|
||||
}
|
||||
|
||||
image = mtl.kdMap;
|
||||
if (tex != null) {
|
||||
vertices[j][PGraphics.U] = tex.x;
|
||||
vertices[j][PGraphics.V] = tex.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void addChildren(ArrayList<OBJFace> faces,
|
||||
ArrayList<OBJMaterial> materials,
|
||||
ArrayList<PVector> coords,
|
||||
ArrayList<PVector> normals,
|
||||
ArrayList<PVector> texcoords) {
|
||||
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) {
|
||||
// To make sure that at least we get the default material
|
||||
mtlIdxCur = PApplet.max(0, face.matIdx);
|
||||
mtl = materials.get(mtlIdxCur);
|
||||
}
|
||||
|
||||
// Creating child shape for current face.
|
||||
PShape child = new PShapeOBJ(face, mtl, coords, normals, texcoords);
|
||||
addChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static protected void parseOBJ(PApplet parent,
|
||||
BufferedReader reader,
|
||||
ArrayList<OBJFace> faces,
|
||||
ArrayList<OBJMaterial> materials,
|
||||
ArrayList<PVector> coords,
|
||||
ArrayList<PVector> normals,
|
||||
ArrayList<PVector> texcoords) {
|
||||
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[] parts = line.split("\\s+");
|
||||
// if not a blank line, process the line.
|
||||
if (parts.length > 0) {
|
||||
if (parts[0].equals("v")) {
|
||||
// vertex
|
||||
PVector tempv = new PVector(Float.valueOf(parts[1]).floatValue(),
|
||||
Float.valueOf(parts[2]).floatValue(),
|
||||
Float.valueOf(parts[3]).floatValue());
|
||||
coords.add(tempv);
|
||||
readv = true;
|
||||
} else if (parts[0].equals("vn")) {
|
||||
// normal
|
||||
PVector tempn = new PVector(Float.valueOf(parts[1]).floatValue(),
|
||||
Float.valueOf(parts[2]).floatValue(),
|
||||
Float.valueOf(parts[3]).floatValue());
|
||||
normals.add(tempn);
|
||||
readvn = true;
|
||||
} else if (parts[0].equals("vt")) {
|
||||
// uv, inverting v to take into account Processing's inverted Y axis
|
||||
// with respect to OpenGL.
|
||||
PVector tempv = new PVector(Float.valueOf(parts[1]).floatValue(),
|
||||
1 - Float.valueOf(parts[2]).
|
||||
floatValue());
|
||||
texcoords.add(tempv);
|
||||
readvt = true;
|
||||
} else if (parts[0].equals("o")) {
|
||||
// Object name is ignored, for now.
|
||||
} else if (parts[0].equals("mtllib")) {
|
||||
if (parts[1] != null) {
|
||||
BufferedReader mreader = parent.createReader(parts[1]);
|
||||
if (mreader != null) {
|
||||
parseMTL(parent, mreader, materials, mtlTable);
|
||||
}
|
||||
}
|
||||
} else if (parts[0].equals("g")) {
|
||||
gname = 1 < parts.length ? parts[1] : "";
|
||||
} else if (parts[0].equals("usemtl")) {
|
||||
// Getting index of current active material (will be applied on
|
||||
// all subsequent faces).
|
||||
if (parts[1] != null) {
|
||||
String mtlname = parts[1];
|
||||
if (mtlTable.containsKey(mtlname)) {
|
||||
Integer tempInt = mtlTable.get(mtlname);
|
||||
mtlIdxCur = tempInt.intValue();
|
||||
} else {
|
||||
mtlIdxCur = -1;
|
||||
}
|
||||
}
|
||||
} else if (parts[0].equals("f")) {
|
||||
// Face setting
|
||||
OBJFace face = new OBJFace();
|
||||
face.matIdx = mtlIdxCur;
|
||||
face.name = gname;
|
||||
|
||||
for (int i = 1; i < parts.length; i++) {
|
||||
String seg = parts[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 parts[] = line.split("\\s+");
|
||||
if (parts.length > 0) {
|
||||
// Extract the material data.
|
||||
if (parts[0].equals("newmtl")) {
|
||||
// Starting new material.
|
||||
String mtlname = parts[1];
|
||||
currentMtl = new OBJMaterial(mtlname);
|
||||
materialsHash.put(mtlname, new Integer(materials.size()));
|
||||
materials.add(currentMtl);
|
||||
} else if (parts[0].equals("map_Kd") && parts.length > 1) {
|
||||
// Loading texture map.
|
||||
String texname = parts[1];
|
||||
currentMtl.kdMap = parent.loadImage(texname);
|
||||
} else if (parts[0].equals("Ka") && parts.length > 3) {
|
||||
// The ambient color of the material
|
||||
currentMtl.ka.x = Float.valueOf(parts[1]).floatValue();
|
||||
currentMtl.ka.y = Float.valueOf(parts[2]).floatValue();
|
||||
currentMtl.ka.z = Float.valueOf(parts[3]).floatValue();
|
||||
} else if (parts[0].equals("Kd") && parts.length > 3) {
|
||||
// The diffuse color of the material
|
||||
currentMtl.kd.x = Float.valueOf(parts[1]).floatValue();
|
||||
currentMtl.kd.y = Float.valueOf(parts[2]).floatValue();
|
||||
currentMtl.kd.z = Float.valueOf(parts[3]).floatValue();
|
||||
} else if (parts[0].equals("Ks") && parts.length > 3) {
|
||||
// The specular color weighted by the specular coefficient
|
||||
currentMtl.ks.x = Float.valueOf(parts[1]).floatValue();
|
||||
currentMtl.ks.y = Float.valueOf(parts[2]).floatValue();
|
||||
currentMtl.ks.z = Float.valueOf(parts[3]).floatValue();
|
||||
} else if ((parts[0].equals("d") ||
|
||||
parts[0].equals("Tr")) && parts.length > 1) {
|
||||
// Reading the alpha transparency.
|
||||
currentMtl.d = Float.valueOf(parts[1]).floatValue();
|
||||
} else if (parts[0].equals("Ns") && parts.length > 1) {
|
||||
// The specular component of the Phong shading model
|
||||
currentMtl.ns = Float.valueOf(parts[1]).floatValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static int rgbaValue(PVector color) {
|
||||
return 0xFF000000 | ((int)(color.x * 255) << 16) |
|
||||
((int)(color.y * 255) << 8) |
|
||||
(int)(color.z * 255);
|
||||
}
|
||||
|
||||
|
||||
protected static int rgbaValue(PVector color, float alpha) {
|
||||
return ((int)(alpha * 255) << 24) |
|
||||
((int)(color.x * 255) << 16) |
|
||||
((int)(color.y * 255) << 8) |
|
||||
(int)(color.z * 255);
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,8 +243,8 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
}
|
||||
|
||||
|
||||
static protected PShape2D loadShapeImpl(PGraphics pg, String filename,
|
||||
String extension) {
|
||||
static protected PShape loadShapeImpl(PGraphics pg, String filename,
|
||||
String extension) {
|
||||
PShapeSVG svg = null;
|
||||
|
||||
if (extension.equals("svg")) {
|
||||
@@ -262,7 +262,7 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
}
|
||||
|
||||
if (svg != null) {
|
||||
PShape2D p2d = PShape2D.createShape(pg.parent, svg);
|
||||
PShapeOpenGL p2d = PShapeOpenGL.createShape2D(pg.parent, svg);
|
||||
return p2d;
|
||||
} else {
|
||||
return null;
|
||||
@@ -277,7 +277,7 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
|
||||
@Override
|
||||
public PShape createShape(PShape source) {
|
||||
return PShape2D.createShape(parent, source);
|
||||
return PShapeOpenGL.createShape2D(parent, source);
|
||||
}
|
||||
|
||||
|
||||
@@ -299,44 +299,45 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
}
|
||||
|
||||
|
||||
static protected PShape2D createShapeImpl(PApplet parent, int type) {
|
||||
PShape2D shape = null;
|
||||
static protected PShapeOpenGL createShapeImpl(PApplet parent, int type) {
|
||||
PShapeOpenGL shape = null;
|
||||
if (type == PConstants.GROUP) {
|
||||
shape = new PShape2D(parent, PConstants.GROUP);
|
||||
shape = new PShapeOpenGL(parent, PConstants.GROUP);
|
||||
} else if (type == PShape.PATH) {
|
||||
shape = new PShape2D(parent, PShape.PATH);
|
||||
shape = new PShapeOpenGL(parent, PShape.PATH);
|
||||
} else if (type == POINTS) {
|
||||
shape = new PShape2D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(POINTS);
|
||||
} else if (type == LINES) {
|
||||
shape = new PShape2D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(LINES);
|
||||
} else if (type == TRIANGLE || type == TRIANGLES) {
|
||||
shape = new PShape2D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(TRIANGLES);
|
||||
} else if (type == TRIANGLE_FAN) {
|
||||
shape = new PShape2D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(TRIANGLE_FAN);
|
||||
} else if (type == TRIANGLE_STRIP) {
|
||||
shape = new PShape2D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(TRIANGLE_STRIP);
|
||||
} else if (type == QUAD || type == QUADS) {
|
||||
shape = new PShape2D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(QUADS);
|
||||
} else if (type == QUAD_STRIP) {
|
||||
shape = new PShape2D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(QUAD_STRIP);
|
||||
} else if (type == POLYGON) {
|
||||
shape = new PShape2D(parent, PShape.GEOMETRY);
|
||||
shape = new PShapeOpenGL(parent, PShape.GEOMETRY);
|
||||
shape.setKind(POLYGON);
|
||||
}
|
||||
shape.is3D(false);
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
static protected PShape2D createShapeImpl(PApplet parent, int kind,
|
||||
float... p) {
|
||||
PShape2D shape = null;
|
||||
static protected PShapeOpenGL createShapeImpl(PApplet parent,
|
||||
int kind, float... p) {
|
||||
PShapeOpenGL shape = null;
|
||||
int len = p.length;
|
||||
|
||||
if (kind == POINT) {
|
||||
@@ -344,49 +345,49 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape2D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(POINT);
|
||||
} else if (kind == LINE) {
|
||||
if (len != 4) {
|
||||
showWarning("Wrong number of parameters");
|
||||
return null;
|
||||
}
|
||||
shape = new PShape2D(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 PShape2D(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 PShape2D(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 PShape2D(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 PShape2D(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 PShape2D(parent, PShape.PRIMITIVE);
|
||||
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
|
||||
shape.setKind(ARC);
|
||||
} else if (kind == BOX) {
|
||||
showWarning("Primitive not supported in 2D");
|
||||
@@ -400,6 +401,7 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
shape.setParams(p);
|
||||
}
|
||||
|
||||
shape.is3D(false);
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012 Ben Fry and Casey Reas
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation, version 2.1.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.opengl;
|
||||
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PGraphics;
|
||||
import processing.core.PShape;
|
||||
|
||||
public class PShape2D extends PShapeOpenGL {
|
||||
|
||||
public PShape2D(PApplet parent, int family) {
|
||||
super(parent, family);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is2D() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is3D() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Shape copy
|
||||
|
||||
|
||||
static public PShape2D createShape(PApplet parent, PShape src) {
|
||||
PShape2D dest = null;
|
||||
if (src.getFamily() == GROUP) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, GROUP);
|
||||
PShape2D.copyGroup(parent, src, dest);
|
||||
} else if (src.getFamily() == PRIMITIVE) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, src.getKind(),
|
||||
src.getParams());
|
||||
PShape.copyPrimitive(src, dest);
|
||||
} else if (src.getFamily() == GEOMETRY) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, src.getKind());
|
||||
PShape.copyGeometry(src, dest);
|
||||
} else if (src.getFamily() == PATH) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, PATH);
|
||||
PShape.copyPath(src, dest);
|
||||
}
|
||||
dest.setName(src.getName());
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static public void copyGroup(PApplet parent, PShape src, PShape dest) {
|
||||
copyMatrix(src, dest);
|
||||
copyStyles(src, dest);
|
||||
copyImage(src, dest);
|
||||
|
||||
for (int i = 0; i < src.getChildCount(); i++) {
|
||||
PShape c = PShape2D.createShape(parent, src.getChild(i));
|
||||
dest.addChild(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
|
||||
// Drawing methods
|
||||
|
||||
@Override
|
||||
public void vertex(float x, float y, float z) {
|
||||
PGraphics.showDepthWarningXYZ("vertex");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vertex(float x, float y, float z, float u, float v) {
|
||||
PGraphics.showDepthWarningXYZ("vertex");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
|
||||
// Bezier curves
|
||||
|
||||
@Override
|
||||
public void bezierVertex(float x2, float y2, float z2,
|
||||
float x3, float y3, float z3,
|
||||
float x4, float y4, float z4) {
|
||||
PGraphics.showDepthWarningXYZ("bezierVertex");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void quadraticVertex(float x2, float y2, float z2,
|
||||
float x4, float y4, float z4) {
|
||||
PGraphics.showDepthWarningXYZ("quadVertex");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void curveVertex(float x, float y, float z) {
|
||||
PGraphics.showDepthWarningXYZ("curveVertex");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
|
||||
// Geometric transformations
|
||||
|
||||
@Override
|
||||
public void translate(float tx, float ty, float tz) {
|
||||
PGraphics.showVariationWarning("translate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotateX(float angle) {
|
||||
PGraphics.showDepthWarning("rotateX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotateY(float angle) {
|
||||
PGraphics.showDepthWarning("rotateY");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotateZ(float angle) {
|
||||
PGraphics.showDepthWarning("rotateZ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(float angle, float vx, float vy, float vz) {
|
||||
PGraphics.showVariationWarning("rotate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyMatrix(float n00, float n01, float n02, float n03,
|
||||
float n10, float n11, float n12, float n13,
|
||||
float n20, float n21, float n22, float n23,
|
||||
float n30, float n31, float n32, float n33) {
|
||||
PGraphics.showVariationWarning("applyMatrix");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scale(float sx, float sy, float sz) {
|
||||
PGraphics.showDepthWarningXYZ("scale");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
|
||||
// Setters/getters of individual vertices
|
||||
|
||||
@Override
|
||||
public float getVertexZ(int index) {
|
||||
PGraphics.showDepthWarningXYZ("getVertexZ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVertex(int index, float x, float y) {
|
||||
super.setVertex(index, x, y, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVertex(int index, float x, float y, float z) {
|
||||
PGraphics.showDepthWarningXYZ("setVertex");
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012 Ben Fry and Casey Reas
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation, version 2.1.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.opengl;
|
||||
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PShape;
|
||||
|
||||
public class PShape3D extends PShapeOpenGL {
|
||||
|
||||
public PShape3D(PApplet parent, int family) {
|
||||
super(parent, family);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is2D() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is3D() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Shape copy
|
||||
|
||||
|
||||
static public PShape3D createShape(PApplet parent, PShape src) {
|
||||
PShape3D dest = null;
|
||||
if (src.getFamily() == GROUP) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, GROUP);
|
||||
PShape3D.copyGroup(parent, src, dest);
|
||||
} else if (src.getFamily() == PRIMITIVE) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, src.getKind(),
|
||||
src.getParams());
|
||||
PShape.copyPrimitive(src, dest);
|
||||
} else if (src.getFamily() == GEOMETRY) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, src.getKind());
|
||||
PShape.copyGeometry(src, dest);
|
||||
} else if (src.getFamily() == PATH) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, PATH);
|
||||
PShape.copyPath(src, dest);
|
||||
}
|
||||
dest.setName(src.getName());
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static public void copyGroup(PApplet parent, PShape src, PShape dest) {
|
||||
copyMatrix(src, dest);
|
||||
copyStyles(src, dest);
|
||||
copyImage(src, dest);
|
||||
|
||||
for (int i = 0; i < src.getChildCount(); i++) {
|
||||
PShape c = PShape3D.createShape(parent, src.getChild(i));
|
||||
dest.addChild(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,6 @@ public class PShapeOpenGL extends PShape {
|
||||
// Texturing
|
||||
|
||||
protected HashSet<PImage> textures;
|
||||
protected PImage texture;
|
||||
protected boolean strokedTexture;
|
||||
|
||||
// ........................................................
|
||||
@@ -377,8 +376,8 @@ public class PShapeOpenGL extends PShape {
|
||||
strokedTexture(true);
|
||||
}
|
||||
} else {
|
||||
if (c3d.texture != null) {
|
||||
addTexture(c3d.texture);
|
||||
if (c3d.image != null) {
|
||||
addTexture(c3d.image);
|
||||
if (c3d.stroke) {
|
||||
strokedTexture(true);
|
||||
}
|
||||
@@ -493,6 +492,77 @@ public class PShapeOpenGL extends PShape {
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Shape creation (temporary hack)
|
||||
|
||||
|
||||
static protected PShapeOpenGL createShape3D(PApplet parent, PShape src) {
|
||||
PShapeOpenGL dest = null;
|
||||
if (src.getFamily() == GROUP) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, GROUP);
|
||||
copyGroup3D(parent, src, dest);
|
||||
} else if (src.getFamily() == PRIMITIVE) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, src.getKind(),
|
||||
src.getParams());
|
||||
PShape.copyPrimitive(src, dest);
|
||||
} else if (src.getFamily() == GEOMETRY) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, src.getKind());
|
||||
PShape.copyGeometry(src, dest);
|
||||
} else if (src.getFamily() == PATH) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, PATH);
|
||||
PShape.copyPath(src, dest);
|
||||
}
|
||||
dest.setName(src.getName());
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static public PShapeOpenGL createShape2D(PApplet parent, PShape src) {
|
||||
PShapeOpenGL dest = null;
|
||||
if (src.getFamily() == GROUP) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, GROUP);
|
||||
copyGroup2D(parent, src, dest);
|
||||
} else if (src.getFamily() == PRIMITIVE) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, src.getKind(),
|
||||
src.getParams());
|
||||
PShape.copyPrimitive(src, dest);
|
||||
} else if (src.getFamily() == GEOMETRY) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, src.getKind());
|
||||
PShape.copyGeometry(src, dest);
|
||||
} else if (src.getFamily() == PATH) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, PATH);
|
||||
PShape.copyPath(src, dest);
|
||||
}
|
||||
dest.setName(src.getName());
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static public void copyGroup3D(PApplet parent, PShape src, PShape dest) {
|
||||
copyMatrix(src, dest);
|
||||
copyStyles(src, dest);
|
||||
copyImage(src, dest);
|
||||
|
||||
for (int i = 0; i < src.getChildCount(); i++) {
|
||||
PShape c = createShape3D(parent, src.getChild(i));
|
||||
dest.addChild(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public void copyGroup2D(PApplet parent, PShape src, PShape dest) {
|
||||
copyMatrix(src, dest);
|
||||
copyStyles(src, dest);
|
||||
copyImage(src, dest);
|
||||
|
||||
for (int i = 0; i < src.getChildCount(); i++) {
|
||||
PShape c = createShape2D(parent, src.getChild(i));
|
||||
dest.addChild(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
@@ -674,13 +744,13 @@ public class PShapeOpenGL extends PShape {
|
||||
child.texture(tex);
|
||||
}
|
||||
} else {
|
||||
PImage tex0 = texture;
|
||||
texture = tex;
|
||||
PImage tex0 = image;
|
||||
image = tex;
|
||||
if (tex0 != tex && parent != null) {
|
||||
((PShapeOpenGL)parent).removeTexture(tex);
|
||||
}
|
||||
if (parent != null) {
|
||||
((PShapeOpenGL)parent).addTexture(texture);
|
||||
((PShapeOpenGL)parent).addTexture(image);
|
||||
if (is2D() && stroke) {
|
||||
((PShapeOpenGL)parent).strokedTexture(true);
|
||||
}
|
||||
@@ -697,8 +767,8 @@ public class PShapeOpenGL extends PShape {
|
||||
child.noTexture();
|
||||
}
|
||||
} else {
|
||||
PImage tex0 = texture;
|
||||
texture = null;
|
||||
PImage tex0 = image;
|
||||
image = null;
|
||||
if (tex0 != null && parent != null) {
|
||||
((PShapeOpenGL)parent).removeTexture(tex0);
|
||||
if (is2D()) {
|
||||
@@ -785,7 +855,7 @@ public class PShapeOpenGL extends PShape {
|
||||
if (family == GROUP) {
|
||||
return textures != null && textures.contains(tex);
|
||||
} else {
|
||||
return texture == tex;
|
||||
return image == tex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -794,7 +864,7 @@ public class PShapeOpenGL extends PShape {
|
||||
if (family == GROUP) {
|
||||
return strokedTexture;
|
||||
} else {
|
||||
return texture != null && stroke;
|
||||
return image != null && stroke;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -857,6 +927,10 @@ public class PShapeOpenGL extends PShape {
|
||||
|
||||
@Override
|
||||
public void vertex(float x, float y, float z) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showDepthWarningXYZ("vertex");
|
||||
// return;
|
||||
// }
|
||||
vertexImpl(x, y, z, 0, 0);
|
||||
}
|
||||
|
||||
@@ -872,8 +946,12 @@ public class PShapeOpenGL extends PShape {
|
||||
PGraphics.showWarning("Cannot add vertices to GROUP shape");
|
||||
return;
|
||||
}
|
||||
// if (!is3D) {
|
||||
// PGraphics.showDepthWarningXYZ("vertex");
|
||||
// return;
|
||||
// }
|
||||
|
||||
boolean textured = texture != null;
|
||||
boolean textured = image != null;
|
||||
int fcolor = 0x00;
|
||||
if (fill || textured) {
|
||||
if (!textured) {
|
||||
@@ -887,9 +965,9 @@ public class PShapeOpenGL extends PShape {
|
||||
}
|
||||
}
|
||||
|
||||
if (texture != null && textureMode == IMAGE) {
|
||||
u = PApplet.min(1, u / texture.width);
|
||||
v = PApplet.min(1, v / texture.height);
|
||||
if (image != null && textureMode == IMAGE) {
|
||||
u = PApplet.min(1, u / image.width);
|
||||
v = PApplet.min(1, v / image.height);
|
||||
}
|
||||
|
||||
int scolor = 0x00;
|
||||
@@ -1202,7 +1280,7 @@ public class PShapeOpenGL extends PShape {
|
||||
if (fillColor == newFillColor) return;
|
||||
fillColor = newFillColor;
|
||||
|
||||
if (texture == null) {
|
||||
if (image == null) {
|
||||
Arrays.fill(inGeo.colors, 0, inGeo.vertexCount,
|
||||
PGL.javaToNativeARGB(fillColor));
|
||||
if (shapeEnded && tessellated && hasPolys) {
|
||||
@@ -1344,7 +1422,7 @@ public class PShapeOpenGL extends PShape {
|
||||
stroke = true;
|
||||
}
|
||||
updateStrokeColor(calcColor);
|
||||
if (is2D() && texture != null && parent != null) {
|
||||
if (is2D() && image != null && parent != null) {
|
||||
((PShapeOpenGL)parent).strokedTexture(true);
|
||||
}
|
||||
}
|
||||
@@ -1496,7 +1574,7 @@ public class PShapeOpenGL extends PShape {
|
||||
if (tintColor == newTintColor) return;
|
||||
tintColor = newTintColor;
|
||||
|
||||
if (texture != null) {
|
||||
if (image != null) {
|
||||
Arrays.fill(inGeo.colors, 0, inGeo.vertexCount,
|
||||
PGL.javaToNativeARGB(tintColor));
|
||||
if (shapeEnded && tessellated && hasPolys) {
|
||||
@@ -1796,6 +1874,10 @@ public class PShapeOpenGL extends PShape {
|
||||
|
||||
@Override
|
||||
public void translate(float tx, float ty, float tz) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showVariationWarning("translate");
|
||||
// return;
|
||||
// }
|
||||
transform(TRANSLATE, tx, ty, tz);
|
||||
}
|
||||
|
||||
@@ -1806,8 +1888,38 @@ public class PShapeOpenGL extends PShape {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void rotateX(float angle) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showDepthWarning("rotateX");
|
||||
// return;
|
||||
// }
|
||||
rotate(angle, 1, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void rotateY(float angle) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showDepthWarning("rotateY");
|
||||
// return;
|
||||
// }
|
||||
rotate(angle, 0, 1, 0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void rotateZ(float angle) {
|
||||
transform(ROTATE, angle);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void rotate(float angle, float v0, float v1, float v2) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showVariationWarning("rotate");
|
||||
// return;
|
||||
// }
|
||||
transform(ROTATE, angle, v0, v1, v2);
|
||||
}
|
||||
|
||||
@@ -1826,6 +1938,10 @@ public class PShapeOpenGL extends PShape {
|
||||
|
||||
@Override
|
||||
public void scale(float x, float y, float z) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showDepthWarningXYZ("scale");
|
||||
// return;
|
||||
// }
|
||||
transform(SCALE, x, y, z);
|
||||
}
|
||||
|
||||
@@ -1850,6 +1966,10 @@ public class PShapeOpenGL extends PShape {
|
||||
float n10, float n11, float n12, float n13,
|
||||
float n20, float n21, float n22, float n23,
|
||||
float n30, float n31, float n32, float n33) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showVariationWarning("applyMatrix");
|
||||
// return;
|
||||
// }
|
||||
transform(MATRIX, n00, n01, n02, n03,
|
||||
n10, n11, n12, n13,
|
||||
n20, n21, n22, n23,
|
||||
@@ -2000,6 +2120,10 @@ public class PShapeOpenGL extends PShape {
|
||||
public void bezierVertex(float x2, float y2, float z2,
|
||||
float x3, float y3, float z3,
|
||||
float x4, float y4, float z4) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showDepthWarningXYZ("bezierVertex");
|
||||
// return;
|
||||
// }
|
||||
bezierVertexImpl(x2, y2, z2,
|
||||
x3, y3, z3,
|
||||
x4, y4, z4);
|
||||
@@ -2030,6 +2154,10 @@ public class PShapeOpenGL extends PShape {
|
||||
@Override
|
||||
public void quadraticVertex(float cx, float cy, float cz,
|
||||
float x3, float y3, float z3) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showDepthWarningXYZ("quadraticVertex");
|
||||
// return;
|
||||
// }
|
||||
quadraticVertexImpl(cx, cy, cz,
|
||||
x3, y3, z3);
|
||||
}
|
||||
@@ -2075,6 +2203,10 @@ public class PShapeOpenGL extends PShape {
|
||||
|
||||
@Override
|
||||
public void curveVertex(float x, float y, float z) {
|
||||
// if (!is3D) {
|
||||
// PGraphics.showDepthWarningXYZ("curveVertex");
|
||||
// return;
|
||||
// }
|
||||
curveVertexImpl(x, y, z);
|
||||
}
|
||||
|
||||
@@ -2517,7 +2649,7 @@ public class PShapeOpenGL extends PShape {
|
||||
|
||||
tessellator.setInGeometry(inGeo);
|
||||
tessellator.setTessGeometry(tessGeo);
|
||||
tessellator.setFill(fill || texture != null);
|
||||
tessellator.setFill(fill || image != null);
|
||||
tessellator.setStroke(stroke);
|
||||
tessellator.setStrokeColor(strokeColor);
|
||||
tessellator.setStrokeWeight(strokeWeight);
|
||||
@@ -2591,8 +2723,8 @@ public class PShapeOpenGL extends PShape {
|
||||
tessellatePath();
|
||||
}
|
||||
|
||||
if (texture != null && parent != null) {
|
||||
((PShapeOpenGL)parent).addTexture(texture);
|
||||
if (image != null && parent != null) {
|
||||
((PShapeOpenGL)parent).addTexture(image);
|
||||
}
|
||||
|
||||
firstPolyIndexCache = tessellator.firstPolyIndexCache;
|
||||
@@ -3159,7 +3291,7 @@ public class PShapeOpenGL extends PShape {
|
||||
|
||||
|
||||
protected boolean startStrokedTex(int n) {
|
||||
return texture != null && (n == firstLineIndexCache ||
|
||||
return image != null && (n == firstLineIndexCache ||
|
||||
n == firstPointIndexCache);
|
||||
}
|
||||
|
||||
@@ -4101,7 +4233,7 @@ public class PShapeOpenGL extends PShape {
|
||||
}
|
||||
|
||||
} else {
|
||||
render(gl, texture);
|
||||
render(gl, image);
|
||||
}
|
||||
|
||||
post(gl);
|
||||
|
||||
Reference in New Issue
Block a user