View Matrix in LWJGL 3 not showing right - java

My view matrix in my camera class is setup up correctly, with the rotation and negative translation, but it moves the camera somewhere else, and I can't seem to find my model. Rotation and translation matrices are working because translations are working and my model and projection matrices are also working, but when I add the view matrix, it only shows parts of the model. By the way, made my own matrix math classes.
Matrix Math Class
package engine.maths;
public class Matrix4f {
private float[][] matrix;
public Matrix4f() {
matrix = new float[4][4];
}
public Matrix4f identity() {
matrix[0][0] = 1; matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0;
matrix[1][0] = 0; matrix[1][1] = 1; matrix[1][2] = 0; matrix[1][3] = 0;
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = 1; matrix[2][3] = 0;
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1;
return this;
}
public Matrix4f translate(Vector3f vector) {
matrix[0][0] = 1; matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = vector.getX();
matrix[1][0] = 0; matrix[1][1] = 1; matrix[1][2] = 0; matrix[1][3] = vector.getY();
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = 1; matrix[2][3] = vector.getZ();
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1;
return this;
}
public Matrix4f rotate(Vector3f vector) {
Matrix4f rotateX = new Matrix4f();
Matrix4f rotateY = new Matrix4f();
Matrix4f rotateZ = new Matrix4f();
Vector3f rotatedVector = new Vector3f((float) Math.toRadians(vector.getX()), (float) Math.toRadians(vector.getY()), (float) Math.toRadians(vector.getZ()));
rotateZ.matrix[0][0] = (float)Math.cos(rotatedVector.getZ()); rotateZ.matrix[0][1] = -(float)Math.sin(rotatedVector.getZ()); rotateZ.matrix[0][2] = 0; rotateZ.matrix[0][3] = 0;
rotateZ.matrix[1][0] = (float)Math.sin(rotatedVector.getZ()); rotateZ.matrix[1][1] = (float)Math.cos(rotatedVector.getZ()); rotateZ.matrix[1][2] = 0; rotateZ.matrix[1][3] = 0;
rotateZ.matrix[2][0] = 0; rotateZ.matrix[2][1] = 0; rotateZ.matrix[2][2] = 1; rotateZ.matrix[2][3] = 0;
rotateZ.matrix[3][0] = 0; rotateZ.matrix[3][1] = 0; rotateZ.matrix[3][2] = 0; rotateZ.matrix[3][3] = 1;
rotateX.matrix[0][0] = 1; rotateX.matrix[0][1] = 0; rotateX.matrix[0][2] = 0; rotateX.matrix[0][3] = 0;
rotateX.matrix[1][0] = 0; rotateX.matrix[1][1] = (float)Math.cos(rotatedVector.getX()); rotateX.matrix[1][2] = -(float)Math.sin(rotatedVector.getX()); rotateX.matrix[1][3] = 0;
rotateX.matrix[2][0] = 0; rotateX.matrix[2][1] = (float)Math.sin(rotatedVector.getX()); rotateX.matrix[2][2] = (float)Math.cos(rotatedVector.getX()); rotateX.matrix[2][3] = 0;
rotateX.matrix[3][0] = 0; rotateX.matrix[3][1] = 0; rotateX.matrix[3][2] = 0; rotateX.matrix[3][3] = 1;
rotateY.matrix[0][0] = (float)Math.cos(rotatedVector.getY()); rotateY.matrix[0][1] = 0; rotateY.matrix[0][2] = -(float)Math.sin(rotatedVector.getY()); rotateY.matrix[0][3] = 0;
rotateY.matrix[1][0] = 0; rotateY.matrix[1][1] = 1; rotateY.matrix[1][2] = 0; rotateY.matrix[1][3] = 0;
rotateY.matrix[2][0] = (float)Math.sin(rotatedVector.getY()); rotateY.matrix[2][1] = 0; rotateY.matrix[2][2] = (float)Math.cos(rotatedVector.getY()); rotateY.matrix[2][3] = 0;
rotateY.matrix[3][0] = 0; rotateY.matrix[3][1] = 0; rotateY.matrix[3][2] = 0; rotateY.matrix[3][3] = 1;
matrix = rotateZ.mul(rotateY.mul(rotateX)).getMatrix();
return this;
}
public Matrix4f scale(Vector3f vector) {
matrix[0][0] = vector.getX(); matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0;
matrix[1][0] = 0; matrix[1][1] = vector.getY(); matrix[1][2] = 0; matrix[1][3] = 0;
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = vector.getZ(); matrix[2][3] = 0;
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1;
return this;
}
public Matrix4f projection(float fov, float aspectRatio, float zNear, float zFar) {
float tanHalfFOV = (float) Math.tan(Math.toRadians(fov / 2));
float zRange = zNear - zFar;
matrix[0][0] = 1.0f / (tanHalfFOV * aspectRatio); matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0;
matrix[1][0] = 0; matrix[1][1] = 1.0f / tanHalfFOV; matrix[1][2] = 0; matrix[1][3] = 0;
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = (-zNear - zFar) / zRange; matrix[2][3] = 2 * zFar * zNear / zRange;
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 1; matrix[3][3] = 0;
return this;
}
public Matrix4f mul(Matrix4f m) {
Matrix4f result = new Matrix4f();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
result.set(i, j, matrix[i][0] * m.get(0, j) +
matrix[i][1] * m.get(1, j) +
matrix[i][2] * m.get(2, j) +
matrix[i][3] * m.get(3, j));
}
}
return result;
}
public float[][] getMatrix() {
return matrix;
}
public void setMatrix(float[][] matrix) {
this.matrix = matrix;
}
public float get(int x, int y) {
return matrix[x][y];
}
public void set(int x, int y, float value) {
matrix[x][y] = value;
}
public String toString() {
String matrix = "";
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrix += (Float.toString(get(i, j)) + ", ");
}
matrix += "\n";
}
return matrix + "";
}
}
Camera Class
package engine.rendering;
import engine.maths.Matrix4f;
import engine.maths.Vector3f;
public class Camera {
private Vector3f position, rotation;
public Camera(Vector3f position, Vector3f rotation) {
this.position = position;
this.rotation = rotation;
}
public Matrix4f getViewMatrix() {
Matrix4f rotationMatrix = new Matrix4f().identity().rotate(rotation);
Vector3f negativePosition = new Vector3f(-position.getX(), -position.getY(), -position.getZ());
Matrix4f translationMatrix = new Matrix4f().identity().translate(negativePosition);
return rotationMatrix.mul(translationMatrix);
}
public void addPosition(float x, float y, float z) {
position.add(new Vector3f(x, y, z));
}
public void addPosition(Vector3f value) {
position.add(value);
}
public void setPosition(float x, float y, float z) {
position = new Vector3f(x, y, z);
}
public void setPosition(Vector3f pos) {
position = pos;
}
public Vector3f getPosition() {
return position;
}
public void addRotation(float x, float y, float z) {
rotation.add(new Vector3f(x, y, z));
}
public void addRotation(Vector3f value) {
rotation.add(value);
}
public void setRotation(float x, float y, float z) {
rotation = new Vector3f(x, y, z);
}
public void setRotation(Vector3f rot) {
rotation = rot;
}
public Vector3f getRotation() {
return rotation;
}
}
Loading Matrix Class
package engine.shaders;
import engine.maths.Matrix4f;
public class BasicShader extends Shader {
private static final String VERTEX_FILE = "src/engine/shaders/basicVertexShader.glsl";
private static final String FRAGMENT_FILE = "src/engine/shaders/basicFragmentShader.glsl";
private int tvpMatrixLocation;
private Matrix4f transformationMatrix = new Matrix4f().identity(), projectionMatrix = new Matrix4f().identity(), viewMatrix = new Matrix4f().identity();
public BasicShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
#Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
super.bindAttribute(1, "textCoords");
}
#Override
protected void getAllUniforms() {
tvpMatrixLocation = super.getUniform("tvpMatrix");
}
public void useMatrices() {
super.loadMatrixUniform(tvpMatrixLocation, transformationMatrix.mul(projectionMatrix.mul(viewMatrix)));
}
public void loadTransformationMatrix(Matrix4f matrix) {
transformationMatrix = matrix;
}
public void loadProjectionMatrix(Matrix4f matrix) {
projectionMatrix = matrix;
}
public void loadViewMatrix(Matrix4f matrix) {
viewMatrix = matrix;
}
}

