so I'm pretty new with opengl and creating 3d shapes. So for my example I have two squares, one with a height/width 2 with the center at the origin coordinate (0,0,-10), and one that is to the far left side of the window. I am trying to rotate the square that lies in the origin along the x-z plane without rotating the square that is located to the far left side of the screen. My approach to this was to save each xyz coordinate of the center square to a variable, and creating a method that uses the behavior of cos(theta) to rotate the square along the x-z plane. My code works, but I assume this is a horrible approach as there must be some more efficient method that is already created that can do the same functionality. I looked at glRotatef(), but from what I understood this only rotates my camera view which in the end would rotate both the middle square and the far left square whereas I only want to rotate the middle square. Is there some other method that already exists that can easily rotate a single 2d shape in 3d space?
In case its relevant, I have included the rotating code I made myself for the middle square: (btw the blue class is just some class I made that has the squares coordinates and the circle degree for cos(theta))
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
blue.setCircle(blue.getCircle()+1f);//getCircle is initially zero and gets incremented by 1 for everytime the program loops with the user holding the left button.
blue.setXfrontTR((float)Math.cos(Math.toRadians(blue.getCircle())));//Changing top-right x coordinate of the middle square
blue.setZfrontTR(-10f+ ((float)Math.cos(Math.toRadians(blue.getCircle()+270f)))); //Changing top-right z coordinate of the middle square.
blue.setXfrontTL((float)Math.cos(Math.toRadians(blue.getCircle()+180f)));
blue.setZfrontTL(-10f+ ((float)Math.cos(Math.toRadians(blue.getCircle()+90f))));//Changing top-left x,z coordinates
blue.setXfrontBL((float)Math.cos(Math.toRadians(blue.getCircle()+180f)));
blue.setZfrontBL(-10f+ ((float)Math.cos(Math.toRadians(blue.getCircle()+90f))));//Changing bottom-left x,z coordinates
blue.setXfrontBR((float)Math.cos(Math.toRadians(blue.getCircle())));
blue.setZfrontBR(-10f+ ((float)Math.cos(Math.toRadians(blue.getCircle()+270f))));//Changing bottom-right x-z coordinates
}
If you give each object that requires independent movement a model-view matrix you can achieve this. The other option to quickly draw/move a few independent objects is to:
for each object:
pushMatrix()
draw object
popMatrix()
while in the modelview matrix...
The method of drawing depends greatly on the OpenGL version you're coding to but the above will work for simple drawing. I'm not an expert on OpenGL / 3D programming so, if you wait a bit you may hear(see) better wisdom than what I offer :)
Related
I managed to position a 3D model on a vertical plane (using ARCore 1.4); it works well enough but the model is not in landscape starting position; instead, it starts randomly placed rotated, clockwise or counterclockwise (random degrees).
Is there a way to force it to start horizontally?
Fixed.
I've passed the pose object of the plane to the createAnchor method, in my onTapArPlaneListener.
Like this:
anchor = mySession.createAnchor(plane.getCenterPose());
I am working on a program to visualize an n-body particle simulation. To do this I have created a camera which is used to project particle positions unto the screen. Then, using a spritebatch these particles are rendered in the correct positions. However, for this to work, the origin of the coordinate system must be located at the bottom left of the screen. This is often not the case and instead the origin is located about a fourth of the screen up and to the left in all cases, and this changes when resizing the screen.
How do I guarantee the coordinate system origin is always at the bottom left of the screen, instead of elevated by a few hundred pixels in either axis?
Thank you.
If you decided to use sprite you should stick with proposed workflow and draw them with:
sprite.draw(batch);
I mean, what's the purpose using sprites if you are getting textures and drawing them?
When you draw a texture to screen at position (0,0) it means that it's bottom left corner will be at screen bottom left corner. That' is sprite's "hot-spot" or "origin" is at it's left bottom corner by default.
But you can change that with setOrigin method:
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Sprite.html#setOrigin-float-float-
That is, origin is kinda "center" of the sprite, so i.e. if it rotates it will rotate around that spot. Also when you draw sprite at some coordinates sprites origin will be exactly at those coordinates. That way you don't have to adjust sprite drawing position.
Check on that page what methods you have for sprite class...
I fixed my problem. Instead of using:
sprite.draw(batch);
I used:
batch.setColor(color);
batch.draw(sprite.getTexture(),sprite.getX(),sprite.getY(),sprite.getWidth()*sprite.getScaleX(),sprite.getHeight()*sprite.getScaleY());
I do not know why this worked.
Firstly, apologies for the long title; I could not think of a way to sufficiently cover my problem yet also compact it further.
I am in the process of creating a 2D game in Java with a character in the centre of the screen. My character has a collision box and I have images on the map (looking from above) which also have collision boxes.
However, I'd like to be able to have a "slide" situation if a collision occurs into a side that is not perpendicular to my direction.
For example, if my character is moving east, and there is a wall to his east going in the southwest to northeast direction, instead of just noting that there is an object to the east and not moving, I'd like my character to be able to "slide" along the wall, moving northeast to achieve the attempted Eastern movement.
Is there any easy way to do this?
If it helps in any way, I am using Java Slick2D, and have the collision box of the character as a rectangle where he stands, and the collision boxes of other objects as polygons.
Thanks in advance for any replies!
When you have solved the problem of identifying when a collision has occurred, the sliding motion can be achieved by calculating the component of the motion that is perpendicular to the wall and subtract that from your motion vector.
Say you have a motion vector v = (v_x, v_y) and the normal of the wall n = (n_x,n_y). The normal vector should be of length 1.
Then your new motion vector should be
v_new = v - (v * n) * n.
That in X and Y separately is
v_new_x = v_x - (v_x * n_x + v_y * n_y) * n_y,
and the same way for Y
Class java.awt.geom.Area has a method intersects( Area a ) which should be useful for determining the "point" of impact, call it P. If the character's collision box is a rectangle and the obstacle is bounded by an arbitrary polygon you'll have to determine
the point or side of the rectangle participating in the collision
the point or side of the polygon participating in the collision
If side meets side (they should be parallel), the charcter can't move any more in the current direction; no slide should occur. Equally, if a rectangle side meets a polygon point, movement is blocked.
If a point meets a point, you might resolve this by (arbitrarily?) select one of the sides of the polygon and handle the situation based on that.
Finally, if a rectangle corner meets a slanting side, you'll have to analyze the geometry of this side. (Verify that a 10-to-4 side is met by the upper right (lower left) hand corner if going north or east (south or west), or a 7-to-1 side is met by the upper left (lower right) hand corner when going north or west (south or east)). Then you can determine the forced path along the slanted side.
While this sounds relatively simple, there may be much more complex situations lurking literally round the corner if the collision boxes of objects - polygons - may have concave sections.
im trying do develop a Zelda like game. So far i am using bitmaps and everything runs smooth. At this point the camera of the hero is fixed, meaning, that he can be anywhere on the screen.
The problem with that is scaling. Supporting every device and keeping every in perfect sized rects doesnt seem to be that easy :D
To prevent that i need a moving camera. Than i can scale everything to be equally sized on every device. The hero would than be in the middle of the screen for the first step.
The working solution for that is
xCam += hero.moveX;
yCam += hero.moveY;
canvas.translate(xCam,yCam);
drawRoom();
canvas.restore();
drawHero();
I do it like this, because i dont wand to rearrange every tile in the game. I guess that could be too much processing on some devices. As i said, this works just fine. the hero is in the middle of the screen, and the whole room is moving.
But the problem is collision detection.
Here a quick example:
wall.rect.intersects(hero.rect);
Assuming the wall was originally on (0/0) and the hero is on (screenWitdh/2 / screenHeight/2) they should collide on some point.
The problem is, that the x and y of the wall.rect never change. They are (0/0) at any point of the canvas translation, so they can never collide.
I know, that I can work with canvas.getClipBounds() and then use the coordinates of the returned rect to change every tile, but as I mentioned above, I am trying to avoid that plus, the returned rect only works with int values, and not float.
Do you guys know any solution for that problem, or has anyone ever fixed something like this?
Looking forward to your answers!
You can separate your model logic and view logic. Suppose your development dimension for the window is WxH. In this case if your sprite in the model is 100x100 and placed at 0,0, it will cover area from 0,0 to 100, 100. Let's add next sprite (same 100x100 dimension) at 105,0 (basically slightly to the right of the first one), which covers area from 105,0 to 205,100. It is obvious that in the model they are not colliding. Now, as for view if your target device happens to be WxH you just draw the model as it is. If your device has a screen with w = 2*W, h = 2*H, so twice as big in each direction. You just multiply the x and y by w / W and h / H respectively. Therefore we get 2x for x and y, which on screen becomes 1st object - from 0,0 to 200, 200, 2nd object - from 210,0 to 410, 200. As can be seen they are still not colliding. To sum up, separate your game logic from your drawing (rendering) logic.
I think you should have variables holding the player's position on the "map". So you can use this to determine the collision with the non changing wall. It should look something like (depensing on the rest of your code):
canvas.translate(-hero.rect.centerX(), -.rect.centerY());
drawRoom();
canvas.restore();
drawHero();
Generally you should do the calculations in map coordinates, not on screen. For rendering just use the (negative) player position for translation.
I'm trying to make use of the following algorithm: http://www.skytopia.com/project/articles/compsci/clipping.html
But for my special case, I don't have a line that crosses the rectangle 2 times, but it starts in the center of the rectangle and only crosses it one single time.
Using the algorithm above I want to get the single intersection point for drawings on a canvas.
Problem: a canvas does not have a normal coordinate space where Y grows to the top, but Y grows to the bottom.
What would I have to change in order to "mirror" the y-axis and make it work in a canvas coordinate system?
Indeed the algorithm can be just ported as it is for using with canvas. I had some typo in the algor and after elemination it just works as expected.