/* This file is part of jpcsp. Jpcsp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Jpcsp 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 General Public License for more details. You should have received a copy of the GNU General Public License along with Jpcsp. If not, see <http://www.gnu.org/licenses/>. */ package jpcsp.graphics.RE.software; /** * @author gid15 * */ public class PrimitiveState { public float p1x, p1y, p1z, p1w, p1wInverted; public float p2x, p2y, p2z, p2w, p2wInverted; public float p3x, p3y, p3z, p3w, p3wInverted; public int pxMin, pxMax, pyMin, pyMax, pzMin, pzMax; public float t1u, t1v; public float t2u, t2v; public float t3u, t3v; public int tuMin, tuMax, tvMin, tvMax; public float uStart, uStep; public float vStart, vStep; public int destinationWidth; public int destinationHeight; public boolean needResample; public float resampleFactorWidth; public float resampleFactorHeight; // Pre-computed values for triangle weights public float diff13x; public float diff13y; public float diff32x; public float diff23y; public float denomInverted; protected void copy(PrimitiveState from) { p1x = from.p1x; p1y = from.p1y; p1z = from.p1z; p1w = from.p1w; p1wInverted = from.p1wInverted; p2x = from.p2x; p2y = from.p2y; p2z = from.p2z; p2w = from.p2w; p2wInverted = from.p2wInverted; p3x = from.p3x; p3y = from.p3y; p3z = from.p3z; p3w = from.p3w; p3wInverted = from.p3wInverted; pxMin = from.pxMin; pxMax = from.pxMax; pyMin = from.pyMin; pyMax = from.pyMax; pzMin = from.pzMin; pzMax = from.pzMax; t1u = from.t1u; t1v = from.t1v; t2u = from.t2u; t2v = from.t2v; t3u = from.t3u; t3v = from.t3v; tuMin = from.tuMin; tuMax = from.tuMax; tvMin = from.tvMin; tvMax = from.tvMax; uStart = from.uStart; uStep = from.uStep; vStart = from.vStart; vStep = from.vStep; destinationWidth = from.destinationWidth; destinationHeight = from.destinationHeight; diff13x = from.diff13x; diff13y = from.diff13y; diff32x = from.diff32x; diff23y = from.diff23y; denomInverted = from.denomInverted; } public void preComputeTriangleWeights() { diff13x = p1x - p3x; diff13y = p1y - p3y; diff32x = p3x - p2x; diff23y = p2y - p3y; float denom = diff23y * diff13x + diff32x * diff13y; denomInverted = 1.f / denom; } public void computeTriangleWeights(PixelState pixel, int x, int y) { // Based on http://en.wikipedia.org/wiki/Barycentric_coordinates_%28mathematics%29 // // All the values independent of the current pixel haven been pre-computed // in preComputeTriangleWeights(). // float diff03x = x - p3x + 0.01f; float diff03y = y - p3y; pixel.triangleWeight1 = (diff23y * diff03x + diff32x * diff03y) * denomInverted; pixel.triangleWeight2 = (diff13x * diff03y - diff13y * diff03x) * denomInverted; pixel.triangleWeight3 = 1.f - (pixel.triangleWeight1 + pixel.triangleWeight2); } /** * Update the triangle weights (Barycentric coordinates) by knowing that * pixel.x * has been incremented by 1. */ public void deltaXTriangleWeigths(PixelState pixel) { // When pixel.x is incremented by 1, diff03x is also incremented by 1. // Which leads to simple increments of the triangle weights. pixel.triangleWeight1 += diff23y * denomInverted; pixel.triangleWeight2 -= diff13y * denomInverted; pixel.triangleWeight3 = 1.f - (pixel.triangleWeight1 + pixel.triangleWeight2); } public boolean isClockwise() { float crossProduct = (p2x - p1x) * (p3y - p1y) - (p2y - p1y) * (p3x - p1x); return crossProduct >= 0.f; } @Override public String toString() { return String.format("Prim[pos (%d-%d),(%d,%d), tex (%d-%d),(%d-%d)]", pxMin, pxMax, pyMin, pyMax, tuMin, tuMax, tvMin, tvMax); } }