mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
remove smooth triangle code
This commit is contained in:
@@ -197,19 +197,13 @@ public class PGraphics3D extends PGraphics {
|
||||
protected float bottomScreen;
|
||||
protected float nearPlane; //depth of near clipping plane
|
||||
|
||||
/** true if frustum has been called to set perspective, false if ortho */
|
||||
private boolean frustumMode = false;
|
||||
|
||||
/**
|
||||
* Use PSmoothTriangle for rendering instead of PTriangle?
|
||||
* Usually set by calling smooth() or noSmooth()
|
||||
*/
|
||||
static protected boolean s_enableAccurateTextures = false; //maybe just use smooth instead?
|
||||
|
||||
/** Used for anti-aliased and perspective corrected rendering. */
|
||||
public PSmoothTriangle smoothTriangle;
|
||||
|
||||
|
||||
|
||||
// ........................................................
|
||||
|
||||
// pos of first vertex of current shape in vertices array
|
||||
@@ -393,7 +387,6 @@ public class PGraphics3D extends PGraphics {
|
||||
|
||||
line = new PLine(this);
|
||||
triangle = new PTriangle(this);
|
||||
smoothTriangle = new PSmoothTriangle(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1177,50 +1170,25 @@ public class PGraphics3D extends PGraphics {
|
||||
float bx2 = ox2-dx1;
|
||||
float by2 = oy2+dy1;
|
||||
|
||||
if (smooth) {
|
||||
smoothTriangle.reset(3);
|
||||
smoothTriangle.smooth = true;
|
||||
smoothTriangle.interpARGB = true; // ?
|
||||
triangle.reset();
|
||||
|
||||
// render first triangle for thick line
|
||||
smoothTriangle.setVertices(ax1, ay1, a[TZ],
|
||||
bx2, by2, b[TZ],
|
||||
ax2, ay2, a[TZ]);
|
||||
smoothTriangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
|
||||
b[SR], b[SG], b[SB], b[SA],
|
||||
a[SR], a[SG], a[SB], a[SA]);
|
||||
smoothTriangle.render();
|
||||
// render first triangle for thick line
|
||||
triangle.setVertices(ax1, ay1, a[TZ],
|
||||
bx2, by2, b[TZ],
|
||||
ax2, ay2, a[TZ]);
|
||||
triangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
|
||||
b[SR], b[SG], b[SB], b[SA],
|
||||
a[SR], a[SG], a[SB], a[SA]);
|
||||
triangle.render();
|
||||
|
||||
// render second triangle for thick line
|
||||
smoothTriangle.setVertices(ax1, ay1, a[TZ],
|
||||
bx2, by2, b[TZ],
|
||||
bx1, by1, b[TZ]);
|
||||
smoothTriangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
|
||||
b[SR], b[SG], b[SB], b[SA],
|
||||
b[SR], b[SG], b[SB], b[SA]);
|
||||
smoothTriangle.render();
|
||||
|
||||
} else {
|
||||
triangle.reset();
|
||||
|
||||
// render first triangle for thick line
|
||||
triangle.setVertices(ax1, ay1, a[TZ],
|
||||
bx2, by2, b[TZ],
|
||||
ax2, ay2, a[TZ]);
|
||||
triangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
|
||||
b[SR], b[SG], b[SB], b[SA],
|
||||
a[SR], a[SG], a[SB], a[SA]);
|
||||
triangle.render();
|
||||
|
||||
// render second triangle for thick line
|
||||
triangle.setVertices(ax1, ay1, a[TZ],
|
||||
bx2, by2, b[TZ],
|
||||
bx1, by1, b[TZ]);
|
||||
triangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
|
||||
b[SR], b[SG], b[SB], b[SA],
|
||||
b[SR], b[SG], b[SB], b[SA]);
|
||||
triangle.render();
|
||||
}
|
||||
// render second triangle for thick line
|
||||
triangle.setVertices(ax1, ay1, a[TZ],
|
||||
bx2, by2, b[TZ],
|
||||
bx1, by1, b[TZ]);
|
||||
triangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
|
||||
b[SR], b[SG], b[SB], b[SA],
|
||||
b[SR], b[SG], b[SB], b[SA]);
|
||||
triangle.render();
|
||||
|
||||
} else {
|
||||
line.reset();
|
||||
@@ -2223,55 +2191,7 @@ public class PGraphics3D extends PGraphics {
|
||||
float cg = clamp(triangleColors[i][2][TRI_DIFFUSE_G] + triangleColors[i][2][TRI_SPECULAR_G]);
|
||||
float cb = clamp(triangleColors[i][2][TRI_DIFFUSE_B] + triangleColors[i][2][TRI_SPECULAR_B]);
|
||||
|
||||
// ACCURATE TEXTURE CODE
|
||||
boolean failedToPrecalc = false;
|
||||
if (s_enableAccurateTextures && frustumMode){
|
||||
boolean textured = true;
|
||||
smoothTriangle.reset(3);
|
||||
smoothTriangle.smooth = true;
|
||||
smoothTriangle.interpARGB = true;
|
||||
smoothTriangle.setIntensities(ar, ag, ab, a[A],
|
||||
br, bg, bb, b[A],
|
||||
cr, cg, cb, c[A]);
|
||||
if (tex > -1 && textures[tex] != null) {
|
||||
smoothTriangle.setCamVertices(a[VX], a[VY], a[VZ],
|
||||
b[VX], b[VY], b[VZ],
|
||||
c[VX], c[VY], c[VZ]);
|
||||
smoothTriangle.interpUV = true;
|
||||
smoothTriangle.texture(textures[tex]);
|
||||
float umult = textures[tex].width; // apparently no check for textureMode is needed here
|
||||
float vmult = textures[tex].height;
|
||||
smoothTriangle.vertices[0][U] = a[U]*umult;
|
||||
smoothTriangle.vertices[0][V] = a[V]*vmult;
|
||||
smoothTriangle.vertices[1][U] = b[U]*umult;
|
||||
smoothTriangle.vertices[1][V] = b[V]*vmult;
|
||||
smoothTriangle.vertices[2][U] = c[U]*umult;
|
||||
smoothTriangle.vertices[2][V] = c[V]*vmult;
|
||||
} else {
|
||||
smoothTriangle.interpUV = false;
|
||||
textured = false;
|
||||
}
|
||||
|
||||
smoothTriangle.setVertices(a[TX], a[TY], a[TZ],
|
||||
b[TX], b[TY], b[TZ],
|
||||
c[TX], c[TY], c[TZ]);
|
||||
|
||||
|
||||
if (!textured || smoothTriangle.precomputeAccurateTexturing()){
|
||||
smoothTriangle.render();
|
||||
} else {
|
||||
// Something went wrong with the precomputation,
|
||||
// so we need to fall back on normal PTriangle
|
||||
// rendering.
|
||||
failedToPrecalc = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Normal triangle rendering
|
||||
// Note: this is not an end-if from the smoothed texturing mode
|
||||
// because it's possible that the precalculation will fail and we
|
||||
// need to fall back on normal rendering.
|
||||
if (!s_enableAccurateTextures || failedToPrecalc || (frustumMode == false)){
|
||||
if (tex > -1 && textures[tex] != null) {
|
||||
triangle.setTexture(textures[tex]);
|
||||
triangle.setUV(a[U], a[V], b[U], b[V], c[U], c[V]);
|
||||
@@ -2285,26 +2205,7 @@ public class PGraphics3D extends PGraphics {
|
||||
b[TX], b[TY], b[TZ],
|
||||
c[TX], c[TY], c[TZ]);
|
||||
|
||||
triangle.render();
|
||||
}
|
||||
|
||||
/*
|
||||
// removing for 0149 with the return of P2D
|
||||
if (drawing2D() && shifted){
|
||||
a[TX] -= shift;
|
||||
a[TY] -= shift;
|
||||
a[VX] -= shift*a[VW];
|
||||
a[VY] -= shift*a[VW];
|
||||
b[TX] -= shift;
|
||||
b[TY] -= shift;
|
||||
b[VX] -= shift*b[VW];
|
||||
b[VY] -= shift*b[VW];
|
||||
c[TX] -= shift;
|
||||
c[TY] -= shift;
|
||||
c[VX] -= shift*c[VW];
|
||||
c[VY] -= shift*c[VW];
|
||||
}
|
||||
*/
|
||||
triangle.render();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3460,8 +3361,6 @@ public class PGraphics3D extends PGraphics {
|
||||
0, y, 0, ty,
|
||||
0, 0, z, tz,
|
||||
0, 0, 0, 1);
|
||||
|
||||
frustumMode = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3520,7 +3419,6 @@ public class PGraphics3D extends PGraphics {
|
||||
bottomScreen = bottom;
|
||||
topScreen = top;
|
||||
nearPlane = znear;
|
||||
frustumMode = true;
|
||||
|
||||
//System.out.println(projection);
|
||||
projection.set((2*znear)/(right-left), 0, (right+left)/(right-left), 0,
|
||||
|
||||
@@ -1,968 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004-08 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.android.core;
|
||||
|
||||
|
||||
/**
|
||||
* Smoothed triangle renderer for P3D.
|
||||
*
|
||||
* Based off of the PPolygon class in old versions of Processing.
|
||||
* Name and location of this class will change in a future release.
|
||||
*/
|
||||
public class PSmoothTriangle implements PConstants {
|
||||
|
||||
// really this is "debug" but..
|
||||
private static final boolean EWJORDAN = false;
|
||||
private static final boolean FRY = false;
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
PGraphics3D parent;
|
||||
int pixels[];
|
||||
float[] zbuffer;
|
||||
|
||||
// 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
|
||||
// TODO ewjordan: can probably remove this variable
|
||||
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;
|
||||
|
||||
/* Variables needed for accurate texturing. */
|
||||
//private PMatrix textureMatrix = new PMatrix3D();
|
||||
private float[] camX = new float[3];
|
||||
private float[] camY = new float[3];
|
||||
private float[] camZ = new float[3];
|
||||
private float ax,ay,az;
|
||||
private float bx,by,bz;
|
||||
private float cx,cy,cz;
|
||||
private float nearPlaneWidth, nearPlaneHeight, nearPlaneDepth;
|
||||
//private float newax, newbx, newcx;
|
||||
private float xmult, ymult;
|
||||
|
||||
|
||||
final private int MODYRES(int y) {
|
||||
return (y & SUBYRES1);
|
||||
}
|
||||
|
||||
|
||||
public PSmoothTriangle(PGraphics3D 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
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
smooth = true;//TODO
|
||||
// these may have changed due to a resize()
|
||||
// so they should be refreshed here
|
||||
pixels = parent.pixels;
|
||||
zbuffer = parent.zbuffer;
|
||||
|
||||
noDepthTest = false;//parent.hints[DISABLE_DEPTH_TEST];
|
||||
|
||||
// In 0148+, should always be true if this code is called at all
|
||||
//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 = true;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
//System.out.println(l[V] + " " + r[V] + " " +sp[V] + " " +sdp[V]);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// System.out.println("P3D interp uv " + interpUV + " " +
|
||||
// vertices[2][U] + " " + vertices[2][V]);
|
||||
|
||||
interpX = false;
|
||||
int tr, tg, tb, ta;
|
||||
//System.out.println("lx: "+lx + "\nrx: "+rx);
|
||||
for (int x = lx; x <= rx; x++) {
|
||||
|
||||
// added == because things on same plane weren't replacing each other
|
||||
// makes for strangeness in 3D [ewj: yup!], but totally necessary for 2D
|
||||
//if (noDepthTest || (sp[Z] < zbuffer[offset+x])) {
|
||||
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;
|
||||
//System.out.println("tu: "+tu+" ; tv: "+tv+" ; txy: "+txy);
|
||||
float[] uv = new float[2];
|
||||
txy = getTextureIndex(x, y*1.0f/SUBYRES, uv);
|
||||
// txy = getTextureIndex(x* 1.0f/SUBXRES, y*1.0f/SUBYRES, uv);
|
||||
|
||||
tu = (int)uv[0]; tv = (int)uv[1];
|
||||
// if (tu > twidth1) tu = twidth1;
|
||||
// if (tv > theight1) tv = theight1;
|
||||
// if (tu < 0) tu = 0;
|
||||
// if (tv < 0) tv = 0;
|
||||
txy = twidth*tv + tu;
|
||||
// if (EWJORDAN) System.out.println("x/y/txy:"+x + " " + y + " " +txy);
|
||||
//PApplet.println(sp);
|
||||
|
||||
//smooth = true;
|
||||
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));
|
||||
|
||||
int tuf1 = (int) (255f * (uv[0] - tu));
|
||||
int tvf1 = (int) (255f * (uv[1] - 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];
|
||||
//System.out.println("1: "+pixel00);
|
||||
//check
|
||||
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
|
||||
//ACCTEX: Getting here when smooth is on
|
||||
ta = interpARGB ? ((int) (sp[A]*255)) : a2orig;
|
||||
//System.out.println("4: "+ta + " " +interpARGB + " " + sp[A] + " " + a2orig);
|
||||
//check
|
||||
}
|
||||
|
||||
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;
|
||||
//System.out.println("5: "+tr + " " + tg + " " +tb);
|
||||
//check
|
||||
} 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;
|
||||
//System.out.println(ta);
|
||||
//System.out.println("8");
|
||||
//check
|
||||
} 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);
|
||||
|
||||
//System.out.println("17");
|
||||
//check
|
||||
if (ta > ZBUFFER_MIN_COVERAGE) zbuffer[offset+x] = sp[Z];
|
||||
}
|
||||
|
||||
//System.out.println("18");
|
||||
//check
|
||||
} 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))) {
|
||||
//if (!smooth)
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
//incrementalize_x(l, r, sp, sdp, lx);
|
||||
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;
|
||||
//System.out.println(p2[Z]+" " +p1[Z]+" " +dp[Z]);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pass camera-space coordinates for the triangle.
|
||||
* Needed to render if hint(ENABLE_ACCURATE_TEXTURES) enabled.
|
||||
* Generally this will not need to be called manually,
|
||||
* currently called from PGraphics3D.render_triangles()
|
||||
*/
|
||||
public void setCamVertices(float x0, float y0, float z0,
|
||||
float x1, float y1, float z1,
|
||||
float x2, float y2, float z2) {
|
||||
camX[0] = x0;
|
||||
camX[1] = x1;
|
||||
camX[2] = x2;
|
||||
|
||||
camY[0] = y0;
|
||||
camY[1] = y1;
|
||||
camY[2] = y2;
|
||||
|
||||
camZ[0] = z0;
|
||||
camZ[1] = z1;
|
||||
camZ[2] = z2;
|
||||
}
|
||||
|
||||
public void setVertices(float x0, float y0, float z0,
|
||||
float x1, float y1, float z1,
|
||||
float x2, float y2, float z2) {
|
||||
vertices[0][X] = x0;
|
||||
vertices[1][X] = x1;
|
||||
vertices[2][X] = x2;
|
||||
|
||||
vertices[0][Y] = y0;
|
||||
vertices[1][Y] = y1;
|
||||
vertices[2][Y] = y2;
|
||||
|
||||
vertices[0][Z] = z0;
|
||||
vertices[1][Z] = z1;
|
||||
vertices[2][Z] = z2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Precompute a bunch of variables needed to perform
|
||||
* texture mapping.
|
||||
* @return True unless texture mapping is degenerate
|
||||
*/
|
||||
boolean precomputeAccurateTexturing() {
|
||||
int o0 = 0;
|
||||
int o1 = 1;
|
||||
int o2 = 2;
|
||||
|
||||
PMatrix3D myMatrix = new PMatrix3D(vertices[o0][U], vertices[o0][V], 1, 0,
|
||||
vertices[o1][U], vertices[o1][V], 1, 0,
|
||||
vertices[o2][U], vertices[o2][V], 1, 0,
|
||||
0, 0, 0, 1);
|
||||
|
||||
// A 3x3 inversion would be more efficient here,
|
||||
// given that the fourth r/c are unity
|
||||
boolean invertSuccess = myMatrix.invert();// = myMatrix.invert();
|
||||
|
||||
// If the matrix inversion had trouble, let the caller know.
|
||||
// Note that this does not catch everything that could go wrong
|
||||
// here, like if the renderer is in ortho() mode (which really
|
||||
// must be caught in PGraphics3D instead of here).
|
||||
if (!invertSuccess) return false;
|
||||
|
||||
float m00, m01, m02, m10, m11, m12, m20, m21, m22;
|
||||
m00 = myMatrix.m00*camX[o0]+myMatrix.m01*camX[o1]+myMatrix.m02*camX[o2];
|
||||
m01 = myMatrix.m10*camX[o0]+myMatrix.m11*camX[o1]+myMatrix.m12*camX[o2];
|
||||
m02 = myMatrix.m20*camX[o0]+myMatrix.m21*camX[o1]+myMatrix.m22*camX[o2];
|
||||
m10 = myMatrix.m00*camY[o0]+myMatrix.m01*camY[o1]+myMatrix.m02*camY[o2];
|
||||
m11 = myMatrix.m10*camY[o0]+myMatrix.m11*camY[o1]+myMatrix.m12*camY[o2];
|
||||
m12 = myMatrix.m20*camY[o0]+myMatrix.m21*camY[o1]+myMatrix.m22*camY[o2];
|
||||
m20 = -(myMatrix.m00*camZ[o0]+myMatrix.m01*camZ[o1]+myMatrix.m02*camZ[o2]);
|
||||
m21 = -(myMatrix.m10*camZ[o0]+myMatrix.m11*camZ[o1]+myMatrix.m12*camZ[o2]);
|
||||
m22 = -(myMatrix.m20*camZ[o0]+myMatrix.m21*camZ[o1]+myMatrix.m22*camZ[o2]);
|
||||
|
||||
float px = m02;
|
||||
float py = m12;
|
||||
float pz = m22;
|
||||
|
||||
float TEX_WIDTH = this.twidth;
|
||||
float TEX_HEIGHT = this.theight;
|
||||
|
||||
float resultT0x = m00*TEX_WIDTH+m02;
|
||||
float resultT0y = m10*TEX_WIDTH+m12;
|
||||
float resultT0z = m20*TEX_WIDTH+m22;
|
||||
float result0Tx = m01*TEX_HEIGHT+m02;
|
||||
float result0Ty = m11*TEX_HEIGHT+m12;
|
||||
float result0Tz = m21*TEX_HEIGHT+m22;
|
||||
float mx = resultT0x-m02;
|
||||
float my = resultT0y-m12;
|
||||
float mz = resultT0z-m22;
|
||||
float nx = result0Tx-m02;
|
||||
float ny = result0Ty-m12;
|
||||
float nz = result0Tz-m22;
|
||||
|
||||
//avec = p x n
|
||||
ax = (py*nz-pz*ny)*TEX_WIDTH; //F_TEX_WIDTH/HEIGHT?
|
||||
ay = (pz*nx-px*nz)*TEX_WIDTH;
|
||||
az = (px*ny-py*nx)*TEX_WIDTH;
|
||||
//bvec = m x p
|
||||
bx = (my*pz-mz*py)*TEX_HEIGHT;
|
||||
by = (mz*px-mx*pz)*TEX_HEIGHT;
|
||||
bz = (mx*py-my*px)*TEX_HEIGHT;
|
||||
//cvec = n x m
|
||||
cx = ny*mz-nz*my;
|
||||
cy = nz*mx-nx*mz;
|
||||
cz = nx*my-ny*mx;
|
||||
|
||||
//System.out.println("a/b/c: "+ax+" " + ay + " " + az + " " + bx + " " + by + " " + bz + " " + cx + " " + cy + " " + cz);
|
||||
|
||||
nearPlaneWidth = (parent.rightScreen-parent.leftScreen);
|
||||
nearPlaneHeight = (parent.topScreen-parent.bottomScreen);
|
||||
nearPlaneDepth = parent.nearPlane;
|
||||
|
||||
// one pixel width in nearPlane coordinates
|
||||
xmult = nearPlaneWidth / parent.width;
|
||||
ymult = nearPlaneHeight / parent.height;
|
||||
// Extra scalings to map screen plane units to pixel units
|
||||
// newax = ax*xmult;
|
||||
// newbx = bx*xmult;
|
||||
// newcx = cx*xmult;
|
||||
|
||||
|
||||
// System.out.println("nearplane: "+ nearPlaneWidth + " " + nearPlaneHeight + " " + nearPlaneDepth);
|
||||
// System.out.println("mults: "+ xmult + " " + ymult);
|
||||
// System.out.println("news: "+ newax + " " + newbx + " " + newcx);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the texture map location based on the current screen
|
||||
* coordinates. Assumes precomputeAccurateTexturing() has
|
||||
* been called already for this texture mapping.
|
||||
* @param sx
|
||||
* @param sy
|
||||
* @return
|
||||
*/
|
||||
private int getTextureIndex(float sx, float sy, float[] uv) {
|
||||
if (EWJORDAN) System.out.println("Getting texel at "+sx + ", "+sy);
|
||||
//System.out.println("Screen: "+ sx + " " + sy);
|
||||
sx = xmult*(sx-(parent.width/2.0f) +.5f);//+.5f)
|
||||
sy = ymult*(sy-(parent.height/2.0f)+.5f);//+.5f)
|
||||
//sx /= SUBXRES;
|
||||
//sy /= SUBYRES;
|
||||
float sz = nearPlaneDepth;
|
||||
float a = sx * ax + sy * ay + sz * az;
|
||||
float b = sx * bx + sy * by + sz * bz;
|
||||
float c = sx * cx + sy * cy + sz * cz;
|
||||
int u = (int)(a / c);
|
||||
int v = (int)(b / c);
|
||||
uv[0] = a / c;
|
||||
uv[1] = b / c;
|
||||
if (uv[0] < 0) {
|
||||
uv[0] = u = 0;
|
||||
}
|
||||
if (uv[1] < 0) {
|
||||
uv[1] = v = 0;
|
||||
}
|
||||
if (uv[0] >= twidth) {
|
||||
uv[0] = twidth-1;
|
||||
u = twidth-1;
|
||||
}
|
||||
if (uv[1] >= theight) {
|
||||
uv[1] = theight-1;
|
||||
v = theight-1;
|
||||
}
|
||||
int result = v*twidth + u;
|
||||
//System.out.println("a/b/c: "+a + " " + b + " " + c);
|
||||
//System.out.println("cx/y/z: "+cx + " " + cy + " " + cz);
|
||||
//if (result < 0) result = 0;
|
||||
//if (result >= timage.pixels.length-2) result = timage.pixels.length - 2;
|
||||
if (EWJORDAN) System.out.println("Got texel "+result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public void setIntensities(float ar, float ag, float ab, float aa,
|
||||
float br, float bg, float bb, float ba,
|
||||
float cr, float cg, float cb, float ca) {
|
||||
vertices[0][R] = ar;
|
||||
vertices[0][G] = ag;
|
||||
vertices[0][B] = ab;
|
||||
vertices[0][A] = aa;
|
||||
vertices[1][R] = br;
|
||||
vertices[1][G] = bg;
|
||||
vertices[1][B] = bb;
|
||||
vertices[1][A] = ba;
|
||||
vertices[2][R] = cr;
|
||||
vertices[2][G] = cg;
|
||||
vertices[2][B] = cb;
|
||||
vertices[2][A] = ca;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user