LibGDX: Viewport using PerspectiveCamera - libgdx

I want to create a viewport for my scenegraph, that uses a perspective camera. I created a new class that extends the abstract Viewport class.
It only contains the following constructor:
public UiViewPort(float worldWidth, float worldHeight) {
setWorldSize(worldWidth, WorldHeight);
PerspectiveCamera camera = new PerspectiveCamera(60, worldWidth, worldHeight);
camera.position.set(worldWidth / 2f, worldHeight / 2f, (worldHeight / 2f) * (float)Math.tan(Math.PI * 60.0 / 180.0));
camera.lookAt(worldWidth / 2f, worldHeight / 2f, 0f);
camera.near = 1f;
camera.far = 2 * worldWidth;
camera.update();
setCamera(camera);
}
But I can't see anything from my stage. Interestingly enough I can a least see a part of what I draw, when I change the cameras position to something like: 50, 50, 100.
I don't understand what's wrong. If I'm not using a scenegraph and a stage but only a shaperenderer to draw things, everything works as aspected.
I want to use a perspective camera to zoom into my gui.

Related

3D ball rolling on wrong axis LibGDX

Hello I'm trying to make a billiards game using libgdx. I'm using 3d models for the balls and an Orthographic Camera to view them. I am having trouble getting them to roll correctly after rolling on a different axis. Here is a clip of what they look like when they're rolling.
As you can see they appear to be rotating as if they were on their starting axis. Is there any way to rotate it so that it looks like it's actually rolling. I am also not very familiar with transformation matrices or quaternions so im not too sure where to go.
Edit: Updated for clarity
Here is the code I use to update the rotation
public boolean update() {
if (!visible) {
return false;
}
Vector2 vBall = ballBody.getLinearVelocity();
float vAngle = ballBody.getAngularVelocity();
isMoving = true;
float x = ballBody.getPosition().x * SCALE;
float y = ballBody.getPosition().y * SCALE;
Vector2 axisInPlane = new Vector2(y - center.y, x - center.x).rotateRad(Math.PI/2f);
Vector3 axis3D = new Vector3(axisInPlane.x,axisInPlane.y,0f);
ball3D.transform.rotate(axis, (float) Math.toDegrees(dist / RADIUS_PX));
ball3D.transform.setTranslation(mapX(x), mapY(y), 0);
Just to be sure, center is an arbitrary fixed point where there is no rotation and all rotations are derived from this distance/angle as the ball has no slippage.
So you can directly get the axis with
Vector2 axisInPlane = new Vector2(y - center.y, x - center.x).rotateRad(Math.PI/2f);
Vector3 axis3D = new Vector3(axisInPlane.x,axisInPlane.y,0f);
Also Math.toDegree takes radians as an argument, not a float, so dist/RADIUS_PX will be off, you have to supply as a fraction of 2PI (360 degs in radians). Also this should be the circumference of the ball not the radius. I don't know what class ball3D is but I would check that ball3D.transform.rotate does take degrees as an argument and if it does replace that line with
float rotateRadians =(float) Math.toDegrees((dist/CIRCUMFERENCE_PX)*Math.PI*2f);
ball3D.transform.rotate(axis, rotateRadians );

Few Vertices of mesh gets stick to the origin when making a soft body (sphere) and translating in libgdx?

I am trying to make a soft body by making a sphere and taking all the meshParts from it and making a soft body from that sphere.
and when I render it in libgdx I use a model of sphere so that the soft body is visible which translate as the soft body moves but few vertices are sticked to the spawn location (origin)
can anyone suggest me what am I doing wrong ?
this is my create method :
ModelBuilder modelBuilder1;
modelBuilder1 = new ModelBuilder();
final Material material = new Material(ColorAttribute.createDiffuse(Color.RED));
final long attributes = VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal;
final Model sphere = modelBuilder1.createSphere(2f, 2f, 2f, 24, 24, material, attributes);
meshPart = sphere.meshParts.get(0);
indexMap = BufferUtils.newShortBuffer(meshPart.size);
positionOffset = meshPart.mesh.getVertexAttribute(VertexAttributes.Usage.Position).offset;
normalOffset = meshPart.mesh.getVertexAttribute(VertexAttributes.Usage.Normal).offset;
softBodyBall = new btSoftBody(worldInfo, meshPart.mesh.getVerticesBuffer(), meshPart.mesh.getVertexSize(), positionOffset, 3, meshPart.mesh.getIndicesBuffer(), meshPart.offset, meshPart.size, indexMap, 0);
softBodyBall.setPose(true, false);
dynamicsWorld.addSoftBody(softBodyBall);
btSoftBody.Material pm = softBodyBall.appendMaterial();
softBodyBall.generateBendingConstraints(2, pm);
pm.setKLST(0.9f);
pm.setFlags(0);
softBodyBall.generateBendingConstraints(2, pm);
softBodyBall.setConfig_piterations(7);
softBodyBall.setConfig_kDF(0.2f);
softBodyBall.randomizeConstraints();
softBodyBall.setTotalMass(1);
softBodyBall.translate(new Vector3(1, 5, 1));
instance = new ModelInstance(sphere);
and this is my render method
softBodyBall.getVertices(meshPart.mesh.getVerticesBuffer(), softBodyBall.getNodeCount(), meshPart.mesh.getVertexSize(), 0);
softBodyBall.getWorldTransform(instance.transform);
final float delta = Math.min(1f / 30f, Gdx.graphics.getDeltaTime());
dynamicsWorld.stepSimulation(delta, 5, 1f / 30f);
batch.begin(camera);
batch.render(instance,environment);
batch.render(instances, environment);
batch.end();
here is the image how it looks like :
https://drive.google.com/file/d/1-9UjdlyIAotZPgrLKaoG0Dm5UEVLdzY1/view?usp=sharing
Found it.
needed to render each vertices.
softBodyBall.getVertices(meshPart.mesh.getVerticesBuffer(), meshPart.mesh.getVertexSize(), positionOffset, normalOffset,
meshPart.mesh.getIndicesBuffer(), meshPart.offset, meshPart.size, indexMap, 0);
this instead of
softBodyBall.getVertices(meshPart.mesh.getVerticesBuffer(), softBodyBall.getNodeCount(), meshPart.mesh.getVertexSize(), 0);

Libgdx Box2D body rotation around point sprite position

I need that my body rotate around specific point like shown in picture.
I already done that by this line of code (Please let me know if there is a better way)
PolygonShape shape = new PolygonShape();
shape.setAsBox(1.8f / PPM, 0.2f / PPM, new Vector2(2,2), 0); // vector2 is
now I want to position sprite accordingly to my rotating body. Here what I did
sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
sprite.setPosition(body.getPosition().x * 32 - sprite.getWidth() / 2, body.getPosition().y * 32 - sprite.getHeight() / 2);
and here how I draw everything
public void draw(SpriteBatch sb){
System.out.println(body.getWorldCenter());
sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
sprite.draw(sb);
}
Strange things happen when I run my code. I seee that body rotating correctly, but sprite rotates around its origin (middle of a sprite) because of this line sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2); however I need that sprite position would be always the same as my body position. How can I cheve this?
The origin of all box2d bodies is their location.
Important: The box2d bodies of type box/circle get centered around their location, while the other types of bodies are NOT.
If you want to sync your rotation with the sprite, you should position the sprite origin over the body location and then rotate.
Example: if you have body at location 0,0 and sprite with origin 1,1 you should position that sprite on location -1,-1 in order for the two to rotate synchroniously!

