1) Added support for sky-domes (this needs to be nicer, this is

only a proof of concept (sky boxes are wip).
2) Started work on explosions using the particle engine.
3) Removed plunger when the rubber band snaps.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3274 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2009-03-17 02:52:58 +00:00
parent 11b35c3fa9
commit 9bc24c6a4e
10 changed files with 161 additions and 56 deletions

View File

@ -19,6 +19,9 @@
#include "explosion.hpp"
#include "material.hpp"
#include "material_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "items/projectile_manager.hpp"
#include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp"
@ -27,7 +30,53 @@
Explosion::Explosion(const Vec3& coord, const int explosion_sound)
{
m_mesh = projectile_manager->getExplosionModel();
m_node = irr_driver->addParticleNode();
scene::IParticleEmitter* em = m_node->createBoxEmitter(
core::aabbox3d<f32>(-7,0,-7,7,1,7), // emitter size
core::vector3df(0.0f,0.06f,0.0f), // initial direction
80,100, // emit rate
video::SColor(0,255,255,255), // darkest color
video::SColor(0,255,255,255), // brightest color
800,2000,0, // min and max age, angle
core::dimension2df(10.f,10.f), // min size
core::dimension2df(20.f,20.f)); // max size
m_node->setEmitter(em); // this grabs the emitter
em->drop(); // so we can drop it here without deleting it
scene::IParticleAffector* paf = m_node->createFadeOutParticleAffector();
m_node->addAffector(paf); // same goes for the affector
paf->drop();
//scene::IParticleEmitter *em =
// m_node->createPointEmitter(Vec3(0, 0, 1).toIrrVector(),
// 5, 10 // min and max particles per second
// );
//m_node->setEmitter(em);
//em->drop();
//scene::IParticleAffector *paf =
// m_node->createGravityAffector(Vec3(0, 0, -5).toIrrVector());
//m_node->addAffector(paf);
//paf->drop();
//paf = m_node->createFadeOutParticleAffector();
//m_node->addAffector(paf);
//paf->drop();
m_node->setPosition(coord.toIrrVector());
m_node->setPosition(core::vector3df(5, 5, 5));
m_node->setScale(core::vector3df(2,2,2));
m_node->setMaterialFlag(video::EMF_LIGHTING, false);
m_node->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
Material *m = material_manager->getMaterial("lava.png");
m_node->setMaterialTexture(0, m->getTexture());
m_node->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);
m_explode_sound = sfx_manager->newSFX( (SFXManager::SFXType)explosion_sound );
init(coord);
} // Explosion
@ -47,12 +96,6 @@ void Explosion::init(const Vec3& coord)
m_explode_sound->position(coord);
m_explode_sound->play();
sgCoord c;
c.xyz[0]=coord[0];c.xyz[1]=coord[1];c.xyz[2]=coord[2];
c.hpr[0]=0; c.hpr[1]=0; c.hpr[2]=0;
//setTransform(&c);
m_step = -1;
//stk_scene->add(this);
m_has_ended = false;
}

View File

@ -20,33 +20,26 @@
#ifndef HEADER_EXPLOSION_HPP
#define HEADER_EXPLOSION_HPP
#include "irrlicht.h"
using namespace irr;
class Vec3;
class SFXBase;
namespace irr
{
namespace scene
{
class IMesh;
class ISceneNode;
}
}
class Explosion
{
private:
SFXBase* m_explode_sound;
bool m_has_ended;
irr::scene::IMesh *m_mesh;
irr::scene::ISceneNode *m_node;
SFXBase* m_explode_sound;
bool m_has_ended;
scene::IParticleSystemSceneNode
*m_node;
public:
int m_step ;
Explosion(const Vec3& coord, const int explosion_sound);
~Explosion();
void init (const Vec3& coord);
void update (float delta_t);
int inUse () { return (m_step >= 0); }
int inUse ();
bool hasEnded () { return m_has_ended; }
} ;

View File

@ -102,6 +102,14 @@ scene::ISceneNode *IrrDriver::addOctTree(scene::IMesh *mesh)
return m_scene_manager->addOctTreeSceneNode(mesh);
} // addOctTree
// ----------------------------------------------------------------------------
/** Adds a particle scene node.
*/
scene::IParticleSystemSceneNode *IrrDriver::addParticleNode(bool default_emitter)
{
return m_scene_manager->addParticleSystemSceneNode(default_emitter);
} // addParticleNode
// ----------------------------------------------------------------------------
/** Adds a static mesh to scene. This should be used for smaller objects,
* since the node is not optimised.
@ -139,6 +147,30 @@ scene::ISceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *mesh)
return m_scene_manager->addAnimatedMeshSceneNode(mesh);
} // addAnimatedMesh
// ----------------------------------------------------------------------------
/** Adds a sky dome. Documentation from irrlicht:
* A skydome is a large (half-) sphere with a panoramic texture on the inside
* and is drawn around the camera position.
* \param texture: Texture for the dome.
* \param horiRes: Number of vertices of a horizontal layer of the sphere.
* \param vertRes: Number of vertices of a vertical layer of the sphere.
* \param texturePercentage: How much of the height of the texture is used.
* Should be between 0 and 1.
* \param spherePercentage: How much of the sphere is drawn. Value should be
* between 0 and 2, where 1 is an exact half-sphere and 2 is a full
* sphere.
*/
scene::ISceneNode *IrrDriver::addSkyDome(const std::string &texture_name,
int hori_res, int vert_res,
float texture_percent,
float sphere_percent)
{
ITexture *texture = getTexture(texture_name);
return m_scene_manager->addSkyDomeSceneNode(texture, hori_res, vert_res,
texture_percent,
sphere_percent);
} // addSkyDome
// ----------------------------------------------------------------------------
/** Adds a camera to the scene.
*/

