LibGDX 3D Camera spasm when player looks directly up or down - java

My circumstance
I am making a 3D LibGDX game. I am using a custom camera controller, based off of the one over here. It takes out the use of delta Y, when determining where to move the player, so that they can stay on the same level whether they are looking up or down.
My problem
My problem is that whenever the player looks too far up, or down, the camera kinda starts spazing out. I believe that it is trying to look either strait up, or down. My problem is that I don't want that. In previous projects I have tried to set a limit like so:
if(camera.direction.y + deltaY >= 0.9){
return;
}
(Code might not be exactly correct), but when that happens, the player usually cannot see enough.
My code
There is a link to my code here.

I got my code fixed with the help of one of the fine fellows over at Github. Here is my new FirstPersonCameraController#touchDragged:
float deltaX = -Gdx.input.getDeltaX() * degreesPerPixel;
float deltaY = -Gdx.input.getDeltaY() * degreesPerPixel;
camera.direction.rotate(camera.up, deltaX);
Vector3 oldPitchAxis = tmp.set(camera.direction).crs(camera.up).nor();
Vector3 newDirection = tmp2.set(camera.direction).rotate(tmp, deltaY);
Vector3 newPitchAxis = tmp3.set(tmp2).crs(camera.up);
if (!newPitchAxis.hasOppositeDirection(oldPitchAxis))
camera.direction.set(newDirection);
(I removed a couple of parts that are specific to my game)

Related

Intersect TriangleMesh from screen coordinates in JavaFX

I have a TriangleMesh in javafx and a 2D point in screen space and i want to check whether any triangles in the mesh intersect with that point(basically same as clicking a point in the mesh except that i already have a predefined screen coordinate)
Note that i don't care where the intersection happened etc but only the fact whether it intersected or not.
I did try googling this and found some useful answers, especially one by José Pereda here: https://stackoverflow.com/a/27612786/14999427
However the links are down
Edit: i did find a working link to it, however it just hardcodes the origin/target and im not sure how to compute these from the 2d screen point
Another idea i had was to copy the implementation from openjfx but after some research i figured that i'd have to copy a lot of internals and even then i wasn't sure if i would get it working so i scrapped that idea.
Goal: i want to use my mouse to create a rectangle at an arbitrary position in the mesh and then find all triangles that are inside that rectangle (i believe it's usually called rectangle selection in 3d modeling software)
Update: converting each triangle to 2d screen coordinates using Node#localToScreen and then doing a 2D point inside triangle test works perfectly however it also selects faces that are culled.
Update 2: after also doing the culling myself it works quite well (it's not perfect but it's mostly accurate)
Current code:
Point2D v1Screen = view.localToScreen(mesh.getPoints().get(0), mesh.getPoints()
.get(1), mesh.getPoints().get(2));
Point2D v2Screen = view.localToScreen(mesh.getPoints().get(3), mesh.getPoints()
.get(4), mesh.getPoints().get(5));
Point2D v3Screen = view.localToScreen(mesh.getPoints().get(6), mesh.getPoints()
.get(7), mesh.getPoints().get(8));
Point2D point = new Point2D(mouseX, mouseY);
boolean inTriangle = pointInTriangle(point, v1Screen, v2Screen, v3Screen);
// Back-face culling
double dxAB = v1Screen.getX() - v2Screen.getX();
double dyAB = v1Screen.getY() - v2Screen.getY();
double dxCB = v3Screen.getX() - v2Screen.getX();
double dyCB = v3Screen.getY() - v2Screen.getY();
boolean culled = ((dxAB * dyCB) - (dyAB * dxCB)) <= 0;
if (inTriangle && !culled) {
view.setMaterial(new PhongMaterial(Color.BLUE));
System.out.println("Intersected");
}
I think the answer to this question may help you. How to correctly obtain screen coordinates of 3D shape after rotation If you can compute the screen coordinates of a 3D shape (triangle) the hit test should then be simple.

Set offset for BitmapDrawable while repeating in the x and y direction?

I'm making a 2D platformer game. I have created a texture for the platform, that is meant to be repeated over and over to fill the entire platform, without going over. My first attempt was to draw all the pixels from the bitmap manually, but this caused the background to flicker through while moving the platform (the movement and drawing threads are seperate, so the movement can run at a specific speed, while the FPS doesn't need to suffer). I found this technique worked better:
// Init
bitmap = new BitmapDrawable(res, Texture.PLATFORM.getBitmap());
bitmap.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
// Drawing loop
int x = getX() + (isStill() ? 0 : (int)MainActivity.offsetX);
int y = getY() + (isStill() ? 0 : (int)MainActivity.offsetY);
bitmap.setBounds(x, y, x + getWidth(), y + getHeight());
bitmap.draw(canvas);
However, the bitmap appears to be staying static while the platform is acting as a "view hole" to see through to the bitmap. The only work around I can think of is to somehow "offset" the static bitmap:
bitmap.offset(x, y);
Obviously, that isn't a function. I couldn't find one that would do what I want when looking through the docs.
To summon things up, the BitmapDrawable is causing the background to not move with the platform, making it look super weird.
Thanks in advance!
Try these tips in your code:(I assumed the game moves forward in the horizontal direction)
The GUY should only move up and down(with the appropriate touch input) and not forward and backward as you want the focus(or camera alternatively) solely on the GUY.I noticed that the WALL was moving up in your video when the GUY moved from initial higher position of the wall to little bit lower position later, rectify this because the GUY should move down(try to implement Gravity effect).
The WALL should only move forward(mostly) and backward(less often I guess).The WALL shouldn't move up and down normally. Do not apply Gravity effect to it. You can create at least 2 BitmapDrawable instance of WALL for a screen. They are going to be reused sequencially(for eg: If the 1st one goes totally outside of the screen, reshow it in the desired position using setBounds() method) and continue same for others the whole game.
The currently BLUE BACKGROUND, if it is a part of a larger map, then it needs to be appropriately offsetted.
One of the obstacles that I can think of at the time of writing this is to move the WALL down until it goes out of the screen which results in the death of the GUY.
At those places, where I have used the word move, you need to use the setBounds(a, b, c, d) method to make necessary position based changes as I didn't find other way to update the position of a BitmapDrawable instance. I think, you need to use game framework like libGdx to get method of luxury like setOffset(x, y) or of similar sort.
Sorry that I could only present you the ideas without specific code as I do not have past experience working in a project like this. Hope, it helps you in anyway possible.