LibGdx Bow and arrow game physics

I'm working on a new game written with LibGdx Engine and Java.
I've got a problem with some of the physics in this game.
I want to shoot the arrow in a ballistic trajectory (angry bird style)
and can't find the equation to do so .
I am using these velocity equations:
float velx = (float) (Math.cos(rotation) * spd);
float vely = (float) (Math.sin(rotation) * spd);
I add this to the current position and the arrow shoots in one direction - straight.
I thought maybe changing the rotation would help me achieve what I want (a ballistic path).
It does help, but I want to have the trajectory as well.
I saw this
ProjectileEquation class that someone already posted but didn't know how to work with it:
public class ProjectileEquation
{
public float gravity;
public Vector2 startVelocity = new Vector2();
public Vector2 startPoint = new Vector2();
public Vector2 gravityVec = new Vector2(0,-10f);
public float getX(float n) {
return startVelocity.x * (n ) + startPoint.x;
}
public float getY(float n) {
float t = n;
return 0.5f * gravity * t * t + startVelocity.y * t + startPoint.y;
}
}
I'm looking for some help to help me use this class for ballistic trajectories.
This is how I tried using it:
for(int i =0;i<30;i++)
{
Texture f = ResData.Square_1;
ProjectileEquation e= new ProjectileEquation();
e.gravity = 1;
e.startPoint = new Vector2(bow.getX(),bow.getY());//new Vector2(-bow.getX(),-bow.getY()); //My bow is opposite so it suppose to work fine
e.startVelocity = getVelocityOf(bow.getRotation());
Vector3 touchpos = new Vector3();
s.draw(f,e.getX(i) ,e.getX(i),5,5);
}
The ProjectileEquation class you post looks like it'll calculate the X and Y position given a time delta, so the float you pass in should be the time delta since you started the arrow moving (in seconds).
That code will not give you the angle of the arrow though. To find that, I would suggest you keep hold of the previous X and Y, then you can use Math.atan2() to calculate the angle based on the previous XY and the current XY. Google atan2 for a load of info on how to use it.
The very best way to do this however would be to use Box2d and model the scene correctly. Then you wouldn't have to get involved in the maths at all. I read somewhere that that's what Angry Birds uses, and is an excellent choice for modelling these sorts of physics games.
I hope your game goes well.

