void CDemo::shoot() { scene::ISceneManager* sm = device->getSceneManager(); scene::ICameraSceneNode* camera = sm->getActiveCamera(); if (!camera || !mapSelector) return; SParticleImpact imp; imp.when = 0; // get line of camera core::vector3df start = camera->getPosition(); core::vector3df end = (camera->getTarget() - start); end.normalize(); start += end*5.0f; end = start + (end * camera->getFarValue()); core::triangle3df triangle; core::line3d line(start, end); // get intersection point with map if (sm->getSceneCollisionManager()->getCollisionPoint( line, mapSelector, end, triangle)) { // collides with wall core::vector3df out = triangle.getNormal(); out.setLength(0.03f); imp.when = 1; imp.outVector = out; imp.pos = end; } else { // doesnt collide with wall end = (camera->getTarget() - start); end.normalize(); end = start + (end * 1000); } // create fire ball scene::ISceneNode* node = 0; node = sm->addBillboardSceneNode(0, core::dimension2d(25,25), start); node->setMaterialFlag(video::EMF_LIGHTING, false); node->setMaterialTexture(0, device->getVideoDriver()->getTexture("../../media/fireball.bmp")); node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); f32 length = (f32)(end - start).getLength(); const f32 speed = 0.6f; u32 time = (u32)(length / speed); scene::ISceneNodeAnimator* anim = 0; // set flight line anim = sm->createFlyStraightAnimator(start, end, time); node->addAnimator(anim); anim->drop(); anim = sm->createDeleteAnimator(time); node->addAnimator(anim); anim->drop(); if (imp.when) { // create impact note imp.when = device->getTimer()->getTime() + (time - 100); Impacts.push_back(imp); } // play sound #ifdef USE_IRRKLANG if (ballSound) irrKlang->play2D(ballSound); #endif #ifdef USE_SDL_MIXER if (ballSound) playSound(ballSound); #endif }