mirror of
https://github.com/esp8266/Arduino.git
synced 2025-08-07 00:04:36 +03:00
Merging r327:r331 of the branches/processing-sync into the trunk. This adds the Processing core, and some new features including printing, copy for discourse, better auto-format, improved keyboard shortcuts, etc.
This commit is contained in:
8334
core/PApplet.java
Normal file
8334
core/PApplet.java
Normal file
File diff suppressed because it is too large
Load Diff
322
core/PConstants.java
Normal file
322
core/PConstants.java
Normal file
@@ -0,0 +1,322 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004-06 Ben Fry and Casey Reas
|
||||
Copyright (c) 2001-04 Massachusetts Institute of Technology
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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.core;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Numbers shared throughout processing.core.
|
||||
* <P>
|
||||
* An attempt is made to keep the constants as short/non-verbose
|
||||
* as possible. For instance, the constant is TIFF instead of
|
||||
* FILE_TYPE_TIFF. We'll do this as long as we can get away with it.
|
||||
*/
|
||||
public interface PConstants {
|
||||
|
||||
// renderers known to processing.core
|
||||
|
||||
static final String P2D = "processing.core.PGraphics2D";
|
||||
static final String P3D = "processing.core.PGraphics3D";
|
||||
static final String JAVA2D = "processing.core.PGraphicsJava2D";
|
||||
static final String OPENGL = "processing.opengl.PGraphicsOpenGL";
|
||||
static final String PDF = "processing.pdf.PGraphicsPDF";
|
||||
static final String DXF = "processing.dxf.RawDXF";
|
||||
//static final String SVG = "processing.dxf.PGraphicsSVG";
|
||||
|
||||
|
||||
// platform IDs for PApplet.platform
|
||||
|
||||
static final int WINDOWS = 1;
|
||||
static final int MACOS9 = 2;
|
||||
static final int MACOSX = 3;
|
||||
static final int LINUX = 4;
|
||||
static final int OTHER = 0;
|
||||
|
||||
|
||||
// for better parity between c++ version (at no speed cost)
|
||||
|
||||
static final float EPSILON = 0.0001f;
|
||||
// was around for auto-port to mobile version
|
||||
//static final float ONE = 1.0f;
|
||||
|
||||
|
||||
// useful goodness
|
||||
|
||||
static final float PI = (float) Math.PI;
|
||||
static final float HALF_PI = PI / 2.0f;
|
||||
static final float THIRD_PI = PI / 3.0f;
|
||||
static final float QUARTER_PI = PI / 4.0f;
|
||||
static final float TWO_PI = PI * 2.0f;
|
||||
|
||||
static final float DEG_TO_RAD = PI/180.0f;
|
||||
static final float RAD_TO_DEG = 180.0f/PI;
|
||||
|
||||
|
||||
// angle modes
|
||||
|
||||
//static final int RADIANS = 0;
|
||||
//static final int DEGREES = 1;
|
||||
|
||||
|
||||
// used by split, all the standard whitespace chars
|
||||
// (also includes unicode nbsp, that little bostage)
|
||||
|
||||
static final String WHITESPACE = " \t\n\r\f\u00A0";
|
||||
|
||||
|
||||
// for colors and/or images
|
||||
|
||||
static final int RGB = 1; // image & color
|
||||
static final int ARGB = 2; // image
|
||||
static final int HSB = 3; // color
|
||||
static final int ALPHA = 4; // image
|
||||
|
||||
|
||||
// image file types
|
||||
|
||||
static final int TIFF = 0;
|
||||
static final int TARGA = 1;
|
||||
static final int JPEG = 2;
|
||||
static final int GIF = 3;
|
||||
|
||||
|
||||
// filter/convert types
|
||||
|
||||
static final int BLUR = 11;
|
||||
static final int GRAY = 12;
|
||||
static final int INVERT = 13;
|
||||
static final int OPAQUE = 14;
|
||||
static final int POSTERIZE = 15;
|
||||
static final int THRESHOLD = 16;
|
||||
static final int ERODE = 17;
|
||||
static final int DILATE = 18;
|
||||
|
||||
|
||||
// blend mode keyword definitions
|
||||
// @see processing.core.PImage#blendColor(int,int,int)
|
||||
|
||||
public final static int REPLACE = 0;
|
||||
public final static int BLEND = 1 << 0;
|
||||
public final static int ADD = 1 << 1;
|
||||
public final static int SUBTRACT = 1 << 2;
|
||||
public final static int LIGHTEST = 1 << 3;
|
||||
public final static int DARKEST = 1 << 4;
|
||||
public final static int DIFFERENCE = 1 << 5;
|
||||
public final static int EXCLUSION = 1 << 6;
|
||||
public final static int MULTIPLY = 1 << 7;
|
||||
public final static int SCREEN = 1 << 8;
|
||||
public final static int OVERLAY = 1 << 9;
|
||||
public final static int HARD_LIGHT = 1 << 10;
|
||||
public final static int SOFT_LIGHT = 1 << 11;
|
||||
public final static int DODGE = 1 << 12;
|
||||
public final static int BURN = 1 << 13;
|
||||
|
||||
// colour component bitmasks
|
||||
|
||||
public static final int ALPHA_MASK = 0xff000000;
|
||||
public static final int RED_MASK = 0x00ff0000;
|
||||
public static final int GREEN_MASK = 0x0000ff00;
|
||||
public static final int BLUE_MASK = 0x000000ff;
|
||||
|
||||
|
||||
// for messages
|
||||
|
||||
static final int CHATTER = 0;
|
||||
static final int COMPLAINT = 1;
|
||||
static final int PROBLEM = 2;
|
||||
|
||||
|
||||
// types of projection matrices
|
||||
|
||||
static final int CUSTOM = 0; // user-specified fanciness
|
||||
static final int ORTHOGRAPHIC = 2; // 2D isometric projection
|
||||
static final int PERSPECTIVE = 3; // perspective matrix
|
||||
|
||||
|
||||
// rendering settings
|
||||
|
||||
static final float PIXEL_CENTER = 0.5f; // for polygon aa
|
||||
|
||||
|
||||
// shapes
|
||||
|
||||
// the low four bits set the variety,
|
||||
// higher bits set the specific shape type
|
||||
|
||||
static final int POINTS = (1 << 4) | 0;
|
||||
|
||||
static final int LINES = (1 << 5) | 0;
|
||||
//static final int LINE_STRIP = (1 << 5) | 1;
|
||||
//static final int LINE_LOOP = (1 << 5) | 2;
|
||||
|
||||
static final int TRIANGLES = (1 << 6) | 0;
|
||||
static final int TRIANGLE_STRIP = (1 << 6) | 1;
|
||||
static final int TRIANGLE_FAN = (1 << 6) | 2;
|
||||
|
||||
static final int QUADS = (1 << 7) | 0;
|
||||
static final int QUAD_STRIP = (1 << 7) | 1;
|
||||
|
||||
static final int POLYGON = (1 << 8) | 0;
|
||||
//static final int CONCAVE_POLYGON = (1 << 8) | 1;
|
||||
//static final int CONVEX_POLYGON = (1 << 8) | 2;
|
||||
|
||||
static final int OPEN = 1;
|
||||
static final int CLOSE = 2;
|
||||
|
||||
|
||||
// shape drawing modes
|
||||
|
||||
/** Draw mode convention to use (x, y) to (width, height) */
|
||||
static final int CORNER = 0;
|
||||
/** Draw mode convention to use (x1, y1) to (x2, y2) coordinates */
|
||||
static final int CORNERS = 1;
|
||||
/** @deprecated Use RADIUS instead (as of 0125) */
|
||||
static final int CENTER_RADIUS = 2;
|
||||
/** Draw mode from the center, and using the radius */
|
||||
static final int RADIUS = 2;
|
||||
/** Draw from the center, using second pair of values as the diameter.
|
||||
Formerly called CENTER_DIAMETER in alpha releases */
|
||||
static final int CENTER = 3;
|
||||
|
||||
|
||||
// vertically alignment modes for text
|
||||
|
||||
/** Default vertical alignment for text placement */
|
||||
static final int BASELINE = 0;
|
||||
/** Align text to the top */
|
||||
static final int TOP = 101;
|
||||
/** Align text from the bottom, using the baseline. */
|
||||
static final int BOTTOM = 102;
|
||||
|
||||
|
||||
// uv texture orientation modes
|
||||
|
||||
static final int NORMALIZED = 1; //_SPACE = 0; // 0..1
|
||||
static final int IMAGE = 2;
|
||||
|
||||
|
||||
// text placement modes
|
||||
|
||||
/**
|
||||
* textMode(MODEL) is the default, meaning that characters
|
||||
* will be affected by transformations like any other shapes.
|
||||
* <p/>
|
||||
* Changed value in 0093 to not interfere with LEFT, CENTER, and RIGHT.
|
||||
*/
|
||||
static final int MODEL = 4;
|
||||
|
||||
/**
|
||||
* textMode(SHAPE) draws text using the the glyph outlines of
|
||||
* individual characters rather than as textures. If the outlines are
|
||||
* not available, then textMode(SHAPE) will be ignored and textMode(MODEL)
|
||||
* will be used instead. For this reason, be sure to call textMode()
|
||||
* <EM>after</EM> calling textFont().
|
||||
* <p/>
|
||||
* Currently, textMode(SHAPE) is only supported by OPENGL mode.
|
||||
* It also requires Java 1.2 or higher (OPENGL requires 1.4 anyway)
|
||||
*/
|
||||
static final int SHAPE = 5;
|
||||
|
||||
|
||||
// text alignment modes
|
||||
// are inherited from LEFT, CENTER, RIGHT
|
||||
|
||||
|
||||
// stroke modes
|
||||
|
||||
static final int SQUARE = 1 << 0; // called 'butt' in the svg spec
|
||||
static final int ROUND = 1 << 1;
|
||||
static final int PROJECT = 1 << 2; // called 'square' in the svg spec
|
||||
static final int MITER = 1 << 3;
|
||||
static final int BEVEL = 1 << 5;
|
||||
|
||||
|
||||
// lighting
|
||||
|
||||
static final int AMBIENT = 0;
|
||||
static final int DIRECTIONAL = 1;
|
||||
static final int POINT = 2;
|
||||
static final int SPOT = 3;
|
||||
|
||||
|
||||
// key constants
|
||||
|
||||
// only including the most-used of these guys
|
||||
// if people need more esoteric keys, they can learn about
|
||||
// the esoteric java KeyEvent api and of virtual keys
|
||||
|
||||
// both key and keyCode will equal these values
|
||||
// for 0125, these were changed to 'char' values, because they
|
||||
// can be upgraded to ints automatically by Java, but having them
|
||||
// as ints prevented split(blah, TAB) from working
|
||||
static final char BACKSPACE = 8;
|
||||
static final char TAB = 9;
|
||||
static final char ENTER = 10;
|
||||
static final char RETURN = 13;
|
||||
static final char ESC = 27;
|
||||
static final char DELETE = 127;
|
||||
|
||||
// i.e. if ((key == CODED) && (keyCode == UP))
|
||||
static final int CODED = 0xffff;
|
||||
|
||||
// key will be CODED and keyCode will be this value
|
||||
static final int UP = KeyEvent.VK_UP;
|
||||
static final int DOWN = KeyEvent.VK_DOWN;
|
||||
static final int LEFT = KeyEvent.VK_LEFT;
|
||||
static final int RIGHT = KeyEvent.VK_RIGHT;
|
||||
|
||||
// key will be CODED and keyCode will be this value
|
||||
static final int ALT = KeyEvent.VK_ALT;
|
||||
static final int CONTROL = KeyEvent.VK_CONTROL;
|
||||
static final int SHIFT = KeyEvent.VK_SHIFT;
|
||||
|
||||
|
||||
// cursor types
|
||||
|
||||
static final int ARROW = Cursor.DEFAULT_CURSOR;
|
||||
static final int CROSS = Cursor.CROSSHAIR_CURSOR;
|
||||
static final int HAND = Cursor.HAND_CURSOR;
|
||||
static final int MOVE = Cursor.MOVE_CURSOR;
|
||||
static final int TEXT = Cursor.TEXT_CURSOR;
|
||||
static final int WAIT = Cursor.WAIT_CURSOR;
|
||||
|
||||
|
||||
// hints
|
||||
|
||||
//static final int SCALE_STROKE_WIDTH = 0;
|
||||
//static final int LIGHTING_AFFECTS_STROKE = 1;
|
||||
static final int ENABLE_NATIVE_FONTS = 2;
|
||||
static final int DISABLE_TEXT_SMOOTH = 3;
|
||||
//static final int DISABLE_SMOOTH_HACK = 4;
|
||||
static final int DISABLE_DEPTH_TEST = 5;
|
||||
static final int NO_FLYING_POO = 6;
|
||||
static final int ENABLE_DEPTH_SORT = 7;
|
||||
static final int DISABLE_ERROR_REPORT = 8;
|
||||
static final int ENABLE_ACCURATE_TEXTURES = 9;
|
||||
|
||||
static final int HINT_COUNT = 10;
|
||||
}
|
1019
core/PFont.java
Normal file
1019
core/PFont.java
Normal file
File diff suppressed because it is too large
Load Diff
4308
core/PGraphics.java
Normal file
4308
core/PGraphics.java
Normal file
File diff suppressed because it is too large
Load Diff
1672
core/PGraphics2D.java
Normal file
1672
core/PGraphics2D.java
Normal file
File diff suppressed because it is too large
Load Diff
3943
core/PGraphics3D.java
Normal file
3943
core/PGraphics3D.java
Normal file
File diff suppressed because it is too large
Load Diff
1381
core/PGraphicsJava2D.java
Normal file
1381
core/PGraphicsJava2D.java
Normal file
File diff suppressed because it is too large
Load Diff
2598
core/PImage.java
Normal file
2598
core/PImage.java
Normal file
File diff suppressed because it is too large
Load Diff
1295
core/PLine.java
Normal file
1295
core/PLine.java
Normal file
File diff suppressed because it is too large
Load Diff
640
core/PMatrix.java
Normal file
640
core/PMatrix.java
Normal file
@@ -0,0 +1,640 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://Proce55ing.net
|
||||
|
||||
Copyright (c) 2005-06 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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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.core;
|
||||
|
||||
|
||||
/**
|
||||
* 4x4 matrix implementation.
|
||||
*/
|
||||
public final class PMatrix implements PConstants {
|
||||
|
||||
public float m00, m01, m02, m03;
|
||||
public float m10, m11, m12, m13;
|
||||
public float m20, m21, m22, m23;
|
||||
public float m30, m31, m32, m33;
|
||||
|
||||
final static int DEFAULT_STACK_DEPTH = 0;
|
||||
int maxStackDepth;
|
||||
int stackPointer = 0;
|
||||
float stack[][];
|
||||
|
||||
|
||||
// locally allocated version to avoid creating new memory
|
||||
static protected PMatrix inverseCopy;
|
||||
|
||||
|
||||
public PMatrix() {
|
||||
set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
||||
maxStackDepth = DEFAULT_STACK_DEPTH;
|
||||
}
|
||||
|
||||
|
||||
public PMatrix(int stackDepth) {
|
||||
set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
||||
stack = new float[stackDepth][16];
|
||||
maxStackDepth = stackDepth;
|
||||
}
|
||||
|
||||
|
||||
public PMatrix(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33) {
|
||||
set(m00, m01, m02, m03,
|
||||
m10, m11, m12, m13,
|
||||
m20, m21, m22, m23,
|
||||
m30, m31, m32, m33);
|
||||
maxStackDepth = DEFAULT_STACK_DEPTH;
|
||||
}
|
||||
|
||||
|
||||
// Make a copy of a matrix. We copy the stack depth,
|
||||
// but we don't make a copy of the stack or the stack pointer.
|
||||
public PMatrix(PMatrix src) {
|
||||
set(src);
|
||||
maxStackDepth = src.maxStackDepth;
|
||||
stack = new float[maxStackDepth][16];
|
||||
}
|
||||
|
||||
|
||||
public void reset() {
|
||||
set(1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void clearStack() {
|
||||
stackPointer = 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean push() {
|
||||
if (stackPointer == maxStackDepth) return false;
|
||||
|
||||
stack[stackPointer][0] = m00;
|
||||
stack[stackPointer][1] = m01;
|
||||
stack[stackPointer][2] = m02;
|
||||
stack[stackPointer][3] = m03;
|
||||
|
||||
stack[stackPointer][4] = m10;
|
||||
stack[stackPointer][5] = m11;
|
||||
stack[stackPointer][6] = m12;
|
||||
stack[stackPointer][7] = m13;
|
||||
|
||||
stack[stackPointer][8] = m20;
|
||||
stack[stackPointer][9] = m21;
|
||||
stack[stackPointer][10] = m22;
|
||||
stack[stackPointer][11] = m23;
|
||||
|
||||
stack[stackPointer][12] = m30;
|
||||
stack[stackPointer][13] = m31;
|
||||
stack[stackPointer][14] = m32;
|
||||
stack[stackPointer][15] = m33;
|
||||
|
||||
stackPointer++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean pop() {
|
||||
if (stackPointer == 0) return false;
|
||||
stackPointer--;
|
||||
|
||||
m00 = stack[stackPointer][0];
|
||||
m01 = stack[stackPointer][1];
|
||||
m02 = stack[stackPointer][2];
|
||||
m03 = stack[stackPointer][3];
|
||||
|
||||
m10 = stack[stackPointer][4];
|
||||
m11 = stack[stackPointer][5];
|
||||
m12 = stack[stackPointer][6];
|
||||
m13 = stack[stackPointer][7];
|
||||
|
||||
m20 = stack[stackPointer][8];
|
||||
m21 = stack[stackPointer][9];
|
||||
m22 = stack[stackPointer][10];
|
||||
m23 = stack[stackPointer][11];
|
||||
|
||||
m30 = stack[stackPointer][12];
|
||||
m31 = stack[stackPointer][13];
|
||||
m32 = stack[stackPointer][14];
|
||||
m33 = stack[stackPointer][15];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public void set(PMatrix src) {
|
||||
set(src.m00, src.m01, src.m02, src.m03,
|
||||
src.m10, src.m11, src.m12, src.m13,
|
||||
src.m20, src.m21, src.m22, src.m23,
|
||||
src.m30, src.m31, src.m32, src.m33);
|
||||
}
|
||||
|
||||
|
||||
public void set(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33) {
|
||||
this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
|
||||
this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
|
||||
this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
|
||||
this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
|
||||
}
|
||||
|
||||
|
||||
public void translate(float tx, float ty) {
|
||||
translate(tx, ty, 0);
|
||||
}
|
||||
|
||||
public void invTranslate(float tx, float ty) {
|
||||
invTranslate(tx, ty, 0);
|
||||
}
|
||||
|
||||
|
||||
public void translate(float tx, float ty, float tz) {
|
||||
m03 += tx*m00 + ty*m01 + tz*m02;
|
||||
m13 += tx*m10 + ty*m11 + tz*m12;
|
||||
m23 += tx*m20 + ty*m21 + tz*m22;
|
||||
m33 += tx*m30 + ty*m31 + tz*m32;
|
||||
}
|
||||
|
||||
public void invTranslate(float tx, float ty, float tz) {
|
||||
preApply(1, 0, 0, -tx,
|
||||
0, 1, 0, -ty,
|
||||
0, 0, 1, -tz,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
// OPT could save several multiplies for the 0s and 1s by just
|
||||
// putting the multMatrix code here and removing uneccessary terms
|
||||
|
||||
public void rotateX(float angle) {
|
||||
float c = cos(angle);
|
||||
float s = sin(angle);
|
||||
apply(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void invRotateX(float angle) {
|
||||
float c = cos(-angle);
|
||||
float s = sin(-angle);
|
||||
preApply(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void rotateY(float angle) {
|
||||
float c = cos(angle);
|
||||
float s = sin(angle);
|
||||
apply(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void invRotateY(float angle) {
|
||||
float c = cos(-angle);
|
||||
float s = sin(-angle);
|
||||
preApply(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Just calls rotateZ because two dimensional rotation
|
||||
* is the same as rotating along the z-axis.
|
||||
*/
|
||||
public void rotate(float angle) {
|
||||
rotateZ(angle);
|
||||
}
|
||||
|
||||
|
||||
public void invRotate(float angle) {
|
||||
invRotateZ(angle);
|
||||
}
|
||||
|
||||
|
||||
public void rotateZ(float angle) {
|
||||
float c = cos(angle);
|
||||
float s = sin(angle);
|
||||
apply(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void invRotateZ(float angle) {
|
||||
float c = cos(-angle);
|
||||
float s = sin(-angle);
|
||||
preApply(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void rotate(float angle, float v0, float v1, float v2) {
|
||||
// should be in radians (i think), instead of degrees (gl uses degrees)
|
||||
// based on 15-463 code, but similar to opengl ref p.443
|
||||
|
||||
// TODO should make sure this vector is normalized
|
||||
|
||||
float c = cos(angle);
|
||||
float s = sin(angle);
|
||||
float t = 1.0f - c;
|
||||
|
||||
apply((t*v0*v0) + c, (t*v0*v1) - (s*v2), (t*v0*v2) + (s*v1), 0,
|
||||
(t*v0*v1) + (s*v2), (t*v1*v1) + c, (t*v1*v2) - (s*v0), 0,
|
||||
(t*v0*v2) - (s*v1), (t*v1*v2) + (s*v0), (t*v2*v2) + c, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void invRotate(float angle, float v0, float v1, float v2) {
|
||||
// TODO should make sure this vector is normalized
|
||||
|
||||
float c = cos(-angle);
|
||||
float s = sin(-angle);
|
||||
float t = 1.0f - c;
|
||||
|
||||
preApply((t*v0*v0) + c, (t*v0*v1) - (s*v2), (t*v0*v2) + (s*v1), 0,
|
||||
(t*v0*v1) + (s*v2), (t*v1*v1) + c, (t*v1*v2) - (s*v0), 0,
|
||||
(t*v0*v2) - (s*v1), (t*v1*v2) + (s*v0), (t*v2*v2) + c, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void scale(float s) {
|
||||
apply(s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void invScale(float s) {
|
||||
preApply(1/s, 0, 0, 0, 0, 1/s, 0, 0, 0, 0, 1/s, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void scale(float sx, float sy) {
|
||||
apply(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void invScale(float sx, float sy) {
|
||||
preApply(1/sx, 0, 0, 0, 0, 1/sy, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
// OPTIMIZE: same as above
|
||||
public void scale(float x, float y, float z) {
|
||||
apply(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void invScale(float x, float y, float z) {
|
||||
preApply(1/x, 0, 0, 0, 0, 1/y, 0, 0, 0, 0, 1/z, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public void transform(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) {
|
||||
apply(n00, n01, n02, n03,
|
||||
n10, n11, n12, n13,
|
||||
n20, n21, n22, n23,
|
||||
n30, n31, n32, n33);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public void preApply(PMatrix lhs) {
|
||||
preApply(lhs.m00, lhs.m01, lhs.m02, lhs.m03,
|
||||
lhs.m10, lhs.m11, lhs.m12, lhs.m13,
|
||||
lhs.m20, lhs.m21, lhs.m22, lhs.m23,
|
||||
lhs.m30, lhs.m31, lhs.m32, lhs.m33);
|
||||
}
|
||||
|
||||
|
||||
// for inverse operations, like multiplying the matrix on the left
|
||||
public void preApply(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) {
|
||||
|
||||
float r00 = n00*m00 + n01*m10 + n02*m20 + n03*m30;
|
||||
float r01 = n00*m01 + n01*m11 + n02*m21 + n03*m31;
|
||||
float r02 = n00*m02 + n01*m12 + n02*m22 + n03*m32;
|
||||
float r03 = n00*m03 + n01*m13 + n02*m23 + n03*m33;
|
||||
|
||||
float r10 = n10*m00 + n11*m10 + n12*m20 + n13*m30;
|
||||
float r11 = n10*m01 + n11*m11 + n12*m21 + n13*m31;
|
||||
float r12 = n10*m02 + n11*m12 + n12*m22 + n13*m32;
|
||||
float r13 = n10*m03 + n11*m13 + n12*m23 + n13*m33;
|
||||
|
||||
float r20 = n20*m00 + n21*m10 + n22*m20 + n23*m30;
|
||||
float r21 = n20*m01 + n21*m11 + n22*m21 + n23*m31;
|
||||
float r22 = n20*m02 + n21*m12 + n22*m22 + n23*m32;
|
||||
float r23 = n20*m03 + n21*m13 + n22*m23 + n23*m33;
|
||||
|
||||
float r30 = n30*m00 + n31*m10 + n32*m20 + n33*m30;
|
||||
float r31 = n30*m01 + n31*m11 + n32*m21 + n33*m31;
|
||||
float r32 = n30*m02 + n31*m12 + n32*m22 + n33*m32;
|
||||
float r33 = n30*m03 + n31*m13 + n32*m23 + n33*m33;
|
||||
|
||||
m00 = r00; m01 = r01; m02 = r02; m03 = r03;
|
||||
m10 = r10; m11 = r11; m12 = r12; m13 = r13;
|
||||
m20 = r20; m21 = r21; m22 = r22; m23 = r23;
|
||||
m30 = r30; m31 = r31; m32 = r32; m33 = r33;
|
||||
}
|
||||
|
||||
|
||||
public boolean invApply(PMatrix rhs) {
|
||||
PMatrix copy = new PMatrix(rhs);
|
||||
PMatrix inverse = copy.invert();
|
||||
if (inverse == null) return false;
|
||||
preApply(inverse);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean invApply(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) {
|
||||
if (inverseCopy == null) {
|
||||
inverseCopy = new PMatrix();
|
||||
}
|
||||
inverseCopy.set(n00, n01, n02, n03,
|
||||
n10, n11, n12, n13,
|
||||
n20, n21, n22, n23,
|
||||
n30, n31, n32, n33);
|
||||
PMatrix inverse = inverseCopy.invert();
|
||||
if (inverse == null) return false;
|
||||
preApply(inverse);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public void apply(PMatrix rhs) {
|
||||
apply(rhs.m00, rhs.m01, rhs.m02, rhs.m03,
|
||||
rhs.m10, rhs.m11, rhs.m12, rhs.m13,
|
||||
rhs.m20, rhs.m21, rhs.m22, rhs.m23,
|
||||
rhs.m30, rhs.m31, rhs.m32, rhs.m33);
|
||||
}
|
||||
|
||||
|
||||
public void apply(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) {
|
||||
|
||||
float r00 = m00*n00 + m01*n10 + m02*n20 + m03*n30;
|
||||
float r01 = m00*n01 + m01*n11 + m02*n21 + m03*n31;
|
||||
float r02 = m00*n02 + m01*n12 + m02*n22 + m03*n32;
|
||||
float r03 = m00*n03 + m01*n13 + m02*n23 + m03*n33;
|
||||
|
||||
float r10 = m10*n00 + m11*n10 + m12*n20 + m13*n30;
|
||||
float r11 = m10*n01 + m11*n11 + m12*n21 + m13*n31;
|
||||
float r12 = m10*n02 + m11*n12 + m12*n22 + m13*n32;
|
||||
float r13 = m10*n03 + m11*n13 + m12*n23 + m13*n33;
|
||||
|
||||
float r20 = m20*n00 + m21*n10 + m22*n20 + m23*n30;
|
||||
float r21 = m20*n01 + m21*n11 + m22*n21 + m23*n31;
|
||||
float r22 = m20*n02 + m21*n12 + m22*n22 + m23*n32;
|
||||
float r23 = m20*n03 + m21*n13 + m22*n23 + m23*n33;
|
||||
|
||||
float r30 = m30*n00 + m31*n10 + m32*n20 + m33*n30;
|
||||
float r31 = m30*n01 + m31*n11 + m32*n21 + m33*n31;
|
||||
float r32 = m30*n02 + m31*n12 + m32*n22 + m33*n32;
|
||||
float r33 = m30*n03 + m31*n13 + m32*n23 + m33*n33;
|
||||
|
||||
m00 = r00; m01 = r01; m02 = r02; m03 = r03;
|
||||
m10 = r10; m11 = r11; m12 = r12; m13 = r13;
|
||||
m20 = r20; m21 = r21; m22 = r22; m23 = r23;
|
||||
m30 = r30; m31 = r31; m32 = r32; m33 = r33;
|
||||
}
|
||||
|
||||
|
||||
public void mult3(float vec[], float out[]) {
|
||||
// must use these temp vars because vec may be the same as out
|
||||
float tmpx = m00*vec[0] + m01*vec[1] + m02*vec[2] + m03;
|
||||
float tmpy = m10*vec[0] + m11*vec[1] + m12*vec[2] + m13;
|
||||
float tmpz = m20*vec[0] + m21*vec[1] + m22*vec[2] + m23;
|
||||
|
||||
out[0] = tmpx;
|
||||
out[1] = tmpy;
|
||||
out[2] = tmpz;
|
||||
}
|
||||
|
||||
|
||||
public void mult(float vec[], float out[]) {
|
||||
// must use these temp vars because vec may be the same as out
|
||||
float tmpx = m00*vec[0] + m01*vec[1] + m02*vec[2] + m03*vec[3];
|
||||
float tmpy = m10*vec[0] + m11*vec[1] + m12*vec[2] + m13*vec[3];
|
||||
float tmpz = m20*vec[0] + m21*vec[1] + m22*vec[2] + m23*vec[3];
|
||||
float tmpw = m30*vec[0] + m31*vec[1] + m32*vec[2] + m33*vec[3];
|
||||
|
||||
out[0] = tmpx;
|
||||
out[1] = tmpy;
|
||||
out[2] = tmpz;
|
||||
out[3] = tmpw;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the determinant of the matrix
|
||||
*/
|
||||
public float determinant() {
|
||||
float f =
|
||||
m00
|
||||
* ((m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32)
|
||||
- m13 * m22 * m31
|
||||
- m11 * m23 * m32
|
||||
- m12 * m21 * m33);
|
||||
f -= m01
|
||||
* ((m10 * m22 * m33 + m12 * m23 * m30 + m13 * m20 * m32)
|
||||
- m13 * m22 * m30
|
||||
- m10 * m23 * m32
|
||||
- m12 * m20 * m33);
|
||||
f += m02
|
||||
* ((m10 * m21 * m33 + m11 * m23 * m30 + m13 * m20 * m31)
|
||||
- m13 * m21 * m30
|
||||
- m10 * m23 * m31
|
||||
- m11 * m20 * m33);
|
||||
f -= m03
|
||||
* ((m10 * m21 * m32 + m11 * m22 * m30 + m12 * m20 * m31)
|
||||
- m12 * m21 * m30
|
||||
- m10 * m22 * m31
|
||||
- m11 * m20 * m32);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the determinant of a 3x3 matrix
|
||||
* @return result
|
||||
*/
|
||||
private float determinant3x3(float t00, float t01, float t02,
|
||||
float t10, float t11, float t12,
|
||||
float t20, float t21, float t22) {
|
||||
return (t00 * (t11 * t22 - t12 * t21) +
|
||||
t01 * (t12 * t20 - t10 * t22) +
|
||||
t02 * (t10 * t21 - t11 * t20));
|
||||
}
|
||||
|
||||
|
||||
public PMatrix transpose() {
|
||||
float temp;
|
||||
temp = m01; m01 = m10; m10 = temp;
|
||||
temp = m02; m02 = m20; m20 = temp;
|
||||
temp = m03; m03 = m30; m30 = temp;
|
||||
temp = m12; m12 = m21; m21 = temp;
|
||||
temp = m13; m13 = m31; m31 = temp;
|
||||
temp = m23; m23 = m32; m32 = temp;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invert this matrix
|
||||
* @return this if successful, null otherwise
|
||||
*/
|
||||
public PMatrix invert() {
|
||||
|
||||
float determinant = determinant();
|
||||
|
||||
if (determinant != 0) {
|
||||
// m00 m01 m02 m03
|
||||
// m10 m11 m12 m13
|
||||
// m20 m21 m22 m23
|
||||
// m30 m31 m32 m33
|
||||
float determinant_inv = 1f / determinant;
|
||||
|
||||
// first row
|
||||
float t00 = determinant3x3(m11, m12, m13, m21, m22, m23, m31, m32, m33);
|
||||
float t01 = -determinant3x3(m10, m12, m13, m20, m22, m23, m30, m32, m33);
|
||||
float t02 = determinant3x3(m10, m11, m13, m20, m21, m23, m30, m31, m33);
|
||||
float t03 = -determinant3x3(m10, m11, m12, m20, m21, m22, m30, m31, m32);
|
||||
|
||||
// second row
|
||||
float t10 = -determinant3x3(m01, m02, m03, m21, m22, m23, m31, m32, m33);
|
||||
float t11 = determinant3x3(m00, m02, m03, m20, m22, m23, m30, m32, m33);
|
||||
float t12 = -determinant3x3(m00, m01, m03, m20, m21, m23, m30, m31, m33);
|
||||
float t13 = determinant3x3(m00, m01, m02, m20, m21, m22, m30, m31, m32);
|
||||
|
||||
// third row
|
||||
float t20 = determinant3x3(m01, m02, m03, m11, m12, m13, m31, m32, m33);
|
||||
float t21 = -determinant3x3(m00, m02, m03, m10, m12, m13, m30, m32, m33);
|
||||
float t22 = determinant3x3(m00, m01, m03, m10, m11, m13, m30, m31, m33);
|
||||
float t23 = -determinant3x3(m00, m01, m02, m10, m11, m12, m30, m31, m32);
|
||||
|
||||
// fourth row
|
||||
float t30 = -determinant3x3(m01, m02, m03, m11, m12, m13, m21, m22, m23);
|
||||
float t31 = determinant3x3(m00, m02, m03, m10, m12, m13, m20, m22, m23);
|
||||
float t32 = -determinant3x3(m00, m01, m03, m10, m11, m13, m20, m21, m23);
|
||||
float t33 = determinant3x3(m00, m01, m02, m10, m11, m12, m20, m21, m22);
|
||||
|
||||
// transpose and divide by the determinant
|
||||
m00 = t00*determinant_inv;
|
||||
m11 = t11*determinant_inv;
|
||||
m22 = t22*determinant_inv;
|
||||
m33 = t33*determinant_inv;
|
||||
m01 = t10*determinant_inv;
|
||||
m10 = t01*determinant_inv;
|
||||
m20 = t02*determinant_inv;
|
||||
m02 = t20*determinant_inv;
|
||||
m12 = t21*determinant_inv;
|
||||
m21 = t12*determinant_inv;
|
||||
m03 = t30*determinant_inv;
|
||||
m30 = t03*determinant_inv;
|
||||
m13 = t31*determinant_inv;
|
||||
m31 = t13*determinant_inv;
|
||||
m32 = t23*determinant_inv;
|
||||
m23 = t32*determinant_inv;
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public void print() {
|
||||
int big = (int) Math.abs(max(max(max(max(abs(m00), abs(m01)),
|
||||
max(abs(m02), abs(m03))),
|
||||
max(max(abs(m10), abs(m11)),
|
||||
max(abs(m12), abs(m13)))),
|
||||
max(max(max(abs(m20), abs(m21)),
|
||||
max(abs(m22), abs(m23))),
|
||||
max(max(abs(m30), abs(m31)),
|
||||
max(abs(m32), abs(m33))))));
|
||||
|
||||
// avoid infinite loop
|
||||
if (Float.isNaN(big) || Float.isInfinite(big)) {
|
||||
big = 1000000; // set to something arbitrary
|
||||
}
|
||||
|
||||
int d = 1;
|
||||
while ((big /= 10) != 0) d++; // cheap log()
|
||||
|
||||
System.out.println(PApplet.nfs(m00, d, 4) + " " +
|
||||
PApplet.nfs(m01, d, 4) + " " +
|
||||
PApplet.nfs(m02, d, 4) + " " +
|
||||
PApplet.nfs(m03, d, 4));
|
||||
|
||||
System.out.println(PApplet.nfs(m10, d, 4) + " " +
|
||||
PApplet.nfs(m11, d, 4) + " " +
|
||||
PApplet.nfs(m12, d, 4) + " " +
|
||||
PApplet.nfs(m13, d, 4));
|
||||
|
||||
System.out.println(PApplet.nfs(m20, d, 4) + " " +
|
||||
PApplet.nfs(m21, d, 4) + " " +
|
||||
PApplet.nfs(m22, d, 4) + " " +
|
||||
PApplet.nfs(m23, d, 4));
|
||||
|
||||
System.out.println(PApplet.nfs(m30, d, 4) + " " +
|
||||
PApplet.nfs(m31, d, 4) + " " +
|
||||
PApplet.nfs(m32, d, 4) + " " +
|
||||
PApplet.nfs(m33, d, 4));
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
private final float max(float a, float b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
private final float abs(float a) {
|
||||
return (a < 0) ? -a : a;
|
||||
}
|
||||
|
||||
private final float sin(float angle) {
|
||||
return (float)Math.sin(angle);
|
||||
}
|
||||
|
||||
private final float cos(float angle) {
|
||||
return (float)Math.cos(angle);
|
||||
}
|
||||
}
|
772
core/PPolygon.java
Normal file
772
core/PPolygon.java
Normal file
@@ -0,0 +1,772 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004-06 Ben Fry and Casey Reas
|
||||
Copyright (c) 2001-04 Massachusetts Institute of Technology
|
||||
|
||||
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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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.core;
|
||||
|
||||
|
||||
/**
|
||||
* zbuffer polygon rendering object for PGraphics.
|
||||
* <P>
|
||||
* Likely to be removed before 1.0 as it's no longer particularly used.
|
||||
*/
|
||||
public class PPolygon implements PConstants {
|
||||
|
||||
// identical to the constants from PGraphics
|
||||
|
||||
static final int X = 0; // transformed xyzw
|
||||
static final int Y = 1; // formerly SX SY SZ
|
||||
static final int Z = 2;
|
||||
|
||||
static final int R = 3; // actual rgb, after lighting
|
||||
static final int G = 4; // fill stored here, transform in place
|
||||
static final int B = 5;
|
||||
static final int A = 6;
|
||||
|
||||
static final int U = 7; // texture
|
||||
static final int V = 8;
|
||||
|
||||
//
|
||||
|
||||
static final int DEFAULT_SIZE = 64; // this is needed for spheres
|
||||
float vertices[][] = new float[DEFAULT_SIZE][PGraphics.VERTEX_FIELD_COUNT];
|
||||
int vertexCount;
|
||||
|
||||
// really this is "debug" but..
|
||||
static final boolean FRY = false;
|
||||
|
||||
// after some fiddling, this seems to produce the best results
|
||||
//static final int ZBUFFER_MIN_COVERAGE = 204;
|
||||
|
||||
float r[] = new float[DEFAULT_SIZE]; // storage used by incrementalize
|
||||
float dr[] = new float[DEFAULT_SIZE];
|
||||
float l[] = new float[DEFAULT_SIZE]; // more storage for incrementalize
|
||||
float dl[] = new float[DEFAULT_SIZE];
|
||||
float sp[] = new float[DEFAULT_SIZE]; // temporary storage for scanline
|
||||
float sdp[] = new float[DEFAULT_SIZE];
|
||||
|
||||
// color and xyz are always interpolated
|
||||
boolean interpX;
|
||||
boolean interpZ;
|
||||
boolean interpUV; // is this necessary? could just check timage != null
|
||||
boolean interpARGB;
|
||||
|
||||
int rgba;
|
||||
int r2, g2, b2, a2, a2orig;
|
||||
|
||||
boolean noDepthTest;
|
||||
|
||||
PGraphics parent;
|
||||
int pixels[];
|
||||
|
||||
// the parent's width/height,
|
||||
// or if smooth is enabled, parent's w/h scaled
|
||||
// up by the smooth dimension
|
||||
int width, height;
|
||||
int width1, height1;
|
||||
|
||||
PImage timage;
|
||||
int tpixels[];
|
||||
int theight, twidth;
|
||||
int theight1, twidth1;
|
||||
int tformat;
|
||||
|
||||
// temp fix to behave like SMOOTH_IMAGES
|
||||
boolean texture_smooth;
|
||||
|
||||
// for anti-aliasing
|
||||
static final int SUBXRES = 8;
|
||||
static final int SUBXRES1 = 7;
|
||||
static final int SUBYRES = 8;
|
||||
static final int SUBYRES1 = 7;
|
||||
static final int MAX_COVERAGE = SUBXRES * SUBYRES;
|
||||
|
||||
boolean smooth;
|
||||
int firstModY;
|
||||
int lastModY;
|
||||
int lastY;
|
||||
int aaleft[] = new int[SUBYRES];
|
||||
int aaright[] = new int[SUBYRES];
|
||||
int aaleftmin, aarightmin;
|
||||
int aaleftmax, aarightmax;
|
||||
int aaleftfull, aarightfull;
|
||||
|
||||
final private int MODYRES(int y) {
|
||||
return (y & SUBYRES1);
|
||||
}
|
||||
|
||||
|
||||
public PPolygon(PGraphics iparent) {
|
||||
parent = iparent;
|
||||
reset(0);
|
||||
}
|
||||
|
||||
|
||||
public void reset(int count) {
|
||||
vertexCount = count;
|
||||
interpX = true;
|
||||
interpZ = true;
|
||||
interpUV = false;
|
||||
interpARGB = true;
|
||||
timage = null;
|
||||
}
|
||||
|
||||
|
||||
public float[] nextVertex() {
|
||||
if (vertexCount == vertices.length) {
|
||||
//parent.message(CHATTER, "re-allocating for " +
|
||||
// (vertexCount*2) + " vertices");
|
||||
float temp[][] = new float[vertexCount<<1][PGraphics.VERTEX_FIELD_COUNT];
|
||||
System.arraycopy(vertices, 0, temp, 0, vertexCount);
|
||||
vertices = temp;
|
||||
|
||||
r = new float[vertices.length];
|
||||
dr = new float[vertices.length];
|
||||
l = new float[vertices.length];
|
||||
dl = new float[vertices.length];
|
||||
sp = new float[vertices.length];
|
||||
sdp = new float[vertices.length];
|
||||
}
|
||||
return vertices[vertexCount++]; // returns v[0], sets vc to 1
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if this vertex is redundant. If so, will also
|
||||
* decrement the vertex count.
|
||||
*/
|
||||
/*
|
||||
public boolean redundantVertex(float x, float y, float z) {
|
||||
// because vertexCount will be 2 when setting vertex[1]
|
||||
if (vertexCount < 2) return false;
|
||||
|
||||
// vertexCount-1 is the current vertex that would be used
|
||||
// vertexCount-2 would be the previous feller
|
||||
if ((Math.abs(vertices[vertexCount-2][MX] - x) < EPSILON) &&
|
||||
(Math.abs(vertices[vertexCount-2][MY] - y) < EPSILON) &&
|
||||
(Math.abs(vertices[vertexCount-2][MZ] - z) < EPSILON)) {
|
||||
vertexCount--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public void texture(PImage image) {
|
||||
this.timage = image;
|
||||
this.tpixels = image.pixels;
|
||||
this.twidth = image.width;
|
||||
this.theight = image.height;
|
||||
this.tformat = image.format;
|
||||
|
||||
twidth1 = twidth - 1;
|
||||
theight1 = theight - 1;
|
||||
interpUV = true;
|
||||
}
|
||||
|
||||
|
||||
public void render() {
|
||||
if (vertexCount < 3) return;
|
||||
|
||||
// these may have changed due to a resize()
|
||||
// so they should be refreshed here
|
||||
pixels = parent.pixels;
|
||||
//zbuffer = parent.zbuffer;
|
||||
|
||||
noDepthTest = parent.hints[DISABLE_DEPTH_TEST];
|
||||
smooth = parent.smooth;
|
||||
|
||||
// by default, text turns on smooth for the textures
|
||||
// themselves. but this should be shut off if the hint
|
||||
// for DISABLE_TEXT_SMOOTH is set.
|
||||
texture_smooth = (//parent.drawing_text &&
|
||||
!parent.hints[DISABLE_TEXT_SMOOTH]);
|
||||
|
||||
width = smooth ? parent.width*SUBXRES : parent.width;
|
||||
height = smooth ? parent.height*SUBYRES : parent.height;
|
||||
|
||||
width1 = width - 1;
|
||||
height1 = height - 1;
|
||||
|
||||
if (!interpARGB) {
|
||||
r2 = (int) (vertices[0][R] * 255);
|
||||
g2 = (int) (vertices[0][G] * 255);
|
||||
b2 = (int) (vertices[0][B] * 255);
|
||||
a2 = (int) (vertices[0][A] * 255);
|
||||
a2orig = a2; // save an extra copy
|
||||
rgba = 0xff000000 | (r2 << 16) | (g2 << 8) | b2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
r[i] = 0; dr[i] = 0; l[i] = 0; dl[i] = 0;
|
||||
}
|
||||
|
||||
// hack to not make polygons fly into the screen
|
||||
if (parent.hints[NO_FLYING_POO]) {
|
||||
float nwidth2 = -width * 2;
|
||||
float nheight2 = -height * 2;
|
||||
float width2 = width * 2;
|
||||
float height2 = height * 2;
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
if ((vertices[i][X] < nwidth2) ||
|
||||
(vertices[i][X] > width2) ||
|
||||
(vertices[i][Y] < nheight2) ||
|
||||
(vertices[i][Y] > height2)) {
|
||||
return; // this is a bad poly
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (smooth) {
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
vertices[i][X] *= SUBXRES;
|
||||
vertices[i][Y] *= SUBYRES;
|
||||
}
|
||||
firstModY = -1;
|
||||
}
|
||||
|
||||
// find top vertex (y is zero at top, higher downwards)
|
||||
int topi = 0;
|
||||
float ymin = vertices[0][Y];
|
||||
float ymax = vertices[0][Y]; // fry 031001
|
||||
for (int i = 1; i < vertexCount; i++) {
|
||||
if (vertices[i][Y] < ymin) {
|
||||
ymin = vertices[i][Y];
|
||||
topi = i;
|
||||
}
|
||||
if (vertices[i][Y] > ymax) ymax = vertices[i][Y];
|
||||
}
|
||||
|
||||
// the last row is an exceptional case, because there won't
|
||||
// necessarily be 8 rows of subpixel lines that will force
|
||||
// the final line to render. so instead, the algo keeps track
|
||||
// of the lastY (in subpixel resolution) that will be rendered
|
||||
// and that will force a scanline to happen the same as
|
||||
// every eighth in the other situations
|
||||
//lastY = -1; // fry 031001
|
||||
lastY = (int) (ymax - 0.5f); // global to class bc used by other fxns
|
||||
|
||||
int lefti = topi; // li, index of left vertex
|
||||
int righti = topi; // ri, index of right vertex
|
||||
int y = (int) (ymin + 0.5f); // current scan line
|
||||
int lefty = y - 1; // lower end of left edge
|
||||
int righty = y - 1; // lower end of right edge
|
||||
|
||||
interpX = true;
|
||||
|
||||
int remaining = vertexCount;
|
||||
|
||||
// scan in y, activating new edges on left & right
|
||||
// as scan line passes over new vertices
|
||||
while (remaining > 0) {
|
||||
// advance left edge?
|
||||
while ((lefty <= y) && (remaining > 0)) {
|
||||
remaining--;
|
||||
// step ccw down left side
|
||||
int i = (lefti != 0) ? (lefti-1) : (vertexCount-1);
|
||||
incrementalize_y(vertices[lefti], vertices[i], l, dl, y);
|
||||
lefty = (int) (vertices[i][Y] + 0.5f);
|
||||
lefti = i;
|
||||
}
|
||||
|
||||
// advance right edge?
|
||||
while ((righty <= y) && (remaining > 0)) {
|
||||
remaining--;
|
||||
// step cw down right edge
|
||||
int i = (righti != vertexCount-1) ? (righti + 1) : 0;
|
||||
incrementalize_y(vertices[righti], vertices[i], r, dr, y);
|
||||
righty = (int) (vertices[i][Y] + 0.5f);
|
||||
righti = i;
|
||||
}
|
||||
|
||||
// do scanlines till end of l or r edge
|
||||
while (y < lefty && y < righty) {
|
||||
// this doesn't work because it's not always set here
|
||||
//if (remaining == 0) {
|
||||
//lastY = (lefty < righty) ? lefty-1 : righty-1;
|
||||
//System.out.println("lastY is " + lastY);
|
||||
//}
|
||||
|
||||
if ((y >= 0) && (y < height)) {
|
||||
//try { // hopefully this bug is fixed
|
||||
if (l[X] <= r[X]) scanline(y, l, r);
|
||||
else scanline(y, r, l);
|
||||
//} catch (ArrayIndexOutOfBoundsException e) {
|
||||
//e.printStackTrace();
|
||||
//}
|
||||
}
|
||||
y++;
|
||||
// this increment probably needs to be different
|
||||
// UV and RGB shouldn't be incremented until line is emitted
|
||||
increment(l, dl);
|
||||
increment(r, dr);
|
||||
}
|
||||
}
|
||||
//if (smooth) {
|
||||
//System.out.println("y/lasty/lastmody = " + y + " " + lastY + " " + lastModY);
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
public void unexpand() {
|
||||
if (smooth) {
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
vertices[i][X] /= SUBXRES;
|
||||
vertices[i][Y] /= SUBYRES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void scanline(int y, float l[], float r[]) {
|
||||
//System.out.println("scanline " + y);
|
||||
for (int i = 0; i < vertexCount; i++) { // should be moved later
|
||||
sp[i] = 0; sdp[i] = 0;
|
||||
}
|
||||
|
||||
// this rounding doesn't seem to be relevant with smooth
|
||||
int lx = (int) (l[X] + 0.49999f); // ceil(l[X]-.5);
|
||||
if (lx < 0) lx = 0;
|
||||
int rx = (int) (r[X] - 0.5f);
|
||||
if (rx > width1) rx = width1;
|
||||
|
||||
if (lx > rx) return;
|
||||
|
||||
if (smooth) {
|
||||
int mody = MODYRES(y);
|
||||
|
||||
aaleft[mody] = lx;
|
||||
aaright[mody] = rx;
|
||||
|
||||
if (firstModY == -1) {
|
||||
firstModY = mody;
|
||||
aaleftmin = lx; aaleftmax = lx;
|
||||
aarightmin = rx; aarightmax = rx;
|
||||
|
||||
} else {
|
||||
if (aaleftmin > aaleft[mody]) aaleftmin = aaleft[mody];
|
||||
if (aaleftmax < aaleft[mody]) aaleftmax = aaleft[mody];
|
||||
if (aarightmin > aaright[mody]) aarightmin = aaright[mody];
|
||||
if (aarightmax < aaright[mody]) aarightmax = aaright[mody];
|
||||
}
|
||||
|
||||
lastModY = mody; // moved up here (before the return) 031001
|
||||
// not the eighth (or lastY) line, so not scanning this time
|
||||
if ((mody != SUBYRES1) && (y != lastY)) return;
|
||||
//lastModY = mody; // eeK! this was missing
|
||||
//return;
|
||||
|
||||
//if (y == lastY) {
|
||||
//System.out.println("y is lasty");
|
||||
//}
|
||||
//lastModY = mody;
|
||||
aaleftfull = aaleftmax/SUBXRES + 1;
|
||||
aarightfull = aarightmin/SUBXRES - 1;
|
||||
}
|
||||
|
||||
// this is the setup, based on lx
|
||||
incrementalize_x(l, r, sp, sdp, lx);
|
||||
|
||||
// scan in x, generating pixels
|
||||
// using parent.width to get actual pixel index
|
||||
// rather than scaled by smooth factor
|
||||
int offset = smooth ? parent.width * (y / SUBYRES) : parent.width*y;
|
||||
|
||||
int truelx = 0, truerx = 0;
|
||||
if (smooth) {
|
||||
truelx = lx / SUBXRES;
|
||||
truerx = (rx + SUBXRES1) / SUBXRES;
|
||||
|
||||
lx = aaleftmin / SUBXRES;
|
||||
rx = (aarightmax + SUBXRES1) / SUBXRES;
|
||||
if (lx < 0) lx = 0;
|
||||
if (rx > parent.width1) rx = parent.width1;
|
||||
}
|
||||
|
||||
interpX = false;
|
||||
int tr, tg, tb, ta;
|
||||
|
||||
for (int x = lx; x <= rx; x++) {
|
||||
// added == because things on same plane weren't replacing each other
|
||||
// makes for strangeness in 3D, but totally necessary for 2D
|
||||
//if (noDepthTest || (sp[Z] <= zbuffer[offset+x])) {
|
||||
if (true) {
|
||||
|
||||
// map texture based on U, V coords in sp[U] and sp[V]
|
||||
if (interpUV) {
|
||||
int tu = (int)sp[U];
|
||||
int tv = (int)sp[V];
|
||||
|
||||
if (tu > twidth1) tu = twidth1;
|
||||
if (tv > theight1) tv = theight1;
|
||||
if (tu < 0) tu = 0;
|
||||
if (tv < 0) tv = 0;
|
||||
|
||||
int txy = tv*twidth + tu;
|
||||
|
||||
if (smooth || texture_smooth) {
|
||||
//if (FRY) System.out.println("sp u v = " + sp[U] + " " + sp[V]);
|
||||
//System.out.println("sp u v = " + sp[U] + " " + sp[V]);
|
||||
// tuf1/tvf1 is the amount of coverage for the adjacent
|
||||
// pixel, which is the decimal percentage.
|
||||
int tuf1 = (int) (255f * (sp[U] - (float)tu));
|
||||
int tvf1 = (int) (255f * (sp[V] - (float)tv));
|
||||
|
||||
// the closer sp[U or V] is to the decimal being zero
|
||||
// the more coverage it should get of the original pixel
|
||||
int tuf = 255 - tuf1;
|
||||
int tvf = 255 - tvf1;
|
||||
|
||||
// this code sucks! filled with bugs and slow as hell!
|
||||
int pixel00 = tpixels[txy];
|
||||
int pixel01 = (tv < theight1) ?
|
||||
tpixels[txy + twidth] : tpixels[txy];
|
||||
int pixel10 = (tu < twidth1) ?
|
||||
tpixels[txy + 1] : tpixels[txy];
|
||||
int pixel11 = ((tv < theight1) && (tu < twidth1)) ?
|
||||
tpixels[txy + twidth + 1] : tpixels[txy];
|
||||
|
||||
int p00, p01, p10, p11;
|
||||
int px0, px1; //, pxy;
|
||||
|
||||
if (tformat == ALPHA) {
|
||||
px0 = (pixel00*tuf + pixel10*tuf1) >> 8;
|
||||
px1 = (pixel01*tuf + pixel11*tuf1) >> 8;
|
||||
ta = (((px0*tvf + px1*tvf1) >> 8) *
|
||||
(interpARGB ? ((int) (sp[A]*255)) : a2orig)) >> 8;
|
||||
|
||||
} else if (tformat == ARGB) {
|
||||
p00 = (pixel00 >> 24) & 0xff;
|
||||
p01 = (pixel01 >> 24) & 0xff;
|
||||
p10 = (pixel10 >> 24) & 0xff;
|
||||
p11 = (pixel11 >> 24) & 0xff;
|
||||
|
||||
px0 = (p00*tuf + p10*tuf1) >> 8;
|
||||
px1 = (p01*tuf + p11*tuf1) >> 8;
|
||||
ta = (((px0*tvf + px1*tvf1) >> 8) *
|
||||
(interpARGB ? ((int) (sp[A]*255)) : a2orig)) >> 8;
|
||||
|
||||
} else { // RGB image, no alpha
|
||||
ta = interpARGB ? ((int) (sp[A]*255)) : a2orig;
|
||||
}
|
||||
|
||||
if ((tformat == RGB) || (tformat == ARGB)) {
|
||||
p00 = (pixel00 >> 16) & 0xff; // red
|
||||
p01 = (pixel01 >> 16) & 0xff;
|
||||
p10 = (pixel10 >> 16) & 0xff;
|
||||
p11 = (pixel11 >> 16) & 0xff;
|
||||
|
||||
px0 = (p00*tuf + p10*tuf1) >> 8;
|
||||
px1 = (p01*tuf + p11*tuf1) >> 8;
|
||||
tr = (((px0*tvf + px1*tvf1) >> 8) *
|
||||
(interpARGB ? ((int) sp[R]*255) : r2)) >> 8;
|
||||
|
||||
|
||||
p00 = (pixel00 >> 8) & 0xff; // green
|
||||
p01 = (pixel01 >> 8) & 0xff;
|
||||
p10 = (pixel10 >> 8) & 0xff;
|
||||
p11 = (pixel11 >> 8) & 0xff;
|
||||
|
||||
px0 = (p00*tuf + p10*tuf1) >> 8;
|
||||
px1 = (p01*tuf + p11*tuf1) >> 8;
|
||||
tg = (((px0*tvf + px1*tvf1) >> 8) *
|
||||
(interpARGB ? ((int) sp[G]*255) : g2)) >> 8;
|
||||
|
||||
|
||||
p00 = pixel00 & 0xff; // blue
|
||||
p01 = pixel01 & 0xff;
|
||||
p10 = pixel10 & 0xff;
|
||||
p11 = pixel11 & 0xff;
|
||||
|
||||
px0 = (p00*tuf + p10*tuf1) >> 8;
|
||||
px1 = (p01*tuf + p11*tuf1) >> 8;
|
||||
tb = (((px0*tvf + px1*tvf1) >> 8) *
|
||||
(interpARGB ? ((int) sp[B]*255) : b2)) >> 8;
|
||||
|
||||
} else { // alpha image, only use current fill color
|
||||
if (interpARGB) {
|
||||
tr = (int) (sp[R] * 255);
|
||||
tg = (int) (sp[G] * 255);
|
||||
tb = (int) (sp[B] * 255);
|
||||
|
||||
} else {
|
||||
tr = r2;
|
||||
tg = g2;
|
||||
tb = b2;
|
||||
}
|
||||
}
|
||||
|
||||
// get coverage for pixel if smooth
|
||||
// checks smooth again here because of
|
||||
// hints[SMOOTH_IMAGES] used up above
|
||||
int weight = smooth ? coverage(x) : 255;
|
||||
if (weight != 255) ta = ta*weight >> 8;
|
||||
|
||||
} else { // no smooth, just get the pixels
|
||||
int tpixel = tpixels[txy];
|
||||
|
||||
// TODO i doubt splitting these guys really gets us
|
||||
// all that much speed.. is it worth it?
|
||||
if (tformat == ALPHA) {
|
||||
ta = tpixel;
|
||||
|
||||
if (interpARGB) {
|
||||
tr = (int) sp[R]*255;
|
||||
tg = (int) sp[G]*255;
|
||||
tb = (int) sp[B]*255;
|
||||
if (sp[A] != 1) {
|
||||
ta = (((int) sp[A]*255) * ta) >> 8;
|
||||
}
|
||||
|
||||
} else {
|
||||
tr = r2;
|
||||
tg = g2;
|
||||
tb = b2;
|
||||
ta = (a2orig * ta) >> 8;
|
||||
}
|
||||
|
||||
} else { // RGB or ARGB
|
||||
ta = (tformat == RGB) ? 255 : (tpixel >> 24) & 0xff;
|
||||
|
||||
if (interpARGB) {
|
||||
tr = (((int) sp[R]*255) * ((tpixel >> 16) & 0xff)) >> 8;
|
||||
tg = (((int) sp[G]*255) * ((tpixel >> 8) & 0xff)) >> 8;
|
||||
tb = (((int) sp[B]*255) * ((tpixel) & 0xff)) >> 8;
|
||||
ta = (((int) sp[A]*255) * ta) >> 8;
|
||||
|
||||
} else {
|
||||
tr = (r2 * ((tpixel >> 16) & 0xff)) >> 8;
|
||||
tg = (g2 * ((tpixel >> 8) & 0xff)) >> 8;
|
||||
tb = (b2 * ((tpixel) & 0xff)) >> 8;
|
||||
ta = (a2orig * ta) >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((ta == 254) || (ta == 255)) { // if (ta & 0xf8) would be good
|
||||
// no need to blend
|
||||
pixels[offset+x] = 0xff000000 | (tr << 16) | (tg << 8) | tb;
|
||||
//zbuffer[offset+x] = sp[Z];
|
||||
|
||||
} else {
|
||||
// blend with pixel on screen
|
||||
int a1 = 255-ta;
|
||||
int r1 = (pixels[offset+x] >> 16) & 0xff;
|
||||
int g1 = (pixels[offset+x] >> 8) & 0xff;
|
||||
int b1 = (pixels[offset+x]) & 0xff;
|
||||
|
||||
pixels[offset+x] = 0xff000000 |
|
||||
(((tr*ta + r1*a1) >> 8) << 16) |
|
||||
((tg*ta + g1*a1) & 0xff00) |
|
||||
((tb*ta + b1*a1) >> 8);
|
||||
//if (ta > ZBUFFER_MIN_COVERAGE) zbuffer[offset+x] = sp[Z];
|
||||
}
|
||||
|
||||
} else { // no image applied
|
||||
int weight = smooth ? coverage(x) : 255;
|
||||
|
||||
if (interpARGB) {
|
||||
r2 = (int) (sp[R] * 255);
|
||||
g2 = (int) (sp[G] * 255);
|
||||
b2 = (int) (sp[B] * 255);
|
||||
if (sp[A] != 1) weight = (weight * ((int) (sp[A] * 255))) >> 8;
|
||||
if (weight == 255) {
|
||||
rgba = 0xff000000 | (r2 << 16) | (g2 << 8) | b2;
|
||||
}
|
||||
} else {
|
||||
if (a2orig != 255) weight = (weight * a2orig) >> 8;
|
||||
}
|
||||
|
||||
if (weight == 255) {
|
||||
// no blend, no aa, just the rgba
|
||||
pixels[offset+x] = rgba;
|
||||
//zbuffer[offset+x] = sp[Z];
|
||||
|
||||
} else {
|
||||
int r1 = (pixels[offset+x] >> 16) & 0xff;
|
||||
int g1 = (pixels[offset+x] >> 8) & 0xff;
|
||||
int b1 = (pixels[offset+x]) & 0xff;
|
||||
a2 = weight;
|
||||
|
||||
int a1 = 255 - a2;
|
||||
pixels[offset+x] = (0xff000000 |
|
||||
((r1*a1 + r2*a2) >> 8) << 16 |
|
||||
// use & instead of >> and << below
|
||||
((g1*a1 + g2*a2) >> 8) << 8 |
|
||||
((b1*a1 + b2*a2) >> 8));
|
||||
|
||||
//if (a2 > ZBUFFER_MIN_COVERAGE) zbuffer[offset+x] = sp[Z];
|
||||
}
|
||||
}
|
||||
}
|
||||
// if smooth enabled, don't increment values
|
||||
// for the pixel in the stretch out version
|
||||
// of the scanline used to get smooth edges.
|
||||
if (!smooth || ((x >= truelx) && (x <= truerx))) {
|
||||
increment(sp, sdp);
|
||||
}
|
||||
}
|
||||
firstModY = -1;
|
||||
interpX = true;
|
||||
}
|
||||
|
||||
|
||||
// x is in screen, not huge 8x coordinates
|
||||
private int coverage(int x) {
|
||||
if ((x >= aaleftfull) && (x <= aarightfull) &&
|
||||
// important since not all SUBYRES lines may have been covered
|
||||
(firstModY == 0) && (lastModY == SUBYRES1)) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
int pixelLeft = x*SUBXRES; // huh?
|
||||
int pixelRight = pixelLeft + 8;
|
||||
|
||||
int amt = 0;
|
||||
for (int i = firstModY; i <= lastModY; i++) {
|
||||
if ((aaleft[i] > pixelRight) || (aaright[i] < pixelLeft)) {
|
||||
continue;
|
||||
}
|
||||
// does this need a +1 ?
|
||||
amt += ((aaright[i] < pixelRight ? aaright[i] : pixelRight) -
|
||||
(aaleft[i] > pixelLeft ? aaleft[i] : pixelLeft));
|
||||
}
|
||||
amt <<= 2;
|
||||
return (amt == 256) ? 255 : amt;
|
||||
}
|
||||
|
||||
|
||||
private void incrementalize_y(float p1[], float p2[],
|
||||
float p[], float dp[], int y) {
|
||||
float delta = p2[Y] - p1[Y];
|
||||
if (delta == 0) delta = 1;
|
||||
float fraction = y + 0.5f - p1[Y];
|
||||
|
||||
if (interpX) {
|
||||
dp[X] = (p2[X] - p1[X]) / delta;
|
||||
p[X] = p1[X] + dp[X] * fraction;
|
||||
}
|
||||
if (interpZ) {
|
||||
dp[Z] = (p2[Z] - p1[Z]) / delta;
|
||||
p[Z] = p1[Z] + dp[Z] * fraction;
|
||||
}
|
||||
|
||||
if (interpARGB) {
|
||||
dp[R] = (p2[R] - p1[R]) / delta;
|
||||
dp[G] = (p2[G] - p1[G]) / delta;
|
||||
dp[B] = (p2[B] - p1[B]) / delta;
|
||||
dp[A] = (p2[A] - p1[A]) / delta;
|
||||
p[R] = p1[R] + dp[R] * fraction;
|
||||
p[G] = p1[G] + dp[G] * fraction;
|
||||
p[B] = p1[B] + dp[B] * fraction;
|
||||
p[A] = p1[A] + dp[A] * fraction;
|
||||
}
|
||||
|
||||
if (interpUV) {
|
||||
dp[U] = (p2[U] - p1[U]) / delta;
|
||||
dp[V] = (p2[V] - p1[V]) / delta;
|
||||
|
||||
//if (smooth) {
|
||||
//p[U] = p1[U]; //+ dp[U] * fraction;
|
||||
//p[V] = p1[V]; //+ dp[V] * fraction;
|
||||
|
||||
//} else {
|
||||
p[U] = p1[U] + dp[U] * fraction;
|
||||
p[V] = p1[V] + dp[V] * fraction;
|
||||
//}
|
||||
if (FRY) System.out.println("inc y p[U] p[V] = " + p[U] + " " + p[V]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void incrementalize_x(float p1[], float p2[],
|
||||
float p[], float dp[], int x) {
|
||||
float delta = p2[X] - p1[X];
|
||||
if (delta == 0) delta = 1;
|
||||
float fraction = x + 0.5f - p1[X];
|
||||
if (smooth) {
|
||||
delta /= SUBXRES;
|
||||
fraction /= SUBXRES;
|
||||
}
|
||||
|
||||
if (interpX) {
|
||||
dp[X] = (p2[X] - p1[X]) / delta;
|
||||
p[X] = p1[X] + dp[X] * fraction;
|
||||
}
|
||||
if (interpZ) {
|
||||
dp[Z] = (p2[Z] - p1[Z]) / delta;
|
||||
p[Z] = p1[Z] + dp[Z] * fraction;
|
||||
}
|
||||
|
||||
if (interpARGB) {
|
||||
dp[R] = (p2[R] - p1[R]) / delta;
|
||||
dp[G] = (p2[G] - p1[G]) / delta;
|
||||
dp[B] = (p2[B] - p1[B]) / delta;
|
||||
dp[A] = (p2[A] - p1[A]) / delta;
|
||||
p[R] = p1[R] + dp[R] * fraction;
|
||||
p[G] = p1[G] + dp[G] * fraction;
|
||||
p[B] = p1[B] + dp[B] * fraction;
|
||||
p[A] = p1[A] + dp[A] * fraction;
|
||||
}
|
||||
|
||||
if (interpUV) {
|
||||
if (FRY) System.out.println("delta, frac = " + delta + ", " + fraction);
|
||||
dp[U] = (p2[U] - p1[U]) / delta;
|
||||
dp[V] = (p2[V] - p1[V]) / delta;
|
||||
|
||||
//if (smooth) {
|
||||
//p[U] = p1[U];
|
||||
// offset for the damage that will be done by the
|
||||
// 8 consecutive calls to scanline
|
||||
// agh.. this won't work b/c not always 8 calls before render
|
||||
// maybe lastModY - firstModY + 1 instead?
|
||||
if (FRY) System.out.println("before inc x p[V] = " + p[V] + " " + p1[V] + " " + p2[V]);
|
||||
//p[V] = p1[V] - SUBXRES1 * fraction;
|
||||
|
||||
//} else {
|
||||
p[U] = p1[U] + dp[U] * fraction;
|
||||
p[V] = p1[V] + dp[V] * fraction;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void increment(float p[], float dp[]) {
|
||||
if (interpX) p[X] += dp[X];
|
||||
if (interpZ) p[Z] += dp[Z];
|
||||
|
||||
if (interpARGB) {
|
||||
p[R] += dp[R];
|
||||
p[G] += dp[G];
|
||||
p[B] += dp[B];
|
||||
p[A] += dp[A];
|
||||
}
|
||||
|
||||
if (interpUV) {
|
||||
if (FRY) System.out.println("increment() " + p[V] + " " + dp[V]);
|
||||
p[U] += dp[U];
|
||||
p[V] += dp[V];
|
||||
}
|
||||
}
|
||||
}
|
289
core/PShape.java
Normal file
289
core/PShape.java
Normal file
@@ -0,0 +1,289 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2006 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; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
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.core;
|
||||
|
||||
|
||||
// take a look at the obj loader to see how this fits with things
|
||||
|
||||
// PShape.line() PShape.ellipse()?
|
||||
// PShape s = beginShape()
|
||||
// line()
|
||||
// endShape(s)
|
||||
|
||||
public class PShape {
|
||||
|
||||
int kind;
|
||||
PMatrix matrix;
|
||||
|
||||
int[] opcode;
|
||||
int opcodeCount;
|
||||
// need to reorder vertex fields to make a VERTEX_SHORT_COUNT
|
||||
// that puts all the non-rendering fields into later indices
|
||||
float[][] data; // second param is the VERTEX_FIELD_COUNT
|
||||
// should this be called vertices (consistent with PGraphics internals)
|
||||
// or does that hurt flexibility?
|
||||
|
||||
int childCount;
|
||||
PShape[] children;
|
||||
|
||||
// POINTS, LINES, xLINE_STRIP, xLINE_LOOP
|
||||
// TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN
|
||||
// QUADS, QUAD_STRIP
|
||||
// xPOLYGON
|
||||
static final int PATH = 1; // POLYGON, LINE_LOOP, LINE_STRIP
|
||||
static final int GROUP = 2;
|
||||
|
||||
// how to handle rectmode/ellipsemode?
|
||||
// are they bitshifted into the constant?
|
||||
// CORNER, CORNERS, CENTER, (CENTER_RADIUS?)
|
||||
static final int RECT = 3; // could just be QUAD, but would be x1/y1/x2/y2
|
||||
static final int ELLIPSE = 4;
|
||||
|
||||
static final int VERTEX = 7;
|
||||
static final int CURVE = 5;
|
||||
static final int BEZIER = 6;
|
||||
|
||||
|
||||
// fill and stroke functions will need a pointer to the parent
|
||||
// PGraphics object.. may need some kind of createShape() fxn
|
||||
// or maybe the values are stored until draw() is called?
|
||||
|
||||
// attaching images is very tricky.. it's a different type of data
|
||||
|
||||
// material parameters will be thrown out,
|
||||
// except those currently supported (kinds of lights)
|
||||
|
||||
// setAxis -> .x and .y to move x and y coords of origin
|
||||
public float x;
|
||||
public float y;
|
||||
|
||||
// pivot point for transformations
|
||||
public float px;
|
||||
public float py;
|
||||
|
||||
|
||||
public PShape() {
|
||||
}
|
||||
|
||||
|
||||
public PShape(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
/**
|
||||
* Called by the following (the shape() command adds the g)
|
||||
* PShape s = loadShapes("blah.svg");
|
||||
* shape(s);
|
||||
*/
|
||||
public void draw(PGraphics g) {
|
||||
boolean flat = g instanceof PGraphics3D;
|
||||
|
||||
if (matrix != null) {
|
||||
g.pushMatrix();
|
||||
if (flat) {
|
||||
g.applyMatrix(matrix.m00, matrix.m01, matrix.m02,
|
||||
matrix.m10, matrix.m11, matrix.m12);
|
||||
} else {
|
||||
g.applyMatrix(matrix.m00, matrix.m01, matrix.m02, matrix.m03,
|
||||
matrix.m10, matrix.m11, matrix.m12, matrix.m13,
|
||||
matrix.m20, matrix.m21, matrix.m22, matrix.m23,
|
||||
matrix.m30, matrix.m31, matrix.m32, matrix.m33);
|
||||
}
|
||||
}
|
||||
|
||||
// if g subclasses PGraphics2, ignore all lighting stuff and z coords
|
||||
// otherwise if PGraphics3, need to call diffuse() etc
|
||||
|
||||
// unfortunately, also a problem with no way to encode stroke/fill
|
||||
// being enabled/disabled.. this quickly gets into just having opcodes
|
||||
// for the entire api, to deal with things like textures and images
|
||||
|
||||
switch (kind) {
|
||||
case PATH:
|
||||
for (int i = 0; i < opcodeCount; i++) {
|
||||
switch (opcode[i]) {
|
||||
case VERTEX:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GROUP:
|
||||
break;
|
||||
|
||||
case RECT:
|
||||
break;
|
||||
}
|
||||
|
||||
if (matrix != null) {
|
||||
g.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
// can't be 'add' because that suggests additive geometry
|
||||
public void addChild(PShape who) {
|
||||
}
|
||||
|
||||
|
||||
public PShape createGroup() {
|
||||
PShape group = new PShape();
|
||||
group.kind = GROUP;
|
||||
addChild(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
// translate, rotate, scale, apply (no push/pop)
|
||||
// these each call matrix.translate, etc
|
||||
// if matrix is null when one is called,
|
||||
// it is created and set to identity
|
||||
|
||||
|
||||
public void translate(float tx, float ty) {
|
||||
translate(tx, ty, 0);
|
||||
}
|
||||
|
||||
public void translate(float tx, float ty, float tz) {
|
||||
checkMatrix();
|
||||
matrix.translate(tx, ty, 0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
||||
public void rotateX(float angle) {
|
||||
rotate(angle, 1, 0, 0);
|
||||
}
|
||||
|
||||
public void rotateY(float angle) {
|
||||
rotate(angle, 0, 1, 0);
|
||||
}
|
||||
|
||||
public void rotateZ(float angle) {
|
||||
rotate(angle, 0, 0, 1);
|
||||
}
|
||||
|
||||
public void rotate(float angle) {
|
||||
rotateZ(angle);
|
||||
}
|
||||
|
||||
public void rotate(float angle, float v0, float v1, float v2) {
|
||||
checkMatrix();
|
||||
matrix.rotate(angle, v0, v1, v2);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
||||
public void scale(float s) {
|
||||
scale(s, s, s);
|
||||
}
|
||||
|
||||
public void scale(float sx, float sy) {
|
||||
scale(sx, sy, 1);
|
||||
}
|
||||
|
||||
public void scale(float x, float y, float z) {
|
||||
checkMatrix();
|
||||
matrix.scale(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
||||
public void applyMatrix(float n00, float n01, float n02,
|
||||
float n10, float n11, float n12) {
|
||||
checkMatrix();
|
||||
matrix.apply(n00, n01, n02, 0,
|
||||
n10, n11, n12, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
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) {
|
||||
checkMatrix();
|
||||
matrix.apply(n00, n01, n02, n03,
|
||||
n10, n11, n12, n13,
|
||||
n20, n21, n22, n23,
|
||||
n30, n31, n32, n33);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
||||
protected void checkMatrix() {
|
||||
if (matrix == null) {
|
||||
matrix = new PMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
/**
|
||||
* Center the shape based on its bounding box. Can't assume
|
||||
* that the bounding box is 0, 0, width, height. Common case will be
|
||||
* opening a letter size document in Illustrator, and drawing something
|
||||
* in the middle, then reading it in as an svg file.
|
||||
* This will also need to flip the y axis (scale(1, -1)) in cases
|
||||
* like Adobe Illustrator where the coordinates start at the bottom.
|
||||
*/
|
||||
public void center() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the pivot point for all transformations.
|
||||
*/
|
||||
public void pivot(float x, float y) {
|
||||
px = x;
|
||||
py = y;
|
||||
}
|
||||
|
||||
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
|
||||
}
|
3827
core/PTriangle.java
Normal file
3827
core/PTriangle.java
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user