Avoid ground collision with Bullet - c++

I'm trying to use Bullet physic engine to create a 3D world.
I've got my character with a Capsule shape on his body and my ground his made of some static blocs stick together, here is a schema to illustrate my words:
The problem is present when my character run from one block to another: Bullet detect a collision and my character start to jump a little bit on y-axis.
How can I avoid the problem?

What I did to overcome this issue is the following:
Instead of have the capsule slide on the ground, I had a dynamic capsule ride on top of a spring.
I implemented the spring as several ray casts originating from bottom of the capsule.
The length of the spring was like half a meter or less and it would pull and push the capsule to and from the ground.
The grip/pull is important so the character wouldn't jump unexpectedly.
The springs stiffness controls how much bobbing you have.
This had the following effects
No unwanted collision with edge of geometry on the floor, since the capsule floats
Walking up stairs and slopes implemented implicitly. The spring would just "step" onto the stair's step and push the character capsule up.
Implementation of jumping was just matter of releasing the grip on the ground the spring had and giving the body an impulse.
A landing character after a jump or fall automatically displayed "knee-bending" as you would expect
Pleasant smoothing of vertical movements in general. Like on elevator platforms etc.
Due to the grip/pull to the ground, even when running downhill the character would not start to "fly" as you experience in some games (I find that annoying typically).
Ducking character = decrease the length of the spring and/or the capsule.
Sliding downhill? You can fully control it by checking the angles of the floor area the ray cast of the spring hit.
I had to play around a lot with the stiffness of the spring, the length of the spring, the length of the grip etc. but in the end I was very happy about how simple yet well this worked.

