Quinta-feira, Fevereiro 24, 2011

Física dos Veículos: Parte 1 Aceleração

Estou estudando a física dos veículos aplicada a jogos, e achei diversos trabalhos interessantes na área é um assunto bem vasto e nesta parte vamos tratar apenas da aceleração longitudinal e o tutorial de base que eu estou seguindo é este
Então vamos lá, temos diversas forças atuando no veiculo e agora vamos tratar da força aplicada pelo motor até as rodas (estou desconsiderando a transmissão) isso ficará para o futuro, vamos chamar essa força Fengine. Depois vamos considerar a resistência do vento ela é definida por algumas constantes mágicas e a resistência do ar definida na Dinâmica dos fluidos, então temos:

 Fdrag = 0.5 * Cd * S * rho * (v*v)

Onde Cd = 0.30

S é a área frontal do veiculo aqui definimos como 2.2

rho é a Resistência do ar que é de 1.29

v é a velocidade do veiculo,

Fdrag é aplicada aposta a direção do veiculo então temos

Fdrag = -u * Fdrag

Onde u é a direção do veiculo

Temos também a Frr que é a resistência do solo (fricção das rodas) que é definida por:

Frr = -u * Crr * v * |v|

Cdrag = 0.5 * Cd * S * rho
 
Crr = 30 * Cdrag

Frr = -u * Crr

Considerando essas forças atuando no veículo fica desta maneira

Flong = Fengine + Fdrag + Frr

Lembrando que segundo Newton

 v = v + dt * a

a = F / M

Fiz a integração deste calculo no FreeMat  (Equivalente Open Source do MatLab) o resultado de v é:

Perceba que em determinado ponto como as forças estão interrelacionadas, elas se mantén constantes, segue o código:

l = 100
t = [1:l]; %Array de Tempo
v = [1:l]; %Array de Velocidade
u = 1; %Direção do veiculo
rho = 1.29; %resistencia do veloar (Dinamica dos Fluidos)
a = 1; %Aceleração
Cd = 0.30; %Constante de Resistencia do Ar
S = 2.2; % Constante de Largurado Veiculo
Fengine = 450; % Força do Motor
tAmount =1; %Posição do Acelerador em porcentagem
M = 1000 % Massa do Veiculo
Fd = [1:l];
Fr = [1:l];
for (i=2:l);
dt = (t(i) - t(i-1));
vt = v(i-1) + (dt * a); %integração da Velocidade
Fdrag = (0.5 * Cd * S * rho * (vt*vt)); % Resistencia do Vento
Cdrag = 0.5 * Cd * S * rho; %Constante de Resistencia da Solo
Crr = 30*Cdrag; %Resistencia do Vento
Fdrag = -u * Fdrag; %Forca da Resistencia do Vento
Frr = -u * Crr * vt * sqrt(vt); % Forca da Resistencia do Solo
Fe = u*tAmount*Fengine; %Forca do Motor
F = Fe + Fdrag+ Frr; %Calculo das forças do Veiculo
a = F / M; %Calculo da Aceleracao
v(i) = vt;
Fd(i) = Fdrag*-1;
Fr(i) = Frr*-1;
end
plot(t,v)
xlabel('Velocidade');
ylabel('Tempo');
title('Aceleração Longitudional');

 Na próxima parte vamos estudar as transmissões (Marchas) o RPM e as Rodas, e vamos integrar a Simulação na Open Dynamics Engine, espero que tenha gostado e seu Feed Back vai ajudar nas próximas partes

Segunda-feira, Fevereiro 14, 2011

Rotação com a classe de Matrizes C++

Boa tarde pessoal  a um bom tempo trabalho em uma classe de manipulação de matrizes, até o momento só implemente a cópia de matrizes e o operador Igual (=) e a multiplicação (*),
Na classe a métodos que cria matrizes em torno do eixo X, Y  e Z, na Engine o Z aponta para cima no caso para setar a posição da câmera fica desta maneira

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Matrix rz,ry,rx,mm;
rz.RotZ(90);
ry.RotY(90);
rx.RotY(-68); 
mm.setIdentity();
mm = ry * rz *rx;
glMultMatrixf(mm.m);
glTranslatef(6.78,18.78,-5);


O Resultado é este:
 
Segue abaixo as classes de Matrizes

