Irrlicht/Newton Integration Compile Error--Code Blocks

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Alpha Omega
Posts: 288
Joined: Wed Oct 29, 2008 12:07 pm

Irrlicht/Newton Integration Compile Error--Code Blocks

Post by Alpha Omega »

Hi I am trying to compile code written by g_butcher here....

http://irrlicht.sourceforge.net/phpBB2/ ... t=gbutcher

Image

Not sure where the error is being flagged.... doesnt give a line I think it is a MSVC++ reference that Code Blocks doesn't use.

Anyone seen this before and if so what causes it?
abhishekdey1985
Posts: 102
Joined: Sat Jan 17, 2009 4:33 am
Location: Pune
Contact:

Post by abhishekdey1985 »

I didnt go through the g_butcher's code, but try this code instead..

Code: Select all

#include <irrlicht.h>
#include <newton.h>

#ifdef WIN32
#pragma comment(lib,"irrlicht.lib")
#pragma comment(lib,"newton.lib")
#endif

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;

/Struct for collision object
struct SObject
{
//Irrlicht scene node
IMeshSceneNode *irr_node;

//Newton collision object
NewtonCollision *nwtn_collision;

};

//Function to create a NewtonCollision from irrlicht mesh
NewtonCollision *CreateCollisionFromMesh(NewtonWorld *nWorld, IMesh *irr_mesh )
{
int nMeshBuffer = 0; //Mesh Buffer count
IMeshBuffer *mesh_buffer = NULL;
float *vertices; //Array to store vertices

u32 nVertices = 0;

//Get number of vertices
for( nMeshBuffer=0 ; nMeshBuffer < irr_mesh->getMeshBufferCount() ; nMeshBuffer++ )
{
nVertices += irr_mesh->getMeshBuffer(nMeshBuffer)->getVertexCount();
}


//create buffer for vertices
vertices = new float[nVertices * 3];
u32 tmpCounter = 0;

//Get (irr_)mesh buffers and copy face vertices
for( nMeshBuffer=0 ; nMeshBuffer < irr_mesh->getMeshBufferCount() ; nMeshBuffer++ )
{

    mesh_buffer = irr_mesh->getMeshBuffer(nMeshBuffer);

    //Get pointer to vertices and indices
    S3DVertex *S3vertices = (S3DVertex*)mesh_buffer->getVertices();


//copy vertices from mesh to buffer
for(int i=0; i<mesh_buffer->getVertexCount(); i++)
{

        vertices[tmpCounter++] = S3vertices[i].Pos.X;
        vertices[tmpCounter++] = S3vertices[i].Pos.Y;
        vertices[tmpCounter++] = S3vertices[i].Pos.Z;

    }

}

//Create Newton collision object
NewtonCollision *collision_obj = NewtonCreateConvexHull(nWorld,nVertices,vertices,sizeof(float)*3,NULL);

//delete vertices
delete [] vertices;

return collision_obj;

}

//Check for collision between two SObjects
bool CheckForCollision(NewtonWorld *nWorld, SObject *obj_A, SObject *obj_B)
{
//Matrix to store irr_node position
matrix4 mat_A,mat_B;

//Copy position
mat_A.makeIdentity();
mat_B.makeIdentity();

mat_A.setTranslation(obj_A->irr_node->getPosition());
mat_B.setTranslation(obj_B->irr_node->getPosition());

const int nContacts = 2;
float contacts[3 * nContacts];
float normals[3 * nContacts];
float penetration[ nContacts ];

//Check for collision between collision meshes,
// returns number of contact points
int nHits = NewtonCollisionCollide( nWorld,nContacts,

                    obj_A->nwtn_collision, (float*)&mat_A[0],
                    obj_B->nwtn_collision, (float*)&mat_B[0],
                    contacts,
                    normals,
                    penetration);

//Collision detected if nHits > 0
if( nHits > 0)
return true;
return false;

}

