Page 1 of 1

Weird behaviour in a simple code...

Posted: Sat Jun 26, 2010 6:29 am
by Groovy
Hi !

While I'm nearly in holidays, I've tried again this library. I managed to install the library, but I've got a problem when testing it :S .
I just created 4 static shapes in order to set limits to my other bodies. Then I created a triangle and its behaviour is very strange (it sometimes strangely bounces, translates whereas it shouldn't and always finishes by crossing the limits I set...) so I certainly forgot something important in the code.
I also tried to create a second triangle, but even if I set a higher mass to it, it falls at the same velocity than the 1st one :S .

So, let you see my code :
Creation of objects :

Code: Select all

cpInitChipmunk();
    cpSpace* espace = cpSpaceNew();
    espace->iterations = 10;
    espace->gravity = cpv(0, 50);

    // creating a static body
    cpBody* corpsStatique = cpBodyNew(INFINITY, INFINITY);

    // Creating limits
	cpShape *bord1 = cpSegmentShapeNew(corpsStatique, cpv(0,0), cpv(800,0), 0.0f);
	cpShape *bord2 = cpSegmentShapeNew(corpsStatique, cpv(800,0), cpv(800,600), 0.0f);
	cpShape *bord3 = cpSegmentShapeNew(corpsStatique, cpv(800,600), cpv(0,600), 0.0f);
	cpShape *bord4 = cpSegmentShapeNew(corpsStatique, cpv(0,600), cpv(0,0), 0.0f);
	
	bord1->e = 0.9f; bord1->u = 1.0f;
	bord2->e = 0.9f; bord2->u = 1.0f;
	bord3->e = 0.9f; bord3->u = 1.0f;
	bord4->e = 0.9f; bord4->u = 1.0f;
	// Adding them to the space
	cpSpaceAddStaticShape(espace, bord1);
	cpSpaceAddStaticShape(espace, bord2);
	cpSpaceAddStaticShape(espace, bord3);
	cpSpaceAddStaticShape(espace, bord4);

    // Creating a triangle
	int num = 3;
	cpVect points[] = {
		cpv(0,-40),
		cpv(-10, 40),
		cpv( 10, 40)
	};
	cpBody *vaisseau = cpBodyNew(5.f, cpMomentForPoly(5.f, num, points, cpvzero));
	vaisseau->p = cpv(80, 80);
	cpSpaceAddBody(espace, vaisseau);
	cpShape* forme = cpPolyShapeNew(vaisseau, num, points, cpvzero);
    forme->e = 0.3f; forme->u = 0.8f;
    cpSpaceAddShape(espace, forme);

    sf::Shape triangle;
    for(unsigned int i=0; i<num; i++)
    {
        triangle.AddPoint(points[i].x, points[i].y, sf::Color::Red);
    }
    triangle.SetPosition(80, 80);



	cpBody *vaisseau2 = cpBodyNew(30.f, cpMomentForPoly(30.f, num, points, cpvzero));
	vaisseau2->p = cpv(80, 300);
	cpSpaceAddBody(espace, vaisseau2);
	cpShape* forme2 = cpPolyShapeNew(vaisseau2, num, points, cpvzero);
    forme2->e = 0.3f; forme2->u = 0.8f;
    cpSpaceAddShape(espace, forme2);

    sf::Shape triangle2;
    for(unsigned int i=0; i<num; i++)
    {
        triangle2.AddPoint(points[i].x, points[i].y, sf::Color::Green);
    }
    triangle.SetPosition(80, 300);
And I call cpSpaceStep in my loop.

I don't think the problem comes from the library so I certainly forgot something or such.
Moreover, maybe I don't correctly update the rotation of the objet when I display it (Particularly, I don't know if the angle got by cpBodyGetAngle is clockwise and where the origin is)

Anyone could help me, please ?

Thank you in advance ;)

PS : I'm french, sorry for the possible mistakes...

Re: Weird behaviour in a simple code...