//Matrix.h
# include "vec3d.h"
class Matrix
{
 public:
   float m[16];
   Matrix();
   void setIdentity();
   void RotX(float a);
   void RotY(float a);
   void RotZ(float a);
   Matrix& operator*(const Matrix& mat);
   Matrix& operator=(const Matrix& mat);
   //Matrix operator+(Matrix& mat);
   //Matrix operator-(Matrix& mat);
};

//Matrix.cpp
#include
#define M(x,y) (y*4+x)

/**
 * Classe para Manipulação de matrizes
 */

Matrix::Matrix()
{
 setIdentity();
}

/**
 * seta a matrix como identidade
 * |1 0 0 0|
 * |0 1 0 0|
 * |0 0 1 0|
 * |0 0 0 1|
 */

void Matrix::setIdentity()
{

 m[0]  = 1.0f;  m[1]  = 0.0f; m[2]  = 0.0f; m[3]  = 0.0f;
 m[4]  = 0.0f;  m[5]  = 1.0f; m[6]  = 0.0f; m[7]  = 0.0f;
 m[8]  = 0.0f;  m[9]  = 0.0f; m[10] = 1.0f; m[11] = 0.0f;
 m[12] = 0.0f; m[13]  = 0.0f; m[14] = 0.0f; m[15] = 1.0f;

}

/**
 * Multiplica a Matrix por um vetor 3x1
 */
vec3d vecbymat(vec3d vec, Matrix mat)
{
   vec3d r;
   r.x = mat.m[0] * vec.x + mat.m[1]  * vec.y + mat.m[2]    * vec.z + mat.m[3];
   r.y = mat.m[4] * vec.x + mat.m[5]  * vec.y + mat.m[6]    * vec.z + mat.m[7];
   r.z = mat.m[8] * vec.x + mat.m[9]  * vec.y + mat.m[10]   * vec.z + mat.m[11];
   return r;
}


Matrix& Matrix::operator*(const Matrix& mat)
{
                float _m[16];
                for(int i = 0; i <4;i++)
                               for(int j = 0; j<4; j++)
                               {
                                               float sum = 0.0f;
                                               for(int k=0;k<4;k++)
                                                               sum += this->m[i*4+k] * mat.m[k*4+j];
                                               _m[i*4+j] = sum;
                               }
   memcpy(this->m,_m,sizeof(float)*16);

                return *this;
}

Matrix& Matrix::operator=(const Matrix& mat)
{
                memcpy(this->m,mat.m,sizeof(float)*16);
                return *this;
}

void Matrix::RotX(float a)
{
                float c = cosf(DEG2RAD(a));
                float s = sinf(DEG2RAD(a));
                m[0]  = 1.0f;  m[1]  =  0.0f; m[2]  = 0.0f; m[3]  = 0.0f;
                m[4]  = 0.0f;  m[5]  =  c;    m[6]  = s;    m[7]  = 0.0f;
                m[8]  = 0.0f;  m[9]  =  -s;   m[10] = c;    m[11] = 0.0f;
                m[12] = 0.0f; m[13]  =  0.0f; m[14] = 0.0f; m[15] = 1.0f;
}

void Matrix::RotY(float a)
{
                 float c = cosf(DEG2RAD(a));
                 float s = sinf(DEG2RAD(a));

                 m[0]  = c;     m[1]   = 0.0f; m[2]  =  -s; m[3]  = 0.0f;
                 m[4]  = 0.0f;  m[5]   = 1.0f; m[6]  =  0.0f; m[7]  = 0.0f;
                 m[8]  = s;     m[9]   = 0.0f; m[10] =  c; m[11] = 0.0f;
                 m[12] = 0.0f;  m[13]  = 0.0f; m[14] =  0.0f; m[15] = 1.0f;
}

void Matrix::RotZ(float a)
{
                 float c = cosf(DEG2RAD(a));
                  float s = sinf(DEG2RAD(a));

                  m[0]  = c;     m[1]   = s;    m[2]  = 0.0f; m[3]  = 0.0f;
                  m[4]  = -s;    m[5]   = c;    m[6]  = 0.0f; m[7]  = 0.0f;
                  m[8]  = 0.0f;  m[9]   = 0.0f; m[10] = 1.0f; m[11] = 0.0f;
                  m[12] = 0.0f;  m[13]  = 0.0f; m[14] = 0.0f; m[15] = 1.0f;
}

Só para refrescar a memória as matrizes de rotação seguem abaixo:


Quinta-feira, Fevereiro 03, 2011

Vertex Buffer Objects

