So I have been looking through tutorials (And questions on this site) and have found nothing to solve my problem. Here is the current code I am trying to implement:
private void pick() {
float[] matModelView = new float[16], matProjView = new float[16];
int[] view = new int[16];
float mouseX = width / 2;
float mouseY = height / 2;
Vector3f start = new Vector3f();
Vector3f end = new Vector3f();
FloatBuffer modelBuffer = compileBuffer(matModelView);
FloatBuffer projBuffer = compileBuffer(matProjView);
FloatBuffer startBuffer = compileBuffer(new float[]{start.x, start.y, start.z, 1});
FloatBuffer endBuffer = compileBuffer(new float[]{end.x, end.y, end.z, 1});
IntBuffer viewBuffer = compileBuffer(view);
glGetFloat(GL_MODELVIEW_MATRIX, modelBuffer);
glGetFloat(GL_PROJECTION_MATRIX, projBuffer);
glGetInteger(GL_VIEWPORT, viewBuffer);
gluUnProject(mouseX, mouseY, 0.0f, modelBuffer, projBuffer, viewBuffer, startBuffer);
gluUnProject(mouseX, mouseX, 1.0f, modelBuffer, projBuffer, viewBuffer, endBuffer);
start = new Vector3f(startBuffer.get(0), startBuffer.get(1), startBuffer.get(2));
end = new Vector3f(endBuffer.get(0), endBuffer.get(1), endBuffer.get(2));
picks.add(new Vector3f[]{start, end});
System.out.println("Mouse Coords: " + mouseX + ", " + mouseY);
System.out.println("Position: " + position.x + ", " + position.y + ", " + position.z);
System.out.println("Rotation: " + rotation.x + ", " + rotation.y + ", " + rotation.z);
System.out.println("Near Plane: " + start.x + ", " + start.y + ", " + start.z);
System.out.println("Far Plane: " + end.x + ", " + end.y + ", " + end.z);
}
I have the mouseX and Y set the way I do because my mouse is grabbed. Here is an image and some output for you. (I can't really explain the problem)
Mouse Coords: 400.0, 350.0
Position: 0.0, 0.0, 0.0
Rotation: 0.0, 0.0, 0.0
Near Plane: 0.0, 0.0, -0.1
Far Plane: 0.0, 4.2315264, -99.99771
So, for a rotation of X:0 Y:0 Z:0, the expected output of the Y coord should be the same as the input. It is higher. Here is a picture of that output.
Can anyone give me some kind of hint or explanation on why this would happen?
EDIT: Facepalms violently: I was pushing mouseX in the Y parameter of the second gluUnProject
Related
I'm looping through an image with X and Y coordinates. However, I can only set an sRGB value using the method: image.setRGB(int x, int y, int rgb);
I want to set a custom RED, GREEN and BLUE values to the current X and Y coordinates. The new RGB values are in this case the average of the original RGB values.
The result I get is a blue image instead of greyscale.
for (int y = 0; y < imageInput.getHeight(); y++) {
for (int x = 0; x < imageInput.getWidth(); x++) {
int clr = imageInput.getRGB(x, y);
Color color = new Color(clr);
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
int sumRGB = red + green + blue;
int avg = sumRGB/3;
System.out.println("sRGB: " + clr);
System.out.println("Input Image: x= " + x + " y= " + y + " [" + red + "," + green + "," + blue + "]");
System.out.println("Avg RGB: " + avg);
imageCopy.setRGB(x, y, avg);
int clrCopy = imageCopy.getRGB(x, y);
color = new Color(clrCopy);
red = color.getRed();
green = color.getGreen();
blue = color.getBlue();
System.out.println("Output Image: x= " + x + " y= " + y + " [" + red + "," + green + "," + blue + "]\n");
}
}
You could write
Color greyScaleColor = new Color(avg, avg, avg);
int rgbValueForGrey = greyScaleColor.getRGB();
This will give you the int value that you need to set in imageCopy.
I have various entities in my game that have hit-boxes defined by Vector array's,
one of my entities rotates slowly to follow the player's movements so naturally I need the hit-box to rotate too.
My code results in warped and distorted lines as I draw each vertex to the screen. My entites are 64 x 64 in size so + 32 indicates the center of the object.
public void rotateVertices(Vector2[] vertices, double angle) {
double cos = Math.cos(angle);
double sin = Math.sin(angle);
for(int i = 0; i < vertices.length; i++){
Vector2 v = vertices[i];
vertices[i].x = ((v.x - (x + 32)) * cos - (v.y - (y + 32)) * sin) + (x + 32);
vertices[i].y = ((v.x - (x + 32)) * sin + (v.y - (y + 32)) * cos) + (y + 32);
}
}
my constructor:
public EnemyTriBall(Handler handler, float x, float y) {
super(handler, x, y, 3, 6);
vertices[0] = new Vector2(x + 25, y + 13);
vertices[1] = new Vector2(x + 64, y + 33);
vertices[2] = new Vector2(x + 25, y + 53);
}
Here:
Vector2 v = vertices[i];
You don't make a copy of the old vector, you just reference vectices[i]. So when you do this:
vertices[i].x = ((v.x - (x + 32)) * cos - (v.y - (y + 32)) * sin) + (x + 32);
you modify x of of the original vector. Then in the next line:
vertices[i].y = ((v.x - (x + 32)) * sin + (v.y - (y + 32)) * cos) + (y + 32);
You use old v.y but new v.x which gives you weird results. The easiest fix would be to get x and y and use them instead:
float vx = vertices[i].x;
float vy = vertices[i].y;
vertices[i].x = ((vx - (x + 32)) * cos - (vy - (y + 32)) * sin) + (x + 32);
vertices[i].y = ((vx - (x + 32)) * sin + (vy - (y + 32)) * cos) + (y + 32);
There might be other issues, I did not check the formulas but I'd start with this one.
I am trying to create a class in Java which will add a simple box shadow to any given UI element. Normally, it displays correctly, however when it is applied to a button, the shadow gets darker each time the mouse enters or exits the button.
The paint function is as follows:
public void paint(Graphics g)
{
Rectangle bounds = g.getClipBounds();
g.setClip(bounds.x + (SHADOW_OFFSET + shadowOffsetMod) - (SHADOW_SIZE + shadowSizeMod), bounds.y + (SHADOW_OFFSET + shadowOffsetMod) - (SHADOW_SIZE + shadowSizeMod),
bounds.width + 2 * (SHADOW_SIZE + shadowSizeMod), bounds.height + 2 * (SHADOW_SIZE + shadowSizeMod));
int red = UIConstants.SHADOW_COLOR.getRed();
int green = UIConstants.SHADOW_COLOR.getGreen();
int blue = UIConstants.SHADOW_COLOR.getBlue();
int alpha = UIConstants.SHADOW_COLOR.getAlpha();
for (int x = (SHADOW_OFFSET + shadowOffsetMod) - (SHADOW_SIZE + shadowSizeMod); x < bounds.width + (SHADOW_OFFSET + shadowOffsetMod) + (SHADOW_SIZE + shadowSizeMod); x++)
{
for (int y = (SHADOW_OFFSET + shadowOffsetMod) - (SHADOW_SIZE + shadowSizeMod); y < bounds.width + (SHADOW_OFFSET + shadowOffsetMod) + (SHADOW_SIZE + shadowSizeMod); y++)
{
int dx = Math.abs(x - Math.max(Math.min(x, bounds.width + (SHADOW_OFFSET + shadowOffsetMod)), (SHADOW_OFFSET + shadowOffsetMod)));
int dy = Math.abs(y - Math.max(Math.min(y, bounds.height + (SHADOW_OFFSET + shadowOffsetMod)), (SHADOW_OFFSET + shadowOffsetMod)));
float dist = (float) Math.sqrt(dx * dx + dy * dy);
dist /= (SHADOW_SIZE + shadowSizeMod);
if (dist > 1)
dist = 1;
dist = 1 - dist;
g.setColor(new Color(red, green, blue, ((float)alpha * dist) / 255));
g.fillRect(x, y, 1, 1);
}
}
g.setClip(bounds);
super.paint(g);
}
the shadow gets darker each time the mouse enters or exits the button.
Not sure exactly how your code is used. But (assuming you are usign Swing) this is a problem resulting from using a background color with transparency.
Swing components are either
opaque, in which case they guarantee to paint the background
non-opaque, in which case the parent component is used to paint the background.
In your case it sounds like the component is opaque, but the background is transparent so you break rule and you have painting issues.
Check out Backgrouds With Transparency fore more information and a couple of solutions:
make the component non-opaque and paint the background yourself
use a custom component as a wrapper to paint the background for you.
Alright, I have Poin3d class that takes x y and z:
public class Point3d {
public double x, y, z;
public Point3d(double a, double b, double c){
x = a;
y = b;
z = c;
}
public Point3d inverse(){
System.out.println("XYZ: " + x + ", " + y + ", " + z);
return new Point3d(-x, -y, -z);
}
}
And I also have a class calling this function in one of its own functions, and prints the X,Y,Z of the original point, and the inverted point:
public Model mirror(boolean x, boolean y, boolean z){
init();
Point3d pos = getPosition();
System.out.println("Position: " + pos.x + ", " + pos.y + ", " + pos.z);
Point3d negPos = pos.inverse();
for(Line3d l : lines){
l.start.add(negPos);
l.end.add(negPos);
if(x){l.start.x*=-1;l.end.x*=-1;angleX = !angleX;}
if(y){l.start.y*=-1;l.end.y*=-1;angleY = !angleY;}
if(z){l.start.z*=-1;l.end.z*=-1;angleZ = !angleZ;}
l.start.add(pos);
l.end.add(pos);
}
System.out.println("Inverse: " + pos.x + ", " + pos.y + ", " + pos.z);
return this;
}
Just looking at the println's, here's the sort of results I'm getting:
Position: 500.0, 65.0, 725.0
XYZ: 500.0, 65.0, 725.0
Inverse: 500.0, 65.0, 725.0
Position: 500.0, 460.0, 500.0
XYZ: 500.0, 460.0, 500.0
Inverse: -3000.0, -920.0, -3000.0
Position: 500.0, 460.0, 500.0
XYZ: 500.0, 460.0, 500.0
Inverse: -3000.0, -920.0, -3000.0
So basically, why on earth is the inverse this seemingly random set of numbers rather than just the negatives of the original point? Where are -3000 and -920 coming from?
EDIT: So I messed around with the code a bit and found that, for the first few iterations of the for loop, each value(x, y, z) of pos is reduced by its initial value. Anyone know why?
Point3d.add():
public Point3d add(Point3d add){
x += add.x;
y += add.y;
z += add.z;
return this;
}
So, I'm making a platformer where you should be able to drag your mouse to launch a projectile from your character in the direction of the mouse release, with a velocity of the distance between the two points.
public void mouseDragged(MouseEvent e) {
player.setAiming(true);
Point2D.Float aimpoint = new Point2D.Float(e.getXOnScreen(), e.getYOnScreen());
player.setAimpoint(aimpoint);
player.setAimDistance(GetDistanceToPoint(player.getPos(), aimpoint));
}
public static float GetAngleOfLine(Point2D.Float p1, Point2D.Float p2) {
double xDiff = p2.x - p1.x;
double yDiff = p2.y - p1.y;
System.out.println("P1X: " + p1.x + " P1Y: " + p1.y + " P2X: " + p2.x + " P2Y: " + p2.y + " Angle: " + Math.toDegrees(Math.atan2(yDiff, xDiff)));
return (float) Math.toDegrees(Math.atan2(yDiff, xDiff));
}
public static float GetDistanceToPoint(Point2D.Float p1, Point2D.Float p2){
float distance = (float) Math.sqrt(Math.pow(p2.y - p1.y, 2) + Math.pow((p2.x - p1.x), 2));
return distance;
}
And then, when the mouse is released,
player.setAimingangle(GetAngleOfLine(player.getPos(), player.getAimpoint()));
And then a projectile is created, where angle is player.aimingangle and strength is player.aimingdistance:
float yvel = (float) (strength * Math.sin(angle));
float xvel = (float) (strength * Math.cos(angle));
I'm getting incredibly weird projectiles, which are flying everywhere.
Math.sin and Math.cos take radians arguments, but you're feeding them degrees.