Work on water splash effect a bit; only lighthouse was changed for now, we can change other tracks when Joerg modified the track exported. The effect can still be improved of course, I mostly did the basic code aspect

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7375 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria
2011-01-12 03:01:57 +00:00
parent e5a5a7dc33
commit 03af38c9b0
9 changed files with 122 additions and 33 deletions

30
data/splash.xml Normal file
View File

@@ -0,0 +1,30 @@
<?xml version="1.0"?>
<particles emitter="box" box_x="0.75" box_y="0.75" box_z="0.75">
<spreading angle="120" />
<velocity x="0.000"
y="0.009"
z="0.000" />
<material file="water-splash.png" />
<!-- Amount of particles emitted per second -->
<rate min="1000"
max="1200" />
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
<lifetime min="600"
max="900" />
<!-- Size of the particles -->
<size min="0.60"
max="0.90" />
<color min="255 255 255"
max="255 255 255" />
<!-- How much time in milliseconds before the particle is fully faded out -->
<fadeout time="500" />
</particles>

View File

@@ -285,24 +285,26 @@ void Camera::computeNormalCameraPosition(Vec3 *wanted_position,
{
*wanted_target = m_kart->getXYZ();
wanted_target->setY(wanted_target->getY()+ 0.75f);
// This first line moves the camera around behind the kart, pointing it
// towards where the kart is turning (and turning even more while skidding).
// The skidding effect is dampened.
float steering = m_kart->getSteerPercent()
* (1.0f + (m_kart->getSkidding() - 1.0f)/2.3f );
* (1.0f + (m_kart->getSkidding() - 1.0f)/2.3f );
// quadratically to dampen small variations (but keep sign)
float dampened_steer = fabsf(steering) * steering;
float angle_around = m_kart->getHeading()
+ m_rotation_range * dampened_steer * 0.5f;
+ m_rotation_range * dampened_steer * 0.5f;
float angle_up = m_kart->getKartProperties()->getCameraForwardUpAngle()
- m_kart->getPitch() ;
- m_kart->getPitch() ;
wanted_position->setX(-sin(angle_around));
wanted_position->setY( sin(angle_up) );
wanted_position->setZ(-cos(angle_around));
*wanted_position *= m_distance;
*wanted_position += *wanted_target;
} // computeNormalCameraPosition
//-----------------------------------------------------------------------------
@@ -336,6 +338,18 @@ void Camera::update(float dt)
smoothMoveCamera(dt, wanted_position, wanted_target);
break;
}
case CM_FALLING:
{
Vec3 previous_wanted_position = wanted_position;
computeNormalCameraPosition(&wanted_position, &wanted_target);
//const float previousY = wanted_position.getY();
//wanted_position.setY(m_camera->getPosition().Y - (m_camera->getPosition().Y - previousY)*dt);
wanted_position = m_camera->getPosition();
smoothMoveCamera(dt, wanted_position, wanted_target);
break;
}
case CM_FINAL:
{
handleEndCamera(dt);
@@ -481,3 +495,11 @@ void Camera::activate()
irr_driver->getVideoDriver()->setViewPort(m_viewport);
} // activate
// ----------------------------------------------------------------------------
void Camera::setFallMode(bool mode)
{
if (mode) m_mode = CM_FALLING;
else m_mode = CM_NORMAL;
}

View File