Bom dia pessoal a grande novidade agora são os Vertex Buffer Objects, para quem não conhece os VBO é uma maneiro de enviar os arrays dos vetores, indices coordenadas de textura, normais para a memória da placa de video desta maneira não é necessário chamar o glVertex* para cada vetor diminuindo drasticamento o overred do programa desta maneira você envia os arrays para a placa de video uma única vez, e depois chama o  glDrawElements ele desenha seu mesh.

a um vasto conteudo na internet sobre VBO, abaixo segue alguns links de referência:

http://www.songho.ca/opengl/gl_vbo.html
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=45

na engine consegui colocar o terreno no VBO, tive que fazer um re-build na estrutura basicamente por causa do tipo de dados, mas como tudo aqui é experimental ainda vão haver muitas modificações, os indices funcionão corretamente, só as coordenadas de textura que me deram uma bela surra.

 Abaixo segue as respectivas classes e um exemplo de utilização:
**** VertexBufferObject.h
/**
* @brief Gera Buffer Object
**/

class VertexBufferObject
{
    public:
        unsigned int vertexBuffId; //id do buffer vertices
        unsigned int indexBuffId; //id do buffer indices
        unsigned int normalBuffId; //id do buffer de normal
        unsigned int texBuffId; //id do buffer de coordenada de textura
        unsigned int numIndices;
        float *vertices; // data dos vertices
        unsigned int *indexs; // data dos indicex
        float *normals; // data das normais
        float *texCoord; //data das coordenadas de Texturas

        VertexBufferObject();

        /**
        * @brief seta os vetices do VBO
        * @param vec3d *data ponteiro para os vertices
        * @param uint32 size tamanho do buffer
        */
        void setVertices(float *data,unsigned int size);

        /**
        * @brief seta os indices do VBO
        * @param uint32 *data ponteiro para os indices
        * @param uint32 size tamanho do buffer
        */
        void setIndexs(unsigned int *data,unsigned int size);

        /**
        * @brief seta as normais do VBO
        * @param vec3d *data ponteiro para os normais
        * @param uint32 size tamanho do buffer
        */
        void setNormals(float *data,unsigned int size);

        /**
        * @brief seta as coordenadas de textura VBO
        * @param TexCoord2 *data ponteiro para os vertices
        * @param uint32 size tamanho do buffer
        */
        void setTexCoords(float *data,unsigned int size);

        /**
        * @brief desenha o VBO
        */
        void draw();
        virtual ~VertexBufferObject();
};

***EOF***
***VertexBufferObject.cpp****

VertexBufferObject::VertexBufferObject()
{
    vertexBuffId = 0;
    indexBuffId = 0;
    normalBuffId = 0;
    texBuffId = 0;
    numIndices = 0;
    vertices = NULL;
    indexs = NULL;
    normals = NULL;
    texCoord = NULL;

}

void VertexBufferObject::setVertices(float *data,unsigned int size)
{


    glGenBuffersARB( 1, &vertexBuffId);
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, vertexBuffId );

    vertices = data;

    glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, data, GL_STATIC_DRAW_ARB );

}
void VertexBufferObject::setIndexs(unsigned int *data,unsigned int size)
{
    glGenBuffersARB( 1, &indexBuffId );
    glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, indexBuffId );

    indexs = data;

    numIndices = (size/sizeof(unsigned int));
    glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW_ARB );
}

void VertexBufferObject::setNormals(float *data,unsigned int size)
{
    glGenBuffersARB( 1, &normalBuffId );
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, normalBuffId );

    normals = data;

    glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, data, GL_STATIC_DRAW_ARB );
}

void VertexBufferObject::setTexCoords(float *data,unsigned int size)
{
    glGenBuffersARB( 1, &texBuffId );
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, texBuffId );

    texCoord = data;
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, data, GL_STATIC_DRAW_ARB );
}

void VertexBufferObject::draw()
{

    if (vertexBuffId != 0 )
    {
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexBuffId);
        glEnableClientState(GL_VERTEX_ARRAY);

        glVertexPointer(3,GL_FLOAT,0,0);
    }

    if (indexBuffId != 0 )
    {
        glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, indexBuffId);
        glEnableClientState(GL_INDEX_ARRAY);
        glIndexPointer(GL_UNSIGNED_INT,0,0);
    }

    if (normalBuffId != 0)
    {
        glEnableClientState(GL_NORMAL_ARRAY);
        glNormalPointer(GL_FLOAT,0,normals);
    }

    if (texBuffId != 0)
    {
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, texBuffId);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer(2,GL_FLOAT,0,0);
    }

    //glDrawArrays(GL_TRIANGLES,0,3);
    glDrawElements(GL_TRIANGLES,numIndices,GL_UNSIGNED_INT,0);


    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_INDEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

