Problems with moving camera in openGL - opengl

Ok, I'd like to start off by saying that I know I'm not actually moving the camera, but it's easier to explain that way.
My problem is that I'm trying to move the camera with my character in a top down 2d rpg, and I can't find the correct way to do it. I know about glTranslate() but then I can only use a speed instead of an x and y coordinate. I'm not sure how to move the camera keeping the delta in mind. I don't even know if glTranslate() is even the method I should be using.
In case I'm not making any sense (which is very likely), here's some of my code.
My test while loop:
while(!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)&&!Display.isCloseRequested())
{
glClear(GL11.GL_COLOR_BUFFER_BIT);
delta=getDelta();
update(delta);
glTranslatef(speedx, speedy, 0);
level1.checkCurrent(x, y);
level1.draw();
Display.update();
Display.sync(60);
}
Here is where I set the speed:
if(Keyboard.isKeyDown(Keyboard.KEY_DOWN))
{
y+=0.5*delta;
screenY+=0.5*delta;
speedy=(int) (-0.5*delta);
direction=2;
}
else if(Keyboard.isKeyDown(Keyboard.KEY_UP))
{
y-=0.5*delta;
screenY-=0.5*delta;
speedy=(int) (0.5*delta);
direction=8;
}
else
speedy=0;

Right now you're treating OpenGL as if it were a scene graph. However OpenGL is only meant to draw things on the screen. Whatever you do, you should always think about your problem in a way, as if all the rest of the infrastructure wasn't there.
You want to accelerate an object? Well, then you need to increment some speed variable over time and that speed variable multiplied by time adds to the position. In essence Newton's laws of motion:
a = dv/dt => v = a*t + v_0
v = dr/dt => r = v*t + r_0 = a*t² + v_0*t + r_0
This you evaluate for each of your objects. Then when drawing the animation, you use the state to place the object geometry accordingly.

Related

OpenGL Raycasting with any object

I'm just wondering if there was any way which one can perform mouse picking detection onto any object. Whether it would be generated object or imported object.
[Idea] -
The idea I have in mind is that, there would be iterations with every object in the scene. Checking if the mouse ray has intersected with an object. For checking the intersection, it would check the mouse picking ray with the triangles that make up the object.
[Pros] -
I believe the benefit of this approach is that, every object can be detected with mouse picking since they all inherit from the detection method.
[Cons] -
I believe this drawbacks are mainly the speed and the method being very expensive. So would need fine tuning of optimization.
[Situation] -
In the past I have read about mouse picking and I too have implemented some basic form of mouse picking. But all those were crappy work which I am not proud of. So again today, I have re-read some of the stuff from online. Nowadays I see alot of mouse picking using color ids and shaders. I'm not too keen for this method. I'm more into a mathematical side.
So here is my mouse picking ray thingamajig.
maths::Vector3 Camera::Raycast(s32 mouse_x, s32 mouse_y)
{
// Normalized Device Coordinates
maths::Vector2 window_size = Application::GetApplication().GetWindowSize();
float x = (2.0f * mouse_x) / window_size.x - 1.0f;
float y = 1.0f;
float z = 1.0f;
maths::Vector3 normalized_device_coordinates_ray = maths::Vector3(x, y, z);
// Homogeneous Clip Coordinates
maths::Vector4 homogeneous_clip_coordinates_ray = maths::Vector4(normalized_device_coordinates_ray.x, normalized_device_coordinates_ray.y, -1.0f, 1.0f);
// 4D Eye (Camera) Coordinates
maths::Vector4 camera_ray = maths::Matrix4x4::Invert(projection_matrix_) * homogeneous_clip_coordinates_ray;
camera_ray = maths::Vector4(camera_ray.x, camera_ray.y, -1.0f, 0.0f);
// 4D World Coordinates
maths::Vector3 world_coordinates_ray = maths::Matrix4x4::Invert(view_matrix_) * camera_ray;
world_coordinates_ray = world_coordinates_ray.Normalize();
return world_coordinates_ray;
}
I have this ray plane intersection function which calculates if a certain ray as intersected with a certain plane. DUH!
Here is the code for that.
bool Camera::RayPlaneIntersection(const maths::Vector3& ray_origin, const maths::Vector3& ray_direction, const maths::Vector3& plane_origin, const maths::Vector3& plane_normal, float& distance)
{
float denominator = plane_normal.Dot(ray_direction);
if (denominator >= 1e-6) // 1e-6 = 0.000001
{
maths::Vector3 vector_subtraction = plane_origin - ray_origin;
distance = vector_subtraction.Dot(plane_normal);
return (distance >= 0);
}
return false;
}
There are many more out there. E.g. Plane Sphere Intersection, Plane Disk Intersection. These things are like very specific. So it feel that is very hard to do mouse picking intersections on a global scale. I feel this way because, for this very RayPlaneIntersection function. What I expect to do with it is, retrieve the objects in the scene and retrieve all the normals for that object (which is a pain in the ass). So now to re-emphasize my question.
Is there already a method out there which I don't know, that does mouse picking in one way for all objects? Or am I just being stupid and not knowing what to do when I have everything?
Thank you. Thank you.
Yes, it is possible to do mouse-picking with OpenGL: you render all the geometry into a special buffer that stores a unique id of the object instead of its shaded color, then you just look at what value you got at the pixel below the mouse and know the object by its id that is written there. However, although it might be simpler, it is not a particularly efficient solution if your camera or geometry constantly moves.
Instead, doing an analytical ray-object intersection is the way to go. However, you don't need to check the intersection of every triangle of every object against the ray. That would be inefficient indeed. You should cull entire objects by their bounding boxes, or even portions of the whole scene. Game engines have their own spacial index data structure to speed-up ray-object intersections. They need it not only for mouse picking, but also for collision-detection, physics simulations, AI, and what-not.
Also note that the geometry used for the picking might be different from the one used for rendering. One example that comes to mind is that of semi-transparent objects.

