I have a triangle like this;
shapeRenderer.begin(ShapeType.Line);
shapeRenderer.setColor(1, 1, 0, 1);
shapeRenderer.polygon(new float[] { -10, 0, 10, 0, 0, 200 });
shapeRenderer.rotate(0, 0, 1, 1);
shapeRenderer.end();
and I rotate 1 degree in each render. But I want to fix rotation (e.g. 45) to an angle. How can I do this?
Thanks.
To have a fixed rotation you hav to rotate the ShapeRenderer only once.
There are 2 possible ways i can think about:
call shapeRenderer.rotate(0, 0, 1, 45); in the constructor or in create() / show() method
This call rotates your ShapeRenderer by 45° (last parameter) arround the Z-Axis (The 3rd parameter)
call shapeRenderer.rotate(0, 0, 1, 45); in the rendermethod, only if you did not rotate yet. So you have to keep a boolean rotated and only if it is false you call rotate() and set it to true.
To answer the question in your comment: You cannot directly set the rotation, you can only rotate (relative to the current rotation). So i would suggest to store a float rotation, and everytime you rotate your ShapeRenderer you set the new value. To set a rotation in degrees you have to rotate like:
shapeRenderer.rotate(0, 0, 1, newRotation - rotation);
rotation = newRotation;
This works only if you always rotate arround the same axis, in your case the Z-axis. Else you would have to store 3 rotations (x,y,z). If you rotate arround a custom axis, defined by for example (0.1, 0.3, 0.6) you would need to calculate the rotation for all axes. But i don't really know how to do that. I think some Vectormath would do that. But i don't think you need that.
Related
I'm using the camera anchor in ArCore to create a static object in the scene.
float scaleFactor = 1.0f;
camera.getPose().toMatrix(cameraAnchorMatrix, 0);
// Update and draw the model and its shadow.
Matrix.rotateM(cameraAnchorMatrix, 0, 110, 0f, 1f, 0f);
virtualObject.updateModelMatrix(cameraAnchorMatrix, scaleFactor / 10);
virtualObject.draw(viewmtx, projmtx, colorCorrectionRgba);
However rotating the object sometimes makes it not visible, also translating it doesn't seem to work. I'm also kinda guessing the values for the rotation. Also the object is visible from the top, how can I make it look more natural? (It's an arrow that's supposed to show a direction.)
How can I move the object to the bottom left corner of the screen and rotate it from left to right?
This is how it looks at the moment. I want to move the arrow down and to the left and also tilt it forward. Then it should be able to rotate left and right. Thank your for your help.
Solved it with the following code:
camera.getPose().compose(Pose.makeTranslation(0.37f, -0.17f, -1f)).extractTranslation().toMatrix(cameraAnchorMatrix, 0);
This makes the object appear 'behind' the camera and moves it to the bottom-left. Then you can rotate the object with the angle value:
Matrix.rotateM(cameraAnchorMatrix, 0, 230 - directionChange, 0f, 1f, 0f);
Hello I'm tring to make a neverending background. So I try to wrap my texture.
texture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
And draw it:
bach.begin();
bach.draw(texture, 0, 0);
bach.end();
I'm ending with no changes to the texture when I use setWrap.
If i draw the texture that way:
bach.begin();
bach.draw(texture, 0, 0, texture.width, texture.height, 0, 0, 1, 1);
bach.end();
It repeats the texture but flipped...
If I try to flip the y and x in the bach.draw I get an error.
I only can flip the camera but then the position y flips too (translating up goes negative value / translating down goes positive value)
To repeat a texture, you need it to use UVs bigger than one, which you can do with a TextureRegion that is bigger than the Texture it references.
TextureRegion backgroundTextureRegion = new TextureRegion(texture, bgWidth, bgHeight);
//...
batch.begin();
batch.draw(backgroundTextureRegion, 0, 0, cameraWidth, cameraHeight);
batch.end();
Where bgWidth and bgHeight are how many texels wide and high you want to draw the background. For instance, if your camera's viewportWidth is 1920 and you want your texture to be drawn at 1:1 scale (texture pixels : camera units), then bgWidth would be 1920.
If you need to flip it vertically, you can use -bgHeight instead without messing with the camera.
currently I am scaling a matrix like so:
public void scale(float aw, float ah){
Matrix.scaleM(modelMatrix, 0, aw, ah, 1f);
updateMVP();
}
private void updateMVP(){
Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, modelMatrix, 0);
}
And using: gl_Position = u_Matrix * a_Position; in my vertex shader, u_Matrix being the mvpMatrix. The camera I am using is the default and the projectionMatrix is created by:
ASPECT_RATIO = (float) height / (float) width;
orthoM(projectionMatrix, 0, -1f, 1f, -ASPECT_RATIO, ASPECT_RATIO, -1f, 1f);
Now I can scale my object properly, but the only problem is that every time I scale the matrix, the object moves a little bit. I was wondering how I could scale the matrix while keeping the center point and not having the object translate. Anyone know how I can do this in OpenGL ES 2.0 on Android? Thanks
Do you have any other matrices (rotation/translation)?
If so: you might not be multiplying your matrices in the correct order, which can cause issues.
(proper order multiply right to left)
Translate * Rotation * Scale
Your error sounds like the one explained here:
You translate the ship by (10,0,0). Its center is now at 10 units of the origin.
You scale your ship by 2. Every coordinate is multiplied by 2 relative to the origin, which is far away… So you end up with a big
ship, but centered at 2*10 = 20. Which you don’t want.
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
Alright, so I got this code for gluLookAt:
lookAt = new Vector3f(-player.pos.x, -player.pos.y, -player.pos.z);
lookAt.x += (float)Math.cos(Math.toRadians(player.yaw)) * Math.cos(Math.toRadians(player.pitch));
lookAt.y += (float)Math.sin(Math.toRadians(player.pitch));
lookAt.z += (float) Math.sin(Math.toRadians(player.yaw)) * Math.cos(Math.toRadians(player.pitch));
GLU.gluLookAt(-player.pos.x, -player.pos.y, -player.pos.z,
lookAt.x, lookAt.y, lookAt.z,
0, 1, 0);
And when I try to draw a rotated cube it does not rotate properly.
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glTranslatef(-cube.pos.x, -cube.pos.y, -cube.pos.z);
GL11.glRotatef(cube.yaw, 0, 1, 0);
GL11.glTranslatef(cube.pos.x, cube.pos.y, cube.pos.z);
/*draw the cube normally*/
GL11.glPopMatrix();
So my question is am I handling the alterations to the matrix done by glulookat properly? or am I doing somethign wrong? The result I am looking for is to return the cube to 0,0,0 and rotate it, then put it back where it was.
problem is here:
GL11.glTranslatef(-cube.pos.x, -cube.pos.y, -cube.pos.z);
GL11.glRotatef(cube.yaw, 0, 1, 0);
GL11.glTranslatef(cube.pos.x, cube.pos.y, cube.pos.z);
The cube is already 'at' 0,0,0. This is because the Medel matrix is identity (as you called glLoadIdentity()).
so you should do:
GL11.glRotatef(cube.yaw, 0, 1, 0);
GL11.glTranslatef(cube.pos.x, cube.pos.y, cube.pos.z);
which should have the desired effect. If not, try it with a fixed camera to see if the code you added before glulookat() is causing the lookat target to be too far away from 0,0,0 (where your cube is)
Calling glLoadIdentity before drawing your cube will wipe out whatever gluLookAt has setup in your view matrix, I don't think it should be there.
How can we rotate a Image Clockwise using LibGDX? what i am looking is when a image is loaded,suppose a star, i need to rotate it from beginning of screen to end of the screen horizontally, with star rotating,how can i do that in libgdx?
When you draw the Texture with your SpriteBatch, you can use one of the draw functions that includes rotation. This javadoc has all the draw functions: SpriteBatch
You can keep a variable for position and rotation, and increase the rotation and x component of the position each time you render to make it rotate while moving horizontally.
Libgdx gives you more then one way to do that:
You can use Scene2D and add an Image to your Stage. Image is a subclass of Actor, so you can add Actions to it:
Image myImage = new Image(myTexture);
myImage.addAction(Actions.parallel(Actions.moveTo(endX, endY, duration), Actions.rotateBy(degrees, duration)));
myImage.setPosition(startX, startY);
myImage.setOrigin(sizeX/2, sizeY/2);
stage.add(myImage);
In render you can then call stage.act(), which updates the position, rotation, scale... of all your Actors and then call stage.draw() which will call draw() for all your Actors.
Image allready handles the draw() so you don't need to care about that anymore.
You can also do it without scene2d, by updating everything yourself:
You can store a int rotationSpeed in degrees/sec
You can store a int moveSpeed in units/sec (maybe pixel but i would suggest to use camera or viewport and use your own unit, which is equal on all devices)
Store the float angle, which is the current rotation of your Texture
and store a Vector2 position, which contains the x and y position of your Texture.
If you want to move in x and y direction you can also store a Vector2 direction, which is a normalized Vector, giving the percent of movement in x and y direction, but thats a different story.
Then in your render(float delta) you update everything:
angle+=delta*rotationSpeed;
angl%=360; // Limits the angle to be <= 360
while (angle < 0) // Unfortunally the "modulo" in java gives negative result for negativ values.
angle+=360;
position.x+=direction.x*moveSpeed*delta;
position.y+=direction.y*movSpeed*delta;
spriteBatch.draw(yourTextureRegion, position.x, position.y, sizeX/2, sizeY/2, sizeX, sizeY, scaleX, scaleY, angle);
For clockwise rotation simply use a negative rotationSpeed or replace the angle+= with angle-=.
Hope it helps.
Following is the implementation to rotate any sprite
batch.draw(sprite,(Gdx.graphics.getWidth() - sprite.getRegionWidth()) / 2.0f,(Gdx.graphics.getHeight() - sprite.getRegionHeight()) / 2.0f,sprite.getRegionWidth()/2.0f,sprite.getRegionHeight()/2.0f, sprite.getRegionWidth(), sprite.getRegionHeight(), 1f, 1f,count, false);
if(count < 0.0f)
count = 360.0f;
else
count --;
Initially set counter to
private float count =360.0f;
You can also use the Scene2D actions. I have an example here with asteroid-type thing falling down the screen and rotating.
http://www.netthreads.co.uk/2012/02/09/libgdx-scene2d-demo-with-scene-transitions/
To rotate anticlockwise and horizontally..
create a textureRegion
then
Sprite sprite = new Sprite(textureRegion, 0, 0, 128, 128);
sprite.setPosition(++mX, 0);
angle++;
sprite.setRotation(angle);
sprite.draw(batcher);
You can do it too like this:
on your create method
sprite.setOrigin(sprite.getWitdh() /2f, sprite.getHeight() /2f);
sprite.setPosition( 0, 200 ); //200 it's a example
on your render(float delta)
sprite.setX( sprite.getX() + delta ).setRotation( sprite.getRotation() + delta );
Here is a simple to rotate an actor in libgdx. First you need to set the origin:
img.setOrigin(getWidth/2,getHeight/2);
And then you can rotate clockwise and anticlockwise according to your need:
img.rotate(2f); or img.rotate(-2f);
So the following sample worked for me (infinite rotation)
Method 1: (recommended)
loadingActor.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.rotateBy(360, 1)));
Method 2:
Image loadingActor = new Image(AssetsController.getInstance().getLoading());
loadingActor.setOrigin(Align.center);
final SequenceAction infiniteRotate = Actions.sequence();
infiniteRotate.addAction(Actions.rotateTo(0 , 0f) );
infiniteRotate.addAction(Actions.rotateTo(360 , 1f) );
loadingActor.addAction(Actions.forever(infiniteRotate));