Why disabling world gravity has no effect on moving rigid body? - bulletphysics

I am building a sandbox for playing around and testing ammo.js (a javascript port of the Bullet physic engine v2.82). So this question should apply to both Ammo and Bullet I guess.
I am starting my scene with a falling sphere and the world gravity is set to (0, -9.8, 0).
Before the sphere touch the ground, I am disabling the world's gravity:
physicsWorld.setGravity(new ammo.btVector3(0, 0, 0));
I am expecting the sphere to "freeze" it's movement, since no gravity should be applied anymore, but the sphere is still falling and hit the ground. I am wondering why.

It's due to inertia. The first Newton's law says that if the forces applied on an object is zero (the case of your sphere after your gravity change), the acceleration is zero. But it does not mean that the velocity is null. In your case, the velocity will stay constant.
Another way to convince you is with Newton's second law which is probably coded in ammo.js:
ma = F
a is the acceleration, m the mass, F the sum of external forces.
Let's say that a = (v_{t+1} - v_t) / dt. With F=0, you will get v_{t+1} = v_t, a constant velocity.
v is the velocity, dt the time step.

Related

Is there a way to have smooth/subpixel motion without turning on smoothing on graphics?

I'm creating this 2D, pixel art game. When the camera follows the player (it uses easing), on the final approach, the position gets several subpixel adjustments.
If I have smoothing ON (on my graphic assets), the graphics look good (sharp. it's pixel art) but the subpixel motion is jerky/jumpy.
If I have smoothing OFF, the subpixel motion is smooth, but the pixel art graphics look blurry.
I'm using Flash player v21. I've tried this with Starling and with Flash's display list.
You have a pixelated object that is moving in increments of less than the pixel size, but you don't want to restrict your mathematical easing to integers, or even worse, factors of 8 or what have you. The solution I am using in my project for this exact issue is posted below (I just got it working last week!)
Concept
create a driver that is controlled by the easing using floating point numbers.
Allow this driver to then control where the actual display object is rendered. We can use a constraint to only allow the display object to render on your chosen resolution.
Code Example
// you'll put these lines or equivalent in the correct spots for your particular needs.
// SCALE_UP will be your resolution control. If your pixels are 4 pixels wide, use 4.
const SCALE_UP: int = 4;
var d:CharacterDriver = new CharacterDriver();
var c:Character = new Character();
c._driver = d; // I've found it useful to be able to reference the driver
d._drives = c; // or the thing the driver drives via the linked object.
// you don't have to do this.
then when you are ready to do your easing of the driver:
function yourEase(c:Character, d:CharacterDriver):void{
c.x = Math.ceil(d.x - Math.ceil(d.x)%SCALE_UP);//this converts a floating point number into a factor of SCALE_UP
c.y = Math.ceil(d.y - Math.ceil(d.y)%SCALE_UP);
Now this will make your character move around 4 pixels at a time, but still be able to experience easing!
The bit with the modulo (%) operator is the key. For instance, 102-102%4 = 100. 103-103%4 = 100. 104-104%4 = 104.
In case anyone is confused by that, look at what 102%4 does: 4 goes into 102 25 times with a remainder of 2. so 102%4 = 2. Then 102 - 2 = 100.
In your case, since the "camera" is following the player (i.e. the background is moving, right?) then you really need to apply drivers to everything in the background instead, but it is basically the same idea.
Hope this helps.
since you specifically mentioned the "final approach" i think your problem comes from the fact that the easing equations puts your graphics at fractional coordinates, especially while getting closer to the target, but you should also notice it during the rest of the animation.
depending on the easing "engine" that you're using you should be able to set a "round values" flag, so all the coordinates set will be integer values and not fractional
if that's not possible, find a way in your display objects to round the x and y values every time they change

AS3 landing smoothly under affect of Gravity

I'm attempting a to make a fighting game with multiple platforms. I've successfully made the controls, movement, (double)jumping, and gravity parts of the game.
The issue is, when a player jumps, upon reaching the ground, they seem to go a bit deeper than they should on the platform (they should land and stay on the surface of the platform). This is more visible when the player double jumps.
I know why this happens; it's because sometimes hitTestObject takes a while to react when objects come in too quickly.
So, the first thing I thought of is to make the player's foot's y axis equal to the y axis of the top of the platform he lands on.
Though, that solution resulted in a rather jerky landing.
My question is: Is there a way to make the player to land smoothly on the top surface of the platform?
Some things I've tried:
-Raising FPS, it just made the same effect happen, but more quickly.
-Decreasing the speed at which the player falls, but that makes the game less fun, so I've crossed it out.
And here's my relevant code:
stage.addEventListener(Event.ENTER_FRAME, loop);
var jumpConstant:Number = 30;
var gravityConstant:Number = 1.8;
function loop(e:Event):void //happens
{
if(player.leg1.foreleg1.foot1.hitTestObject(platforms.ground)||player.leg2.foreleg2.foot2.hitTestObject(platforms.ground)) //if either of the player's legs are colliding with the platform [ps: nested movieclips]
{
player.ySpeed = 0; //the player stops going downwards
player.y = platforms.y; //the player's y becomes the platform's y. don't worry, it puts the player in the right place, just not smoothly.
if (player.b_up) //if Up control button (W or Up Arrow) is being pressed
{
player.ySpeed = -player.jumpConstant; //make the player jump
}
else //if the player isn't colliding with the platform
{
player.ySpeed += player.gravityConstant; //the player is affected by gravity and is pulled downwards
}
Link to the game if you wanna try it out to see the jerky effect:
http://www.fastswf.com/-64Ux3I
The problem is that you are only checking for a collision at increments of ySpeed. Since y speed increases during a fall by 1.8 per step, you are quickly looking at collision checks spaced widely apart. If you want pixel precise collision checks, you need to check for collision at 1px increments. This means if y speed is 10, you need 10 collision checks during one loop update. Use a for loop within your loop function to accomplish this.
Why don't you set hitTestObject y coordinates a bit above the ground so the sinking into the ground will actually make it touch the ground now.

Using box2d to detect collisions, but ignore the forces

I'm using libgdx and box2d to detect collisions, but I want some collision to be detected but the forces not to play out.
Eg, I want to detect when the character collides with a coin but don't want the coin to affect the player's movements.
Is this even possible using box2d? If so, how can I go about doing it?
I'm not sure what you want do, but if I understand what you want to do, you can create a sensor fixture type, this pseudo example:
FixtureDef fd1 = new FixtureDef();
//fd1.friction = 0.5f;
PolygonShape pSTest = new PolygonShape();
//size you want for example:
pSTest.setAsBox(4f / PIXEL_POR_METRO,
1f / PIXEL_POR_METRO,
new Vector2(22f / PIXEL_POR_METRO, -1f / PIXEL_POR_METRO),
0f);
fd1.shape = pSTest;
fd1.isSensor = true;
yourBody.createFixture(fd1).setUserData("yourId");
looks ContactListener interface, for example preSolve
note that sensor, this is not called for sensors.
info
setAsBox(float hx, float hy, Vector2 center, float angle)
Parameters:
hx the half-width.
hy the half-height.
center the center of the box in local coordinates.
angle the rotation in radians of the box in local coordinates.
Quoted from: https://gamedev.stackexchange.com/a/22542
Read up on collision filtering in the Box2D manual:
Collision filtering allows you to prevent collision between fixtures.
For example, say you make a character that rides a bicycle. You want
the bicycle to collide with the terrain and the character to collide
with the terrain, but you don't want the character to collide with the
bicycle (because they must overlap). Box2D supports such collision
filtering using categories and groups.
Box2D supports 16 collision categories. For each fixture you can
specify which category it belongs to. You also specify what other
categories this fixture can collide with. For example, you could
specify in a multiplayer game that all players don't collide with each
other and monsters don't collide with each other, but players and
monsters should collide
Link to manual here. (Search for Filtering)
.

How to calculate the trajectory of reflections from other physical objects?

Is there an easy way to calculate the expected trajectory of the bullet in the Nape? I need to build something like this path reflected no more than one or two bodis. Like billiard games. My game do not have gravity.
Start with a stationary rectangle. I assume you can determine which edge the bullet will strike. If it strikes a horizontal edge (constant Y), then reverse the Y-component of the trajectory; If it strikes a vertical edge (constant X), then reverse the X-component of the velocity.
In the case of a circle, you must find the ray from the center of the circle to the point of impact, then reverse the component of the velocity parallel to that ray (do you know how to find the component of a vector parallel to a given vector?).
If the objects can move, and the speed of the bullet is much greater than the speed of the objects, then all you need is the instantaneous positions of the objects-- as far as the bullet is concerned, they are stationary.
If the objects are moving with speed comparable to the speed of the bullet, you must be able to do simple coordinate transformation, in order to shift in and out of the object's frame. For instance, if the object has velocity (2,3) and the bullet has velocity (-5, 9), then in the frame of the object the object is stationary and the bullet has velocity (-7, 6). Then you can calculate the collision in this frame (where the object is stationary), then transform back. For instance, if the object is a rectangle and the bullet hits its bottom edge, the bullet's velocity becomes (-7, -6), which we transform back into the world frame: (-5, -3).

Actionscript collisions: solving exceptions and strange cases

I have created a collision class to detect collisions using pixels. In my class I've also developed some functions for determining the collsion angle. Based on this I created some examples:
http://megaswf.com/serve/25437/
http://megaswf.com/serve/25436/
(Space to change gravity, right/left to give some speed to the ball.)
As you will probably notice, there are strange things that happen:
When the ball speed is very low
When the direction of the ball is
almost tangent to the obstacle.
collision http://img514.imageshack.us/img514/4059/colisao.png
The above image shows how I calculate the collision angle.
I call the red dots the keypoints. I search for a maximum number of keypoints (normally 4). If I find more then 2 keypoints, I choose the 2 farthest ones (as shown in one of the blue objects). Thats how I then find the normal angle to where in the surface the object collided. I don't know if this is an obsolete way of doing things.
based on that angle, I rotate the speed vector to do the bouncing.
The piece of code to do the maths is here:
static public function newSpeedVector(speedX: Number, speedY: Number, normalAngle: Number): Object{
var vector_angle: Number = Math.atan2(speedY, speedX) * (180/Math.PI);
var rotating_angle: Number = (2*(normalAngle - vector_angle) + 180) % 360;
var cos_ang: Number = Math.cos(rotating_angle/DEGREES_OF_1RAD);
var sin_ang: Number = Math.sin(rotating_angle/DEGREES_OF_1RAD);
var final_speedX: Number = speedX * cos_ang - speedY * sin_ang;
var final_speedY: Number = speedX * sin_ang + speedY * cos_ang;
return {x_speed: final_speedX, y_speed: final_speedY};
}
This is how the new speed vector is calculated...
My question is, has anyone faced this kind of problem or has some idea on how to avoid this from happening?
Without seeing your code, this is the best I can provide.
Collision physics should have some velocity threshold that is considered "stopped". That is, once the velocity gets small enough you should explicitly mark an object as stopped and exempt it from your collision code. This will help stabilize slow moving objects. Trial and error is required for a good threshold.
When a collision happens, it is important to at least attempt to correct any inter-penetration. This is most likely the reason why tangent collisions are behaving strangely. Attempt to move the colliding object away from what it hit in a reasonable manner.
Your method of determining the normal should work fine. Game physics is all about cheating (cheating in a way that still looks good). I take it rotation and friction isn't a part of what you're going for?
Try this. You have the contact normal. When you detect a collision, calculate the penetration depth and move your object along the normal so that is isn't penetrating anymore. You can use the two points you have already calculated to get one point of penetration, you'll need to calculate the other though. For circles it's easy (center point + radius in direction of normal). There are more complex ways of going about this but see if the simple method works well for you.
I have read and recommend this book: Game Physics Engine Development
I did something a little like that and got a similar problem.
What I did is that when the pixels from the bouncing object (a ball in your case) overlap with the pixels from the obstacle, you need to move the ball out of the obstacle so that they are not overlapping.
Say the ball is rolling on the obstacle, before your render the ball again you need to move it back by the amount of 'overlap'. If you know at what angle the ball hit the obstable just move it out along that angle.
You also need to add some damping otherwise the ball will never stop. Take a (very) small value, if the ball velocity is bellow that value, set the velocity to 0.
You can try one more thing, which I think is very effective.
You can make functions such as getNextX() and getNextY()(Which of course give their position coordinated after the next update) in your game objects and Check collision on objects based on their next position instead of their current position.
This way, the objects will never overlap, you'll know when they are about collide and apply your after collision physics gracefully!