VertexBufferObject::~VertexBufferObject()
{

}
***EOF***

Um exemplo da maneira que se possa utilizar segue abaixo isso vai desenhar um quadrado na tela.

// vertex coords array
GLfloat vertices[] =
{1,-1,1, 1,1,1, -1,1,1,
-1,-1,1
 };


unsigned int indices[] = {0,1,2,2,3,0};

float texCord[] = {0,1, 1,1, 1,0, 0,0, 0,1};

VertexBufferObject *vbo = NULL;
TexturePCX *tex = NULL;
...
...
...

int main(int argc,char **argv)
{
 ...
 ...
 ...

 vbo = new VertexBufferObject();
 vbo->setVertices(vertices,sizeof(vertices));
 vbo->setIndexs(indices,sizeof(indices));
tex = new TexturePCX("storage//textures//ground.bmp"); //Não era pra carregar um bmp?
}

void draw()
{
 ...
 glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glTranslatef(0.0f,0.0f,-5.0f);
    tex->begin();
    vbo->draw();
    tex->end();
    glPopMatrix();
}

o resultado é o quadrado na tela você pode perceber que as texturas não estão aparecendo corretamente, você pode perceber tb o terreno sendo desenhado em um vbo, com o terreno coloquei um mapa de 512*512 sem sentir queda no FPS:

no gDEBugger você pode ver na placa de video como estão os dados:
Vertices:
Indices:
se você quiser ver os códigos completos da um pulo lá no svn:
https://newbie-engine.svn.sourceforge.net/svnroot/newbie-engine

Segunda-feira, Janeiro 17, 2011

Newbie Engine Updates

Nova versão saindo.
Os próximos passos são estudar a Fisica Aplicada a Veiculos, achei uma referencia muito boa na hexGear Engine
Vou esmiuçar esse motor

Segunda-feira, Outubro 04, 2010

Newbie Game Engine Updates

Olá pessoal temos uma nova versão, creio que a simulação fisica esta totalmente estável e o mesh do terreno esta colidindo corretamente com os objetos, há uma demonstração com sen x cos, ainda não re-escrevi a parte relativa ao carregamento de um HeightMap através de uma imagem pretendo usar png, pois este tem 4 camadas e da pra colocar informações por escala nas 4 camadas, uma para Grandes Morros a nivel geral, e ir dimunuindo o nivel de detalhe gradativamente, mas antes de fazer isso tenho que dividir o mapa em setores e fazer um colling para assim trabalhar com a ordem de 1024x1024.



https://sourceforge.net/projects/newbie-engine/

vou demorar um pouco pra   ataulizar o SVN mas o arquivo sf já foi atualizado

Quarta-feira, Julho 14, 2010

Newbie Game Engine Updates

Olá pessoal não ainda estou vivo, e fiz uma atualização no SVN com a nova estrutura do projeto creio que agora só precise do SDL para compilar (./configure && make) talvez tenha que usar o autotools também mas não fiz os tetes em outras plataformas.

uma ataualização pendente que estou pra enviar é a correção do Mesh de Terreno agora colide com o Mapa normalmente, agora tenho que dividir os mapas em partes 32x32 para fazer um cooling e texturizar.

bom pessoal por enquanto é isso, se puderem tentar compilar é uma boa.

agora vou atualizar o arquivo do sf.

o path do repositório é

svn co https://newbie-engine.svn.sourceforge.net/svnroot/newbie-engine newbie-engin

https://sourceforge.net/projects/newbie-engine/


até mais pessoal.

Terça-feira, Dezembro 01, 2009

Ausência

Olá pessoal, o Blog anda sem atualizações e me desculpo por, isso bom agora é fim de ano e estou descansando a medida do possivel, também estou com milhares de tarefas que estão sugando toda energia dispónivel.

Quanto a Engine fiz uma motificação na hierarquia do projeto, a ODE está integrada ao projeto (na verdade adicionei o projeto no Makefile do ODE), também separei a engine do projeto do jogo, está separado desta maneira:

- ODE / OPCODE
- Newbie Game Engine (Código da Engine)
- Lunatycs - (Projeto do Game das ultimas imagens)
- Lab - (Usado para experiências).

Só falta ativar a camera, ai faço as atualições, tb to querendo aprontar algo com Apache, MySQL e WebServices na parte Web.

Um abraço e boas festas.