Your projection matrix has a fault: matrix[3][2] = 1 must be -1.
This is due to OpenGL NDC space is special, cross product XxY gives -Z instead of Z.
The surprising fact is that all visible objects must have a negative Z-coordinate in view space.

This is not making any sense:
super.loadMatrixUniform(tvpMatrixLocation, transformationMatrix.mul(projectionMatrix.mul(viewMatrix)));
No matter what conventions you use, and which order the mul() method actually multiplies. you either end up with T*P*V, or V*P*T, which both woudln't be correct (for the typical use case of not applying some additional transformation after the projection).

Related

Transforming an Image to move diagnally

public void draw(Graphics g, Graphics g2d, double theta, int NEWY){
g.setColor(Color.orange);
int drawLocationX = character.x;
int drawLocationY = character.y-47;
double rotationRequired = Math.toRadians (theta);
double locationX = this.getWidth()/2;
double locationY = this.getHeight()/2;
AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
g2d.drawImage(op.filter(image, null), drawLocationX, NEWY, null);
}
public int getHeightWorld(int x){
//meant to find height of land at specified location
int highest = 0;
int checked = 0;
for(int c = panel.HEIGHT-1; c >= 0; c--){
if(this.inColRange(x)&& this.inRowRange(c))
if(LandList[c][x] == 2){
highest = c;
checked++;
}
}
return (1000 - highest);
}
public double getAngleWorldT1(){
//meant to find angle tank needs to be rotated at
int g = this.getHeightWorld(tank1.getNEWX());
int h = this.getHeightWorld((tank1.getWidth()+ tank1.getNEWX()));
double trythis = this.NewEquation();
int newg = tank1.getWidth()+ tank1.getNEWX();
int newh = tank2.getWidth()+ tank2.getNEWX();
double newery = (trythis*newg);
double newery2 = (trythis*tank1.getNEWX());
double newval = newery - newery2;
double u = 5;
double width = tank1.getWidth();
if(Math.abs(h-g) > tank1.getWidth()){
u = width/(g-h);
}
else{
u = (g-h)/width;
}
double p = 57.6846779*Math.asin(Math.toRadians(u));
return p;
}
public double NewEquation(){
int dividethis = 0;
int subtractthis = 0;
int numnegative = 0;
for(int what = 0; what < tank1.getWidth(); what++){
if(Math.abs(this.getHeightWorld(what)-this.getHeightWorld(what-1)) < 2){
dividethis += this.getHeightWorld(what);
if(this.getHeightWorld(what)-this.getHeightWorld(what-1) < 0){
numnegative++;
}
}
else{
subtractthis++;
}
}
dividethis = dividethis/(tank1.getWidth()-subtractthis);
if((numnegative - tank1.getWidth()) > tank1.getWidth()/2){
dividethis = dividethis*-1;
}
return dividethis;
}
public void draw(Graphics g) {
//MOVE TO DIFF METHOD
int newy = this.getHeightWorld(tank1.getNEWX()) - tank1.getHeight();
int newy2 = this.getHeightWorld(tank2.getNEWX()) - tank2.getHeight();
if( LandList[newy][tank1.getNEWX()] == 2){
while (LandList[newy][tank1.getNEWX()] == 2){
newy--;
// System.out.println("FIRST HERE");
// System.out.println(newy);
}
// System.out.println("FIRST");
}
if( LandList[newy+1][tank1.getNEWX()] != 2){
while (LandList[newy+1][tank1.getNEWX()] != 2){
newy++;
// System.out.println("SECOND HERE");
}
// System.out.println("SECOND");
}
//System.out.println("YESSSSS" +Math.toDegrees(this.getAngleWorldT1()) );
tank1.draw(g, g, Math.toDegrees(this.getAngleWorldT1()), newy - tank1.getHeight()-50);
tank2.draw(g, g, Math.toDegrees(this.getAngleWorldT2()), newy2 - tank2.getHeight());
// System.out.println("2");
for(int x = 0; x < platforms.size(); x++){
platforms.get(x).draw(g);
}
}
}
(Sorry for the messy code.)
These are two classes I am using to design a tank shooter game. In this portion, I am attempting to make the image rotate according to the land it is over(to appear traveling uphill or downhill) and I don't want any piece inside of the land. "LandList" is a 2D array that has a value of 2 if there is land and 1 if there is no land. Two issues is A) rotating at incorrect heights and not rotating at all points
B)Image cuts off at a certain height
Thank you for your help.
BOTH CLASSES IN FULL
public class World {
Land[][] land;
List<Land> platforms = new ArrayList<Land>();
private GraphicsPanel panel;
int[][] LandList = new int[800][1500];
private int delay = 30;
private Timer timer;
private Random r;
Tank tank1;
Tank tank2;
public World(GraphicsPanel marioPanel) {
panel = marioPanel;
land = new Land[panel.WIDTH][panel.HEIGHT-500-3];
setUpWorld();
setUpTimer();
}
private void setUpWorld() {
for(int r = 0; r < panel.WIDTH; r++){
for(int c = 0; c < panel.HEIGHT; c++){
LandList[c][r] = 1;
}
}
//tank not displaying
//a lot of stuff copied over
tank1 = new Tank(25,442,100,60,1);
tank2 = new Tank(700,442,100,60,2);
r = new Random();
int w = 0;
int n = 0;
for(int x = 0; x < panel.WIDTH; x+=5){
if(x > 0 && x < panel.WIDTH/6 +1){
//for(int y = (int) (500+(-(100*Math.random())*((x%2)+1))); y < panel.HEIGHT; y+=5){
for(int y = 500; y < panel.HEIGHT; y+=5){
Land creating = new Land(x, y, 5, 5);
platforms.add(creating);
for(int r = 0; r < 5; r++){
for(int c = 0; c < 5; c++){
if(inRowRange(x+r) && inColRange(y+c))
LandList[y+r][x+c] = 2;
}
}
}
}
if(x > panel.WIDTH/6 && x < 2*panel.WIDTH/6 +1){
//for(int y = (int) (500+(-(100*Math.random())*((x%2)+1))); y < panel.HEIGHT; y+=5){
for(int y = 500+ 4*w; y < panel.HEIGHT; y+=5){
Land creating = new Land(x, y, 5, 5);
platforms.add(creating);
for(int r = 0; r < 5; r++){
for(int c = 0; c < 5; c++){
if(inRowRange(y+r) && inColRange(x+c))
LandList[y+r][x+c] = 2;
}
}
}
w--;
}
if(x > 2*panel.WIDTH/6 && x < 3*panel.WIDTH/6 +1){
//for(int y = (int) (500+(-(100*Math.random())*((x%2)+1))); y < panel.HEIGHT; y+=5){
for(int y = 500+ 4*w; y < panel.HEIGHT; y+=5){
Land creating = new Land(x, y, 5, 5);
platforms.add(creating);
for(int r = 0; r < 5; r++){
for(int c = 0; c < 5; c++){
if(inRowRange(y+r) && inColRange(x+c))
LandList[y+r][x+c] = 2;
}
}
}
w++;
}
if(x > 3*panel.WIDTH/6 && x < 4*panel.WIDTH/6 +1){
//for(int y = (int) (500+(-(100*Math.random())*((x%2)+1))); y < panel.HEIGHT; y+=5){
for(int y = 500+ 4*n; y < panel.HEIGHT; y+=5){
Land creating = new Land(x, y, 5, 5);
platforms.add(creating);
for(int r = 0; r < 5; r++){
for(int c = 0; c < 5; c++){
if(inRowRange(y+r) && inColRange(x+c))
LandList[y+r][x+c] = 2;
}
}
}
n--;
}
if(x > 4*panel.WIDTH/6 && x < 5*panel.WIDTH/6 +1){
//for(int y = (int) (500+(-(100*Math.random())*((x%2)+1))); y < panel.HEIGHT; y+=5){
for(int y = 500+ 4*n; y < panel.HEIGHT; y+=5){
Land creating = new Land(x, y, 5, 5);
platforms.add(creating);
for(int r = 0; r < 5; r++){
for(int c = 0; c < 5; c++){
if(inRowRange(y+r) && inColRange(x+c))
LandList[y+r][x+c] = 2;
}
}
}
n++;
}
if(x > 5*panel.WIDTH/6){
//for(int y = (int) (500+(-(100*Math.random())*((x%2)+1))); y < panel.HEIGHT; y+=5){
for(int y = 500; y < panel.HEIGHT; y+=5){
Land creating = new Land(x, y, 5, 5);
platforms.add(creating);
for(int r = 0; r < 5; r++){
for(int c = 0; c < 5; c++){
if(inRowRange(y+r) && inColRange(x+c))
LandList[y+r][x+c] = 2;
// System.out.println(LandList[x+r][y+c]);
}
}
}
}
// else{
// for(int y = 500; y < panel.HEIGHT; y+=5){
// Land creating = new Land(x, y, 5, 5);
// platforms.add(creating);
// }
//
// }
}
for(int r = 0; r < panel.WIDTH; r++){
for(int c = 0; c < panel.HEIGHT; c++){
//System.out.println(LandList[r][c]);
}
}
for(int checked = 0; checked < panel.WIDTH; checked++){
System.out.println(this.getHeightWorld(checked));
}
// System.out.println(LandList);
}
private boolean inColRange(int i) {
// TODO Auto-generated method stub
return i>=0 && i<LandList[0].length;
}
private boolean inRowRange(int i) {
// TODO Auto-generated method stub
return i>=0 && i<LandList.length;
}
private void setUpTimer() {
timer = new Timer(delay, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// what should happen each time the timer goes off?
panel.repaint();
moveStuff();
checkHitBoxes();
//System.out.println(mario.getY());
}
});
timer.start();
}
protected void checkHitBoxes() {
}
protected void moveStuff() {
tank1.move();
panel.repaint();
}
public int getHeightWorld(int x){
//meant to find height of land at specified location
int highest = 0;
int checked = 0;
for(int c = panel.HEIGHT-1; c >= 0; c--){
if(this.inColRange(x)&& this.inRowRange(c))
if(LandList[c][x] == 2){
highest = c;
checked++;
}
}
return (1000 - highest);
}
public double getAngleWorldT1(){
//meant to find angle tank needs to be rotated at
int g = this.getHeightWorld(tank1.getNEWX());
int h = this.getHeightWorld((tank1.getWidth()+ tank1.getNEWX()));
double trythis = this.NewEquation();
int newg = tank1.getWidth()+ tank1.getNEWX();
int newh = tank2.getWidth()+ tank2.getNEWX();
double newery = (trythis*newg);
double newery2 = (trythis*tank1.getNEWX());
double newval = newery - newery2;
double u = 5;
double width = tank1.getWidth();
if(Math.abs(h-g) > tank1.getWidth()){
u = width/(g-h);
}
else{
u = (g-h)/width;
}
double p = 57.6846779*Math.asin(Math.toRadians(u));
return p;
}
public double getAngleWorldT2(){
int a = this.getHeightWorld(tank2.getNEWX());
int s = this.getHeightWorld((tank2.getWidth() + tank2.getNEWX() + 100) );
// a = 100;
// s = 700;
int o = (a-s)/tank2.getWidth();
//System.out.println(o);
double p = -57.6846779*(Math.asin(Math.toRadians(o)));
//System.out.println(p);
return p;
}
public double NewEquation(){
int dividethis = 0;
int subtractthis = 0;
int numnegative = 0;
for(int what = 0; what < tank1.getWidth(); what++){
if(Math.abs(this.getHeightWorld(what)-this.getHeightWorld(what-1)) < 2){
dividethis += this.getHeightWorld(what);
if(this.getHeightWorld(what)-this.getHeightWorld(what-1) < 0){
numnegative++;
}
}
else{
subtractthis++;
}
}
dividethis = dividethis/(tank1.getWidth()-subtractthis);
if((numnegative - tank1.getWidth()) > tank1.getWidth()/2){
dividethis = dividethis*-1;
}
return dividethis;
}
public void draw(Graphics g) {
//MOVE TO DIFF METHOD
int newy = this.getHeightWorld(tank1.getNEWX()) - tank1.getHeight();
int newy2 = this.getHeightWorld(tank2.getNEWX()) - tank2.getHeight();
if( LandList[newy][tank1.getNEWX()] == 2){
while (LandList[newy][tank1.getNEWX()] == 2){
newy--;
// System.out.println("FIRST HERE");
// System.out.println(newy);
}
// System.out.println("FIRST");
}
if( LandList[newy+1][tank1.getNEWX()] != 2){
while (LandList[newy+1][tank1.getNEWX()] != 2){
newy++;
// System.out.println("SECOND HERE");
}
// System.out.println("SECOND");
}
//System.out.println("YESSSSS" +Math.toDegrees(this.getAngleWorldT1()) );
tank1.draw(g, g, Math.toDegrees(this.getAngleWorldT1()), newy - tank1.getHeight()-50);
tank2.draw(g, g, Math.toDegrees(this.getAngleWorldT2()), newy2 - tank2.getHeight());
// System.out.println("2");
for(int x = 0; x < platforms.size(); x++){
platforms.get(x).draw(g);
}
}
}
public class Tank extends Moveable{
private boolean moveRight,moveLeft;
private String direction = "NONE";
private int dx =5;
//graphics
BufferedImage image = null;
private URL file;
private Rectangle character;
private Rectangle hitBox;
JLabel label = new JLabel();
private int NEWX;
public Tank(int x, int y, int w, int h, int color){
character = new Rectangle(x,y,w,h);
this.create(null,x,y,w,h);
NEWX = character.x;
BufferedImage img =null;
if(color == 1){
// file= getClass().getResource("pictures\\green_tank1");
try {
img = ImageIO.read(new File("green_tank1.png"));
image = img;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
// file = getClass().getResource("pictures\\blue_tank1");
try {
img = ImageIO.read(new File("blue_tank1.png"));
image = img;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void draw(Graphics g, Graphics g2d, double theta, int NEWY){
g.setColor(Color.orange);
int drawLocationX = character.x;
int drawLocationY = character.y-47;
double rotationRequired = Math.toRadians (theta);
double locationX = this.getWidth()/2;
double locationY = this.getHeight()/2;
AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
g2d.drawImage(op.filter(image, null), drawLocationX, NEWY, null);
//System.out.println("This is new X " + NEWX);
// label.setVisible(true);
// label.isOpaque();
// label.setBounds(character.x, character.y, character.width, character.height);
// label.repaint();
//g.drawImage(image, 0, 0, null);
// int centerx = character.x + character.width/2;
// int centery = character.y + character.height/2;
//
// int point1 = (int) (centerx + (character.width/2)*Math.cos(Math.toRadians(theta)) - (character.height/2)* Math.sin(Math.toRadians(theta)));
// int point2 = (int) (centery + (character.height/2)*Math.cos(Math.toRadians(theta))+(character.width/2)*Math.sin(Math.toRadians(theta)));
// int point3 =(int) (centerx - (character.width/2)*Math.cos(Math.toRadians(theta)) + (character.height/2)* Math.sin(Math.toRadians(theta)));
// int point4 = (int) (centery - (character.height/2)*Math.cos(Math.toRadians(theta))-(character.width/2)*Math.sin(Math.toRadians(theta)));
// //System.out.println(theta);
// g.drawImage(image, point1,point2,point3,point4, null);
//// System.out.println("3");
// Rotation information
// AffineTransform tx = AffineTransform.getRotateInstance(Math.toRadians (theta), character.x, character.y);
// AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
//
// // Drawing the rotated image at the required drawing locations
// g.drawImage(op.filter((BufferedImage) image, null), character.x, character.y, null);
// System.out.println(this.getX());
// System.out.println(this.getY());
// System.out.println(this.getWidth());
// System.out.println(this.getHeight());
// g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
// this.setBounds(this.getX(), this.getY(), this.getWidth(), this.getHeight());
//
}
public Rectangle getRect(){
return this.character;
}
public void move(){
if(moveLeft == true){
character.setBounds(character.x -2, character.y, character.width, character.height);
character.x = character.x -2;
NEWX += -2;
}
if(moveRight == true){
character.setBounds(character.x +2, character.y, character.width, character.height);
character.x = character.x +2;
NEWX += 2;
}
}
public void setDirection(String s){
this.direction = s;
String x = s.toUpperCase().substring(0, 1);
if(x.equals("L")){
//System.out.println(x);
moveLeft = true;
moveRight = false;
}
if(x.equals("R")){
moveRight = true;
moveLeft = false;
// System.out.println("im here");
}
else if(x.equals("N")){
moveRight = false;
moveLeft =false;
// System.out.println("I Got Here #2");
}
}
public String getDirection(){
return this.direction;
}
public int getNEWX(){
return this.NEWX;
}
}

Raytracing: Dark rings appear

I am getting strange rings of black on my spheres when I render with lighting. I just added lighting and I cannot figure out why the black rings are being created.
Here is my code for my tracer.
public class Tracer {
public Camera Cam;
public int Width, Height;
public BufferedImage Image;
public Color BackGroundColor;
public int StartX, StartY, EndX, EndY,RowCount,ColCount;
public ArrayList<GeometricObject> GeoObjects;
public ArrayList<LightObject> LightObjects;
public boolean Tracing;
public double AmbientLight;
public Tracer(Camera cam, int width, int height, BufferedImage image, Color backGroundColor, int startX, int startY, int endX, int endY, int rowCount, int colCount, ArrayList<GeometricObject> Geoobjects,ArrayList<LightObject> Lightobjects,double ambientLight) {
super();
Cam = cam;
Width = width;
Height = height;
Image = image;
BackGroundColor = backGroundColor;
StartX = startX;
StartY = startY;
EndX = endX;
EndY = endY;
RowCount = rowCount;
ColCount = colCount;
GeoObjects = Geoobjects;
LightObjects = Lightobjects;
if(ambientLight > 1){
AmbientLight = 1;
}else if(ambientLight < 0){
AmbientLight = 0;
}else{
AmbientLight = ambientLight;
}
}
public void TracePixelFast(int x, int y) {
Color color = new Color(BackGroundColor.r,BackGroundColor.g,BackGroundColor.b);
for(int o = 0;o < GeoObjects.size();o++){
GeometricObject GO = GeoObjects.get(o);
Ray r = new Ray(Cam.GetRayPos(Width, Height, x, y, 1, 1, RowCount, ColCount), Cam.GetRayDir(Width, Height, x, y, 1,1, RowCount, ColCount));
double hit = GO.hit(r);
if (hit != 0.0) {
color = Cal_Pixel(x,y);
Image.setRGB(x, y, color.toInt());
break;
}
}
}
public void TracePixelSmooth(int x, int y) {
Image.setRGB(x, y,Cal_Pixel(x,y).toInt());
}
public Color Cal_Pixel(int x,int y){
Color color = new Color(BackGroundColor);
Color colorh = new Color(BackGroundColor);
Color bgc = new Color(BackGroundColor);
int HIT = 0;
int MISS = 0;
for (int row = 0; row < RowCount; row++) {
for (int col = 0; col < ColCount; col++) {
double min = Double.MAX_VALUE;
for (int o = 0; o < GeoObjects.size(); o++) {
GeometricObject GO = GeoObjects.get(o);
Ray r = new Ray(Cam.GetRayPos(Width, Height, x, y, row, col, RowCount, ColCount),Cam.GetRayDir(Width, Height, x, y, row, col, RowCount, ColCount));
double hit = GO.hit(r);
if (hit != 0.0 && hit < min) {
min = hit;
colorh = ShadePixel(GO, r, hit);
HIT++;
} else {
double min2 = Double.MAX_VALUE;
for (int o2 = 0; o2 < GeoObjects.size(); o2++) {
if(o!=o2){
GeometricObject GO2 = GeoObjects.get(o2);
double hit2 = GO2.hit(r);
if (hit2 != 0.0 && hit2 < min2) {
min2 = hit2;
bgc = ShadePixel(GO2, r, hit2);
}
}
}
MISS++;
}
}
}
}
for(int h = 0;h < HIT;h++){
color.Add(colorh);
}
for(int m = 0;m < MISS;m++){
color.Add(bgc);
}
color.Divide(RowCount * ColCount);
return color;
}
public Color ShadePixel(GeometricObject GO,Ray ray,double t){
ArrayList<Color> PixelShade = new ArrayList<Color>();
Normal normal = GO.Cal_Normal(ray, t);
for(int l = 0;l < LightObjects.size();l++){
LightObject light = LightObjects.get(l);
Vector3D r_Dir = light.Pos.Sub(normal.Origin);
r_Dir.normalize();
Ray raytolight = new Ray(normal.Origin,r_Dir);
int WAS_HIT = 0;
for(int o = 0;o < GeoObjects.size();o++){
GeometricObject NGO = GeoObjects.get(o);
double hit = NGO.hit(raytolight);
if (hit != 0.0) {
WAS_HIT = 1;
}
}
if(WAS_HIT == 0){
double Dot = normal.Direction.Dot(r_Dir);
if(Dot < 0){
Dot = 0;
}
double Diffuse = 1 - AmbientLight;
Color color = new Color(GO.Color);
double Shade = AmbientLight + Diffuse*Dot;
color.Mul(Shade);
PixelShade.add(color);
}else{
Color color = new Color(GO.Color);
double Shade = AmbientLight;
color.Mul(Shade);
PixelShade.add(color);
}
}
Color Final = new Color();
for(int s = 0;s < PixelShade.size();s++){
Final.Add(PixelShade.get(s));
}
Final.Divide(PixelShade.size());
return Final;
}
public void TraceArea(boolean SmoothTracing) {
Tracing = true;
if(SmoothTracing){
for (int x = StartX; x < EndX; x++) {
for (int y = StartY; y < EndY; y++) {
TracePixelSmooth(x,y);
}
}
}else{
for (int x = StartX; x < EndX; x++) {
for (int y = StartY; y < EndY; y++) {
TracePixelFast(x,y);
}
}
}
}
}
And here is the code for the sphere.
public class Sphere extends GeometricObject{
public Vector3D Center;
public double Radius;
public Sphere(Vector3D Center,double Radius,Color Color){
this.Center = Center;
this.Radius = Radius;
this.Color = Color;
}
public double hit(Ray ray) {
double a = ray.Direction.Dot(ray.Direction);
double b = 2 * ray.Origin.Sub(Center).Dot(ray.Direction);
double c = ray.Origin.Sub(Center).Dot(ray.Origin.Sub(Center))-Radius*Radius;
double discreminant = b*b-4*a*c;
if(discreminant < 0.0f){
return 0.0;
}else{
double t = (-b - Math.sqrt(discreminant))/(2*a);
if(t > 10E-9){
return t;
}else{
return 0.0;
}
}
}
public Normal Cal_Normal(Ray ray,double t) {
Vector3D NPos = new Vector3D(ray.Origin.x + ray.Direction.x*t,ray.Origin.y + ray.Direction.y*t,ray.Origin.z + ray.Direction.z*t);
Vector3D NDir = NPos.Sub(Center).Div(Radius);
return new Normal(NPos,NDir);
}
}
I am sure the problem is in shadepixel() but I could be wrong.
I just found out that the more objects that I add the more rings there are:
1 object no rings.
2 objects 1 ring.
3 objects 2 rings.
If you need me to post more of my code.Just ask and I will.
When I get back from school I will post my color class and fix the color problem. I still do not understand why the more objects (spheres) I add, the more rings there are. Can anyone explain to me why this is happening?
Here is my Color code.
public class Color {
public float r,g,b;
public Color(){
r = 0.0f;
g = 0.0f;
b = 0.0f;
}
public Color(float fr,float fg,float fb){
r = fr;
g = fg;
b = fb;
}
public Color(Color color){
r = color.r;
g = color.g;
b = color.b;
}
public void Add(Color color){
r += color.r;
g += color.g;
b += color.b;
}
public void Divide(int scalar){
r /= scalar;
g /= scalar;
b /= scalar;
}
public void Mul(double mul){
r *= mul;
g *= mul;
b *= mul;
}
public int toInt(){
return (int) (r*255)<<16 | (int) (g*255)<<8 | (int) (b*255);
}
There are multiple issues with this code, but the direct reason for the rings is that color component values are overflowing 0-255 range. This in turn is caused by incorrect calculations in what I take to be an attempt at antialiasing in Cal_Pixel(), as well as by no control whatsoever of numeric range in ShadePixel().
Think about how you can visually debug this scene.
First are the normals correct? Display them as the colour to see.
Taking the range for each component [-1..1] to the range [0..255]:
r = 255*(n.x + 1)/2;
g = 255*(n.y + 1)/2;
b = 255*(n.z + 1)/2;
Once you think they look correct move on to the next stage and build it up stage by stage.
e.g. you might look at if your dot product is as expected (again [-1..1] because the vectors are supposedly normalised):
r = 255*(dot + 1)/2;
g = 255*(dot + 1)/2;
b = 255*(dot + 1)/2;

libGDX - My script takes a really long time to process my copy method

So right now I am copying tiles that are within the camera's viewport, and pasting them to the top of the TiledMap using the following function:
public TiledMapTile[][] copyRegion(TiledMapTileLayer layer, int x, int y, int width, int height) {
TiledMapTile[][] region = new TiledMapTile[width][height];
for (int ix = x; ix < x + width; ix++)
for (int iy = y; iy < y + height; iy++) {
Cell cell = layer.getCell(ix, iy);
if(cell == null)
continue;
region[ix - x][iy - y] = cell.getTile();
}
return region;
}
My problem is with this double for loop, its searching through each x and y value of the viewport, which is thousands of loops which is obviously my problem. Before this I was setting the width and height to the TiledMapTileLayer's layer.getTileHeight and layer.getTileWidth and it ran smoothly. This is because the layers x and y values go by the Tiles, so it was only really checking about 100 tiles, which is much faster. How would I go about "merging" the 2 together to only copy the tiles within the viewport, instead of the x and y values within the viewport?
I am calling this function using the following:
clipboard = TileMapCopier.copyRegion(layer, 0, 0, (int) camera.viewportWidth, (int) camera.viewportHeight);
TileMapCopier.pasteRegion(layer, clipboard, 0, layer.getHeight() / 2);
Thanks!
EDIT: I was told to look at how the orthogonal tiled map renderer renders based on viewport. I dont really know how to do this :P Im still new to this.
#Override
public void renderTileLayer (TiledMapTileLayer layer) {
final Color batchColor = spriteBatch.getColor();
final float color = Color.toFloatBits(batchColor.r, batchColor.g, batchColor.b, batchColor.a * layer.getOpacity());
final int layerWidth = layer.getWidth();
final int layerHeight = layer.getHeight();
final float layerTileWidth = layer.getTileWidth() * unitScale;
final float layerTileHeight = layer.getTileHeight() * unitScale;
final int col1 = Math.max(0, (int)(viewBounds.x / layerTileWidth));
final int col2 = Math.min(layerWidth, (int)((viewBounds.x + viewBounds.width + layerTileWidth) / layerTileWidth));
final int row1 = Math.max(0, (int)(viewBounds.y / layerTileHeight));
final int row2 = Math.min(layerHeight, (int)((viewBounds.y + viewBounds.height + layerTileHeight) / layerTileHeight));
float y = row1 * layerTileHeight;
float xStart = col1 * layerTileWidth;
final float[] vertices = this.vertices;
for (int row = row1; row < row2; row++) {
float x = xStart;
for (int col = col1; col < col2; col++) {
final TiledMapTileLayer.Cell cell = layer.getCell(col, row);
if (cell == null) {
x += layerTileWidth;
continue;
}
final TiledMapTile tile = cell.getTile();
if (tile != null) {
final boolean flipX = cell.getFlipHorizontally();
final boolean flipY = cell.getFlipVertically();
final int rotations = cell.getRotation();
TextureRegion region = tile.getTextureRegion();
float x1 = x;
float y1 = y;
float x2 = x1 + region.getRegionWidth() * unitScale;
float y2 = y1 + region.getRegionHeight() * unitScale;
float u1 = region.getU();
float v1 = region.getV2();
float u2 = region.getU2();
float v2 = region.getV();
vertices[X1] = x1;
vertices[Y1] = y1;
vertices[C1] = color;
vertices[U1] = u1;
vertices[V1] = v1;
vertices[X2] = x1;
vertices[Y2] = y2;
vertices[C2] = color;
vertices[U2] = u1;
vertices[V2] = v2;
vertices[X3] = x2;
vertices[Y3] = y2;
vertices[C3] = color;
vertices[U3] = u2;
vertices[V3] = v2;
vertices[X4] = x2;
vertices[Y4] = y1;
vertices[C4] = color;
vertices[U4] = u2;
vertices[V4] = v1;
if (flipX) {
float temp = vertices[U1];
vertices[U1] = vertices[U3];
vertices[U3] = temp;
temp = vertices[U2];
vertices[U2] = vertices[U4];
vertices[U4] = temp;
}
if (flipY) {
float temp = vertices[V1];
vertices[V1] = vertices[V3];
vertices[V3] = temp;
temp = vertices[V2];
vertices[V2] = vertices[V4];
vertices[V4] = temp;
}
if (rotations != 0) {
switch (rotations) {
case Cell.ROTATE_90: {
float tempV = vertices[V1];
vertices[V1] = vertices[V2];
vertices[V2] = vertices[V3];
vertices[V3] = vertices[V4];
vertices[V4] = tempV;
float tempU = vertices[U1];
vertices[U1] = vertices[U2];
vertices[U2] = vertices[U3];
vertices[U3] = vertices[U4];
vertices[U4] = tempU;
break;
}
case Cell.ROTATE_180: {
float tempU = vertices[U1];
vertices[U1] = vertices[U3];
vertices[U3] = tempU;
tempU = vertices[U2];
vertices[U2] = vertices[U4];
vertices[U4] = tempU;
float tempV = vertices[V1];
vertices[V1] = vertices[V3];
vertices[V3] = tempV;
tempV = vertices[V2];
vertices[V2] = vertices[V4];
vertices[V4] = tempV;
break;
}
case Cell.ROTATE_270: {
float tempV = vertices[V1];
vertices[V1] = vertices[V4];
vertices[V4] = vertices[V3];
vertices[V3] = vertices[V2];
vertices[V2] = tempV;
float tempU = vertices[U1];
vertices[U1] = vertices[U4];
vertices[U4] = vertices[U3];
vertices[U3] = vertices[U2];
vertices[U2] = tempU;
break;
}
}
}
spriteBatch.draw(region.getTexture(), vertices, 0, 20);
}
x += layerTileWidth;
}
y += layerTileHeight;
}
}
}

How to make circle clickable

I am developing game using canvas. I have drawn grid of circles using loop. I want to get x,y coordinates of circles. For that I have to make those circles clickable so that whenever player click on a circle it should return its coordinates. I will pass those coordinates to lineDraw() method for drawing line between those circles.
This loop is defining grid of circles:
for (int y=0;y<rows;y++)
{
for (int x=0;x<cols;x++)
{
canvas.drawCircle((x + 1) * dw, (y + 1) *(3* dh), 20, pDot);
}
}
Here dw is (displayWidth) and dh is (displayHeight). Please suggest how I should make these circles clickable?
I had played with this project a little after your previous questions. I'm sure this isn't the most optimized way to do this, but without knowing how you plan to implement the game logic, I think this is flexible enough to adapt. The following is your custom View class, which I've renamed Board, in keeping with Java naming conventions.
public class Board extends View
{
Paint pBack = new Paint();
Paint pDot = new Paint();
Paint pLine = new Paint();
int cols = 5;
int rows = 6;
// Default initialization = false
boolean[][] dots = new boolean[cols][rows];
int canWidth = 0;
int canHeight = 0;
float xStep = 0;
float yStep = 0;
float[] xCoords = new float[cols];
float[] yCoords = new float[rows];
public Board(Context context)
{
super(context);
pBack.setARGB(255, 255, 102, 0);
pDot.setARGB(255, 255, 255, 255);
pLine.setStrokeWidth(5);
pLine.setARGB(255, 90, 10, 0);
}
public void setDots(boolean[][] dotSelected)
{
this.dots = dotSelected;
}
public boolean[][] getDots()
{
return dots;
}
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
canWidth = w;
canHeight = h;
xStep = canWidth / (cols + 1);
yStep = canHeight / (rows + 1);
for (int y = 0; y < rows; y++)
{
yCoords[y] = (y + 1) * yStep;
}
for (int x = 0; x < cols; x++)
{
xCoords[x] = (x + 1) * xStep;
}
}
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawPaint(pBack);
// Grid, lines and box markings
for (int y = 0; y < rows; y++)
{
canvas.drawLine(xStep, yCoords[y], cols * xStep, yCoords[y], pDot);
for (int x = 0; x < cols; x++)
{
if (y == 0)
{
canvas.drawLine(xCoords[x], yStep, xCoords[x], rows * yStep, pDot);
}
if (dots[x][y])
{
boolean left = x > 0 && dots[x - 1][y];
boolean up = y > 0 && dots[x][y - 1];
if (left)
{
canvas.drawLine(xCoords[x], yCoords[y], xCoords[x - 1], yCoords[y], pLine);
}
if (up)
{
canvas.drawLine(xCoords[x], yCoords[y], xCoords[x], yCoords[y - 1], pLine);
}
if (left && up && dots[x - 1][y - 1])
{
canvas.drawCircle(xCoords[x] - xStep / 2, yCoords[y] - yStep / 2, 10, pLine);
}
}
}
}
// Dots
for (int y = 0; y < rows; y++)
{
for (int x = 0; x < cols; x++)
{
canvas.drawCircle(xCoords[x], yCoords[y], 20, pDot);
if (dots[x][y])
{
canvas.drawCircle(xCoords[x], yCoords[y], 15, pBack);
}
}
}
}
public boolean onTouchEvent(MotionEvent event)
{
super.onTouchEvent(event);
if (event.getAction() != MotionEvent.ACTION_DOWN)
return true;
int xNear = 0;
int yNear = 0;
float xMin = canWidth;
float yMin = canHeight;
for (int x = 0; x < cols; x++)
{
if (Math.abs(xCoords[x] - event.getX()) < xMin)
{
xMin = Math.abs(xCoords[x] - event.getX());
xNear = x;
}
}
for (int y = 0; y < rows; y++)
{
if (Math.abs(yCoords[y] - event.getY()) < yMin)
{
yMin = Math.abs(yCoords[y] - event.getY());
yNear = y;
}
}
dots[xNear][yNear] = !dots[xNear][yNear];
invalidate();
return true;
}
}
Store the data of your circles (for instance the position and the radius) in a list and check each of them for mouse collision(register a mouseeventlistener).
public class Circle
{
private int radius;
private int positionX;
private int positionY;
public Circle(int positionX, int positionY, int radius)
{
this.radius = radius;
this.positionX = positionX;
this.positionY = positionY;
}
public int getPositionX()
{
return this.positionX;
}
public int getPositionY()
{
return this.positionY;
}
public boolean contains(int posX, int posY)
{
int distanceX = this.positionX - posX;
int distanceY = this.positionY - posY;
return Math.sqrt((distanceX * distanceX) + (distanceY * distanceY)) <= this.radius;
}

java graphics gouraud shading

I want to fill triangles with gouraud shading
I calculated normals for each vertex and used the following code but it dosn't work correctly
I interpolated colors against y using these formulas
Ir = Ir2 - (Ir2 - Ir1)* (v2.y -y)/dy;
Ig = Ig2 - (Ig2 - Ig1)* (v2.y -y)/dy;
Ib = Ib2 - (Ib2 - Ib1)* (v2.y -y)/dy;
and against x direction using
rr = r2- (r2-r1)*(Xs2-j)/dxs;
in method drawCurrentTriangle(Graphics2D g) how can i calculate color from interpolated vertex normal.(there is no lights in the scene (only triangle color))
public boolean convert(Triangle triangle) {
ensureCapacity();
clearCurrentScan();
triangle.getVlist()[0].r = triangle.normals[0].x;
triangle.getVlist()[0].g = triangle.normals[0].y;
triangle.getVlist()[0].b = triangle.normals[0].z;
triangle.getVlist()[1].r = triangle.normals[1].x;
triangle.getVlist()[1].g = triangle.normals[1].y;
triangle.getVlist()[1].b = triangle.normals[1].z;
triangle.getVlist()[2].r = triangle.normals[2].x;
triangle.getVlist()[2].g = triangle.normals[2].y;
triangle.getVlist()[2].b = triangle.normals[2].z;
for (int i = 0; i < 3; i++) {
Vector3d v1 = triangle.getVlist()[i];
Vector3d v2;
if (i == 2) {
v2 = triangle.getVlist()[0];
} else {
v2 = triangle.getVlist()[i + 1];
}
// ensure v1.y < v2.y
if (v1.y > v2.y) {
Vector3d temp = v1;
v1 = v2;
v2 = temp;
}
double dy = v2.y - v1.y;
Ir1 = v1.r;
Ig1 = v1.g;
Ib1 = v1.b;
Ir2 = v2.r;
Ig2 = v2.g;
Ib2 = v2.b;
// ignore horizontal lines
if (dy == 0) {
continue;
}
int startY = Math.max(FastMath.ceil(v1.y), minY);
int endY = Math.min(FastMath.ceil(v2.y) - 1, maxY);
top = Math.min(top, startY);
bottom = Math.max(bottom, endY);
double dx = v2.x - v1.x;
double Ir;
double Ig;
double Ib;
double Ic;
double Ia;
double Yc;
// special case: vertical line
if (dx == 0) {
int x = FastMath.ceil(v1.x);
// ensure x within view bounds
x = Math.min(maxX + 1, Math.max(x, minX));
for (int y = startY; y <= endY; y++) {
Ir = Ir2 - (Ir2 - Ir1)* (v2.y -y)/dy;
Ig = Ig2 - (Ig2 - Ig1)* (v2.y -y)/dy;
Ib = Ib2 - (Ib2 - Ib1)* (v2.y -y)/dy;
scans[y].setBoundary(x, Ir, Ig, Ib);
}
} else {
// scan-convert this edge (line equation)
double gradient = dx / dy;
// (slower version)
for (int y = startY; y <= endY; y++) {
int x = FastMath.ceil(v1.x + (y - v1.y) * gradient);
// ensure x within view bounds
x = Math.min(maxX + 1, Math.max(x, minX));
Ir = Ir2 - (Ir2 - Ir1)* (v2.y -y)/dy;
Ig = Ig2 - (Ig2 - Ig1)* (v2.y -y)/dy;
Ib = Ib2 - (Ib2 - Ib1)* (v2.y -y)/dy;
scans[y].setBoundary(x, Ir, Ig, Ib);
}
// check if visible (any valid scans)
for (int i = top; i <= bottom; i++) {
if (scans[i].isValid()) {
return true;
}
}
return false;
}
}
}
protected void drawCurrentTriangle(Graphics2D g) {
int y = scanConverter.getTopBoundary();
double Xs1 = 0;
double Xs2 = 0;
double dxs = 0;
double r1 = 0;
double g1 = 0;
double b1 = 0;
double r2 = 0;
double g2 = 0;
double b2 = 0;
double rr = 0;
double gg = 0;
double bb = 0;
while (y <= scanConverter.getBottomBoundary()) {
GouraudTriangleScanConverter.Scan scan = scanConverter.getScan(y);
if (scan.isValid()) {
r1 = scan.rL;
g1 = scan.gL;
b1 = scan.bL;
r2 = scan.rR;
g2 = scan.gR;
b2 = scan.bR;
Xs1 = scan.left;
Xs2 = scan.right;
dxs = Xs2-Xs1;
for (int j = scan.left; j < scan.right; j++) {
rr = r2- (r2-r1)*(Xs2-j)/dxs;
gg = g2- (g2-g1)*(Xs2-j)/dxs;
bb = b2- (b2-b1)*(Xs2-j)/dxs;
if(rr > 255) rr = 255;
if(gg > 255) gg = 255;
if(bb > 255) bb = 255;
g.setColor(new Color((int)rr, (int)gg, (int)bb));
g.drawLine(j,y,j,y);
}
//g.drawLine(scan.right,y,scan.right,y);
}
y++;
}
}
public static class Scan {
public int left;
public int right;
public double rL = -1;
public double gL = -1;
public double bL = -1;
public double rR = -1;
public double gR = -1;
public double bR = -1;
/**
* Sets the left and right boundary for this scan if
* the x value is outside the current boundary.
*/
public void setBoundary(int x, double r, double g, double b) {
if (x > max)
max = x;
if (x < left) {
left = x;
rL = r;
gL = g;
bL = b;
}
if (x - 1 > right) {
right = x - 1;
rR = r;
gR = g;
bR = b;
}
}
/**
* Determines if this scan is valid (if left <= right).
*/
public boolean isValid() {
return (left <= right);
}
}
how can i apply colors to mesh.when i in
fix colors(no lighting)

Categories

Resources