View File

@ -52,6 +52,11 @@ public:
video::ITexture *getTexture(const std::string &filename);
scene::ISceneNode *addOctTree(scene::IMesh *mesh);
scene::ISceneNode *addMesh(scene::IMesh *mesh);
scene::IParticleSystemSceneNode
*addParticleNode(bool default_emitter=true);
scene::ISceneNode *addSkyDome(const std::string &texture, int hori_res,
int vert_res, float texture_percent,
float sphere_percent);
void removeNode(scene::ISceneNode *node);
void removeMesh(scene::IMesh *mesh);
scene::ISceneNode *addAnimatedMesh(scene::IAnimatedMesh *mesh);

View File

@ -42,7 +42,8 @@ Attachment::Attachment(Kart* _kart)
//-----------------------------------------------------------------------------
Attachment::~Attachment()
{
irr_driver->removeNode(m_node);
if(m_node)
irr_driver->removeNode(m_node);
} // ~Attachment
//-----------------------------------------------------------------------------

View File

@ -257,7 +257,7 @@ void Flyable::hit(Kart *kart_hit, MovingPhysics* moving_physics)
projectile_manager->notifyRemove();
// Now remove this projectile from the graph:
irr_driver->removeMesh(m_mesh);
irr_driver->removeNode(getNode());
// The explosion is a bit higher in the air
Vec3 pos_explosion=getXYZ();

View File

@ -20,6 +20,7 @@
#include "items/plunger.hpp"
#include "race_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/scene.hpp"
#include "items/rubber_band.hpp"
#include "items/projectile_manager.hpp"
@ -106,11 +107,7 @@ Plunger::~Plunger()
} // ~Plunger
// -----------------------------------------------------------------------------
#ifdef HAVE_IRRLICHT
void Plunger::init(const lisp::Lisp* lisp, scene::IMesh *plunger_model)
#else
void Plunger::init(const lisp::Lisp* lisp, ssgEntity *plunger_model)
#endif
{
Flyable::init(lisp, plunger_model, POWERUP_PLUNGER);
} // init
@ -126,12 +123,6 @@ void Plunger::update(float dt)
{
setHasHit();
projectile_manager->notifyRemove();
#ifdef HAVE_IRRLICHT
#else
ssgTransform *m = getModelTransform();
m->removeAllKids();
stk_scene->remove(m);
#endif
}
if(m_rubber_band != NULL) m_rubber_band->update(dt);
return;
@ -178,10 +169,7 @@ void Plunger::hit(Kart *kart, MovingPhysics *mp)
// objects is simply removed from the scene graph, it might be auto-deleted
// because the ref count reaches zero.
Vec3 hell(0, 0, -10000);
#ifdef HAVE_IRRLICHT
#else
getModelTransform()->setTransform(hell.toFloat());
#endif
getNode()->setPosition(hell.toIrrVector());
RaceManager::getWorld()->getPhysics()->removeBody(getBody());
}
else
@ -191,11 +179,12 @@ void Plunger::hit(Kart *kart, MovingPhysics *mp)
// Make this object invisible by placing it faaar down. Not that if this
// objects is simply removed from the scene graph, it might be auto-deleted
// because the ref count reaches zero.
Vec3 hell(0, 0, -10000);
#ifdef HAVE_IRRLICHT
#else
getModelTransform()->setTransform(hell.toFloat());
#endif
scene::ISceneNode *node = getNode();
if(node)
{
Vec3 hell(0, 0, -10000);
getNode()->setPosition(hell.toIrrVector());
}
RaceManager::getWorld()->getPhysics()->removeBody(getBody());
if(kart)

View File