int main()
{
//Create irrlicht device
IrrlichtDevice *device = createDevice(EDT_OPENGL, dimension2d<s32>(800, 600), 16,

                    false, false, true, 0);


//Create newton world
NewtonWorld *nWorld = NewtonCreate(NULL,NULL);

// set 0 for exact collision detection,
// 1 or n for use in applications where speed is more important
NewtonSetSolverModel(nWorld,1);

/*
Set the caption of the window to some nice text. Note that there is
a 'L' in front of the string. The Irrlicht Engine uses wide character
strings when displaying text.
*/
device->setWindowCaption(L"Basic Collision Detection with Newton GD");

/*
Get a pointer to the video driver, the SceneManager and the
graphical user interface environment, so that
we do not always have to write device->getVideoDriver(),
device->getSceneManager() and device->getGUIEnvironment().
*/
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
//IGUIEnvironment* guienv = device->getGUIEnvironment();


//Create two SObjects
SObject sphere;
SObject cube;

//Load mesh and create new irrlicht node
sphere.irr_node = smgr->addMeshSceneNode(smgr->getMesh("sphere.3ds")->getMesh(0));
cube.irr_node = smgr->addMeshSceneNode(smgr->getMesh("cube.3ds")->getMesh(0));
sphere.irr_node->getMaterial(0).EmissiveColor.set(255,0,255,5);
cube.irr_node->getMaterial(0).EmissiveColor.set(255,0,255,255);

//Now create collision mesh from irrlicht mesh
sphere.nwtn_collision = CreateCollisionFromMesh(nWorld,sphere.irr_node->getMesh());
cube.nwtn_collision = CreateCollisionFromMesh(nWorld,cube.irr_node->getMesh());

//Set position
sphere.irr_node->setPosition(vector3df(-5,0,0));
cube.irr_node->setPosition(vector3df(0,0,0));

//Add camera
smgr->addCameraSceneNode(0, vector3df(0,1,-7), vector3df(0,0,0));

/*
Ok, now we have set up the scene, lets draw everything:
We run the device in a while() loop, until the device does not
want to run any more. This would be when the user closed the window
or pressed ALT+F4 in windows.
*/

//Defines where the node should be moved
float vel=0.1f;

while(device->run())
{
driver->beginScene(true, true, SColor(0,200,200,200));

smgr->drawAll();

driver->endScene();

//let's move the sphere
sphere.irr_node->setPosition(sphere.irr_node->getPosition()+vector3df(1,0,0)*vel);
if(sphere.irr_node->getPosition().X > 5.5f)
vel = -0.05f;
if(sphere.irr_node->getPosition().X < -5.5f)
vel = 0.05f;
//check for collision and set red color if collision detected
if(CheckForCollision(nWorld,&sphere,&cube))
cube.irr_node->getMaterial(0).EmissiveColor.set(255,255,0,0);
else //use blue color
cube.irr_node->getMaterial(0).EmissiveColor.set(255,0,0,255);
}

// We need to release newton collision mesh if we don't need it anymore
NewtonReleaseCollision(nWorld, sphere.nwtn_collision);
NewtonReleaseCollision(nWorld, cube.nwtn_collision);

//Destroy newton world
NewtonDestroy(nWorld);

device->drop();

return 0;

}
Code has been taken from http://www.irrlicht3d.org/wiki/index.ph ... nDetection

AFAIK the Newton build should work with both GCC and MSVC. Try to check your linker settings too.
I work on "The Best Real-Time 3D Engine"
Alpha Omega
Posts: 288
Joined: Wed Oct 29, 2008 12:07 pm

Post by Alpha Omega »

I found the error.

I got this error when I declared

Code: Select all

MyEventReceiver receiver;
inside Int main().... but why this is not valid?
Nimrod
Posts: 8
Joined: Sun Feb 22, 2009 8:10 pm

Post by Nimrod »

The original code has "class MyEventReceiver"; it doesn't seem like you have it in your code.

Edit: sorry never mind, I mistaken abhishekdey1985's code as your code.
Last edited by Nimrod on Fri Mar 20, 2009 3:55 pm, edited 1 time in total.
Alpha Omega
Posts: 288
Joined: Wed Oct 29, 2008 12:07 pm

Post by Alpha Omega »

No it is in there and for some reason that class MyEventReceiver is the problem but I dont see why when I replace it with one in the tutorial section it compiles with no errors.
Nimrod
Posts: 8
Joined: Sun Feb 22, 2009 8:10 pm

Post by Nimrod »

Since I have stepped into this thread already, I will give it a random guess:

When I see "undefined reference to: wired obscure thing" I would check and see if the libraries are properly linked.

Note I am not familiar with Code::Blocks, it's just a guess.

Edit: Another possibility is that sometimes you get those errors when you try to mix the libraries built by different compilers.
Alpha Omega
Posts: 288
Joined: Wed Oct 29, 2008 12:07 pm

Post by Alpha Omega »

The error is here somewhere....

Code: Select all

 Entity *tmp = MakeEntity(cam->getPosition());
        if (!tmp) return false;
        vector3df camvec = (cam->getTarget() - cam->getPosition()).normalize() * 500;
        float newpos[3] = { camvec.X, camvec.Y, camvec.Z };
        NewtonBodySetVelocity(tmp->body, (float*)newpos);