@@ -46,7 +46,8 @@ public:
CM_REVERSE, //!< Looking backwards
CM_LEADER_MODE, //!< for deleted player karts in follow the leader
CM_FINAL, //!< Final camera
CM_SIMPLE_REPLAY
CM_SIMPLE_REPLAY,
CM_FALLING
};
private:
@@ -95,7 +96,7 @@ private:
/** Velocity of the target of the camera, only used for end camera. */
core::vector3df m_target_velocity;
/** A class that stores information about the different end cameras
* which can be specified in the scene.xml file. */
class EndCameraInformation
@@ -194,6 +195,10 @@ public:
/** Returns the scaling in x/y direction for this camera. */
const core::vector2df& getScaling() const {return m_scaling; }
/** In "fall mode", the camera stays up and looks down at the falling kart
(mainly to avoid following the kart underwater) */
void setFallMode(bool fallMode);
/** Returns the camera scene node. */
scene::ICameraSceneNode *getCameraSceneNode()
{

View File

@@ -137,7 +137,12 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
assert(lifeTimeMax >= lifeTimeMin);
#ifdef DEBUG
std::string debug_name = std::string("particles(") + material->getTexture()->getName().getPath().c_str() + ")";
video::ITexture* tex = material->getTexture();
assert(tex != NULL);
const io::SNamedPath& name = tex->getName();
const io::path& tpath = name.getPath();
std::string debug_name = std::string("particles(") + tpath.c_str() + ")";
m_node->setName(debug_name.c_str());
#endif

View File

@@ -26,7 +26,7 @@
#include "physics/btKart.hpp"
#include "utils/constants.hpp"
WaterSplash::WaterSplash(Kart* kart) : m_kart(kart), m_particle_size(0.33f)
WaterSplash::WaterSplash(Kart* kart) : m_kart(kart), m_particle_size(0.75f)
{
m_node = irr_driver->addParticleNode();
#ifdef DEBUG
@@ -45,12 +45,12 @@ WaterSplash::WaterSplash(Kart* kart) : m_kart(kart), m_particle_size(0.33f)
m->setMaterialProperties(&(m_node->getMaterial(0)));
m_node->setMaterialTexture(0, m->getTexture());
m_emitter = m_node->createPointEmitter(core::vector3df(0, 0, 0), // velocity in m/ms
m_emitter = m_node->createPointEmitter(core::vector3df(0, 0.05, 0), // velocity in m/ms
5, 10,
video::SColor(255,0,0,0),
video::SColor(255,255,255,255),
300, 500,
20 // max angle
60 // max angle
);
m_emitter->setMinStartSize(core::dimension2df(m_particle_size/1.5f, m_particle_size/1.5f));
m_emitter->setMaxStartSize(core::dimension2df(m_particle_size*1.5f, m_particle_size*1.5f));
@@ -96,16 +96,6 @@ void WaterSplash::update(float t)
m_node->setPosition(core::vector3df(c.getX()+ m_particle_size*0.25f * (left?+1:-1),
c.getY(),
c.getZ()+m_particle_size*0.25f));
// There seems to be no way to randomise the velocity for particles,
// so we have to do this manually, by changing the default velocity.
// Irrlicht expects velocity (called 'direction') in m/ms!!
float f=m_kart->getSpeed();
if(f<1) return; // avoid problem with modulo 0
Vec3 dir((rand()%int(f))*(left?-1:1)*0.004f,
sin(DEGREE_TO_RAD*(rand()%180))*0.004f,
sin(DEGREE_TO_RAD*(rand()%100))*0.004f);
m_emitter->setDirection(dir.toIrrVector());
} // update
//-----------------------------------------------------------------------------

View File

@@ -314,9 +314,14 @@ void PlayerController::update(float dt)
// if automatic reverse camera is active
if (m_controls->m_look_back || (UserConfigParams::m_reverse_look_threshold>0 &&
m_kart->getSpeed()<-UserConfigParams::m_reverse_look_threshold))
{
m_kart->getCamera()->setMode(Camera::CM_REVERSE);
}
else
m_kart->getCamera()->setMode(Camera::CM_NORMAL);
{
if (m_kart->getCamera()->getMode() == Camera::CM_REVERSE)
m_kart->getCamera()->setMode(Camera::CM_NORMAL);
}
// We can't restrict rescue to fulfil isOnGround() (which would be more like
// MK), since e.g. in the City track it is possible for the kart to end

View File

@@ -733,7 +733,7 @@ void Kart::update(float dt)
if (UserConfigParams::m_graphical_effects && m_terrain_particles)
{
m_terrain_particles->update();
m_water_splash_system->update(dt);
m_water_splash_system->update();
} // UserConfigParams::m_graphical_effects
m_nitro->update();
@@ -1458,7 +1458,10 @@ void Kart::loadData()
std::cerr << e.what() << std::endl;
}
}
m_water_splash_system = new WaterSplash(this);
//m_water_splash_system = new WaterSplash(this);
m_water_splash_system = new ParticleEmitter(ParticleKindManager::get()->getParticles("splash.xml"),
core::vector3df(0.0f, 0.0f, 0.0f), getNode());
core::vector3df position(0, getKartHeight()*0.35f, -getKartLength()*0.35f);
@@ -1626,12 +1629,40 @@ void Kart::updateGraphics(const Vec3& offset_xyz,
}
}
}
if(m_water_splash_system)
{
float f = getMaterial() && getMaterial()->hasWaterSplash() && isOnGround()
? sqrt(getSpeed())*40.0f
: 0.0f;
m_water_splash_system->setCreationRate(f);
const Material* m = getMaterial();
if (m != NULL)
{
const float hot = getHoT();
if (m->hasWaterSplash() && hot != Track::NOHIT)
{
const int hat = getXYZ().getY() - hot;
// TODO: don't hardcode height, get from exporter
if (hat < 4.0f && hat > 2.0f)
{
m_water_splash_system->setCreationRate(m_water_splash_system->getParticlesInfo()->getMaxRate());
}
else
{
if (m_camera != NULL) m_camera->setFallMode(true);
m_water_splash_system->setCreationRate(0);
}
}
else
{
if (m_camera != NULL) m_camera->setFallMode(false);
m_water_splash_system->setCreationRate(0);
}
}
//float f = getMaterial() && getMaterial()->hasWaterSplash() && isOnGround()
// ? sqrt(getSpeed())*40.0f
// : 0.0f;
//m_water_splash_system->setCreationRate(f);
}
if (m_nitro)
{

View File

@@ -88,10 +88,6 @@ private:
/** Current race position (1-num_karts). */
int m_race_position;
/** The camera for each kart. Not all karts have cameras (e.g. AI karts
* usually don't), but there are exceptions: e.g. after the end of a
* race an AI kart is replacing the kart for a player.
*/
protected: // Used by the AI atm
@@ -99,6 +95,10 @@ protected: // Used by the AI atm
Powerup m_powerup;
Attachment *m_attachment;
/** The camera for each kart. Not all karts have cameras (e.g. AI karts
* usually don't), but there are exceptions: e.g. after the end of a
* race an AI kart is replacing the kart for a player.
*/
Camera *m_camera;
private:
@@ -139,7 +139,7 @@ private:
ParticleEmitter *m_terrain_particles;
/** Water splash when driving in water. */
WaterSplash *m_water_splash_system;
ParticleEmitter *m_water_splash_system;
/** Graphical effect when using a nitro. */
ParticleEmitter *m_nitro;

View File

@@ -44,8 +44,9 @@ public:
virtual void update(const Vec3 &pos);
/** Returns the height above the terrain. */
/** Returns the height of the terrain. we're currently above */
float getHoT() const {return m_HoT; }
/** Returns the current material the kart is on. */
const Material *getMaterial() const {return m_material; }
/** Returns the previous material the kart was one (which might be