@ -20,10 +20,8 @@
#ifndef HEADER_MISSILE_HPP
#define HEADER_MISSILE_HPP
#ifdef HAVE_IRRLICHT
#include "irrlicht.h"
using namespace irr;
#endif
#include "flyable.hpp"
class RubberBand;
@ -42,11 +40,7 @@ private:
public:
Plunger(Kart *kart);
~Plunger();
#ifdef HAVE_IRRLICHT
static void init(const lisp::Lisp* lisp, scene::IMesh* missile);
#else
static void init (const lisp::Lisp* lisp, ssgEntity* missile);
#endif
static void init(const lisp::Lisp* lisp, scene::IMesh* missile);
/** Sets the keep-alive value. Setting it to 0 will remove the plunger
* at the next update - which is used if the rubber band snaps.
*/

View File

@ -65,7 +65,6 @@ Track::Track( std::string filename_, float w, float h, bool stretch )
m_description = "";
m_designer = "";
m_screenshot = "";
m_top_view = "";
m_version = 0;
m_track_mesh = new TriangleMesh();
m_non_collision_mesh = new TriangleMesh();
@ -867,6 +866,9 @@ void Track::loadTrack(const std::string &filename)
const XMLNode *node = xml->getNode("track");
if(!node)
{
std::ostringstream o;
o<<"Can't load track '"<<filename<<"', no track element.";
throw std::runtime_error(o.str());
}
node->get("name", &m_name);
node->get("description", &m_description);
@ -877,10 +879,8 @@ void Track::loadTrack(const std::string &filename)
getMusicInformation(filenames, m_music);
node->get("item", &m_item_style);
node->get("screenshot", &m_screenshot);
node->get("topview", &m_top_view);
node->get("item", &m_item_style);
node->get("screenshot", &m_screenshot);
node->get("topview", &m_top_view);
node->get("sky-color", &m_sky_color);
node->get("start-x", &m_start_x);
node->get("start-y", &m_start_y);
@ -908,9 +908,34 @@ void Track::loadTrack(const std::string &filename)
&m_camera_final_hpr) !=1;
m_camera_final_hpr.degreeToRad();
m_sky_type = SKY_NONE;
node = xml->getNode("sky-dome");
if(node)
{
m_sky_type = SKY_DOME;
m_sky_vert_segments = 16;
m_sky_hori_segments = 16;
m_sky_sphere_percent = 1.0f;
m_sky_texture_percent = 1.0f;
std::string s;
node->get("texture", &s );
m_sky_textures.push_back(s);
node->get("vertical", &m_sky_vert_segments );
node->get("horizontal", &m_sky_hori_segments );
node->get("sphere-percent", &m_sky_sphere_percent );
node->get("texture-percent", &m_sky_texture_percent);
} // if sky-dome
node = xml->getNode("sky-box");
if(node)
{
m_sky_type = SKY_BOX;
} // if sky-box
// Set the correct paths
m_screenshot = file_manager->getTrackFile(m_screenshot, getIdent());
m_top_view = file_manager->getTrackFile(m_top_view, getIdent());
} // loadTrack
//-----------------------------------------------------------------------------
@ -1480,6 +1505,15 @@ void Track::loadTrackModel()
fclose ( fd ) ;
#endif
if(m_sky_type==SKY_DOME)
{
irr_driver->addSkyDome(m_sky_textures[0],
m_sky_hori_segments, m_sky_vert_segments,
m_sky_texture_percent, m_sky_sphere_percent);
}
else if(m_sky_type==SKY_BOX)
{
}
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath ();

View File

@ -48,7 +48,6 @@ private:
float m_gravity;
std::string m_ident;
std::string m_screenshot;
std::string m_top_view;
std::vector<MusicInformation*> m_music;
std::vector<float> m_start_x, m_start_y, m_start_z, m_start_heading;
std::string m_item_style;
@ -67,6 +66,22 @@ private:
bool m_is_arena;
int m_version;
bool loadMainTrack(const XMLNode &node);
/** The type of sky to be used for the track. */
enum {SKY_NONE, SKY_BOX,
SKY_DOME} m_sky_type;
/** A list of the textures for the sky to use. It contains one texture
* in case of a dome, and 6 textures for a box. */
std::vector<std::string> m_sky_textures;
/** If a sky dome is used, the number of horizontal segments
* the sphere should be divided in. */
int m_sky_hori_segments;
/** If a sky dome is used, the number of vertical segments
* the sphere should be divided in. */
int m_sky_vert_segments;
/** If a sky dome is used, percentage of the sphere to be used. */
float m_sky_sphere_percent;
/** If a sky dome is used, percentage of the texture to be used. */
float m_sky_texture_percent;
public:
enum RoadSide{ RS_DONT_KNOW = -1, RS_LEFT = 0, RS_RIGHT = 1 };
@ -182,7 +197,6 @@ public:
const float& getFogEnd () const {return m_fog_end; }
const std::string& getDescription () const {return m_description; }
const std::string& getDesigner () const {return m_designer; }
const std::string& getTopviewFile () const {return m_top_view; }
const std::string& getScreenshotFile () const {return m_screenshot; }
const std::vector<SGfloat>& getWidth () const {return m_path_width; }
const std::string& getItemStyle () const {return m_item_style; }