Your problem caller "Internal Edge Collision". I just found the solution few our hour ago.
If you are using btHeightfieldTerrainShapefor your world then you must use btBvhTriangleMeshShape to slove this problem.
Here is the answer.
Add this callback:
static bool CustomMaterialCombinerCallback(btManifoldPoint& cp,const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
{
btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1);
return true;
}
extern ContactAddedCallback gContactAddedCallback;
Afterwards create the btBvhTriangleMeshShape and add this code where pGround is your btBvhTriangleMeshShape:
// Enable custom material callback
pGround->setCollisionFlags(pGround->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
btGenerateInternalEdgeInfo(pGroundShape, triangleInfoMap);
Or you can open the InternalEdgeDemo example in Bullet to see how to implement it in detail.

Related

How to apply Orbital Gravity in cocos2d chipmunk

I am building an IOS game in Cocos2d - Chipmunk - Spritebuilder. I need to make a characters orbit around around a point, and I was having quite some difficulty in implementing orbits with real physics.
So far, I have tried two methods, one is creating a distance joint from the player to the planet, and then applying a 90 degree force on the player where an angle is created between the end of the distance joint and an imaginary line drawn at a 90 angle to it. He moves around crazily and this method is not working for me.
I then tried calculating 180 points on the circumference at a radius from the planet (which is the bounds of detecting and implementing its effects on the player) - and then in a scheduled update method [character.physicsbody applyForce:nextCircumferencePoint]; This does not work, as he does not follow the path exactly and is quite far from it. I am thinking that I need to also apply a gravitational force towards the planet which would cause him to circle it. Though I don't know how to calculate that force, apply it, or if it would even help.
A third method which would never work, but was used for testing was to set his position to the next circumference point. He does orbit, but any collision won't work (such as if a piece of space junk goes in his way.) He will simply be positioned right over any other object. This world great if you don't need collisions, are writing your own physics engine. This is not a polished way of doing things, so will avoid it.
Please correct anything I have already done and tell me how it would work, or shed light on other options and how to implement them.
Check out my answer here. It's for box2d, but you can do it with Chipmunk. If bodyA position will change, orbit will be same. You just need to change speed of body movement for your needs, just increase smoothness and slow down your update method.

Keeping Velocity Constant and Player in Position - Sidescrolling

I'm working on a Little Mobile Game with Cocos2D-X and Box2D.
The Point where I got stuck is the movement of a box2d-body (the main actor) and the according Sprite. Now I want to :
move this Body with a constant velocity along the x-axis, no matter if it's rolling (it's a circleshape) upwards or downwards
keep the body nearly sticking to the ground on which it's rolling
keep the Body and the according Sprite in the Center of the Screen.
What I tried :
in the update()- method I used body->SetLinearVelocity(b2Vec2(x,y)) to higher/lower values, if the Body was passing a constant value for his velocity
I used to set very high y-Values in body->SetLinearVelocity(b2Vec2(x,y))
First tried to use CCFollow with my playerSprite, which was also Scrolling along the y-axis, as i only need to scroll along the x-axis, so I decided to move the whole layer which is containing the ambience (platforms etc.) to the left of my Screen and my Player Body & Player sprite to the right of the Screen, adjusting the speed values to Keep the Player in the Center of the Screen.
Well...
...didn't work as i wanted it to, because each time i set the velocity manually (I also tried to use body->applyLinearImpulse(...) when the Body is moving upwards just as playing around with the value of velocityIterations in world->Step(...)) there's a small delay, which pushes the player Body more or less further of the Center of the Screen.
... didn't also work as I expected it to, because I needed to adjust the x-Values, when the Body was moving upwards to Keep it not getting slowed down, this made my Body even less sticky to the ground....
... CCFollow did a good Job, except that I didn't want to scroll along the y-axis also and it Forces the overgiven sprite to start in the Center of the Screen. Moving the whole Layer even brought no good results, I have tried a Long time to adjust values of the movement Speed of the layer and the Body to Keep it negating each other, that the player stays nearly in the Center of the Screen....
So my question is :
Does anyone of you have any Kind of new Approach for me to solve this cohesive bunch of Problems ?
Cheers,
Seb
To make it easy to control the body, the main figure to which the force is applied should be round. This should be done because of the processing mechanism of collisions. More details in this article: Why does the character get stuck?.
For processing collisions with the present contour of the body you can use the additional fixtures and sensors with an id or using category and mask bits. For of constant velocity is often better to use SetLinearVelocity, because even when using impulse velocity gets lost at sharp uphill or when jumping. If you want to use the implulse to change the position of the body, then you need to use the code for the type of this:
b2Vec2 vel = m_pB2Body->GetLinearVelocity();
float desiredVel = mMoveSpeed.x; //set there your speed x value
float velChange = desiredVel - vel.x;
float impulse = m_pB2Body->GetMass() * velChange;
m_pB2Body->ApplyLinearImpulse( b2Vec2(impulse, mMoveSpeed.y), m_pB2Body->GetWorldCenter());
This will allow maintain a constant speed most of the time. Do not forget that these functions must be called every time in your game loop. You can combine these forces, depending on the situation. For example, if the at the beginning you need to make a small acceleration, it is possible to use ApplyForce to the body, and when a desired speed is to use ApplyLinearImpulse or SetLinearVelocity. How correctly to use it is described here: Moving at constant speed
If you use world with the normal gravity(b2Vec2(0, -9.81)), then it should not be a problem.
I answer for this question here: Cocos2D-x - Issues when with using CCFollow. I use this code, it may be useful to you:
CCPoint position = ccpClamp(playerPosition, mLeftBounds, mRightBounds);
CCPoint diff = ccpSub(mWorldScrollBound, mGameNode->convertToWorldSpace(position));
CCPoint newGameNodePosition = ccpAdd(mGameNode->getPosition(), mGameNode->getParent()->convertToNodeSpace(diff));
mGameNode->setPosition(newGameNodePosition);
P.S. If you are new to box2d, it is advisable to read all the articles iforce2d(tuts), they are among the best in the network, as well as his Box2D Editor - RUBE. At one time they really helped me.
I do not know if this is possible but I have an idea:
Keep the circle at a fixed position and move the background relatively. For example, during the course of the game, if the circle has a velocity of 5 towards left then keep circle fixed and move screen with velocity 5 towards right. If circle has 5 velocity towards left and screen has 3 velocity towards right, then keep circle fixed and move screen with 8 velocity towards left and so on. This should allow you to fix the circle at the center of the screen.
Another method would be to translate the entire screen along with the ball. Make everything on the screen an object that can have a velocity. And the x-component of the velocity of the ball (circle) should be the velocity of all other objects. This way, whenever the circle moves, all the other objects will try and keep up with it.

Minecraft like collision