Strange stability issues with Matrix scale/rotation in Actionscript

I have a Flash app where I am performing a scale and rotation operation about the center of _background:MovieClip (representing a page of a book). I have simple event listeners on the GESTURE_ROTATE and GESTURE_SCALE events of this MC which update some variables currentRotation and currentScaleX, currentScaleY. I then have the following code trigger on the ENTER_FRAME event of the app.
The problem I am encountering is upon rotating the MC beyond the limits of roughly 60 or -60 degrees, or scaling slightly and rotating, the MC begins to oscillate and finally spin wildly out of control and off the screen. I've tried several things to debug it, and even tried Math.flooring the currentRotationValue and rounding the values of currentScaleX/Y to the tenths place (Math.floor(currentScale * 10) / 10), but neither of these seems to remedy it. I'm a little stuck at this point and have tried researching as much as I can, but couldn't find anything. Any suggestions? Is there an issue with doing this operation on each frame perhaps?
private function renderPage(e:Event) {
var matrix:Matrix = new Matrix();
// Get dimension of current rectangle.
var rect:Rectangle = _background.getBounds(_background.parent);
// Calculate the center.
var centerX = rect.left + (rect.width/2);
var centerY = rect.top + (rect.height/2);
// Translating to the desired reference point.
matrix.translate(-centerX, -centerY);
matrix.rotate(currentRotation / 180) * Math.PI);
matrix.scale(currentScaleX, currentScaleY);
matrix.translate(centerX, centerY);
_background.transform.matrix = matrix;
}
I'm not certain what behaviour you're trying to produce, but I think the problem is that centerX and centerY define the middle of _background in _background.parent's coordinate space. You're then translating the matrix so that _background is rotated around the values centerX, centerY, but in _background's coordinate space.
Assuming you want _background to rotate around a point which remains static on screen, what you actually need to do is use two different Points:
matrix.translate(-_rotateAroundPoint.x, -_rotateAroundPoint.y);
matrix.rotate(currentRotation / 180) * Math.PI);
matrix.scale(currentScaleX, currentScaleY);
matrix.translate(_centerOnPoint.x, _centerOnPoint.y);
Where _rotateAroundPoint is the point around which _background should turn in it's own coordinate space, and _centerOnPoint is the point around which it should turn in its parent's coordinate space.
Both of those values only need to be recalculated when you want to pan _background, rather than every frame. For example:
private var _rotateAroundPoint:Point = new Point(_background.width * 0.5, _background.height * 0.5);
private var _centerOnPoint:Point = new Point(50, 50);
private function renderPage(e:Event) {
var matrix:Matrix = new Matrix();
matrix.translate(-_rotateAroundPoint.x, -_rotateAroundPoint.y);
matrix.rotate((currentRotation / 180) * Math.PI);
matrix.scale(currentScaleX, currentScaleY);
matrix.translate(_centerOnPoint.x, _centerOnPoint.y);
_background.transform.matrix = matrix;
}