@Slayer93: Thanks, you were right again. Just by changing the code from /MD to /MT solved the problem.
@binsky: Thanks for your code, i learned a lot from it.
Anyway, here's an adaption of one of Jim Williams JV-ODE demos i ported to DarkGDK, but this time using ODE directly:
#include "DarkGDK.h"
#include "ode/ode.h"
#include <list>
#pragma comment(lib, "ode_single.lib")
using namespace std;
int findFreeObject(int objNumber=1)
{
while (dbObjectExist(objNumber) != 0)
{
objNumber++;
}
return objNumber;
}
int findFreeImage(int number=1)
{
while (dbImageExist(number) != 0)
{
number++;
}
return number;
}
int findFreeMemblock(int number=1)
{
while (dbMemblockExist(number) != 0)
{
number++;
}
return number;
}
int random(int min,int max)
{
int num = min + dbRND(max-min-1);
return num;
}
D3DXVECTOR3 matrixToEuler(const dReal* fRotate)
{
D3DXVECTOR3 returnVec3;
D3DXMATRIX matrix;
matrix._11 = fRotate [ 0 ];
matrix._12 = fRotate [ 4 ];
matrix._13 = fRotate [ 8 ];
matrix._14 = 0;
matrix._21 = fRotate [ 1 ];
matrix._22 = fRotate [ 5 ];
matrix._23 = fRotate [ 9 ];
matrix._24 = 0;
matrix._31 = fRotate [ 2 ];
matrix._32 = fRotate [ 6 ];
matrix._33 = fRotate [ 10 ];
matrix._34 = 0;
matrix._41 = 0;
matrix._42 = 0;
matrix._43 = 0;
matrix._44 = 1;
float m00 = matrix._11;
float m01 = matrix._12;
float m02 = matrix._13;
float m12 = matrix._23;
float m22 = matrix._33;
float heading = (float)atan2(m01,m00);
float attitude = (float)atan2(m12,m22);
float bank = (float)asin(-m02);
returnVec3.x = D3DXToDegree (attitude);
returnVec3.y = D3DXToDegree (bank);
returnVec3.z = D3DXToDegree (heading);
return returnVec3;
}
void eulerToMatrix(dMatrix3 &returnMatrix, float bank, float heading, float attitude)
{
float sinB, cosB, sinH, cosH, sinA, cosA;
sinB = dbSin(bank);
cosB = dbCos(bank);
sinH = dbSin(heading);
cosH = dbCos(heading);
sinA = dbSin(attitude);
cosA = dbCos(attitude);
returnMatrix[0] = cosH * cosA;
returnMatrix[1] = sinH * sinB - cosH * sinA * cosB;
returnMatrix[2] = cosH * sinA * sinB + sinH * cosB;
returnMatrix[3] = 0;
returnMatrix[4] = sinA;
returnMatrix[5] = cosA * cosB;
returnMatrix[6] = -cosA * sinB;
returnMatrix[7] = 0;
returnMatrix[8] = -sinH * cosA;
returnMatrix[9] = sinH * sinA * cosB + cosH * sinB;
returnMatrix[10] = -sinH * sinA * sinB + cosH * cosB;
returnMatrix[11] = 1;
}
int createDefaultTexture(DWORD color1 = dbRGB(255,255,255), DWORD color2 = dbRGB(0,200,80), unsigned int sizeX=128, unsigned int sizeY=128, unsigned char alpha=100)
{
unsigned char red1,green1,blue1,red2,green2,blue2,alphaValue;
if (alpha > 100)
{
alpha = 100;
}
alphaValue = 255*(alpha/100.0);
red1 = (color1 & 0x00FF0000) >> 16;
green1 = (color1 & 0x0000FF00) >> 8;
blue1 = (color1 & 0x000000FF) >> 0;
red2 = (color2 & 0x00FF0000) >> 16;
green2 = (color2 & 0x0000FF00) >> 8;
blue2 = (color2 & 0x000000FF) >> 0;
int memID = findFreeMemblock();
dbMakeMemblock(memID,sizeX*sizeY*4+12);
dbWriteMemblockDword(memID,0,sizeX);
dbWriteMemblockDword(memID,4,sizeY);
dbWriteMemblockDword(memID,8,32);
int halfWidth = floor(sizeX/2.0);
int halfHeight = floor(sizeY/2.0);
int Offset = 0;
for (int height = 1; height < sizeY+1; height++)
{
for (int width=1; width < sizeX+1; width++)
{
if (height < sizeY/2 && width < sizeX/2)
{
dbWriteMemblockByte(memID,12+Offset,blue1);
dbWriteMemblockByte(memID,12+Offset+1,green1);
dbWriteMemblockByte(memID,12+Offset+2,red1);
dbWriteMemblockByte(memID,12+Offset+3,alphaValue);
Offset+=4;
}
else if (height < sizeY/2 && width > sizeX/2)
{
dbWriteMemblockByte(memID,12+Offset,blue2);
dbWriteMemblockByte(memID,12+Offset+1,green2);
dbWriteMemblockByte(memID,12+Offset+2,red2);
dbWriteMemblockByte(memID,12+Offset+3,alphaValue);
Offset+=4;
}
else if (height > sizeY/2 && width < sizeX/2)
{
dbWriteMemblockByte(memID,12+Offset,blue2);
dbWriteMemblockByte(memID,12+Offset+1,green2);
dbWriteMemblockByte(memID,12+Offset+2,red2);
dbWriteMemblockByte(memID,12+Offset+3,alphaValue);
Offset+=4;
}
else
{
dbWriteMemblockByte(memID,12+Offset,blue1);
dbWriteMemblockByte(memID,12+Offset+1,green1);
dbWriteMemblockByte(memID,12+Offset+2,red1);
dbWriteMemblockByte(memID,12+Offset+3,alphaValue);
Offset+=4;
}
}
}
int imgNumber = findFreeImage();
dbMakeImageFromMemblock(imgNumber,memID);
dbDeleteMemblock(memID);
return imgNumber;
}
struct ODEGeom
{
dBodyID body;
dGeomID geom;
int mesh;
};
list<ODEGeom> ODEGeomList;
static dWorldID World;
static dSpaceID Space;
static dJointGroupID ContactGroup;
void AddObject() {
float xp, zp;
ODEGeom odeObj;
xp = random(-10,10);
zp = random(-10,10);
odeObj.body = dBodyCreate(World);
dBodySetPosition(odeObj.body,xp,30,zp);
dMatrix3 setRot;
eulerToMatrix(setRot, 0, 0, 0);
dBodySetRotation(odeObj.body,setRot);
dBodySetAutoDisableFlag(odeObj.body,1);
odeObj.geom = dCreateBox(Space,5,5,5);
dGeomSetBody(odeObj.geom,odeObj.body);
odeObj.mesh = findFreeObject();
dbMakeObjectBox(odeObj.mesh,5,5,5);
dbColorObject(odeObj.mesh,dbRGB(random(0,255),random(0,255),random(0,255)));
dbSetObjectSpecular(odeObj.mesh,dbRGB(255,255,255));
dbSetObjectSpecularPower(odeObj.mesh,20);
ODEGeomList.push_back(odeObj);
}
void UpdateGeoms() {
list<ODEGeom>::iterator odeObj;
for (odeObj=ODEGeomList.begin(); odeObj != ODEGeomList.end(); ++odeObj) {
const dReal *geomPos = dGeomGetPosition((*odeObj).geom);
dbPositionObject((*odeObj).mesh,geomPos[0],geomPos[1],geomPos[2]);
const dReal *geomRot = dGeomGetRotation((*odeObj).geom);
D3DXVECTOR3 euler = matrixToEuler(geomRot);
dbRotateObject((*odeObj).mesh,euler.x,euler.y,euler.z);
}
}
void nearCallback (void *data, dGeomID o0, dGeomID o1)
{
// Create an array of dContact objects to hold the contact joints
static const int MAX_CONTACTS = 10;
dContact contact[MAX_CONTACTS];
for (int i = 0; i < MAX_CONTACTS; i++)
{
contact[i].surface.mode = dContactBounce | dContactSoftCFM;
contact[i].surface.mu = dInfinity;
contact[i].surface.mu2 = 0;
contact[i].surface.bounce = 0.1;
contact[i].surface.bounce_vel = 0.1;
contact[i].surface.soft_cfm = 0.01;
}
if (int numc = dCollide(o0, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact)))
{
// Get the dynamics body for each geom
dBodyID b1 = dGeomGetBody(o0);
dBodyID b2 = dGeomGetBody(o1);
// To add each contact point found to our joint group we call dJointCreateContact which is just one of the many
// different joint types available.
for (int i = 0; i < numc; i++)
{
// dJointCreateContact needs to know which world and joint group to work with as well as the dContact
// object itself. It returns a new dJointID which we then use with dJointAttach to finally create the
// temporary contact joint between the two geom bodies.
dJointID c = dJointCreateContact(World, ContactGroup, contact + i);
dJointAttach(c, b1, b2);
}
}
}
// the main entry point for the application is this function
void DarkGDK()
{
dbSetWindowTitle("ODE & DarkGDK - Cubes Demo");
dbSetDisplayMode(800,600,32);
dbSetWindowSize(800,600);
dbSyncOn();
dbSyncRate(0);
dInitODE();
World = dWorldCreate();
Space = dHashSpaceCreate(0);
ContactGroup = dJointGroupCreate(0);
dWorldSetAutoDisableFlag(World,1);
dWorldSetGravity(World,0,-0.98,0);
int light = 1;
dbMakeLight(light);
dbSetPointLight(light,-40,70,-40);
dbColorLight(light,255,255,255);
dbColorAmbientLight(dbRGB(130,130,130));
dbAutoCamOff();
dbColorBackdrop(dbRGB(0,0,0));
dbSetCameraRange(1,1000);
dbPositionCamera ( 0, 20, -50 );
dbRotateCamera(20,0,0);
dCreatePlane(Space,0,1,0,0);
int plane = findFreeObject();
dbMakeObjectPlain(plane,1500,1500);
dbRotateObject(plane,-90,0,0);
dbSetAlphaMappingOn(plane,80);
int defaultTexture = createDefaultTexture(dbRGB(255,255,255),dbRGB(0,200,80),128,128,80);
dbTextureObject(plane,defaultTexture);
dbSetObjectTransparency(plane,1);
dbScaleObjectTexture(plane,65,65);
int PTime,Timer=0;
float PhysicsTime;
while(LoopGDK())
{
if (dbTimer()-Timer > 700)
{
AddObject();
Timer = dbTimer();
}
UpdateGeoms();
PTime = dbTimer();
dSpaceCollide(Space, 0, &nearCallback);
dWorldQuickStep(World,0.1);
dJointGroupEmpty(ContactGroup);
PhysicsTime = dbTimer()-PTime;
dbSync();
}
dJointGroupDestroy(ContactGroup);
dSpaceDestroy(Space);
dWorldDestroy(World);
dCloseODE();
return;
}
Thanks again for your help, guys!