openGL object real movement simulation

I need to simulate the movement of a row(oar). The oar object is loaded into eclipse with the min3D library which works with openGL.
At this moment, I make the oar move in the 3 axis x, y and z, but I'm not able to control this movement and to make the oar move in the desired way.
(Don't take care of the values, aren't real values)
This is the class which loads the oar, places it in the screen and moves it:
public class Obj3DView extends RendererFragment {
private Object3dContainer rowObject3D;
/** Called when the activity is first created. */
#Override
public void initScene() {
scene.lights().add(new Light());
scene.lights().add(new Light());
Light myLight = new Light();
myLight.position.setZ(150);
scene.lights().add(myLight);
IParser myParser = Parser.createParser(Parser.Type.OBJ, getResources(), "com.masermic.rowingsoft:raw/row_obj",true);
myParser.parse();
rowObject3D = myParser.getParsedObject();
rowObject3D.position().x = rowObject3D.position().y = rowObject3D.position().z = 0;
rowObject3D.scale().x = rowObject3D.scale().y = rowObject3D.scale().z = 0.28f;
scene.addChild(rowObject3D);
}
//THIS MAKES THE OAR MOVE
#Override
public void updateScene() {
rowObject3D.rotation().x += 1; //pitch
rowObject3D.rotation().z += 1; //roll
rowObject3D.rotation().y += 0.5; //yaw
}
roation() method definition: X/Y/Z euler rotation of object, using Euler angles. Units should be in degrees, to match OpenGL usage.
So the question is about how could I define the values that make the oar simulate a real movement?
This looks more like a mathematics question.
I'll present some general tips;
On positioning:
The fixed point of the oar is where the oar is held on the boat, so the oar's rotation is relative to that point, not the center of the oar.
And on top of that, the boat is moving, so is the oar's "fixed" point.
The order for positioning should be:
Translate to the boat position.
Translate the oar so it's center is relative to the correct spot of the boat.
Apply the oar rotation.
Draw it.
On animation:
It will be easier to animate if you alter your model so the origin is at the point where the oar is fixed, but it may complicate other animations/calculae if you later pretend to do more complex manipulations on the oar.
Interpolation of Euler rotation is a mess, I suggest quartenions. You can grab the angles from that nice picture and interpolate. (if you need Euler, still, you can convert the end result to Euler)
For simple animations, (say you just want the oar to repeatedly rotate in some pattern), hardly you will find a better method then key-frames, that is, create a list of coordinates/angles along the path you want the oar to do, and iterate through them, interpolating.
With enough points, a simple linear interpolation will do just fine.

c++ Collision Detection for a turning rectangle

I have some collision detection working when my player hits an object. But this only works when my players x & y co-ordinates hit my marker (which is the centre of my character).
Would making a method returning a vector of all of the coordinates that the players texture cover work and what is the best way to implement this?
This is being done in c++ creating a top down game
There are many ways to do it, most simply is probably(depending on you use of classes etc).
This is the simplest, but no where near the best, or infact very good at all. This way means changing your "marker" to the bottom left of the rectangle.
void collisions()
{
//check if the x-coord is between the furthest left and furthest right x coords
if(rect.Getx() > someObject.Getx() && rect.Getx() < someObject.Getx() + someObject.GetWidth())
{
rect.SetMoveSpeed(0);
}
if(rect.Gety() > someObject.Gety() && rect.Gety() < someObject.Gety() + someObject.GetHeight())
{
rect.setMoveSpeed(0);
}
}
You would then have to set the move speed to normal when it is not colliding. That could be done with an else after each if, setting the move speed again. This is a quick fix and is not recommended for use in a game you plan to distribute anywhere.

Collision Detection Between Rectangles - Resulting Angles

Basically I have a bunch of rectangles floating around at 8 different angles (45 degrees, 90 degrees etc). I have collision detection going on between all of them, but one thing still doesn't work as it should. I don't know if I'm just not thinking or what, but I can't seem to get the resulting angles right. I've also tried searching multiple places, but haven't really gained anything from what I've found.
NOTE: the angle system here starts at 0 at the top and increases clockwise.
NOTE: all rectangles have the same mass
Say one rectangle going straight right (90 degrees) hits another going straight left (270 degrees). They will hit off of each other just fine.
Now say one going left gets hit by one going up. Here I can't simply reverse the angles or anything.
If you have more than one way, consider the following: unless I rearrange the CD so it spreads into the other code, I have the positions of all of the rectangles. The CD checks by seeing if two are overlapping, not by comparing where they are going.
As I've been working on pretty much everything except for the collision detection until now, I only have tonight left to get it working and add a few other small things before I'm done.
If you know of a way to make the angles come out right without hardcoding, great. At this point I'm ready to hardcode it (not too much really) if all I have is which rectangle hits the other (ex 2), or if they both do (ex 1). Either one is really helpful.
I think you mean something like this...
Each Rectangle has this functionality, testing against, say an array of other objects.
Obstacle* obstacle = new Obstacle;
Obstacle** obstacles = obstacle*[];
For(int i = 0; i <3; i++)
{
obstacles[0] = New Obstacle(x,y, etc...);
etc...
}
Or something similar... this is a little rusty
void collision(obstacles)
{
for(int i = 0; i < obstacles.sizeOf();i++)
{
//bottom y
if((this.ypos + this.height) > (obstacles[i].ypos - obstacles[i].height))
obstacles[i].doYCollision(this);
//top y
if((this.ypos - this.height) < (obstacles[i].ypos + obstacles[i].height))
obstacles[i].doYCollision(this);
//right x
if((this.xpos + this.width) > (obstacles[i].xpos - obstacles[i].width))
obstacles[i].doXCollision(this);
//left x
if((this.xpos - this.width) < (obstacles[i].xpos + obstacles[i].width))
obstacles[i].doXCollision(this);
}
}
again im a little rusty but if you follow it you should be able to relaise what im doing.
then all you need is the resulting function calls.
void doYCollision(Obstacle obstacle)
{
// Whatever y direction they are going do the opposite
obstacle.yDir = obstacle.yDir * -1;
}
void doXCollision(Obstacle obstacle)
{
// Whatever x direction they are going do the opposite
obstacle.xDir = obstacle.xDir * -1;
}
where yDir, xDir is the x and y velocity of the current object.
i should point out again this is very rusty and without having some code from you this is the best ive got. but either way this should start you off into collision detection, the code above shoudl allow for all collisions with all obstacles/objects/pink flamingos/ whatever youve got. Im hoping also that itll do what you want when it comes to multiple collisions at the same time.
You shouldnt need to worry too much about the exact angle (unless you need it for something else), as velocity is a vector mass so has both speed and direction and you can get direction by treating x and y as two different elements. You can do this using the dot product method aswell => http://www.topcoder.com/tc?d1=tutorials&d2=geometry1&module=Static, but if they are just rectangles this should be fine.
Hopes this helps

Scanning through a tilemap and checking properties for each tile

How does one iterate through a tilemap and check each tile?
Is there a correct way to do this, is there a built in function to in cocos2d to check a tile?
Or could it be done e.g. take the tile size set when creating the tile, make a nested for loop and take (x,y) for the middle of the first tile and just iterate by adding tilesize to the x on the inner loop and tilesize to the y on the outer loop?
I am wondering if there is a built in, more performance aware approach.
Thanks
I think you might be able to do it using a for loop and CGPoints.
I'm going to for examples sake get color
and store it in an array I guess
CGPoint myPt;
NSMutableArray *tilesofGray;
for (int x = 0; x < tilemapLength)
{
for (int y = 0; y < tilemapHeight)
{
myPt.x = x;
myPt.y = y;
if([[[tilemap layerNamed:#"background"] tileAt:myPt] getColor] == Grey)
{
[tilesofGray addObject:[[tilemap layerNamed:#"background] tileAt:myPt]];
}
}
}
Is this for a game, for like collision detection or, simply for rendering based on tile type?
Your question here is really ambiguous. Please be specific in what you want. The 3rd sentence in particular would make more sense if you explain what you are needing.
But i'll try to answer based on the title alone....
How big is the tileset? if it's not very big, brute-force may be perfectly fine.
If performance is a concern/issue, or if the tileset is large and not all tiles are ever drawn within the screen at any given time, you need to do scene management of some sort.
scene management:
i think there is a technical term/phrase for this, but basically based on some x,y pt on the tileset (i.e. matrix), you can determine (by a function) which tiles you will need to iterate thru. it should be fun to figure it out as it's presumably a 2d array.