Box2D - Controlled Movement with Physics

I am creating a Java desktop 2D Game using LibGDX.
I need to be able to move objects (controlled by the player with W/A/S/D).
The movement speed is always the same (read out from a field of the moving object).
While they are moving, they should still be affected by physics.
This means that when moving away from a magnet would make you move slower, moving towards it makes you faster and moving past it would cause you to move a curve. (see blue part of image)
Also a single impulse in while moving would knock you away but you keep moving (see red part of image)
You should also be able to change direction or stop, only stopping your own movement, so you will still be affected by physics.
So I need to apply constant forces that will still be accessible (and removable) after the next step.
Can I do this with Box2D?
-If yes, how?
-If no, any other libraries that can do this? I don't really need density and stuff like that, the use cases in the image is pretty much all I need (+ Collision Detection).
*A magnet would be a body constantly pulling other bodies in a certain range to itself
*Kockback would just be a simple impulse or the collision of a projectile with the object.
EDIT: If you know The Binding of Isaac, thats the kinda physics I'm aiming for.
Set the distance where the magnet has his influence:
float magnetRadius = 30;
Set the attractive force of the magnet:
float magnetForce = 400;
Get the position of the player and of the magnet:
Vector2 magnetPos = magnet.getWorldCenter();
Vector2 playerPos = player.getWorldCenter();
Now calculate the distance between the player and the magnet:
Vector2 magnetDist = new Vector2((playerPos.x - magnetPos.x), (playerPos.y - magnetPos.y));
float distance = (float) Math.sqrt((magnetPos.x) * (magnetPos.x) + (magnetPos.y) * (magnetPos.y));
Then, if the player is inside the magnet's radius, you must apply a force to him that depends on the distance of the player from the magnet:
if (distance <= magnetRadius) {
float vecSum = Math.abs(magnetDist.x)+Math.abs(magnetDist.y);
Vector2 force = new Vector2((magnetForce*magnetDist.x * ((1/vecSum)*magnetRadius/distance)), (magnetForce*magnetDist.y * ((1/vecSum)*planetRadius/distance)));
player.applyForceToCenter(force, true);
}

Cocos2d-android detecting randomly created sprites or rects

