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:
30
data/splash.xml
Normal file
30
data/splash.xml
Normal 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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user