Posted: Sat Jun 26, 2010 7:01 am
by maximile
I also tried to create a second triangle, but even if I set a higher mass to it, it falls at the same velocity than the 1st one :S .
This is how real life physics works. Some things might fall more slowly due to air resistance; you can approximate that by setting the space drag.

The rotation angle is in radians about the body position, which is also the centre of mass. Your centre of mass is the origin you set your vertices around when you made the shape. Yours is slightly wrong for a triangle, and this can lead to strange physics. Hope that helps a bit.

Re: Weird behaviour in a simple code...

Posted: Sat Jun 26, 2010 11:50 am
by Groovy
Yes, I didn't think about it, but I know mass doesn't change gravity. (Fortunately I'm on holidays soon :p ) However, the problem remains when I set espace->damping = 0.5f;
So, I deduce it's not this damping which should change something, so how to set a space drag ?

I also tried to add that in the loop :

Code: Select all

cpBodyApplyForce(vaisseau, cpv(- cpBodyGetVel(vaisseau).x, - cpBodyGetVel(vaisseau).y), cpBodyGetPos(vaisseau));
            cpBodyApplyForce(vaisseau2, cpv(- cpBodyGetVel(vaisseau2).x, - cpBodyGetVel(vaisseau2).y), cpBodyGetPos(vaisseau2));
But it behaves still more weird, whether I add a coefficient to the velocity or not... (the triangles turn around themselves very fast...)...

What surprises me the more is that triangles sometimes cross over the limits, so how to solve this problem ? Increasing the iterations ? (I tried to, but even with iterations = 3000, they cross over the limit if they go too fast...)

I start despair... I can't get what I want...

Re: Weird behaviour in a simple code...

Posted: Sat Jun 26, 2010 12:32 pm
by slembcke
As maximille said, things with more mass don't fall faster. Light objects like paper may have more drag to slow them down. This is a common mistake.

The triangle vertexes you are passing to Chipmunk look fine. Does the object continue to fall through or does it just stop at the wrong place? Maybe you are just drawing it at the wrong place.

Re: Weird behaviour in a simple code...

Posted: Sun Jun 27, 2010 2:53 am
by Groovy
No, the error is still there...
I don't understand how chipmunk works...

To display, I use the library SFML, maybe you know it.
Here is the code I use :

Code: Select all

#include <iostream>
#include <SFML/Graphics.hpp>
#include <chipmunk/chipmunk.h>

using namespace std;

int main()
{
    const float iterations = 60.f;

    cpInitChipmunk();
    cpSpace* espace = cpSpaceNew();
    espace->elasticIterations = 30;
    espace->iterations = 30.f;
    espace->gravity = cpv(0, 50);

    // On crée un corps statique (on ne l'ajoute pas à l'espace)
    cpBody* corpsStatique = cpBodyNew(INFINITY, INFINITY);

    // On crée les différents bords
	cpShape *bord1 = cpSegmentShapeNew(corpsStatique, cpv(0,0), cpv(800,0), 0.0f);
	cpShape *bord2 = cpSegmentShapeNew(corpsStatique, cpv(800,0), cpv(800,600), 0.0f);
	cpShape *bord3 = cpSegmentShapeNew(corpsStatique, cpv(800,600), cpv(0,600), 0.0f);
	cpShape *bord4 = cpSegmentShapeNew(corpsStatique, cpv(0,600), cpv(0,0), 0.0f);
	// On précise leurs paramètres
	bord1->e = 0.9f; bord1->u = 1.0f;
	bord2->e = 0.9f; bord2->u = 1.0f;
	bord3->e = 0.9f; bord3->u = 1.0f;
	bord4->e = 0.9f; bord4->u = 1.0f;
	// On les ajoute à l'espace en tant que formes statiques
	cpSpaceAddStaticShape(espace, bord1);
	cpSpaceAddStaticShape(espace, bord2);
	cpSpaceAddStaticShape(espace, bord3);
	cpSpaceAddStaticShape(espace, bord4);

    // Puis un triangle en guise de vaisseau
	int num = 3;
	cpVect points[] = {
      cpv(0,-40),
      cpv(-10, 40),
      cpv( 10, 40)
    };
	cpBody *vaisseau = cpBodyNew(5.f, cpMomentForPoly(5.f, num, points, cpvzero));
	vaisseau->p = cpv(80, 80);
	cpSpaceAddBody(espace, vaisseau);
	cpShape* forme = cpPolyShapeNew(vaisseau, num, points, cpvzero);
    forme->e = 0.3f; forme->u = 0.8f;
    cpSpaceAddShape(espace, forme);

    sf::Shape triangle;
    for(unsigned int i=0; i<num; i++)
    {
        triangle.AddPoint(points[i].x, points[i].y, sf::Color::Red);
    }
    triangle.SetPosition(80, 80);



	cpBody *vaisseau2 = cpBodyNew(300.f, cpMomentForPoly(300.f, num, points, cpvzero));
	vaisseau2->p = cpv(80, 300);
	cpSpaceAddBody(espace, vaisseau2);
	cpShape* forme2 = cpPolyShapeNew(vaisseau2, num, points, cpvzero);
    forme2->e = 0.3f; forme2->u = 0.8f;
    cpSpaceAddShape(espace, forme2);

    sf::Shape triangle2;
    for(unsigned int i=0; i<num; i++)
    {
        triangle2.AddPoint(points[i].x, points[i].y, sf::Color::Green);
    }
    triangle.SetPosition(80, 300);


    sf::Clock chrono;
    float compteur = 0.f;

    sf::RenderWindow fenetre(sf::VideoMode(800, 600), "TRE");

    bool test = true;

    while(fenetre.IsOpened())
    {
        compteur += chrono.GetElapsedTime();
        chrono.Reset();

        while(compteur >= 1.f/iterations)
        {
            cpSpaceStep(espace, 1.f/iterations);
            compteur -= 1.f/iterations;
        }

        sf::Event evenement;
        while(fenetre.GetEvent(evenement))
        {
            if(evenement.Type == sf::Event::Closed) fenetre.Close();
        }

        triangle.SetPosition(cpBodyGetPos(vaisseau).x, cpBodyGetPos(vaisseau).y);
        triangle.SetRotation(- cpBodyGetAngle(vaisseau) * 180.f / M_PI);

        triangle2.SetPosition(cpBodyGetPos(vaisseau2).x, cpBodyGetPos(vaisseau2).y);
        triangle2.SetRotation(- cpBodyGetAngle(vaisseau2) * 180.f / M_PI);

        fenetre.Clear();
        fenetre.Draw(triangle);
        fenetre.Draw(triangle2);
        fenetre.Display();

        if(test)
        {
            sf::Sleep(5);
            test = false;
            chrono.Reset();
        }
    }

    cpSpaceFree(espace);

    return 0;
}
With this code, the red triangle go through the bottom limit...

Re: Weird behaviour in a simple code...

Posted: Thu Jul 01, 2010 7:42 am
by Groovy
No one can help me ?
:s

Re: Weird behaviour in a simple code...

Posted: Thu Jul 01, 2010 10:08 am
by slembcke
Can you post a screenshot or video of the problem. What you are describing could be any number of things, and it's really hard to know without a clearer description of the problem.

Re: Weird behaviour in a simple code...

Posted: Fri Jul 02, 2010 7:23 am
by Groovy
Yeh.
Here's a video of the problem :
http://www.youtube.com/watch?v=oDmVXEEqjBA

As you see, the behaviour of the red triangle doesn't seem ok, and it goes through the border (contrary to the green triangle)...

Re: Weird behaviour in a simple code...

Posted: Fri Jul 02, 2010 9:44 am
by slembcke
I don't see anything obvious from just looking at the source. I'll try and see if I have the time to install SFML and run it this weekend. Probably will have to wait until Monday though.