I am developing an android game on Eclipse in which a sprite is jumping on several platforms to get to the top but I am having difficulties. Here is my case: I have the character sprite (I'll name this as Sprite1 in this case) that moves and I am creating another 3 sprites(the platforms) at random positions when my app starts. The platforms are successfully created when the app starts. But the collision between them and Sprite1 is not detected. I tried many solutions and I am stuck for a couple of days now. Any help or suggestion will be appreciated.
I tried making rects when the platforms are created then using the rects to detecting collisions but they still don't collide. I use Java language. :)
I use this to create the sprites and detect collisions:
Creating platform sprites (this is how i randomly spawn platforms, if there are mistakes here, i'm sure i just copied wrong because the creating or platform sprites works correctly.):
public void addRandomPlatform(){
Random rand = new Random();
randPlat = CCSprite.sprite("platform2.png");
randPlat.setPosition(actualX, actualY);
actualY -= (int)(randPlat.getContentSize().height*4);
addChild(randPlat,2);
}
Then I just call this method when my app starts.
Detecting Collision:
playerRect = CGRect.make(player.getPosition().x - (player.getContentSize().width / 4.0f),//- (player.getContentSize().width / 2.0f),
player.getPosition().y - (player.getContentSize().height / 2.0f),
player.getContentSize().width/3.0f,
player.getContentSize().height/8.0f);
if(CGRect.intersects(playerRect, randPlat))
{
*my codes for stopping the jump*
}
I hope this is clear. Thanks in advance!
It looks like the randRect is a CCSprite, and not a CGRect. You should create a CGRect(of the random platform) the same way you created the playerRect.
Also, why do you divide the player's width/height by respectively 3 and 8? I don't think that's what you want, and it causes the playerRect to be only a thirth of the width, and 1/8 of the height of the actual sprite.
#Override
public boolean ccTouchesEnded(MotionEvent event) {
CGPoint point = ranSprite.getPosition();// THE POSITION MUST BE YOUR RANDOM SPRITES POSITIONS
List<CCNode> childsList = this.getChildren();
for(CCNode childSprite : childsList){
if(childSprite.getTag() == Constants.PLAYER_TAG && childSprite.getBoundingBox().contains(point.x, point.y)){
// Do what ever you want
}
}

Perspective 3D Projection in Java

I'm working on creating a simple 3D rendering engine in Java. I've messed about and found a few different ways of doing perspective projection, but the only one I got partly working had weird stretching effects the further away from the centre of the screen the object was moved, making it look very unrealistic. Basically, I want a method (however simple or complicated it needs to be) that takes a 3D point to be projected and the 3D point and rotation (possibly?) of the 'camera' as arguments, and returns the position on the screen that that point should drawn at. I don't care how long/short/simple/complicated this method is. I just want it to generate the same kind of perspective you see in a modern 3D first person shooters or any other game, and I know I may have to use matrix multiplication for this. I don't really want to use OpenGL or any other libraries because I'd quite like to do this as a learning exercise and roll my own, if it's possible.
Any help would be appreciated quite a lot :)
Thanks, again
- James
Update: To show what I mean by the 'stretching effects' here are some screen shots of a demo I've put together. Here a cube (40x40x10) centered at the coords (-20,-20,-5) is drawn with the only projection method I've got working at all (code below). The three screens show the camera at (0, 0, 50) in the first screenshot then moved in the X dimension to show the effect in the other two.
Projection code I'm using:
public static Point projectPointC(Vector3 point, Vector3 camera) {
Vector3 a = point;
Vector3 c = camera;
Point b = new Point();
b.x = (int) Math.round((a.x * c.z - c.x * a.z) / (c.z - a.z));
b.y = (int) Math.round((a.y * c.z - c.y * a.z) / (c.z - a.z));
return b;
}
You really can't do this without getting stuck in to the maths. There are loads of resources on the web that explain matrix multiplication, homogeneous coordinates, perspective projections etc. It's a big topic and there's no point repeating any of the required calculations here.
Here is a possible starting point for your learning:
http://en.wikipedia.org/wiki/Transformation_matrix
It's almost impossible to say what's wrong with your current approach - but one possibility based on your explanation that it looks odd as the object moves away from the centre is that your field of view is too wide. This results in a kind of fish-eye lens distortion where too much of the world view is squashed in to the edge of the screen.

Categories