Need Some Guru help.
im trying to make a splinter cell style camera. this Code. works perfectly. except. if you move the mouse. while your loading the program it crashes. and sometimes the model rotates the long way around to get to his desired position.
any help to fix these two problems is greatly appreciated.
//this is Cdemo.h
#include <irrlicht.h>
#include <audiere.h> // your compiler throws an error here? get audiere from
// http://audiere.sourceforge.net
using namespace audiere;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class CDemo : public IEventReceiver
{
public:
CDemo(bool fullscreen, bool music, bool shadows, bool additive,
EDriverType driver);
~CDemo();
void run();
virtual bool OnEvent(SEvent event);
//private:
void createLoadingScreen();
void loadSceneData();
void switchToNextScene();
void update();
bool fullscreen;
bool music;
bool shadows;
bool additive;
EDriverType driverType;
IrrlichtDevice *device;
bool keys[KEY_KEY_CODES_COUNT];
void startAudiere();
AudioDevicePtr audiereDevice;
OutputStreamPtr stream;
s8 currentScene;
u32 sceneStartTime;
s32 timeForThisScene;
SColor backColor;
IAnimatedMesh* quakeLevelMesh;
ISceneNode* quakeLevelNode;
ISceneNode* skyboxNode;
IAnimatedMeshSceneNode* model1;
IAnimatedMeshSceneNode* model2;
IBillboardSceneNode* bill;
IBillboardSceneNode* bill2;
ILightSceneNode* light;
ILightSceneNode* light2;
IMetaTriangleSelector* metaSelector;
ITriangleSelector* mapSelector;
ICameraSceneNode* camera;
ISceneManager* sm;// = device->getSceneManager();
f32 degrees;
f32 degreesModel;
f32 degreesCam;
f32 height;
u32 target;
bool move;
bool rotate;
bool up;
bool down;
bool left;
bool right;
s32 direction;
void CDemo::doMove(u32 direction);
position2d<s32> m;
f32 mouseSen;
u32 then;
u32 now;
f32 timeCorrect;
f32 moveSpeed;
f32 mouseWheel2;
u32 mouseWheel;
f32 rotSpeed;
ISceneNodeAnimator* go;
};
/////////////////////////////////////////////////////////////////////////////////
//this is Cdemo.cpp
#include "CDemo.h"
using namespace irr;
int main()
{
bool fullscreen = false;
bool music = false;
bool shadows = false;
bool additive = false;
EDriverType driverType = EDT_DIRECTX9;
CDemo demo(fullscreen, music, shadows, additive, driverType);
demo.run();
return 0;
}
CDemo::CDemo(bool f, bool m, bool s, bool a, EDriverType d)
: fullscreen(f), music(m), shadows(s), additive(a), driverType(d),
device(0), currentScene(-2), timeForThisScene(0)//, quakeLevelMesh(0),
// quakeLevelNode(0), skyboxNode(0), mapSelector(0), metaSelector(0)
{
}
CDemo::~CDemo()
{
if (mapSelector)
mapSelector->drop();
if (metaSelector)
metaSelector->drop();
}
void CDemo::run()
{
for(int x = 0; x < KEY_KEY_CODES_COUNT; x++) keys[x] = false;
degrees = 0;
degreesModel = 360;
degreesCam = 360;
height = 40.0f;
move = false;
rotate = false;
up = false;
down = false;
left = false;
right = false;
direction = 0;
mouseSen = 3.0f;
moveSpeed = 100.0f;
mouseWheel = 100;
rotSpeed = 3.0f;
target = (u32)(degreesModel - degreesCam);
device = createDevice(driverType, dimension2d<s32>(640,480), 16,
fullscreen, shadows, this);
device->getCursorControl()->setPosition(position2d<s32>(400,300));
device->getFileSystem()->addZipFileArchive("data\\levels\\t7.zip");
IVideoDriver* driver = device->getVideoDriver();
driver->setAmbientLight(SColorf(0.2f,0.2f,0.2f,0.0f));
driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true);
ISceneManager* smgr = device->getSceneManager();
int fps;
wchar_t tmp[1024];
while(device->run() && driver)
{
then = device->getTimer()->getTime();
if (device->isWindowActive())
{
fps = driver->getFPS();
// load next scene if necessary
if (then - sceneStartTime > timeForThisScene && timeForThisScene!=-1)
switchToNextScene();
m = device->getCursorControl()->getPosition();
update();
device->getCursorControl()->setPosition(position2d<s32>(400,300));
// draw everything
driver->beginScene(true, true, backColor);
smgr->drawAll();
driver->endScene();
}
now = device->getTimer()->getTime() - then;
timeCorrect = now * 0.001f;
}
device->drop();
}
bool CDemo::OnEvent(SEvent event)
{
if (!device)
return false;
if (event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.Key == KEY_ESCAPE &&
event.KeyInput.PressedDown == false)
{
// user wants to quit.
if (currentScene < 1)
timeForThisScene = 0;
else
device->closeDevice();
}
else
if(event.EventType == EET_KEY_INPUT_EVENT)
{
keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
return true;
}
if (event.EventType == EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Wheel != mouseWheel)
{
mouseWheel2 = event.MouseInput.Wheel;
mouseWheel += (u32)mouseWheel2;
}
else
return false;
}
void CDemo::switchToNextScene()
{
currentScene++;
if (currentScene > 3)
currentScene = 1;
ISceneManager* sm = device->getSceneManager();
camera = sm->getActiveCamera();
if (camera)
{
sm->setActiveCamera(0);
camera->remove();
}
switch(currentScene)
{
case -1: // loading screen
timeForThisScene = 0;
createLoadingScreen();
break;
case 0: // load scene
timeForThisScene = 0;
loadSceneData();
break;
case 1: // interactive, go around
{
timeForThisScene = -1;
camera = sm->addCameraSceneNode(0, model1->getPosition() +
vector3df(100,40,0), model1->getPosition());
}
break;
}
}
void CDemo::loadSceneData()
{
// load quake level
IVideoDriver* driver = device->getVideoDriver();
sm = device->getSceneManager();
quakeLevelMesh = sm->getMesh("t7.bsp");
if (quakeLevelMesh)
{
quakeLevelNode = sm->addOctTreeSceneNode(quakeLevelMesh->getMesh(0));
if (quakeLevelNode)
{
quakeLevelNode->setVisible(true);
quakeLevelNode->setMaterialType(EMT_LIGHTMAP_M2);
// create map triangle selector
mapSelector = sm->createOctTreeTriangleSelector(
quakeLevelMesh->getMesh(0), quakeLevelNode, 128);
// set additive blending if wanted
if (additive)
quakeLevelNode->setMaterialType(EMT_LIGHTMAP_ADD);
}
}
// load goblin
IAnimatedMesh* mesh = 0;
mesh = sm->getMesh("data\\goblin\\tris.md2");
if (mesh)
{
model1 = sm->addAnimatedMeshSceneNode(mesh);
if (model1)
{
model1->setMaterialTexture(0, driver->getTexture(
"data\\goblin\\hobgoblin.jpg"));
model1->setPosition(vector3df(-100,56,-150));
model1->setScale(vector3df(2,2,2));
model1->setFrameLoop(0, 310);
model1->setMaterialFlag(EMF_LIGHTING, true);
model1->setRotation(vector3df(0,180,0));
model1->addShadowVolumeSceneNode();
}
}
// load gate
mesh = sm->getMesh("data\\objects\\gate\\gate.ms3d");
if (mesh)
{
model2 = sm->addAnimatedMeshSceneNode(mesh);
if (model2)
{
model2->setMaterialTexture(0, driver->getTexture(
"data\\objects\\gate\\grey.jpg"));
model2->setPosition(vector3df(120,160,360));
model2->setScale(vector3df(15,15,15));
model2->setMaterialFlag(EMF_LIGHTING, true);
model2->setRotation(vector3df(0,90,0));
model2->addShadowVolumeSceneNode();
sm->setShadowColor(SColor(200,0,0,0));
}
}
//create a light
light = sm->addLightSceneNode(0, vector3df(370,250,250),
SColorf(1.0f, 1.0f, 1.0f, 1.0f), 190);
bill = sm->addBillboardSceneNode(light, dimension2d<f32>(50, 50));
bill->setMaterialFlag(EMF_LIGHTING, false);
bill->setMaterialType(EMT_TRANSPARENT_ADD_COLOR);
bill->setMaterialTexture(0, driver->getTexture(
"data\\light\\particlewhite.bmp"));
//bill->setVisible(false);
//create a light 2
light2 = sm->addLightSceneNode(0, vector3df(-100,250,-200),
SColorf(1.0f, 1.0f, 1.0f, 1.0f), 190);
bill2 = sm->addBillboardSceneNode(light2, dimension2d<f32>(50, 50));
bill2->setMaterialFlag(EMF_LIGHTING, false);
bill2->setMaterialType(EMT_TRANSPARENT_ADD_COLOR);
bill2->setMaterialTexture(0, driver->getTexture(
"data\\light\\particlewhite.bmp"));
//bill->setVisible(false);
// create sky box
skyboxNode = sm->addSkyBoxSceneNode(
driver->getTexture("data\\skybox\\irrlicht2_up.bmp"),
driver->getTexture("data\\skybox\\irrlicht2_dn.bmp"),
driver->getTexture("data\\skybox\\irrlicht2_lf.bmp"),
driver->getTexture("data\\skybox\\irrlicht2_rt.bmp"),
driver->getTexture("data\\skybox\\irrlicht2_ft.bmp"),
driver->getTexture("data\\skybox\\irrlicht2_bk.bmp"));
//create meta triangle selector with all triangles selectors in it.
metaSelector = sm->createMetaTriangleSelector();
metaSelector->addTriangleSelector(mapSelector);
// load music
if (music)
startAudiere();
}
void CDemo::createLoadingScreen()
{
device->getCursorControl()->setVisible(false);
// setup loading screen
backColor.set(0,0,0,0);
}
void CDemo::startAudiere()
{
audiereDevice = OpenDevice();
if (!audiereDevice)
return;
stream = OpenSound(audiereDevice.get(),
"data\\music\\IrrlichtTheme.mp3", true);
stream->setRepeat(true);
stream->setVolume(0.5f); // 50% volume
stream->play();
}
void CDemo::update()
{
if(keys[KEY_KEY_W])
{
move = true;
up = true;
direction = 0;
}
if(keys[KEY_KEY_S])
{
move = true;
down = true;
direction = -180;
}
if(keys[KEY_KEY_A])
{
move = true;
left = true;
direction = -90;
}
if(keys[KEY_KEY_D])
{
move = true;
right = true;
direction = 90;
}
//if(keys[KEY_UP])
if(m.Y > 300)
{
rotate = true;
height += mouseSen;
if (height >= 90.0f) height = 90.0f;
}
//if(keys[KEY_DOWN])
if(m.Y < 300)
{
rotate = true;
height -= mouseSen;
if (height <= -45.0f) height = -45.0f;
}
//if(keys[KEY_LEFT])
if(m.X < 400)
{
target = (u32)(degreesModel - degreesCam);
while(abs(target) > 360)
{
target -= 360;
}
rotate = true;
degrees += mouseSen;
degreesCam -= mouseSen;
}
//if(keys[KEY_RIGHT])
if(m.X > 400)
{
target = (u32)(degreesModel - degreesCam);
while(abs(target) > 360)
{
target -= 360;
}
rotate = true;
degrees -= mouseSen;
degreesCam += mouseSen;
}
if (mouseWheel != 100)
{
if (mouseWheel > 100)
{
moveSpeed += 100.0f;
mouseWheel = 100;
}
if (mouseWheel < 100)
{
moveSpeed -= 100.0f;
mouseWheel = 100;
}
}
// correction for multiple keys
if (move)
{
if (up && right)
{
direction = 45;
}
if (up && left)
{
direction = -45;
}
if (down && right)
{
direction = 135;
}
if (down && left)
{
direction = -135;
}
if (degreesModel > degreesCam + direction)
{
model1->setRotation(model1->getRotation() + vector3df(0,-rotSpeed,0));
degreesModel -= rotSpeed;
}
if (degreesModel < degreesCam + direction)
{
model1->setRotation(model1->getRotation() + vector3df(0,rotSpeed,0));
degreesModel += rotSpeed;
}
if (degreesModel == degreesCam + direction)
{
doMove(direction);
}
}
if(rotate)
{
doMove(direction);
}
}
void CDemo::doMove(u32 dir)
{
if (up || down || left || right)
{
// this Comment is old code
// Rotate the Model
// model1->setRotation(vector3df(0,degreesCam,0) +
// vector3df(0,direction,0));
// Create movement directions based on node's orientation
vector3df forward( (f32)sin( model1->getRotation().Y * GRAD_PI2 ), 0,
(f32)cos( model1->getRotation().Y * GRAD_PI2 ) );
//MD2 format specifies positive-X as 'forward',
// so we need to rotate the model
forward.rotateXZBy(-90, vector3df(0,0,0) ); //hack for md2
forward = forward.normalize();
go = sm->createFlyStraightAnimator(model1->getPosition(),
model1->getPosition() + forward * moveSpeed * timeCorrect, 1, false);
model1->addAnimator(go);
// model1->setPosition(model1->getPosition() + forward * moveSpeed * timeCorrect);
}
// Move the Circle Cam
camera->setPosition(model1->getPosition() +
vector3df( (cos(degrees*(GRAD_PI2))*100.0f),
height, (sin(degrees*(GRAD_PI2))*100.0f)) );
camera->setTarget(model1->getPosition());
// reset vars
move = false;
rotate = false;
up = false;
down = false;
left = false;
right = false;
}
thanks again.
Need Some Guru help
-
Guest