domingo, Janeiro 05, 2014

Fractais: Mandelbrot em C++ com SDL

Final de semana sem nada pra fazer e sempre tive vontade de brincar com fractais, então depois de umas pesquisas no google portei um que tinha achado em C++ fazia o output em um arquivo .bmp, como o arquivo estava no formato errado resolvi fazer um port para  C++ e SDL desse fractal de Mandelbrot:


Sem mais comentários pois foi só um passatempo, você pode baixar o código nesse link:

https://drive.google.com/file/d/0B48ThBHnxF4UNnJ3SlpLT1U3blk/edit?usp=sharing
http://pt.wikipedia.org/wiki/Conjunto_de_Mandelbrot
http://www.vivaolinux.com.br/script/Conjunto-de-Mandelbrot-(Fractal) (src usado como base)
Abraço.

quinta-feira, Dezembro 12, 2013

Singleton para jogos em C++

Olá pessoal, hoje vou compartilhar minha implementação de Singleton, segundo a Wikipédia Singleton é: 
Singleton é um padrão de projeto de software (do inglês Design Pattern). Este padrão garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto.
Ou seja uma maneira elegante de utilizar objetos globais aos quais só tem uma única instância, o melhor exemplo disso seria a Câmera, o nó raiz da cena, ou qualquer outro objeto que tenha acesso global.

#ifndef __SINGLETON__
#define __SINGLETON__
#include
#include "ObjectManager.h"
#include "Camera.h"
class Singleton
{
private:
    Singleton() {}
public:
    static Singleton *instance;
    dWorldID world;
    dSpaceID space;
    ObjectManager rootSceneNode;
    Camera rootCamera;
    dJointGroupID contactGroup;
    // Função-membro que retorna sempre a mesma instância do objeto
    static Singleton& getInstance()
    {
        if (!instance) instance = new Singleton();
        return *instance;
    }
};

#endif // __SINGLETON__

percebam que o construtor é privado isso impede de dar new na classe e criar uma nova instância; O que mas como eu vou usar então sem dar new na classe? Resposta sempre através do método getInstance, segue o exemplo de utilização.

Singleton::getInstance().world = dWorldCreate();
dWorldSetGravity(Singleton::getInstance().world,0.0,0.0,-9.8);
...
Singleton::getInstance().rootSceneNode.add(object);
...
Singleton::getInstance().rootSceneNode.Draw();
 ...
Espero que a implementação seja útil:
Saudações.

Mais referência: http://pt.wikipedia.org/wiki/Singleton

sexta-feira, Abril 26, 2013

Aventuras com Texturas

Estou me aventurando com as texturas, no caso das caixas de do terreno ficou até que bom, o SkyBox está com borda nas texturas e eu não consegui entender o por que.


pode baixar aqui:

terça-feira, Agosto 28, 2012

Mapeamento de malha de terreno em Vertex Buffer Object


Para gerar o terreno criei uma malha  de vetores de n * n, cada item da matriz representa um quadrado formado por dois trianglos, então no caso de uma matriz de 32 x 32, teremos 2.048 trianglos, 4096 vértices (x,y,z), 6.144 índices (i) e 6.144 coordenadas de textura (u,v).

Este primeiro é responsável por preparar a malha de terreno, aqui é o ponto ideal para criar montanhas e crateras através do eixo z
                numIndexs = (height * width * 6);
                        numVecs = (height * width * 4);
                        vecs = new vec3d[numVecs];
                        texCoord = new TexCoord2[numVecs];
                        indexs = new dTriIndex[numVecs];
                      for (int y=0; y< h; y++)
                         for (int x=0; x< w; x++)
                        {
                         int offset = w*y+x;
                         vecs[offset].x = (x*scale);
                         vecs[offset].y = (y*scale);
                        vecs[offset].z = 0.0f;
                        }

Depois de preparada a malha com todas as suas depressões e montanhas, mapeamos os índices do terreno como percebeu o numero de índice é bem maior que o número de vértices isto porque eles são compartilhados entre os trianglos assim não repetimos um vértice que tem as mesmas coordenadas.


 int nIndex = 0;       
 for(int y=0; y
        for(int x=0; x
        {
            //a
            int  a = w*y+x;
            //b
            int  b = w*y+(x+1);
            //c
            int   c = w*(y+1)+(x+1);
            //d
            int d = w*(y+1)+x;

            //Triangulo 1
            indexs[nIndex] = a;
            nIndex++;

            indexs[nIndex] = b;
            nIndex++;

            indexs[nIndex] = c;
            nIndex++;

            //Triangulo 2
            indexs[nIndex] = c;
            nIndex++;

            indexs[nIndex] = d;
            nIndex++;

            indexs[nIndex] = a;
            nIndex++;
    }




 O desenho é feito através de um VertexBufferObject herdado da classe Mesh as texturas também estão armazenadas no Mesh e por final a classe Terrain que contém as características do terreno e a implementação dos algoritmos de carga das informações dos vértices, texturas e índices (blocos acima).



Depois de mapeado copio os buffers para a memória do hardware através da classe quem implementa o VBO
vbo = new VertexBufferObject();
vbo->glMode = GL_TRIANGLES;

 vbo->setVertices(vecs,numVecs);
 vbo->setIndexs(indexs,numIndexs);
 vbo->setTexCoords(texCoord,numIndexs);

Por fim no método Draw, faço a render do terreno.

    glPushMatrix();
    glMatrixMode(GL_MODELVIEW);
    glTranslatef(iPosition.x,iPosition.y,iPosition.z);
    //Draw Here
    texture->begin();
    vbo->draw();
   texture->end();
   glPopMatrix();

Este foi um terreno de 32x32 a ideia agora é criar terrenos de até 2048x2048, para isso vou precisar dividir o terreno em várias partes menores e só deixar na memória as partes que estão sendo visualizadas pelo ator, além de possibilitar multi textura é um grande desafio pela frente.



segunda-feira, Abril 02, 2012

Classe Servo Motor

Olá pessoal, implementei uma Classe para simular um motor servo e consegui construir um triciclo com cinco servos, há também um "radar" em cima do robô que é mais um Servo, como previsto por estar utilizando a Open Dynamics Engine para física vou poder usar a engine para simulação robóticas, estou pensando em criar uma luta de robôs, implementando mais uma joint o Pistão com isso vai dar pra criar até um trator (Sempre quis um trator)


você pode ver como o robô foi montado no header R1D1.h
não preciso dizer que falta muita coisa ainda pra sair um jogo mas o trabalho continua.

você pode fazer o download no Source Forge, neste link  agora no pacote tambén tem as libs usadas é só corrigir os "path" no projedo do CodeBlocks que da pra compilar.

Link para Download 

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: