When I make a lot of bodies (rectangles) stacked on each other they don't stand stable. Even if restitution is set to 0. They are bouncy and fall off each other. I tried setting the density to a very low value, but it didn't change.
Is there a possibility to fix that?
shape.setAsBox(0.1f, 0.1f, new Vector2(0, 0), 0);
bDef = new BodyDef();
bDef.type = BodyDef.BodyType.DynamicBody;
bDef.position.set(0, 0);
fDef.shape = shape;
fDef.density = 0.001f;
fDef.friction = 0.5f;
fDef.restitution = 0.0f;
for (int i = 1; i < 50; i++) {
bDef.position.set(0, i * 0.201f);
body1 = world.createBody(bDef);
fixture = body1.createFixture(fDef);
}
So long as this is the problem that I think it is, then yes, this is fixable. Albeit with additional work. But in the short term, no.
When I run the "Vertical Stack" test of the Testbed from Box2D 2.3.2, I see a bunch of boxes drop down on top of each other in a vertical stack. At first they stack, then they wobble, then they tip over. This is how Box2D is designed to work. I didn't like that behavior so I changed it.
I suspect that this is essentially the same problem as you are seeing. The "fix" I used to modify this and gain a stable stacking behavior, involves changing the internal Box2D library code.
Algorithmically speaking, I modified the way position resolution is done from resolving impulses being applied one collision manifold point at a time, to resolving impulses being applied in order of penetration depth or simultaneously when they're almost equal. Code wise, I essentially made this algorithmic change to Erin's b2ContactSolver::SolvePositionConstraints and b2ContactSolver::SolveTOIPositionConstraints methods (in Erin's b2ContactSolver.cpp).
Code for this altered algorithm is in the dev branch of my fork of Box2D (see the SolvePositionConstraint function in the ContactSolver.cpp file). Unfortunately, I don't have a diff that would just apply to those methods as my code changes extend beyond those. Additionally, the changes that I've made modify the Box2D library public interface so even if you can get it to build for your platform, you'll still need to adapt your code to the new interface I have.
Related
I'm developing a cocos2d-x game (version 3.8). My game uses chipmunk physics and it has a static body that works like an interruptor. This interruptor is enabled when another body is over it. The interruptor is disabled when bodies separate each other.
I want to:
Moving body don't collision with interruptor. It has to cross interruptor with no bounce
I want to detect when moving body separates the interruptor
My first approach was implementing onContactBegin method. I return false when those two bodies get in touch. This way the body crosses the interruptor and does not bounce.
The problem is onContactSeparate method is not called, because contact did not happen.
If I return true in onContactBegin method, onContactSeparate is called and I can detect it. The problem is the body does not cross the interruptor, it bounces.
[EDIT] More info
This is the scenario where two sprites are separated. The ball can move and interruptor is a static body. Ball could be over the interruptor.
This is the scenario where two sprites are in contact and object1 (the ball) is over the interruptor. I want to detect where two sprites separate each other.
Any help would be appreciated!
It seems to me like you are using Box2D within cocos, so I'll answer with that as my base assumption.
This is what i would do.
My interrupter would be a b2Body* with no BodyDef dimensions defined or just a 0x0 dimension def.
I would set the user data for the bodyDef to a rectangle that describes my interruption area. This way you can always have your interruption area represented, but will not collide with anything.
(Optional) If you want the interruption area to move around based on the fake body you assigned to it, you can updated it just after the step function using something like below.
world->Step(delta, 10, 10);
for (auto physicsBody = _world->GetBodyList(); physicsBody; physicsBody = physicsBody->GetNext())
{
auto userData = static_cast<Node*>(physicsBody->GetUserData());
if(userData != NULL)
{
// Set interruptor area rectangle = physicsBody->GetPosition();
}
}
To let the rest of the system know when I have left the interrupter I would store a function pointer to the function I want to call when this happens, When a object enters the interruption area I would flag it saying "I'm in the area" after that, the first update step you get when it's not in the area anymore I would fire the callback and reset the flags I used to get to that point.
I hope this helps. You are not giving a lot of context for what you want to do, an image would be helpful. Especially when it comes to looking for help with code that has a visual representation as well.
[EDIT]
Based on the behaviour you want this is the way I did this. The first thing to know is that you don't need physics collisions for the behaviour you want. You can do this by using bounding box intersection tests and use flags and callbacks to figure out the rest.
I have an object that knows about both the ball and my interrupter nodes. In the update loop of this object I check if the two intersects. I set a flag indicating "I am in the interrupter", the next frame that I am not in the interrupter and my flag is still true I call the function that I assigned with my "leaving logic" in it, and set then flag back to false.
This may be an issue that I simply do no know the proper terminology to research the answer to this, I am pretty sure the solution is a function of trig.
I have a method which accepts an X/Y position coordinate and an angle in degrees. It should return an updated X/Y based on the rotation angle provided.
For example, A point is usually located at x=0,y=2 (top middle). Now I need to rotate it to it's side by 90 degrees. In my mind I know it's location is now x=2,y=0 (middle right) but I do not know the equation to produce this.
I think I need to first determine the quadrant of the starting point, and then perform the proper trig function from there. This is for a game I am developing using libgdx which is where the Vector2 object comes from.
I have come this far:
public Vector2 getPointsRotated(Vector2 startPoint, float angle){
Vector2 newPoint = new Vector2(0,0);
// determine the starting quadrant
int quad=0;
if((startPoint.x>=0)&&(startPoint.y>=0)){quad=0;}
if((startPoint.x<0)&&(startPoint.y>=0)){quad=1;}
if((startPoint.x<0)&&(startPoint.y<0)){quad=2;}
if((startPoint.x>=0)&&(startPoint.y<0)){quad=3;}
if(quad==0){
// doesn't work
newPoint.x = (float) ((newPoint.x)* (Math.sin(angle)));
newPoint.y = (float) ((newPoint.y)* (Math.cos(angle)));
}
// ...
// other quadrants also don't work
// ...
return newPoint;
}
Thanks for any help.
Update:
I have been avoiding and returning to this problem for a few days. Now after finally posting the question here I figure it out within minutes (for ppl using libgdx anyway).
Libgdx provides a rotate function for Vector2s
so something like:
Vector2 position = new Vector2(0,2);
position.rotate(angle);
works perfectly.
I find rotation matrices are very helpful for this sort of problem.
https://gamedev.stackexchange.com/questions/54299/tetris-rotations-using-linear-algebra-rotation-matrices
I am making an achtung die kurve-like game in AS3.0. So far I've done the movements of the 4 different players, and it works alright.
I am now to make collision detection, in order to test if a 'worm'-so to speak, is colliding with eachother or its own tail.
As I understand it, if I use hitTestObject(); it will use the registration area of the whole object, which would be a huge problem, seeing since this registration makes a 4-sided registration that contains all of the object. So if this is used, it will 'collide' just by entering this rectangle instead of hitting the actual worm. Is this correctly understood?
I've been looking through different methods of collision detection, and can't seem to find an optimal one for my project.
My thought were to check if the 'worms' are drawing their new sprites on a white background. if they aren't, then it must have hit something.
You can see how I used my code here: code in .as format linked to an .fla file
Sorry for my ill-formulated question, hope it makes somewhat sense.
Any help is greatly appreciated!!
Best regards - Jesper
Try this function if you want a Pixel Perfect Collision Detection with efficient CPU usage:
trace("Collided: " + (areaOfCollision(mc1, mc2) != null));
trace("Where: " + areaOfCollision(mc1, mc2));
function areaOfCollision(object1:DisplayObject, object2:DisplayObject, tolerance:int = 255):Rectangle {
if (object1.hitTestObject(object2)) {
var limits1:Rectangle = object1.getBounds(object1.parent);
var limits2:Rectangle = object2.getBounds(object2.parent);
var limits:Rectangle = limits1.intersection(limits2);
limits.x = Math.floor(limits.x);
limits.y = Math.floor(limits.y);
limits.width = Math.ceil(limits.width);
limits.height = Math.ceil(limits.height);
if (limits.width < 1 || limits.height < 1) return null;
var image:BitmapData = new BitmapData(limits.width, limits.height, false);
var matrix:Matrix = object1.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object1, matrix, new ColorTransform(1, 1, 1, 1, 255, -255, -255, tolerance));
matrix = object2.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object2, matrix, new ColorTransform(1, 1, 1, 1, 255, 255, 255, tolerance), BlendMode.DIFFERENCE);
var intersection:Rectangle = image.getColorBoundsRect(0xFFFFFFFF, 0xFF00FFFF);
if (intersection.width == 0) return null;
intersection.offset(limits.left, limits.top);
return intersection;
}
return null;
}
After a successful preliminary hitTestObject(), this function backgroundly takes a snapshot from the shapes of both objects painted with different colors each, then overlays them intersecting the colors on a new one, returning the Rectangle of the resulting shape. So cool.
To learn more about Pixel Perfect Collision Detection you can google Collision Detection followed by one of these names: "The ActionScript Man", "Troy Gilbert", "Boulevart (wim)", "Grant Skinner (gSkinner)" or "Senocular". Those guys are awesome AS3 references by the way.
The problem you discribe is a very common problem for collission detection because the object has a set width and height and therefor defines a rectangle as the object.
There is a solution however to make a colission detection system on pixel level I have found this on the official site and this made me able to make collission detection for bitmaps on pixel level.
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d55.html
hope it helps you out in the same way.
Looking at the screenshots of that game, I think the best model would be to describe each worm as a chain of circles. Then divide the world/level in a grid with cells somewhat larger than the circle radii.
The collision check would then be:
clear grid
place each circle into the 1 or more grid cells it falls in
iterate over all cells, for each cell:
for each pair of circles (partially) in this cell, check if they intersect. If they do; collision.
Note that this may result in more than 1 collision occurrence between circle A and B, so you'd also need to check that to avoid duplicates.
Step 1 and 2 can be optimized by not clearing the grid, and instead of step 2, updating each circle's cell after it moves. If you size your cells like 5x the size of a circle, a circle can stay in the same cell for a few frames, avoiding excessive add/remove operations.
I'm doing something similar in a project of mine right now, except with space ships! My grid cells are currently 256x256 (too big for your project I think) and my units have radii of about 20.
I'm using a flip mechanism to navigate through my site (flip file & demo). The problem is, once it's flipped the content been displayed good just like I want it, but there's some offset from the flipped (right) parts en the solid left part (visible when you look closely). Also the right part is now a little blurred (which is the disturbing part of my issue). This all caused by the flip (I think the rotationY is causing the problem).
When I click a button I do the following:
flip=new Flip(currentPage,nextPage,richting);
content.addChild(flip);
currentPage=nextPage;
nextPage = new MovieClip();
there is a fix for it, consider the following:
// store original matrix
var origMatrix:Matrix = box.transform.matrix;
// set initial position
box.rotationY = -180;
// start animation
TweenLite.to(box, 1, {rotationY:0, onComplete:cleanBlur})
// execute after animation complete
function cleanBlur():void {
box.transform.matrix = origMatrix;
}
maybe you can find better results using other 3d library.
EDIT: sorry the "box" object, I was testing in flash, but box would be any of your pages to flip. Just apply the same logic.
Matteo at Flash & Math has an excellent solution for this. He actually found that when you bring an object into native 3D space it expands the object by one pixel in both the width and height. This can be counteracted by scaling your object back and then setting it's z to 0 which will scale it back up. Now the object is ready to play with without the blur.
http://www.flashandmath.com/flashcs4/blursol/index.html
adding: This fixes the scale issue, but not the blurriness. You will still need to use the matrix transformation fix posted above.
I'd like to display 100 floating cubes using DirectX or OpenGL.
I'm looking for either some sample source code, or a description of the technique. I have trouble getting more one cube to display correctly.
I've combed the net for a good series of tutorials and although they talk about how to do 3D primitives, what I can't find is information on how to do large numbers of 3D primitives - cubes, spheres, pyramids, and so forth.
You say you have enough trouble getting one cube to display... so I am not sure if you have got one to display or not.
Basically... put your code for writing a cube in one function, then just call that function 100 times.
void DrawCube()
{
//code to draw the cube
}
void DisplayCubes()
{
for(int i = 0; i < 10; ++i)
{
for(int j = 0; j < 10; ++j)
{
glPushMatrix();
//alter these values depending on the size of your cubes.
//This call makes sure that your cubes aren't drawn overtop of each other
glTranslatef(i*5.0, j*5.0, 0);
DrawCube();
glPopMatrix();
}
}
}
That is the basic outline for how you could go about doing this. If you want something more efficient take a look into Display Lists sometime once you have the basics figured out :)
Just use glTranslatef (or the DirectX equivalent) to draw a cube using the same code, but moving the relative point where you draw it. Maybe there's a better way to do it though, I'm fairly new to OpenGL. Be sure to set your viewpoint so you can see them all.
Yeah, if you were being efficient you'd throw everything into the same vertex buffer, but I don't think drawing 100 cubes will push any GPU produced in the past 5 years, so you should be fine following the suggestions above.
Write a basic pass through vertex shader, shade however you desire in the pixel shader. Either pass in a world matrix and do the translation in the vertex shader, or just compute the world space vertex positions on the CPU side (do this if your cubes are going to stay fixed).
You could get fancy and do geometry instancing etc, but just get the basics going first.
This answer isn't just for OP's question. It also answers a more general question - displaying many cubes in general.
Drawing many cube meshes
This is probably the most naive way of doing things. We draw the same cube mesh with many different transformation matrices:
prepare();
for (int i = 0; i < numCubes; i++) {
setTransformation(matrices[i]);
drawCube();
}
/* and so on... */
The nice thing is that this is SUPER easy to implement, and it's not too slow (at least for 100 cubes). I'd recommend this as a starter.
The problem
Ok, but let's say you want to make a Minecraft clone, or at least some sort of project that requires thousands, if not tens of thousands of cubes to be rendered. That's where the performance starts to go down. The problem is that each drawCube() sends a draw call to the GPU, and the time in each draw call adds up, so that eventually, it's unbearable.
However, we can fix this. The solution is batching, a way to do only one draw call for all of the cubes.
Batching
We join all the (transformed) cubes into one single mesh. This means that we will have to deal with only one draw call, instead of thousands. Here is some pseudocode for doing so:
vector<float> transformedVerts;
for (int i = 0; i < numCubes; i++) {
cubeData = cubes[i];
for (int j = 0; j < numVertsPerCube; j++) {
vert = verts[j];
/* We transform the position by the transformation matrix. */
vec3 vposition = matrices[i] * verts.position;
transformedVerts.push(vposition);
/* We don't need to transform the colors, so we just directly push them. */
transformedVerts.push(vert.color);
}
}
...
sendDataToBuffer(transformedVerts);
If the cubes are moving, or one of the cubes is added or deleted, you'll have to recalculate transformedVerts and then resend it to the buffer - but this is minor.
Then at the end we draw the entire lumped-together mesh in one draw call, instead of many.