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;
}