Position of slipstream graphical effect now depends on the 'target' kart, and
is using the height of the terrain instead of the karts' positions (since then the suspension will make the slipstream jump). Pretty much work-in-progress, and not activated atm. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4547 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
c25297b7a3
commit
aca45713c2
src
@ -45,9 +45,10 @@ SlipStream::SlipStream(Kart* kart) : m_kart(kart), MovingTexture(0, 0)
|
||||
|
||||
createMesh(m);
|
||||
m_node = irr_driver->addMesh(m_mesh);
|
||||
m_node->setParent(m_kart->getNode());
|
||||
//m_node->setParent(m_kart->getNode());
|
||||
m_node->setPosition(core::vector3df(0,
|
||||
0*0.25f,
|
||||
// 0*0.25f,
|
||||
0*0.25f+2.5,
|
||||
m_kart->getKartLength()) );
|
||||
setTextureMatrix(&(m_node->getMaterial(0).getTextureMatrix(0)));
|
||||
} // SlipStream
|
||||
@ -76,7 +77,7 @@ void SlipStream::createMesh(const video::SMaterial &material)
|
||||
// The distance of each of the circle from the kart. The number of
|
||||
// entries in this array must be the same as the number of non-zero
|
||||
// entries in the radius[] array above. No 'end of list' entry required.
|
||||
float distance[] = {0.0f, 2.0f, 4.0f };
|
||||
float distance[] = {2.0f, 6.0f, 14.0f };
|
||||
|
||||
// The alpha values for the rings, no 'end of list' entry required.
|
||||
int alphas[] = {0, 255, 0};
|
||||
@ -89,8 +90,12 @@ void SlipStream::createMesh(const video::SMaterial &material)
|
||||
// Length is distance of last circle to distance of first circle:
|
||||
float length = distance[num_circles-1] - distance[0];
|
||||
|
||||
// The number of points for each circle.
|
||||
const int num_segments = 15;
|
||||
// The number of points for each circle. Since part of the slip stream
|
||||
// might be under the ground (esp. first and last segment), specify
|
||||
// which one is the first and last to be actually drawn.
|
||||
const int num_segments = 7;
|
||||
const int first_segment = 0;
|
||||
const int last_segment = 6;
|
||||
const float f = 2*M_PI/float(num_segments);
|
||||
scene::SMeshBuffer *buffer = new scene::SMeshBuffer();
|
||||
buffer->Material = material;
|
||||
@ -98,30 +103,34 @@ void SlipStream::createMesh(const video::SMaterial &material)
|
||||
{
|
||||
float curr_distance = distance[j]-distance[0];
|
||||
// Create the vertices for each of the circle
|
||||
for(unsigned int i=0; i<num_segments; i++)
|
||||
for(unsigned int i=first_segment; i<=last_segment; i++)
|
||||
{
|
||||
video::S3DVertex v;
|
||||
v.Pos.X = sin(i*f)*radius[j];
|
||||
v.Pos.Y = -cos(i*f)*radius[j];
|
||||
video::S3DVertex v;
|
||||
// Offset every 2nd circle by one half segment to increase
|
||||
// the number of planes so it looks better.
|
||||
v.Pos.X = sin((i+(j%2)*0.5f)*f)*radius[j];
|
||||
v.Pos.Y = -cos((i+(j%2)*0.5f)*f)*radius[j];
|
||||
v.Pos.Z = distance[j];
|
||||
v.Color = video::SColor(alphas[j], alphas[j], alphas[j], alphas[j]);
|
||||
v.TCoords.X = curr_distance/length;
|
||||
v.TCoords.Y = (float)i/(num_segments-1);
|
||||
v.TCoords.Y = (float)(i-first_segment)/(last_segment-first_segment);
|
||||
buffer->Vertices.push_back(v);
|
||||
} // for i<num_segments
|
||||
} // while radius[num_circles]!=0
|
||||
|
||||
// Now create the triangles.
|
||||
// Now create the triangles from circle j to j+1 (so the loop
|
||||
// only goes to num_circles-1).
|
||||
const int diff_segments = last_segment-first_segment+1;
|
||||
for(unsigned int j=0; j<num_circles-1; j++)
|
||||
{
|
||||
for(unsigned int i=0; i<num_segments-1; i++)
|
||||
for(unsigned int i=first_segment; i<last_segment; i++)
|
||||
{
|
||||
buffer->Indices.push_back( j *num_segments+i );
|
||||
buffer->Indices.push_back((j+1)*num_segments+i );
|
||||
buffer->Indices.push_back( j *num_segments+i+1);
|
||||
buffer->Indices.push_back( j *num_segments+i+1);
|
||||
buffer->Indices.push_back((j+1)*num_segments+i );
|
||||
buffer->Indices.push_back((j+1)*num_segments+i+1);
|
||||
buffer->Indices.push_back( j *diff_segments+i );
|
||||
buffer->Indices.push_back((j+1)*diff_segments+i );
|
||||
buffer->Indices.push_back( j *diff_segments+i+1);
|
||||
buffer->Indices.push_back( j *diff_segments+i+1);
|
||||
buffer->Indices.push_back((j+1)*diff_segments+i );
|
||||
buffer->Indices.push_back((j+1)*diff_segments+i+1);
|
||||
}
|
||||
} // for j<num_circles-1
|
||||
|
||||
@ -139,18 +148,65 @@ void SlipStream::createMesh(const video::SMaterial &material)
|
||||
* 1 = collecting
|
||||
* 2 = using slip stream bonus
|
||||
*/
|
||||
void SlipStream::setIntensity(float f)
|
||||
void SlipStream::setIntensity(float f, const Kart *kart)
|
||||
{
|
||||
// For now: disable them permanently
|
||||
m_node->setVisible(false);
|
||||
return;
|
||||
|
||||
|
||||
if(!kart)
|
||||
{
|
||||
m_node->setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const float above_terrain = 0.2f;
|
||||
core::vector3df my_pos = m_kart->getNode()->getPosition();
|
||||
my_pos.Y = m_kart->getHoT()+above_terrain;
|
||||
m_node->setPosition(my_pos);
|
||||
|
||||
core::vector3df other_pos = kart->getNode()->getPosition();
|
||||
other_pos.Y = kart->getHoT()+above_terrain;
|
||||
core::vector3df diff = other_pos - my_pos;
|
||||
core::vector3df rotation = diff.getHorizontalAngle();
|
||||
m_node->setRotation(rotation);
|
||||
|
||||
// For real testing in game: this needs some tuning!
|
||||
//m_node->setVisible(f!=0);
|
||||
//MovingTexture::setSpeed(f*0.1f, 0);
|
||||
|
||||
//MovingTexture::setSpeed(f, 0);
|
||||
//return;
|
||||
// For debugging: make the slip stream effect visible all the time
|
||||
m_node->setVisible(true);
|
||||
MovingTexture::setSpeed(1.0f, 0.0f);
|
||||
} // setIntensity
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Update, called once per timestep.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void SlipStream::update(float dt)
|
||||
{
|
||||
core::vector3df pos = m_kart->getNode()->getPosition();
|
||||
pos.Y = m_kart->getHoT()+0.2f;
|
||||
m_node->setPosition(pos);
|
||||
|
||||
core::vector3df f = core::vector3df(0, 0, 10) - f;
|
||||
core::vector3df r = f.getHorizontalAngle();
|
||||
m_node->setRotation(r);
|
||||
return;
|
||||
|
||||
// Smooth the rotation: take 80% of old rotation, 20% of new:
|
||||
float weight_old = 0.5f;
|
||||
const core::vector3df &new_rotation = m_kart->getNode()->getRotation();
|
||||
|
||||
const core::quaternion new_rot(m_kart->getNode()->getRotation());
|
||||
const core::quaternion old_rot(m_node->getRotation() );
|
||||
|
||||
core::quaternion interpo;
|
||||
//interpo.slerp(new_rot, old_rot, weight_old);
|
||||
core::vector3df interp;
|
||||
new_rot.toEuler(interp);
|
||||
m_node->setRotation(interp);
|
||||
MovingTexture::update(dt);
|
||||
} // update
|
||||
|
@ -45,7 +45,8 @@ private:
|
||||
public:
|
||||
SlipStream (Kart* kart);
|
||||
virtual ~SlipStream ();
|
||||
void setIntensity(float f);
|
||||
virtual void update(float dt);
|
||||
void setIntensity(float f, const Kart* kart);
|
||||
}; // SlipStream
|
||||
#endif
|
||||
|
||||
|
@ -800,12 +800,17 @@ float Kart::handleSlipstream(float dt)
|
||||
printf("Using slipstream\n");
|
||||
m_slipstream_time -= dt;
|
||||
if(m_slipstream_time<0) m_slipstream_mode=SS_NONE;
|
||||
m_slip_stream->setIntensity(2.0f, NULL);
|
||||
return m_kart_properties->getSlipstreamAddPower();
|
||||
}
|
||||
|
||||
// If this kart is too slow for slipstreaming taking effect, do nothing
|
||||
// --------------------------------------------------------------------
|
||||
if(getSpeed()<m_kart_properties->getSlipstreamMinSpeed()) return 0;
|
||||
if(getSpeed()<m_kart_properties->getSlipstreamMinSpeed())
|
||||
{
|
||||
m_slip_stream->setIntensity(0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Then test if this kart is in the slipstream range of another kart:
|
||||
// ------------------------------------------------------------------
|
||||
@ -813,44 +818,48 @@ float Kart::handleSlipstream(float dt)
|
||||
|
||||
unsigned int n = race_manager->getNumKarts();
|
||||
bool is_sstreaming = false;
|
||||
Kart *target_kart;
|
||||
for(unsigned int i=0; i<n; i++)
|
||||
{
|
||||
Kart *kart = race_manager->getKart(i);
|
||||
target_kart = race_manager->getKart(i);
|
||||
// Don't test for slipstream with itself.
|
||||
if(kart==this) continue;
|
||||
if(target_kart==this) continue;
|
||||
|
||||
// If the kart we are testing against is too slow, no need to test
|
||||
// slipstreaming. Note: We compare the speed of the other kart
|
||||
// against the minimum slipstream speed kart of this kart - not
|
||||
// entirely sure if this makes sense, but it makes it easier to
|
||||
// give karts different slipstream properties.
|
||||
if(kart->getSpeed()<m_kart_properties->getSlipstreamMinSpeed())
|
||||
if(target_kart->getSpeed()<m_kart_properties->getSlipstreamMinSpeed())
|
||||
continue;
|
||||
// Quick test: the kart must be not more than
|
||||
// slipstream length+kart_length() away from the other kart
|
||||
Vec3 delta = getXYZ() - kart->getXYZ();
|
||||
float l = kart->m_kart_properties->getSlipstreamLength()
|
||||
+ kart->getKartLength()*0.5f;
|
||||
Vec3 delta = getXYZ() - target_kart->getXYZ();
|
||||
float l = target_kart->m_kart_properties->getSlipstreamLength()
|
||||
+ target_kart->getKartLength()*0.5f;
|
||||
if(delta.length2_2d() > l*l) continue;
|
||||
|
||||
if(kart->m_slipstream_quad->pointInQuad(getXYZ()))
|
||||
if(target_kart->m_slipstream_quad->pointInQuad(getXYZ()))
|
||||
{
|
||||
is_sstreaming = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} //
|
||||
|
||||
if(!is_sstreaming)
|
||||
{
|
||||
m_slipstream_time -=dt;
|
||||
if(m_slipstream_time<0) m_slipstream_mode = SS_NONE;
|
||||
m_slip_stream->setIntensity(0, NULL);
|
||||
return 0;
|
||||
}
|
||||
} // for i<number of karts
|
||||
|
||||
// Accumulate slipstream credits now
|
||||
m_slipstream_time = m_slipstream_mode==SS_NONE ? dt
|
||||
: m_slipstream_time+dt;
|
||||
printf("Collecting slipstream %f\n", m_slipstream_time);
|
||||
m_slip_stream->setIntensity(m_slipstream_time, target_kart);
|
||||
|
||||
m_slipstream_mode = SS_COLLECT;
|
||||
if(m_slipstream_time>m_kart_properties->getSlipstreamCollectTime())
|
||||
{
|
||||
@ -1296,12 +1305,6 @@ void Kart::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
|
||||
// become a huge unsigned number in the particle scene node!
|
||||
m_nitro->setCreationRate(m_controls.m_nitro && m_collected_energy>0
|
||||
? (10.0f + fabsf(getSpeed())*20.0f) : 0);
|
||||
float f=0;
|
||||
if(m_slipstream_mode==SS_COLLECT)
|
||||
f=1.0f;
|
||||
else if(m_slipstream_mode==SS_USE)
|
||||
f=2.0f;
|
||||
m_slip_stream->setIntensity(f);
|
||||
|
||||
float speed_ratio = getSpeed()/getMaxSpeed();
|
||||
float offset_heading = getSteerPercent()*m_kart_properties->getSkidVisual()
|
||||
|
Loading…
x
Reference in New Issue
Block a user