Improved speedometer and nitrometer (#3177)
* New speedometer and nitrometer gui * Update Speedometer and Nitrometer * Improve nitro background * Improve nitro bar drawing * Improved meters * Improve meter and rank drawing * Agressive smoothing and higher visibility * Helper function for meter drawing * Helper function for meter drawing * Improved meters * New nitro bar, slight 3D effects and hopefully fix compilation * Update license
@ -24,7 +24,11 @@ title_font, by Marianne Gagnon (Auria), released under CC-BY-SA 3+
|
||||
|
||||
screen*.png, by Marianne Gagnon (Auria), including elements from the public domain Tango icon set
|
||||
|
||||
Gauge and bar by Totoplus62, released under CC-BY-SA 3
|
||||
speed.png by Alayan, with elements by Totoplus62, released under CC-BY-SA 3
|
||||
|
||||
speed*.png by Alayan, released under CC-0
|
||||
|
||||
gauge*.png by Alayan, released under CC-0
|
||||
|
||||
menu_story by tavariz91, released under CC-0
|
||||
|
||||
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 126 KiB |
@ -276,6 +276,7 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt)
|
||||
drawLap(kart, viewport, scaling);
|
||||
} // renderPlayerView
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Shows the current soccer result.
|
||||
*/
|
||||
@ -460,7 +461,7 @@ void RaceGUI::drawGlobalMiniMap()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Energy meter that gets filled with nitro. This function is called from
|
||||
* drawSpeedAndEnergy, which defines the correct position of the energy
|
||||
* drawSpeedEnergyRank, which defines the correct position of the energy
|
||||
* meter.
|
||||
* \param x X position of the meter.
|
||||
* \param y Y position of the meter.
|
||||
@ -473,7 +474,7 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
float min_ratio = std::min(scaling.X, scaling.Y);
|
||||
const int GAUGEWIDTH = 78;
|
||||
const int GAUGEWIDTH = 94;//same inner radius as the inner speedometer circle
|
||||
int gauge_width = (int)(GAUGEWIDTH*min_ratio);
|
||||
int gauge_height = (int)(GAUGEWIDTH*min_ratio);
|
||||
|
||||
@ -483,8 +484,8 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
|
||||
else if (state > 1.0f) state = 1.0f;
|
||||
|
||||
core::vector2df offset;
|
||||
offset.X = (float)(x-gauge_width) - 9.0f*scaling.X;
|
||||
offset.Y = (float)y-30.0f*scaling.Y;
|
||||
offset.X = (float)(x-gauge_width) - 9.5f*scaling.X;
|
||||
offset.Y = (float)y-11.5f*scaling.Y;
|
||||
|
||||
|
||||
// Background
|
||||
@ -497,156 +498,58 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
|
||||
NULL /* clip rect */, NULL /* colors */,
|
||||
true /* alpha */);
|
||||
|
||||
// Target
|
||||
// The positions for A to G are defined here.
|
||||
// They are calculated from gauge_full.png
|
||||
// They are further than the nitrometer farther position because
|
||||
// the lines between them would otherwise cut through the outside circle.
|
||||
|
||||
const int vertices_count = 7;
|
||||
|
||||
if (race_manager->getCoinTarget() > 0)
|
||||
{
|
||||
float coin_target = (float)race_manager->getCoinTarget()
|
||||
/ kart->getKartProperties()->getNitroMax();
|
||||
|
||||
video::S3DVertex vertices[5];
|
||||
unsigned int count=2;
|
||||
|
||||
// There are three different polygons used, depending on
|
||||
// the target. Consider the nitro-display texture:
|
||||
//
|
||||
// ----E-x--D (position of v,w,x vary depending on
|
||||
// | nitro)
|
||||
// A w
|
||||
// |
|
||||
// -B--v----C
|
||||
// For nitro state <= r1 the triangle ABv is used, with v between B and C.
|
||||
// For nitro state <= r2 the quad ABCw is used, with w between C and D.
|
||||
// For nitro state > r2 the poly ABCDx is used, with x between D and E.
|
||||
|
||||
vertices[0].TCoords = core::vector2df(0.3f, 0.4f);
|
||||
vertices[0].Pos = core::vector3df(offset.X+0.3f*gauge_width,
|
||||
offset.Y-(1-0.4f)*gauge_height, 0);
|
||||
vertices[1].TCoords = core::vector2df(0, 1.0f);
|
||||
vertices[1].Pos = core::vector3df(offset.X, offset.Y, 0);
|
||||
// The targets at which different polygons must be used.
|
||||
|
||||
const float r1 = 0.4f;
|
||||
const float r2 = 0.65f;
|
||||
if(coin_target<=r1)
|
||||
{
|
||||
count = 3;
|
||||
float f = coin_target/r1;
|
||||
vertices[2].TCoords = core::vector2df(0.08f + (1.0f-0.08f)*f, 1.0f);
|
||||
vertices[2].Pos = core::vector3df(offset.X + (0.08f*gauge_width)
|
||||
+ (1.0f - 0.08f)*f*gauge_width,
|
||||
offset.Y,0);
|
||||
}
|
||||
else if(coin_target<=r2)
|
||||
{
|
||||
count = 4;
|
||||
float f = (coin_target - r1)/(r2-r1);
|
||||
vertices[2].TCoords = core::vector2df(1.0f, 1.0f);
|
||||
vertices[2].Pos = core::vector3df(offset.X + gauge_width,
|
||||
offset.Y, 0);
|
||||
vertices[3].TCoords = core::vector2df(1.0f, (1.0f-f));
|
||||
vertices[3].Pos = core::vector3df(offset.X + gauge_width,
|
||||
offset.Y-f*gauge_height,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 5;
|
||||
float f = (coin_target - r2)/(1-r2);
|
||||
vertices[2].TCoords = core::vector2df(1.0, 1.0f);
|
||||
vertices[2].Pos = core::vector3df(offset.X + gauge_width,
|
||||
offset.Y, 0);
|
||||
vertices[3].TCoords = core::vector2df(1.0,0);
|
||||
vertices[3].Pos = core::vector3df(offset.X + gauge_width,
|
||||
offset.Y-gauge_height, 0);
|
||||
vertices[4].TCoords = core::vector2df(1.0f - f*(1-0.61f), 0);
|
||||
vertices[4].Pos = core::vector3df(offset.X + gauge_width
|
||||
- (1.0f-0.61f)*f*gauge_width,
|
||||
offset.Y-gauge_height, 0);
|
||||
}
|
||||
short int index[5]={0};
|
||||
for(unsigned int i=0; i<count; i++)
|
||||
{
|
||||
index[i]=count-i-1;
|
||||
vertices[i].Color = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
video::SMaterial m;
|
||||
m.setTexture(0, m_gauge_goal);
|
||||
m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
irr_driver->getVideoDriver()->setMaterial(m);
|
||||
draw2DVertexPrimitiveList(m_gauge_goal, vertices, count,
|
||||
index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);
|
||||
|
||||
}
|
||||
core::vector2df position[vertices_count];
|
||||
position[0].X = 0.324f;//A
|
||||
position[0].Y = 0.35f;//A
|
||||
position[1].X = 0.029f;//B
|
||||
position[1].Y = 0.918f;//B
|
||||
position[2].X = 0.307f;//C
|
||||
position[2].Y = 0.99f;//C
|
||||
position[3].X = 0.589f;//D
|
||||
position[3].Y = 0.932f;//D
|
||||
position[4].X = 0.818f;//E
|
||||
position[4].Y = 0.755f;//E
|
||||
position[5].X = 0.945f;//F
|
||||
position[5].Y = 0.497f;//F
|
||||
position[6].X = 0.948f;//G
|
||||
position[6].Y = 0.211f;//G
|
||||
|
||||
|
||||
// The states at which different polygons must be used.
|
||||
|
||||
float threshold[vertices_count-2];
|
||||
threshold[0] = 0.2f;
|
||||
threshold[1] = 0.4f;
|
||||
threshold[2] = 0.6f;
|
||||
threshold[3] = 0.8f;
|
||||
threshold[4] = 1.0f;
|
||||
|
||||
// Filling (current state)
|
||||
|
||||
if(state <=0) return; //Nothing to do
|
||||
|
||||
if (state > 0.0f)
|
||||
{
|
||||
video::S3DVertex vertices[5];
|
||||
unsigned int count=2;
|
||||
video::S3DVertex vertices[vertices_count];
|
||||
|
||||
// There are three different polygons used, depending on
|
||||
// the nitro state. Consider the nitro-display texture:
|
||||
//
|
||||
// ----E-x--D (position of v,w,x vary depending on
|
||||
// | nitro)
|
||||
// A w
|
||||
// |
|
||||
// -B--v----C
|
||||
// For nitro state <= r1 the triangle ABv is used, with v between B and C.
|
||||
// For nitro state <= r2 the quad ABCw is used, with w between C and D.
|
||||
// For nitro state > r2 the poly ABCDx is used, with x between D and E.
|
||||
|
||||
vertices[0].TCoords = core::vector2df(0.3f, 0.4f);
|
||||
vertices[0].Pos = core::vector3df(offset.X+0.3f*gauge_width,
|
||||
offset.Y-(1-0.4f)*gauge_height, 0);
|
||||
vertices[1].TCoords = core::vector2df(0, 1.0f);
|
||||
vertices[1].Pos = core::vector3df(offset.X, offset.Y, 0);
|
||||
// The states at which different polygons must be used.
|
||||
|
||||
const float r1 = 0.4f;
|
||||
const float r2 = 0.65f;
|
||||
if(state<=r1)
|
||||
//3D effect : wait for the full border to appear before drawing
|
||||
for (int i=0;i<5;i++)
|
||||
{
|
||||
count = 3;
|
||||
float f = state/r1;
|
||||
vertices[2].TCoords = core::vector2df(0.08f + (1.0f-0.08f)*f, 1.0f);
|
||||
vertices[2].Pos = core::vector3df(offset.X + (0.08f*gauge_width)
|
||||
+ (1.0f - 0.08f)
|
||||
*f*gauge_width,
|
||||
offset.Y,0);
|
||||
}
|
||||
else if(state<=r2)
|
||||
{
|
||||
count = 4;
|
||||
float f = (state - r1)/(r2-r1);
|
||||
vertices[2].TCoords = core::vector2df(1.0f, 1.0f);
|
||||
vertices[2].Pos = core::vector3df(offset.X + gauge_width,
|
||||
offset.Y, 0);
|
||||
vertices[3].TCoords = core::vector2df(1.0f, (1.0f-f));
|
||||
vertices[3].Pos = core::vector3df(offset.X + gauge_width,
|
||||
offset.Y-f*gauge_height,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 5;
|
||||
float f = (state - r2)/(1-r2);
|
||||
vertices[2].TCoords = core::vector2df(1.0, 1.0f);
|
||||
vertices[2].Pos = core::vector3df(offset.X + gauge_width,
|
||||
offset.Y, 0);
|
||||
vertices[3].TCoords = core::vector2df(1.0,0);
|
||||
vertices[3].Pos = core::vector3df(offset.X + gauge_width,
|
||||
offset.Y-gauge_height, 0);
|
||||
vertices[4].TCoords = core::vector2df(1.0f - f*(1-0.61f), 0);
|
||||
vertices[4].Pos =
|
||||
core::vector3df(offset.X + gauge_width - (1.0f-0.61f)*f*gauge_width,
|
||||
offset.Y-gauge_height, 0);
|
||||
if ((state-0.2f*i < 0.006f && state-0.2f*i >= 0.0f) || (0.2f*i-state < 0.003f && 0.2f*i-state >= 0.0f) )
|
||||
{
|
||||
state = 0.2f*i-0.003f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int count = computeVerticesForMeter(position, threshold, vertices, vertices_count,
|
||||
state, gauge_width, gauge_height, offset);
|
||||
|
||||
short int index[5]={0};
|
||||
for(unsigned int i=0; i<count; i++)
|
||||
{
|
||||
@ -666,6 +569,33 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
|
||||
index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);
|
||||
|
||||
}
|
||||
|
||||
// Target
|
||||
|
||||
if (race_manager->getCoinTarget() > 0)
|
||||
{
|
||||
float coin_target = (float)race_manager->getCoinTarget()
|
||||
/ kart->getKartProperties()->getNitroMax();
|
||||
|
||||
video::S3DVertex vertices[vertices_count];
|
||||
|
||||
unsigned int count = computeVerticesForMeter(position, threshold, vertices, vertices_count,
|
||||
coin_target, gauge_width, gauge_height, offset);
|
||||
|
||||
short int index[5]={0};
|
||||
for(unsigned int i=0; i<count; i++)
|
||||
{
|
||||
index[i]=count-i-1;
|
||||
vertices[i].Color = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
video::SMaterial m;
|
||||
m.setTexture(0, m_gauge_goal);
|
||||
m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
irr_driver->getVideoDriver()->setMaterial(m);
|
||||
draw2DVertexPrimitiveList(m_gauge_goal, vertices, count,
|
||||
index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);
|
||||
}
|
||||
#endif
|
||||
} // drawEnergyMeter
|
||||
|
||||
@ -743,10 +673,10 @@ void RaceGUI::drawRank(const AbstractKart *kart,
|
||||
oss << rank; // the current font has no . :( << ".";
|
||||
|
||||
core::recti pos;
|
||||
pos.LowerRightCorner = core::vector2di(int(offset.X + 0.65f*meter_width),
|
||||
int(offset.Y - 0.55f*meter_height));
|
||||
pos.UpperLeftCorner = core::vector2di(int(offset.X + 0.65f*meter_width),
|
||||
int(offset.Y - 0.55f*meter_height));
|
||||
pos.LowerRightCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
|
||||
int(offset.Y - 0.49f*meter_height));
|
||||
pos.UpperLeftCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
|
||||
int(offset.Y - 0.49f*meter_height));
|
||||
|
||||
static video::SColor color = video::SColor(255, 255, 255, 255);
|
||||
font->draw(oss.str().c_str(), pos, color, true, true);
|
||||
@ -803,65 +733,83 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
|
||||
|
||||
// Draw the actual speed bar (if the speed is >0)
|
||||
// ----------------------------------------------
|
||||
float speed_ratio = speed/KILOMETERS_PER_HOUR/110.0f;
|
||||
float speed_ratio = speed/40.0f; //max displayed speed of 40
|
||||
if(speed_ratio>1) speed_ratio = 1;
|
||||
|
||||
video::S3DVertex vertices[5];
|
||||
unsigned int count;
|
||||
// see computeVerticesForMeter for the detail of the drawing
|
||||
|
||||
// There are three different polygons used, depending on
|
||||
// the speed ratio. Consider the speed-display texture:
|
||||
//
|
||||
// D----x----D (position of v,w,x vary depending on
|
||||
// | speed)
|
||||
// w A
|
||||
// |
|
||||
// C--v-B----E
|
||||
// For speed ratio <= r1 the triangle ABv is used, with v between B and C.
|
||||
// For speed ratio <= r2 the quad ABCw is used, with w between C and D.
|
||||
// For speed ratio > r2 the poly ABCDx is used, with x between D and E.
|
||||
const int vertices_count = 12;
|
||||
|
||||
video::S3DVertex vertices[vertices_count];
|
||||
|
||||
// The positions for A to J2 are defined here.
|
||||
|
||||
// They are calculated from speedometer.png
|
||||
// A is the center of the speedometer's circle
|
||||
// B2, C, D, E, F, G, H, I and J1 are points on the line
|
||||
// from A to their respective 1/8th threshold division
|
||||
// B2 is 36,9° clockwise from the vertical (on bottom-left)
|
||||
// J1 s 70,7° clockwise from the vertical (on upper-right)
|
||||
// B1 and J2 are used for correct display of the 3D effect
|
||||
// They are 1,13* further than the speedometer farther position because
|
||||
// the lines between them would otherwise cut through the outside circle.
|
||||
|
||||
core::vector2df position[vertices_count];
|
||||
|
||||
position[0].X = 0.546f;//A
|
||||
position[0].Y = 0.566f;//A
|
||||
position[1].X = 0.216f;//B1
|
||||
position[1].Y = 1.036f;//B1
|
||||
position[2].X = 0.201f;//B2
|
||||
position[2].Y = 1.023f;//B2
|
||||
position[3].X = 0.036f;//C
|
||||
position[3].Y = 0.831f;//C
|
||||
position[4].X = -0.029f;//D
|
||||
position[4].Y = 0.589f;//D
|
||||
position[5].X = 0.018f;//E
|
||||
position[5].Y = 0.337f;//E
|
||||
position[6].X = 0.169f;//F
|
||||
position[6].Y = 0.134f;//F
|
||||
position[7].X = 0.391f;//G
|
||||
position[7].Y = 0.014f;//G
|
||||
position[8].X = 0.642f;//H
|
||||
position[8].Y = 0.0f;//H
|
||||
position[9].X = 0.878f;//I
|
||||
position[9].Y = 0.098f;//I
|
||||
position[10].X = 1.046f;//J1
|
||||
position[10].Y = 0.285f;//J1
|
||||
position[11].X = 1.052f;//J2
|
||||
position[11].Y = 0.297f;//J2
|
||||
|
||||
vertices[0].TCoords = core::vector2df(0.7f, 0.5f);
|
||||
vertices[0].Pos = core::vector3df(offset.X+0.7f*meter_width,
|
||||
offset.Y-0.5f*meter_height, 0);
|
||||
vertices[1].TCoords = core::vector2df(0.52f, 1.0f);
|
||||
vertices[1].Pos = core::vector3df(offset.X+0.52f*meter_width, offset.Y, 0);
|
||||
// The speed ratios at which different triangles must be used.
|
||||
// These values should be adjusted in case that the speed display
|
||||
// is not linear enough. Mostly the speed values are below 0.7, it
|
||||
// needs some zipper to get closer to 1.
|
||||
const float r1 = 0.2f;
|
||||
const float r2 = 0.6f;
|
||||
if(speed_ratio<=r1)
|
||||
|
||||
float threshold[vertices_count-2];
|
||||
threshold[0] = 0.00001f;//for the 3D margin
|
||||
threshold[1] = 0.125f;
|
||||
threshold[2] = 0.25f;
|
||||
threshold[3] = 0.375f;
|
||||
threshold[4] = 0.50f;
|
||||
threshold[5] = 0.625f;
|
||||
threshold[6] = 0.750f;
|
||||
threshold[7] = 0.875f;
|
||||
threshold[8] = 0.99999f;//for the 3D margin
|
||||
threshold[9] = 1.0f;
|
||||
|
||||
//3D effect : wait for the full border to appear before drawing
|
||||
for (int i=0;i<8;i++)
|
||||
{
|
||||
count = 3;
|
||||
float f = speed_ratio/r1;
|
||||
vertices[2].TCoords = core::vector2df(0.52f*(1-f), 1.0f);
|
||||
vertices[2].Pos = core::vector3df(offset.X+ (0.52f*(1.0f-f)*meter_width),
|
||||
offset.Y,0);
|
||||
if ((speed_ratio-0.125f*i < 0.00625f && speed_ratio-0.125f*i >= 0.0f) || (0.125f*i-speed_ratio < 0.0045f && 0.125f*i-speed_ratio >= 0.0f) )
|
||||
{
|
||||
speed_ratio = 0.125f*i-0.0045f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(speed_ratio<=r2)
|
||||
{
|
||||
count = 4;
|
||||
float f = (speed_ratio - r1)/(r2-r1);
|
||||
vertices[2].TCoords = core::vector2df(0, 1.0f);
|
||||
vertices[2].Pos = core::vector3df(offset.X, offset.Y, 0);
|
||||
vertices[3].TCoords = core::vector2df(0, (1-f));
|
||||
vertices[3].Pos = core::vector3df(offset.X, offset.Y-f*meter_height,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 5;
|
||||
float f = (speed_ratio - r2)/(1-r2);
|
||||
vertices[2].TCoords = core::vector2df(0, 1.0f);
|
||||
vertices[2].Pos = core::vector3df(offset.X, offset.Y, 0);
|
||||
vertices[3].TCoords = core::vector2df(0,0);
|
||||
vertices[3].Pos = core::vector3df(offset.X, offset.Y-meter_height, 0);
|
||||
vertices[4].TCoords = core::vector2df(f, 0);
|
||||
vertices[4].Pos = core::vector3df(offset.X+f*meter_width,
|
||||
offset.Y-meter_height, 0);
|
||||
}
|
||||
short int index[5];
|
||||
|
||||
unsigned int count = computeVerticesForMeter(position, threshold, vertices, vertices_count,
|
||||
speed_ratio, meter_width, meter_height, offset);
|
||||
|
||||
|
||||
short int index[vertices_count];
|
||||
for(unsigned int i=0; i<count; i++)
|
||||
{
|
||||
index[i]=i;
|
||||
@ -876,6 +824,100 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
|
||||
#endif
|
||||
} // drawSpeedEnergyRank
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This function computes a polygon used for drawing the measure for a meter (speedometer, etc.)
|
||||
* The variable measured by the meter is compared to the thresholds, and is then used to
|
||||
* compute a point between the two points associated with the lower and upper threshold
|
||||
* Then, a polygon is calculated linking all the previous points and the variable point
|
||||
* which link back to the first point. This polygon is used for drawing.
|
||||
*
|
||||
* Consider the following example :
|
||||
*
|
||||
* A E
|
||||
* -|
|
||||
* x
|
||||
* |
|
||||
* -D-|
|
||||
* -w-|
|
||||
* |-C--|
|
||||
* -B--v-|
|
||||
*
|
||||
* If the measure is inferior to the first threshold, the function will create a triangle ABv
|
||||
* with the position of v varying proportionally on a line between B and C ;
|
||||
* at B with 0 and at C when it reaches the first threshold.
|
||||
* If the measure is between the first and second thresholds, the function will create a quad ABCw,
|
||||
* with w varying in the same way than v.
|
||||
* If the measure exceds the higher threshold, the function will return the poly ABCDE.
|
||||
*
|
||||
* \param position The relative positions of the vertices.
|
||||
* \param threshold The thresholds at which the variable point switch from a segment to the next.
|
||||
* The size of this array should be smaller by two than the position array.
|
||||
* The last threshold determines the measure over which the meter is full
|
||||
* \param vertices Where the results of the computation are put, for use by the calling function.
|
||||
* \param vertices_count The maximum number of vertices to use. Should be superior or equal to the
|
||||
* size of the arrays.
|
||||
* \param measure The value of the variable measured by the meter.
|
||||
* \param gauge_width The width of the meter
|
||||
* \param gauge_height The height of the meter
|
||||
* \param offset The offset to position the meter
|
||||
*/
|
||||
unsigned int RaceGUI::computeVerticesForMeter(core::vector2df position[], float threshold[], video::S3DVertex vertices[], unsigned int vertices_count,
|
||||
float measure, int gauge_width, int gauge_height, core::vector2df offset)
|
||||
{
|
||||
//Nothing to draw ; we need at least three points to draw a triangle
|
||||
if (vertices_count <= 2 || measure < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int count=2;
|
||||
float f = 1.0f;
|
||||
|
||||
for (unsigned int i=2 ; i < vertices_count ; i++)
|
||||
{
|
||||
count++;
|
||||
|
||||
//Stop when we have found between which thresholds the measure is
|
||||
if (measure < threshold[i-2])
|
||||
{
|
||||
if (i-2 == 0)
|
||||
{
|
||||
f = measure/threshold[i-2];
|
||||
}
|
||||
else
|
||||
{
|
||||
f = (measure - threshold[i-3])/(threshold[i-2]-threshold[i-3]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i=0 ; i < count ; i++)
|
||||
{
|
||||
//if the measure don't fall in this segment, use the next predefined point
|
||||
if (i<count-1 || (count == vertices_count && f == 1.0f))
|
||||
{
|
||||
vertices[i].TCoords = core::vector2df(position[i].X, position[i].Y);
|
||||
vertices[i].Pos = core::vector3df(offset.X+position[i].X*gauge_width,
|
||||
offset.Y-(1-position[i].Y)*gauge_height, 0);
|
||||
}
|
||||
//if the measure fall in this segment, compute the variable position
|
||||
else
|
||||
{
|
||||
//f : the proportion of the next point. 1-f : the proportion of the previous point
|
||||
vertices[i].TCoords = core::vector2df(position[i].X*(f)+position[i-1].X*(1.0f-f),
|
||||
position[i].Y*(f)+position[i-1].Y*(1.0f-f));
|
||||
vertices[i].Pos = core::vector3df(offset.X+ ((position[i].X*(f)+position[i-1].X*(1.0f-f))*gauge_width),
|
||||
offset.Y-(((1-position[i].Y)*(f)+(1-position[i-1].Y)*(1.0f-f))*gauge_height),0);
|
||||
}
|
||||
}
|
||||
|
||||
//the count is used in the drawing functions
|
||||
return count;
|
||||
} //computeVerticesForMeter
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Displays the rank and the lap of the kart.
|
||||
* \param info Info object c
|
||||
|
@ -109,6 +109,12 @@ private:
|
||||
float min_ratio, int meter_width,
|
||||
int meter_height, float dt);
|
||||
|
||||
/* Helper function for drawing meters */
|
||||
|
||||
unsigned int computeVerticesForMeter(core::vector2df position[], float threshold[], video::S3DVertex vertices[],
|
||||
unsigned int vertices_count, float measure, int gauge_width,
|
||||
int gauge_height, core::vector2df offset);
|
||||
|
||||
/** Display items that are shown once only (for all karts). */
|
||||
void drawGlobalMiniMap ();
|
||||
void drawGlobalTimer ();
|
||||
|