I'm working on a Minecraft like game for educational purposes. The rendering is great so far even with 1024x1204 blocks but now that I started integrating the player collision I'm having problems.
I have a aabb for the player and aabb's for all the blocks around him. These are created dynamically and it works out pretty fast.
My problem goes as following:
I have speed vector and the current position. For each axis I calculate the potential position and make out an aabb. I check for collisions and it's free I move there otherwise I set the speed for that component to 0. I separate the axis since I want my player to slide in a direction of partially facing a wall.
The order for the axis is y,x,z. The collision response is great but I'm having some problems with the corners as it sometimes get's stuck in the world without being able to move. Not sure what the reason is for this.
I do not want to implement actual physics since those are more demanding and basically just too much for what I need.
Do you guys have any suggestions on how to implement this in a nice way? I did some searching but I didn't find anything useful for this particular situation.
This is a bit abstract in a sense that the cause of your problem can be related to many things. From the top of my head, maybe a bug in your collision detection code: somehow it allows the objects to cross boundaries by 1 (or more) unit. So when the next collision is computed 1 or more dimension is stuck (imagine having an arm already inside the wall when collision is detected. You can't get your arm out because it collide with the interior of the wall boundary)

Box2D small pocket hole creation

I have a simple question about a game I am making using box2D and cocos2D. I started using the physics engine yesterday so I am rather inexperienced with its usage and capabilities. My game involves rolling a ball around the screen using the accelerometer. I want to add holes to the ground that if the ball rolls into, it will then require a greater acceleration via the accelerometer to escape the hole pocket. I've toyed with friction, linear damping, modifying the accelerometer's gravity vector, and tried adding attractive forces but I haven't had too much success and some of it doesn't really simulate well what I want happening. Basically I just want to create some sensors and give them the properties of a small pocket a ball can fall in to. Any tips and advice is much appreciated. Thanks
I suggest you to use Level Helper . Its an awesome tool to create physic based games.
You can find it here
You could take the y position of the ball every frame and if it is below a certain threshold, then it is in a hole. Based off on this, if the ball is in a hole, reduce the sensitivity. When the ball exits the hole, put the sensitivity back to normal.
As for creating the holes, use Vertex Helper to create bodies that will correspond to your sprites.
If you need more explanation, feel free to ask.
Elaborated:
Now, basically in the picture, I am depicting what I tried to describe earlier. All you really have to do is to change the tilt sensitivity if the player's Y position is below a certain point. I just used 50 as an example.
Some pseudocode:
- (void)update:(ccTime)dt
{
if (player.position.y >= 50) { //If the player's y position is above or equal to 50
if (sensitivity != normalSensitivity) { //We don't need to set it every frame, so lets check
sensitivity = normalSensitivity;
}
}
if (player.position.y < 50) { //If player's position is below our threshold of 50
if (sensitivity != limitedSensitivity) { //Check so we don't set the sensitivity every frame
sensitivity = limitedSensitivity;
}
}
}
Now, as far as Vertex Helper is concerned, it is an open source tool (I believe) that helps you define vertices for custom shapes that can then be copied and pasted directly into your box2d or chipmunk cocos2d project. It can be fond here.
I suggest googling around for tutorials on how this is used. It is very simple, but you may need a quick reference to get you started.
Finally, something to remember, is that box2d can only work with convex shapes, not concave.
A convex shape is a shape where in is impossible to draw a line from any vertex to another without passing through the shape itself. Basically something that has no indentations in it.
I hope this helped. I'm not sure I can elaborate anymore than I have, but if you have more specific questions, feel free to ask.

Box2d dynamic bullet body sinking into static bodies

I'm making a game in cocos2d with box2d and I'm running into some issues.
I have the program iterate through a tilemap's (.tmx) rows and columns , searching for tiles with a "collidable" property set to "true". If one is found, a square static box2d body (with fixtures and all) is set at that tile's position. So essentially, I should end up with a bunch of square bodies set up where I need them (depending on the tilemap) after the iteration is complete. I also have a square dynamic body that is controlled by gesture (up gesture slides it upward, down gesture downward, etc.), and it is supposed to only move in one of four directions: up, down, left, right. The restitution of the body is 0.0f so that it stops on impact with no rebound, and the friction is 0.0f as well because it's not needed (gravity of the world is 0.0f, 0.0f too). Since the iteration through the tilemap can only place bodies that are square, the "walls" in the game are composed of several of these squares lined up adjacent to each other, end to end, which creates a flush edge for the dynamic body to collide with.
The problem arises when the dynamic body collides with the wall of squares. I control movement of the body by setting the velocity of the body according to the gesture. An example of movement to the right would be:
#define bodyVel 100
...
if (gestureRight)
{
body->SetLinearVelocity( b2Vec2(bodyVel / PTM_RATIO, 0) );
}
I have the body set as a bullet so that when it collides with the wall it will not become embedded, but I have encountered some weird results. An example would be this:
I move the body rightwards into a wall and it stops. Good. Next, I want to move it up, so I gesture upwards. Good. But then, at times, as it is sliding up the wall, the body seems to "catch" on to something and it spins out of control and in multiple directions. Bad.
The only explanation I can come up with is that the dynamic body is in fact becoming imbedded in the wall upon the first head on contact, and as it slides up the wall upon the next given gesture for movement, it gets caught on the one of edges of the squares that make up the wall and becomes jarred from a straight path. I confirmed this strange activity by setting the body to have a fixed rotation (not rotate at all), and consequently, instead of the body spinning out of control, it would simply stop. This was expected given my hypothesis. So the dynamic body is becoming embedded is what I'm trying to say.
I don't understand why this is happening because I have the body set to behave like a bullet to avoid problems exactly like this. All I want the object to do is be able to move along a straight path - either up, down, left, or right -, stop upon contact with a wall, and move along the wall without interference from the bodies that make up the wall.
I feel like unless I have a misunderstanding of how bullet bodies work, the embedding that is occurring should not be an issue.
I also used to DebugDraw to see if the square static bodies created a flush wall and they did.
Unfortunately, this is a known issue in Box2d... from the FAQ:
Tile Based Environment
Using many boxes for your terrain may not work well because box-like
characters can get snagged on internal corners. A future update to
Box2D should allow for smooth motion over edge chains. In general you
should avoid using a rectangular character because collision
tolerances will still lead to undesirable snagging.
For more information see this post:
http://box2d.org/forum/viewtopic.php?f=3&t=3048