Autor Wątek: Bullet - dziwne zachowanie ciał  (Przeczytany 2201 razy)

Offline Adam27

  • Użytkownik

# Listopad 16, 2012, 21:10:06
Witam.

Ostatnio w moim silniku na OpenGL implementuję fizykę z użyciem biblioteki Bullet. Na początku testowałem box'y i sphere'y i wszystko było w porządku, natomiast po dodaniu cylindrów zauważyłem ich bardzo dziwne zachowanie. Gdy zostaną wprawione w nawet powolny ruch obrotowy, zamiast upaść na ziemię, kręcą się bez końca wbrew sile grawitacji. Efekt jest tym większy, im mają większą długość. Dobrze to widać na poniższym filmie:

http://youtu.be/0_wH-54b23g (jak embedować filmik?)

Na początku myślałem, że coś z macierzami jest nie tak, ale zacząłem używać transform->getOpenGLMatrix i glMultMatrixf i nadal jest to samo. Możliwe żeby to był bug Bulleta? Czy ktoś spotkał się z podobnym problemem albo ma pomysł jaka może być przyczyna?

Pozdrawiam.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline koirat

  • Użytkownik

# Listopad 16, 2012, 21:47:04
Dobrze ustawiasz tensor momentu bezwładności (macierzy bezwładności) ?

Offline Adam27

  • Użytkownik

# Listopad 16, 2012, 22:04:18
Oto kod na tworzenie cylindra, 'localInertia' to chyba ten tensor bezwładności. Taki sam kod jest w przykładach do Bulleta.

btCollisionShape* shape = new btCylinderShape(btVector3(d/2, h/2, d/2));

btTransform transform;
transform.setIdentity();
transform.setOrigin(btVector3(pos.x, pos.y, pos.z));

btVector3 localInertia(0, 0, 0);
if (mass>0)
shape->calculateLocalInertia(mass, localInertia);

btDefaultMotionState* motionState = new btDefaultMotionState(transform);
body = new btRigidBody(mass, motionState, shape, localInertia);

Offline .:NOXY:.

  • Użytkownik
    • Profil

  • +1
# Listopad 17, 2012, 11:04:05
Wez no dopisz to:

#ifndef enmag_Header_h
#define enmag_Header_h

#include "declare.h"
#include "FurionGL.h"
#include "btBulletDynamicsCommon.h"
#import  "MatrixPool3D.h"

class iFMDebugDrawer : public btIDebugDraw {
public:
    int m_debugMode;
   
    iFMDebugDrawer();
    ~iFMDebugDrawer();
   
    cShader *lineShader;
   
    void drawLine(const btVector3& from,const btVector3& to,const btVector3& color);
   
    //not used
    void drawContactPoint(const btVector3& PointOnB,
                             const btVector3& normalOnB,
                             btScalar distance,
                             int lifeTime,
                             const btVector3& color);
   
void reportErrorWarning(const char* warningString);
   
void draw3dText(const btVector3& location,const char* textString);
   
void setDebugMode(int debugMode);
   
int getDebugMode() const;

};

#endif

plik cpp:

#include "DebugDrawer.h"

///////////////////////////////////////////////////////////////////

iFMDebugDrawer::iFMDebugDrawer():m_debugMode(0)
{
   
    lineShader = [[cShader alloc] init];
    [lineShader InitShader:@"line"];
   
    glBindAttribLocation(lineShader->ShaderProgram, ATTRIB_VERTEX, "position");
 
    [lineShader Link];
   
    glUseProgram(lineShader->ShaderProgram);
   
    lineShader->uniforms[UNI_LIGHT_COLOR] = glGetUniformLocation(lineShader->ShaderProgram, "color");
    lineShader->uniforms[UNI_PROJECTION_MAT] = glGetUniformLocation(lineShader->ShaderProgram, "projection");
    lineShader->uniforms[UNI_MODELVIEW_WORLD_MAT] = glGetUniformLocation(lineShader->ShaderProgram, "modelView");
   
    glUseProgram(0);
}

///////////////////////////////////////////////////////////////////

iFMDebugDrawer::~iFMDebugDrawer()
{
    [lineShader DeInitShader];
    [lineShader release];
}

///////////////////////////////////////////////////////////////////

void iFMDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
{
    glBindVertexArray(0);
   
    const GLfloat squareVertices[] = {
        from.x(), from.y(), from.z(),
        to.x(), to.y(), to.z()
    };
   
    glUseProgram(lineShader->ShaderProgram);
   
    glDisable(GL_TEXTURE_2D);
   
    glUniformMatrix4fv(lineShader->uniforms[UNI_PROJECTION_MAT], 1 ,false , MainMatrix3D->Projection.m);
    glUniformMatrix4fv(lineShader->uniforms[UNI_MODELVIEW_WORLD_MAT], 1 ,false , MainMatrix3D->ModelView.m);
    glUniform3f(lineShader->uniforms[UNI_LIGHT_COLOR],color.x(),color.y(),color.z());
   
    glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, squareVertices);
    glEnableVertexAttribArray(ATTRIB_VERTEX);
   
    glDrawArrays(GL_LINES, 0, 2);

    glEnable(GL_TEXTURE_2D);
    glUseProgram(0);

}

///////////////////////////////////////////////////////////////////

void iFMDebugDrawer::drawContactPoint(const btVector3& PointOnB,
                                      const btVector3& normalOnB,
                                      btScalar distance,
                                      int lifeTime,
                                      const btVector3& color)
{

}

void iFMDebugDrawer::reportErrorWarning(const char* warningString)
{
    NSLog(@"%s",warningString);
}

void iFMDebugDrawer::draw3dText(const btVector3& location,const char* textString)
{

}

void iFMDebugDrawer::setDebugMode(int debugMode)
{
    m_debugMode = debugMode;
}

int iFMDebugDrawer::getDebugMode() const
{
    return m_debugMode;
};


Oczywiscie podmieniajac rysowanie na swoje

i dolacz tak:

DebugDraw = new iFMDebugDrawer();
DebugDraw->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
dynamicsWorld->setDebugDrawer(DebugDraw);

na koniec rysownia swojej sceny wolasz  dynamicsWorld->debugDrawWorld();

I wtedy nagraj filmik to bardziej pomoze nam i tobie w debugowaniu bulleta :)

Offline Adam27

  • Użytkownik

# Listopad 17, 2012, 16:50:07
Z debugiem to wygląda tak:

http://youtu.be/-zU_o9ry6w0

Offline Kos

  • Użytkownik
    • kos.gd

  • +2
# Listopad 17, 2012, 17:25:18
Zachowują się, jakby cała masa była skupiona punktowo w jednym końcu nogi.

Offline Adam27

  • Użytkownik

# Listopad 18, 2012, 00:21:03
Faktycznie, ale problem w tym, dlaczego ona się tam skupia, skoro używam kodu z przykładów Bulleta? ;) Nie wykluczam możliwości że czegoś w Bullecie nie rozumiem albo źle ustawiłem, ale już mi się kończą pomysły.

Offline Kurak

  • Użytkownik

# Listopad 18, 2012, 00:35:37
wbija ci w ogole do calculateLocalInertia? ile wynosi 'mass' w miejscu ifa? zbrejkuj sie tam i sprawdz.

Offline Adam27

  • Użytkownik

# Listopad 18, 2012, 01:18:29
mass jest 10, bez masy ciała by były statyczne, a gdyby localInertia się nie obliczała to ciała by się nie obracały w ogóle. To raczej jest w porządku, chyba że ta funkcja źle działa ale nie chce mi się wierzyć.

Przyjrzałem się bliżej pozostałym rodzajom ciał i problem występuje też dla kapsuł i nawet długich boxów, ale w mniejszym stopniu, bo one szybciej upadają na ziemię.
« Ostatnia zmiana: Listopad 18, 2012, 01:26:16 wysłana przez Adam27 »

Offline DezerteR

  • Użytkownik

# Listopad 18, 2012, 01:45:39
efekt żyroskopowy?

Offline .:NOXY:.

  • Użytkownik
    • Profil

# Listopad 18, 2012, 12:14:17
No to jestem na 90% pewien ze nie robisz wlasnych convexmeshy tylko pozwalasz Bulletowi je tworzyc a twoj model   ma punk 0,0,0 w dolnej krawedzi zamiast na srodku i to powoduje beldne zbudowanie convexu.

rys. a) - ZLE
rys. b) - DOBRZE

Offline Adam27

  • Użytkownik

# Listopad 18, 2012, 13:52:18
Moje modele mają środek w punkcie (0,0,0), jak widać na ostatnim filmiku pokrywają się one z debug drawingiem Bulleta.

Cytuj
No to jestem na 90% pewien ze nie robisz wlasnych convexmeshy tylko pozwalasz Bulletowi je tworzyc
Co masz na myśli? Używam zwykłych shape'ów Bulleta za pomocą kodu który umieściłem, mam to zrobić jakoś inaczej?