I don't know what i've done wrong. I get a SIGABRT error and I guess it's got to do with the for loop in the code below. Could someone please help me out. Thanks in Advance.
b2BodyDef ropeBodyDef;
ropeBodyDef.linearDamping = 0.2;
ropeBodyDef.angularDamping = 0.2;
ropeBodyDef.userData = ropeSprite;
b2Body *ropeBody;
b2Body *ropeStart = starBody;
b2MassData ropeMassData;
ropeMassData.mass = 1;
ropeBody->GetMassData(&ropeMassData);
b2DistanceJointDef ropeJointDef;
b2DistanceJoint *ropeJoint;
float dY = starBody->GetPosition().y - fittingBody->GetPosition().y;
int numSections = ceil(dY/ 55);
for (float i = 0; i < numSections - 1; i++) {
// one rope section body
ropeBodyDef.position.Set(0, starBody->GetPosition().y - dY * i/numSections);
ropeMassData.mass = 0.8 + 0.8 * i / numSections;
// rope body
ropeBody = world->CreateBody(&ropeBodyDef);
ropeFixture = ropeBody->CreateFixture(&ropeShapeDef);
[ropeSegments addObject:[NSValue valueWithPointer:ropeBody]];
// one rope section to another
ropeJointDef.Initialize(ropeStart, ropeBody, ropeStart->GetPosition(), ropeBody->GetPosition());
ropeJoint = (b2DistanceJoint*)world->CreateJoint(&ropeJointDef);
ropeJoint->SetLength(dY / numSections);
// update startpoint for next joint
ropeStart = ropeBody;
}
// final rope joint
ropeJointDef.Initialize(ropeStart, ropeBody, ropeStart->GetPosition(), ropeBody->GetPosition());
ropeJoint = (b2DistanceJoint*)world->CreateJoint(&ropeJointDef); // THIS IS THE LINE THAT I GET THE SIGABRT
ropeJoint->SetLength(dY / numSections);
[ropeSegments addObject:[NSValue valueWithPointer:fittingBody]];
You just declare ropeBody the first line below and you already call a method on it without initializing and assigning its value:
b2Body *ropeBody; <-- declare here
b2Body *ropeStart = starBody;
b2MassData ropeMassData;
ropeMassData.mass = 1;
ropeBody->GetMassData(&ropeMassData); <-- uh, ropeBody is null or rubbish pointer
Related
i'm making a side-scrolling car game with box2D.
I'm currently working on the car and it seems that i'm stuck.
The chassis of my car isn't rotating when for example the car is trying to climb a hill. I don't know if its normal or if i should set the angle of the body.
Here's a quick video that shows the problem : https://streamable.com/d802n
This is my code :
b2BodyDef carBox = b2BodyDef();
carBox.position = b2Vec2(bodyCenterPosition.x, bodyCenterPosition.y);
carBox.type = b2_dynamicBody;
car = game->getWorld()->CreateBody(&carBox);
b2PolygonShape carPolygon = b2PolygonShape();
carPolygon.SetAsBox(bodySize.x, bodySize.y);
b2FixtureDef carFix = b2FixtureDef();
carFix.density = 0.0f;
carFix.shape = &carPolygon;
car->CreateFixture(&carFix);
b2PolygonShape headPolygon = b2PolygonShape();
headPolygon.SetAsBox(headSize.x, headSize.y);
for (int i = 0; i < 8; i++) {
headPolygon.m_vertices[i].x -= 8.0f / RATIO;
headPolygon.m_vertices[i].y -= 24.0f / RATIO;
}
b2FixtureDef headFix = b2FixtureDef();
headFix.density = 0.0f;
headFix.shape = &headPolygon;
car->CreateFixture(&headFix);
b2CircleShape circleShape;
circleShape.m_radius = 0.35f;
circleShape.m_p.SetZero();
b2FixtureDef fd;
fd.shape = &circleShape;
fd.density = 1.0f;
fd.friction = 0.9f;
b2BodyDef wheel1Def;
wheel1Def.type = b2_dynamicBody;
wheel1Def.position = b2Vec2(backWheelCenterPosition.x, backWheelCenterPosition.y);
backWheel = game->getWorld()->CreateBody(&wheel1Def);
backWheel->CreateFixture(&fd);
b2BodyDef wheel2Def;
wheel2Def.type = b2_dynamicBody;
wheel2Def.position = b2Vec2(frontWheelCenterPosition.x, frontWheelCenterPosition.y);
frontWheel = game->getWorld()->CreateBody(&wheel2Def);
frontWheel->CreateFixture(&fd);
b2WheelJointDef springDef1;
springDef1.dampingRatio = 50.0f;
springDef1.maxMotorTorque = 1.0f;
springDef1.frequencyHz = 15.0f;
springDef1.motorSpeed = 0.0f;
springDef1.enableMotor = true;
springDef1.Initialize(car, backWheel, backWheel->GetPosition(), sfVecToB2Vec(sf::Vector2f(0.0f, 1.0f)));
backSpring = (b2WheelJoint*) game->getWorld()->CreateJoint(&springDef1);
springDef1.Initialize(car, frontWheel, frontWheel->GetPosition(), sfVecToB2Vec(sf::Vector2f(0.0f, 1.0f)));
frontSpring = (b2WheelJoint*) game->getWorld()->CreateJoint(&springDef1);
It is normal for a body with a fixture having a zero density to behave like an infinite mass. Sounds like that's not what you intended however.
Looking at the code presented, we see that the carFix.density and headFix.density are being set to 0.0f. Set these to a positive non-zero value, like 1.0f, and the dynamic body they're created on should behave more like a physical mass would. That's assuming all of the other fixtures created on that body also have a density that's greater than zero as well.
For a tutorial on fixtures and density, I'd recommend taking a look at iforce2d's Box2D C++ tutorials - Fixtures.
Hope this solves the problem or at least helps.
By the way, I loved the artwork shown in the video!
i have a little trouble as title said: i can't figure out how to shoot the bullet toward the direction the gun is pointing at.
Here's short version code, for my bullet firing:
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.bullet = true;
bd.position = gun->GetPosition();//bullet start at the middle of the gun
m_bullet = m_world->CreateBody(&bd);
m_bullet->CreateFixture(&fd);
m_bullet->ApplyLinearImpulseToCenter( ??? ,true);
At first i thought first param is the direction you want the body go toward so i put in gun->GetWorldPoint(b2Vec2(0.0f,-5.0f)) (middle of the gun's muzzle). Big miss! After a while i thought i should try put in the vector of current gun's rotation degrees b2Vec2 vect = b2Vec2(cos(angle * PI/180), sin(angle * PI/180)); but then the bullet won't fly at all. Now i am all out of ideas. Please, some light.
Full version of code:
public:
b2Body* m_bullet = NULL;
b2Body* gun;
b2RevoluteJoint* joint1;
b2FixtureDef fd;
TestingStuff()
{
{
//body
b2CircleShape circle1;
circle1.m_radius = 1.6f;
fd.shape = &circle1;
fd.density = 1.0f;
fd.filter.groupIndex = -1;
b2BodyDef bd1;
bd1.type = b2_staticBody;
bd1.position.Set(-5.0f, 9.0f);
b2Body* body1 = m_world->CreateBody(&bd1);
body1->CreateFixture(&fd);
//gun
b2PolygonShape box;
box.SetAsBox(0.5f, 5.0f);
fd.shape = &box;
fd.density = 1.0f;
fd.filter.groupIndex = -1;
b2BodyDef bd2;
bd2.type = b2_dynamicBody;
bd2.position.Set(-5.0f, 8.0f);
gun = m_world->CreateBody(&bd2);
gun->CreateFixture(&fd);
//joint
b2RevoluteJointDef jd1;
jd1.Initialize(gun, body1, bd1.position);
jd1.enableMotor = true;
jd1.maxMotorTorque = 90;
jd1.motorSpeed = 180 * DEGTORAD;//DEGTORAD=0.0174532925199432957f
joint1 = (b2RevoluteJoint*) m_world->CreateJoint(&jd1);
}
}
void Keyboard(int key)
{
switch (key)
{
case GLFW_KEY_COMMA:
if (m_bullet != NULL)
{
m_world->DestroyBody(m_bullet);
m_bullet = NULL;
}
{
//bullet
b2CircleShape shape;
shape.m_radius = 0.25f;
fd.shape = &shape;
fd.density = 1;
fd.restitution = 0.05f;
fd.filter.groupIndex = -1;
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.bullet = true;
bd.position = gun->GetPosition();
m_bullet = m_world->CreateBody(&bd);
m_bullet->CreateFixture(&fd);
m_bullet->ApplyLinearImpulseToCenter( ??? ,true);
}
break;
}
}
After a good sleep i found the solution after few more trial and error.
//bullet
float degAngle = joint1->GetJointAngle() * RADTODEG + 180;
b2Vec2 vect = b2Vec2(sin(degAngle* (b2_pi / 180)) * 10, cos(degAngle* (b2_pi / 180)) * 10);
m_bullet->ApplyLinearImpulseToCenter(vect ,true);
The * 10 is to increase the impulse, make the bullet fly faster and farther, for the sake of testing i just make it 10. Notice that this code is just for testing, if you want to make it more realistic, increase the impulse as well as make the bullet go toward the muzzle instead of go toward the vector it had been fired at.
I stuck at this position and don't know what went wrong in this,
I have enabled ARC in my project. And i made softBody as follows
Ball.h
B2Body *body[NUM_SEGMENT];
CCSprite *ball;
Ball.mm
ball = [CCSprite spriteWithFile:#"Ball1.2.png"];
ball.tag = 1;
for(int i=0;i<NUM_SEGMENT;i++){
float theta = deltaAngle*i;
float x = radius * cosf(theta);
float y = radius * sinf(theta);
b2Vec2 circlePosition = b2Vec2(x/PTM_RATIO,y/PTM_RATIO);
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position = (center + circlePosition);
bodyDef.userData = &ball;
body[i] = world->CreateBody(&bodyDef);
outerBodyFixture[i]=body[i]->CreateFixture(&fixtureDef);
[bodies addObject:[NSValue valueWithPointer:body[i]]];
}
And I have given physics to the tiles as follows,
Tile.h
CCSprite *tile;
Tile.mm
tile = [layer1 tileAt:ccp(i, j)];
tile.tag = 0;
b2BodyDef tileDef;
tileDef.type = b2_staticBody;
tileDef.position.Set((tile.position.x+(tile.contentSize.width/2))/(PTM_RATIO), (tile.position.y + (tile.contentSize.height/2))/PTM_RATIO);
tileDef.userData = &tile;
tileBody = world->CreateBody(&tileDef);
Now i tried to catch collision detection and I have made code which will print the tag number of colliding bodies. The code is as follows,
std::vector<MyContact>::iterator pos;
for (pos=_contactListener->_contacts.begin();
pos != _contactListener->_contacts.end(); ++pos) {
MyContact contact = *pos;
b2Body *bodyA = contact.fixtureA->GetBody();
b2Body *bodyB = contact.fixtureB->GetBody();
if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
At this point Getting ERROR: EXC_BAD_ACCESS
CCSprite *spriteA = (__bridge CCSprite *) bodyA->GetUserData();
At this point Getting ERROR: EXC_BAD_ACCESS
CCSprite *spriteB = (__bridge CCSprite *) bodyB->GetUserData();
printf("contact :%d \n",spriteB.tag);
}
}
Don't Know whats wrong with this code,,Give me some solution for this
Your problem is that you store in userData a pointer to a pointer rather than the pointer itself.
tile is already pointing to a CCSprite instance and &tile points to a pointer to a CCSprite instance making your casting incorrect.
So change it to :
tileDef.userData = tile;
I have written some code to preform 3D picking that for some reason dosn't work entirely correct! (Im using LWJGL just so you know.)
This is how the code looks like:
if(Mouse.getEventButton() == 1) {
if (!Mouse.getEventButtonState()) {
Camera.get().generateViewMatrix();
float screenSpaceX = ((Mouse.getX()/800f/2f)-1.0f)*Camera.get().getAspectRatio();
float screenSpaceY = 1.0f-(2*((600-Mouse.getY())/600f));
float displacementRate = (float)Math.tan(Camera.get().getFovy()/2);
screenSpaceX *= displacementRate;
screenSpaceY *= displacementRate;
Vector4f cameraSpaceNear = new Vector4f((float) (screenSpaceX * Camera.get().getNear()), (float) (screenSpaceY * Camera.get().getNear()), (float) (-Camera.get().getNear()), 1);
Vector4f cameraSpaceFar = new Vector4f((float) (screenSpaceX * Camera.get().getFar()), (float) (screenSpaceY * Camera.get().getFar()), (float) (-Camera.get().getFar()), 1);
Matrix4f tmpView = new Matrix4f();
Camera.get().getViewMatrix().transpose(tmpView);
Matrix4f invertedViewMatrix = (Matrix4f)tmpView.invert();
Vector4f worldSpaceNear = new Vector4f();
Matrix4f.transform(invertedViewMatrix, cameraSpaceNear, worldSpaceNear);
Vector4f worldSpaceFar = new Vector4f();
Matrix4f.transform(invertedViewMatrix, cameraSpaceFar, worldSpaceFar);
Vector3f rayPosition = new Vector3f(worldSpaceNear.x, worldSpaceNear.y, worldSpaceNear.z);
Vector3f rayDirection = new Vector3f(worldSpaceFar.x - worldSpaceNear.x, worldSpaceFar.y - worldSpaceNear.y, worldSpaceFar.z - worldSpaceNear.z);
rayDirection.normalise();
Ray clickRay = new Ray(rayPosition, rayDirection);
Vector tMin = new Vector(), tMax = new Vector(), tempPoint;
float largestEnteringValue, smallestExitingValue, temp, closestEnteringValue = Camera.get().getFar()+0.1f;
Drawable closestDrawableHit = null;
for(Drawable d : this.worldModel.getDrawableThings()) {
// Calcualte AABB for each object... needs to be moved later...
firstVertex = true;
for(Surface surface : d.getSurfaces()) {
for(Vertex v : surface.getVertices()) {
worldPosition.x = (v.x+d.getPosition().x)*d.getScale().x;
worldPosition.y = (v.y+d.getPosition().y)*d.getScale().y;
worldPosition.z = (v.z+d.getPosition().z)*d.getScale().z;
worldPosition = worldPosition.rotate(d.getRotation());
if (firstVertex) {
maxX = worldPosition.x; maxY = worldPosition.y; maxZ = worldPosition.z;
minX = worldPosition.x; minY = worldPosition.y; minZ = worldPosition.z;
firstVertex = false;
} else {
if (worldPosition.x > maxX) {
maxX = worldPosition.x;
}
if (worldPosition.x < minX) {
minX = worldPosition.x;
}
if (worldPosition.y > maxY) {
maxY = worldPosition.y;
}
if (worldPosition.y < minY) {
minY = worldPosition.y;
}
if (worldPosition.z > maxZ) {
maxZ = worldPosition.z;
}
if (worldPosition.z < minZ) {
minZ = worldPosition.z;
}
}
}
}
// ray/slabs intersection test...
// clickRay.getOrigin().x + clickRay.getDirection().x * f = minX
// clickRay.getOrigin().x - minX = -clickRay.getDirection().x * f
// clickRay.getOrigin().x/-clickRay.getDirection().x - minX/-clickRay.getDirection().x = f
// -clickRay.getOrigin().x/clickRay.getDirection().x + minX/clickRay.getDirection().x = f
largestEnteringValue = -clickRay.getOrigin().x/clickRay.getDirection().x + minX/clickRay.getDirection().x;
temp = -clickRay.getOrigin().y/clickRay.getDirection().y + minY/clickRay.getDirection().y;
if(largestEnteringValue < temp) {
largestEnteringValue = temp;
}
temp = -clickRay.getOrigin().z/clickRay.getDirection().z + minZ/clickRay.getDirection().z;
if(largestEnteringValue < temp) {
largestEnteringValue = temp;
}
smallestExitingValue = -clickRay.getOrigin().x/clickRay.getDirection().x + maxX/clickRay.getDirection().x;
temp = -clickRay.getOrigin().y/clickRay.getDirection().y + maxY/clickRay.getDirection().y;
if(smallestExitingValue > temp) {
smallestExitingValue = temp;
}
temp = -clickRay.getOrigin().z/clickRay.getDirection().z + maxZ/clickRay.getDirection().z;
if(smallestExitingValue < temp) {
smallestExitingValue = temp;
}
if(largestEnteringValue > smallestExitingValue) {
//System.out.println("Miss!");
} else {
if (largestEnteringValue < closestEnteringValue) {
closestEnteringValue = largestEnteringValue;
closestDrawableHit = d;
}
}
}
if(closestDrawableHit != null) {
System.out.println("Hit at: (" + clickRay.setDistance(closestEnteringValue).x + ", " + clickRay.getCurrentPosition().y + ", " + clickRay.getCurrentPosition().z);
this.worldModel.removeDrawableThing(closestDrawableHit);
}
}
}
I just don't understand what's wrong, the ray are shooting and i do hit stuff that gets removed but the result of the ray are verry strange it sometimes removes the thing im clicking at, sometimes it removes things thats not even close to what im clicking at, and sometimes it removes nothing at all.
Edit:
Okay so i have continued searching for errors and by debugging the ray (by painting smal dots where it travles) i can now se that there is something oviously wrong with the ray that im sending out... it has its origin near the world center and always shots to the same position no matter where i direct my camera...
My initial toughts is that there might be some error in the way i calculate my viewMatrix (since it's not possible to get the viewmatrix from the glulookat method in lwjgl; I have to build it my self and I guess thats where the problem is at)...
Edit2:
This is how i calculate it currently:
private double[][] viewMatrixDouble = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,1}};
public Vector getCameraDirectionVector() {
Vector actualEye = this.getActualEyePosition();
return new Vector(lookAt.x-actualEye.x, lookAt.y-actualEye.y, lookAt.z-actualEye.z);
}
public Vector getActualEyePosition() {
return eye.rotate(this.getRotation());
}
public void generateViewMatrix() {
Vector cameraDirectionVector = getCameraDirectionVector().normalize();
Vector side = Vector.cross(cameraDirectionVector, this.upVector).normalize();
Vector up = Vector.cross(side, cameraDirectionVector);
viewMatrixDouble[0][0] = side.x; viewMatrixDouble[0][1] = up.x; viewMatrixDouble[0][2] = -cameraDirectionVector.x;
viewMatrixDouble[1][0] = side.y; viewMatrixDouble[1][1] = up.y; viewMatrixDouble[1][2] = -cameraDirectionVector.y;
viewMatrixDouble[2][0] = side.z; viewMatrixDouble[2][1] = up.z; viewMatrixDouble[2][2] = -cameraDirectionVector.z;
/*
Vector actualEyePosition = this.getActualEyePosition();
Vector zaxis = new Vector(this.lookAt.x - actualEyePosition.x, this.lookAt.y - actualEyePosition.y, this.lookAt.z - actualEyePosition.z).normalize();
Vector xaxis = Vector.cross(upVector, zaxis).normalize();
Vector yaxis = Vector.cross(zaxis, xaxis);
viewMatrixDouble[0][0] = xaxis.x; viewMatrixDouble[0][1] = yaxis.x; viewMatrixDouble[0][2] = zaxis.x;
viewMatrixDouble[1][0] = xaxis.y; viewMatrixDouble[1][1] = yaxis.y; viewMatrixDouble[1][2] = zaxis.y;
viewMatrixDouble[2][0] = xaxis.z; viewMatrixDouble[2][1] = yaxis.z; viewMatrixDouble[2][2] = zaxis.z;
viewMatrixDouble[3][0] = -Vector.dot(xaxis, actualEyePosition); viewMatrixDouble[3][1] =-Vector.dot(yaxis, actualEyePosition); viewMatrixDouble[3][2] = -Vector.dot(zaxis, actualEyePosition);
*/
viewMatrix = new Matrix4f();
viewMatrix.load(getViewMatrixAsFloatBuffer());
}
Would be verry greatfull if anyone could verify if this is wrong or right, and if it's wrong; supply me with the right way of doing it...
I have read alot of threads and documentations about this but i can't seam to wrapp my head around it...
I just don't understand what's wrong, the ray are shooting and i do hit stuff that gets removed but things are not disappearing where i press on the screen.
OpenGL is not a scene graph, it's a drawing library. So after removing something from your internal representation you must redraw the scene. And your code is missing some call to a function that triggers a redraw.
Okay so i finaly solved it with the help from the guys at gamedev and a friend, here is a link to the answer where i have posted the code!
I'm new in box2d and I tried to create joint between two body.
I wrote a joint like
b2RevoluteJointDef jointDef;
jointDef.bodyA=worm_head;
jointDef.bodyB=worm_body;
jointDef.lowerAngle = -0.25f * b2_pi; // -45 degrees
jointDef.upperAngle = 0.25f * b2_pi; // 45 degrees
jointDef.enableLimit=true;
jointDef.maxMotorTorque = 10.0f;
jointDef.motorSpeed = 10.0f;
jointDef.enableMotor = true;
joint=(b2DistanceJoint*)_world->CreateJoint(&jointDef);
but body is not moving when head is moving.
my tick method is
- (void)tick:(ccTime) dt {
//we update the position of the b2body based on the sprite position
for (b2Body* body = _world->GetBodyList(); body != nil; body = body->GetNext())
{
if (body->GetUserData() != NULL) {
CCSprite *spritedata = (CCSprite *)body->GetUserData();
if(spritedata.tag==1)
{
b2Vec2 b2Position = b2Vec2(SCREEN_TO_WORLD(spritedata.position.x),
SCREEN_TO_WORLD(spritedata.position.y));
float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(spritedata.rotation);
body->SetTransform(b2Position,b2Angle);
}
else {
spritedata.position = ccp(body->GetPosition().x * PTM_RATIO,
body->GetPosition().y * PTM_RATIO);
spritedata.rotation = -1 * CC_RADIANS_TO_DEGREES(body->GetAngle());
}
}
}
}
Why is not moving ? How should I change my code ?
In b2RevoluteJointDef , one body is static body and another is dynamic body. My problem is using two dynamic problem. Now, it solved.