if I remove this then the project compiles with no errors. I googled the error and it said it had something to do with MSVC. I am using the GCC compiler not MSVC. So my question is where is this reference in this code?
Alpha Omega
Posts: 288
Joined: Wed Oct 29, 2008 12:07 pm

Post by Alpha Omega »

After further analysis the problem lays in this scrap of code...

Code: Select all

vector3df camvec = (cam->getTarget() - cam->getPosition()).normalize() * 500; 
Anyway to state this so the MSVC error is dissolved?

The problem exists with the normalization of the vector if i delete

Code: Select all

.normalize() * 500;
the program compiles.
abhishekdey1985
Posts: 102
Joined: Sat Jan 17, 2009 4:33 am
Location: Pune
Contact:

Post by abhishekdey1985 »

I tried ur code and found no errors. It compiles properly. Might be some library or DLL error. Check your Irrlicht binaries and libraries.
I work on "The Best Real-Time 3D Engine"
Alpha Omega
Posts: 288
Joined: Wed Oct 29, 2008 12:07 pm

Post by Alpha Omega »

What are you compiling with? It will compile on MSVC no problem but for some reason it will not compile on Code Blocks IDE.
abhishekdey1985
Posts: 102
Joined: Sat Jan 17, 2009 4:33 am
Location: Pune
Contact:

Post by abhishekdey1985 »

There are different DLLS and Libraries for GCC and MSVC. I hope you have taken care of that. Or else compile your binarie and libraries.

It should compile with no problem on GCC too.
I work on "The Best Real-Time 3D Engine"
Alpha Omega
Posts: 288
Joined: Wed Oct 29, 2008 12:07 pm

Post by Alpha Omega »

Ok when you mention DLL's. What do DLL's have to do with compiling the program? It will not successfully compile so why would the DLL matter if there is no program to run? When you say link libraries I have linked to Irrlicht and to Newton using the Mingw compiler to compile the program.

And thus get an error with that code so no the code does not compile with GCC.

The problem is with the .normalize() in the code under the EventReceiver. Without it the program compiles and runs fine.

I googled the problem and it said that this problem is with Mingw's alloc() function not being compatible with chktsk() or something so no it doesnt seem to be a simple linking issue as you say.
Alpha Omega
Posts: 288
Joined: Wed Oct 29, 2008 12:07 pm

Post by Alpha Omega »

This is my finished code that gets the error so there are no confusions...

Code: Select all

#define NEWTON_GRAVITY -800.0f

#include <irrlicht.h>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <irrlicht.h>
#include <wchar.h>
#include <Newton.h>

#pragma comment(lib, "Irrlicht.lib")
#pragma comment(lib, "Newton.lib")
// struct Class Entity
struct Entity
    {
        IAnimatedMesh *mesh;
        ISceneNode *node;
        NewtonBody *body;
        NewtonCollision *collision;
    };
//Define Variables
Entity *entities[512];
int currentEntity;
u32 lasttick;

//Irrlicht Variables
IrrlichtDevice *device;
IVideoDriver* driver;
ISceneManager* smgr;
IGUIEnvironment* guienv;

//Newton Variables
NewtonWorld *nWorld;

//Level
IAnimatedMesh* g_map;
ISceneNode* g_mapnode;
ITriangleSelector *g_selector;
NewtonCollision* g_newtonmap;
NewtonBody* g_newtonmapbody;

//Camera
ICameraSceneNode *cam;

void SetMeshTransformEvent(const NewtonBody* body, const float* matrix)
  {
        CMatrix4<float> mat;
        mat.setM(matrix);
        ISceneNode *tmp = (ISceneNode *)NewtonBodyGetUserData(body);

if (tmp)
    {
    tmp->setPosition(mat.getTranslation());
    tmp->setRotation(mat.getRotationDegrees());
    }
  }

void ApplyForceAndTorqueEvent (const NewtonBody* body)
   {
    float mass;
    float Ixx;
    float Iyy;
    float Izz;
    float force[3];
    float torque[3];

    NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);

    force[0] = 0.0f;
    force[1] = NEWTON_GRAVITY * mass;
    force[2] = 0.0f;

    torque[0] = 0.0f;
    torque[1] = 0.0f;
    torque[2] = 0.0f;

    NewtonBodyAddForce (body, force);
    NewtonBodyAddTorque (body, torque);
   }

Entity* MakeEntity(vector3df loc)
  {
    Entity *tmp = new Entity;
    tmp->mesh = smgr->getMesh("barrel.obj");
    tmp->node = smgr->addAnimatedMeshSceneNode(tmp->mesh);
    tmp->node->setMaterialTexture(0, driver->getTexture("wood.jpg"));
    tmp->node->setMaterialFlag(EMF_LIGHTING, false);

    tmp->collision = NewtonCreateBox(nWorld, 1000, 1500, 1000, NULL);
    tmp->body = NewtonCreateBody(nWorld, tmp->collision);

    NewtonBodySetUserData(tmp->body, tmp->node);

    NewtonBodySetMassMatrix (tmp->body, 1.0f, 150.0f, 150.0f, 150.0f);

    NewtonBodySetTransformCallback(tmp->body, SetMeshTransformEvent);
    NewtonBodySetForceAndTorqueCallback(tmp->body, ApplyForceAndTorqueEvent);

    NewtonBodySetAutoFreeze (tmp->body, 0);

    float omega[3]; omega[0] = 1.0f; omega[1] = 0.0f; omega[2] = 0.0f;
    NewtonBodySetOmega (tmp->body, &omega[0]);

    CMatrix4<float> mat;

    mat.setTranslation(loc);
    NewtonBodySetMatrix(tmp->body, mat.pointer());

    if (currentEntity == 512)
        {
            printf("* Too many entities!");
        }

    entities[currentEntity] = tmp;
    currentEntity ++;
    return tmp;
   }

class MyEventReceiver : public IEventReceiver
{
        public:
        // This is the one method that we have to implement
        virtual bool OnEvent(const SEvent& event)
    {
        // Remember whether each key is down or up
        if (event.EventType == irr::EET_KEY_INPUT_EVENT)
        KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;

        return false;
    }

// This is used to check whether a key is being held down
    virtual bool IsKeyDown(EKEY_CODE keyCode) const
        {
            return KeyIsDown[keyCode];
        }

    MyEventReceiver()
    {
        for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
        KeyIsDown[i] = false;
    }

    private:
    // We use this array to store the current state of each key
    bool KeyIsDown[KEY_KEY_CODES_COUNT];
};

int main(int argc, char* argv[])
   {

    MyEventReceiver receiver;
    device = createDevice(EDT_OPENGL, dimension2d<s32>(800, 600), 16, false, true, false, &receiver);

    driver = device->getVideoDriver();
    smgr = device->getSceneManager();
    guienv = device->getGUIEnvironment();

    nWorld = NewtonCreate(NULL, NULL);

    int i = NewtonMaterialGetDefaultGroupID(nWorld);
    NewtonMaterialSetDefaultFriction (nWorld, i, i, 0.8f, 0.4f);
    NewtonMaterialSetDefaultElasticity (nWorld, i, i, 0.3f);
    NewtonMaterialSetDefaultSoftness (nWorld, i, i, 0.05f);
    NewtonMaterialSetCollisionCallback (nWorld, i, i, NULL, NULL, NULL, NULL);


    SKeyMap keyMap[8];
    keyMap[1].Action = EKA_MOVE_FORWARD; keyMap[1].KeyCode = KEY_KEY_W;
    keyMap[2].Action = EKA_JUMP_UP; keyMap[2].KeyCode = KEY_SPACE;
    keyMap[3].Action = EKA_MOVE_BACKWARD; keyMap[3].KeyCode = KEY_KEY_S;
    keyMap[5].Action = EKA_STRAFE_LEFT; keyMap[5].KeyCode = KEY_KEY_A;
    keyMap[7].Action = EKA_STRAFE_RIGHT; keyMap[7].KeyCode = KEY_KEY_D;

    cam = smgr->addCameraSceneNodeFPS(0,100.0f,5.0f,-1, keyMap, 8);
    cam->setPosition(core::vector3df(0,1000,0));
    cam->setAspectRatio(16.0f/9.0f);
    cam->setFarValue(100000.0f);


    lasttick = 0;
    currentEntity = 0;

    g_map = smgr->getMesh("battlemap.obj");
    g_mapnode = smgr->addOctTreeSceneNode(g_map->getMesh(0));
    g_mapnode->setMaterialFlag(EMF_LIGHTING, false);

    g_newtonmap = NewtonCreateTreeCollision(nWorld, NULL);

    NewtonTreeCollisionBeginBuild(g_newtonmap);
    int cMeshBuffer, j;
    int v1i, v2i, v3i;
    IMeshBuffer *mb;

    float vArray[9];

for (cMeshBuffer=0; cMeshBuffer<g_map->getMesh(0)->getMeshBufferCount(); cMeshBuffer++)
   {
        mb = g_map->getMesh(0)->getMeshBuffer(cMeshBuffer);
        video::S3DVertex* mb_vertices = (irr::video::S3DVertex2TCoords*)mb->getVertices();
        u16* mb_indices = mb->getIndices();

for (j=0; j<mb->getIndexCount(); j+=3)
   {
    v1i = mb_indices[j];
    v2i = mb_indices[j+1];
    v3i = mb_indices[j+2];

    vArray[0] = mb_vertices[v1i].Pos.X;
    vArray[1] = mb_vertices[v1i].Pos.Y;
    vArray[2] = mb_vertices[v1i].Pos.Z;
    vArray[3] = mb_vertices[v2i].Pos.X;
    vArray[4] = mb_vertices[v2i].Pos.Y;
    vArray[5] = mb_vertices[v2i].Pos.Z;
    vArray[6] = mb_vertices[v3i].Pos.X;
    vArray[7] = mb_vertices[v3i].Pos.Y;
    vArray[8] = mb_vertices[v3i].Pos.Z;

    NewtonTreeCollisionAddFace(g_newtonmap, 3, (float*)vArray, 12, 1);
   }

   }
NewtonTreeCollisionEndBuild(g_newtonmap, 0);
g_newtonmapbody = NewtonCreateBody(nWorld, g_newtonmap);

float boxP0[3];
float boxP1[3];
float matrix[4][4];
NewtonBodyGetMatrix (g_newtonmapbody, &matrix[0][0]);
NewtonCollisionCalculateAABB (g_newtonmap, &matrix[0][0], &boxP0[0], &boxP1[0]);
printf("min: %f,%f,%f max: %f,%f,%f\n",boxP0[0],boxP0[1],boxP0[2],boxP1[0],
boxP1[1],boxP1[2]);

boxP0[1] -= 1000000.0f;
boxP1[1] += 1000000.0f;
NewtonSetWorldSize (nWorld, (float*)boxP0, (float*)boxP1);

device->getCursorControl()->setVisible(false);

int xo = 5000, yo = 5000;
int x, y;
for (x=0; x<10; x++)
    {
        for (y=0; y<10; y++)
    {
        MakeEntity(vector3df((float)(x*1500)-xo, -4000.0f, (float)(y*1500)-yo));
    }
    }

NewtonSetSolverModel(nWorld, 0);
NewtonSetFrictionModel(nWorld, 0);

cam->setPosition(vector3df(500, 500, -500));
cam->setTarget(vector3df(0, 0, -500));

// Main Loop:
while(device->run())
   {
    driver->beginScene(true, true, video::SColor(0,220,220,255));

    // Render the scene:
    smgr->drawAll();

    driver->endScene();

    // Draw fps counter:
    int fps = driver->getFPS();
    int lastFPS;
    if (lastFPS != fps)
        {
            wchar_t tmp[1024];
            swprintf(tmp, 1024, L"Newton Example [fps:%d] [triangles:%d]",
            fps, driver->getPrimitiveCountDrawn());
            device->setWindowCaption(tmp);
            lastFPS = fps;
        }

// Update newton 100 times / second:
if (device->getTimer()->getTime() > lasttick + 10)
   {
    lasttick = device->getTimer()->getTime();
    NewtonUpdate(nWorld, 0.01f);
   }

if(receiver.IsKeyDown(irr::KEY_KEY_Q))
   {
    // make a cube where the camera is and set its velocity to follow the target:
    Entity *tmp = MakeEntity(cam->getPosition());
    if (!tmp) return false;
    vector3df camvec = (cam->getTarget() - cam->getPosition()).normalize() * 500;
    float newpos[3] = { camvec.X, camvec.Y, camvec.Z };
    NewtonBodySetVelocity(tmp->body, (float*)newpos);
    }
}

// Clean up memory:

// Release the collision tree:
NewtonReleaseCollision(nWorld, g_newtonmap);

// Release the box primitives:
for (int i=0; i<currentEntity; i++)
NewtonReleaseCollision(nWorld, entities[i]->collision);

// Finish Newton & Irrlicht:
NewtonDestroy(nWorld);
device->drop();

return 0;
}
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

well, it's hard to test the code without having the needed assets... :roll: :lol:
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Alpha Omega
Posts: 288
Joined: Wed Oct 29, 2008 12:07 pm

Post by Alpha Omega »

Ahhh ok so code blocks has the option to create Irrlicht applications so do you need to link specifically to the Irrlicht Lib's and DLL's? I havent been and have been compiling fine until this problem so I just manually linked to the Irrlicht Lib's and DLL's and got a crash :shock:

I have recompiled the Irrlicht.a and the Irrlicht.dll and still have a crash.... :shock:
Post Reply