Hud AngleSplit: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
No edit summary
m (clean up, added orphan, deadend tags)
 
(8 intermediate revisions by 4 users not shown)
Line 1: Line 1:
This code is like the two image split for the ammo and health icons in ep1 (near the cross hair) but does it on an angle both on the left side and right side.  
{{Multiple issues|
This uses alot of trig and the code could be simplified a bit.
{{Dead end|date=January 2024}}
{{Orphan|date=January 2024}}
}}
 
This code is like the two image split for the ammo and health icons in ep1 (near the cross hair) but does it on an angle both on the left side and right side and allows for them to be rotated. <br>
This uses a lot of trig and the code could be simplified a bit.


==How it works==
==How it works==
[[Image:Angle_split_working.jpg]]
[[File:Angle_split_working.jpg]]


==Result==
==Result==
[[Image:Angle_split.jpg]]
[[File:Angle_split.jpg]]


==Code==
==Code==
This assumes you all ready have a hud panel set up and ready to use.
This assumes you already have a HUD panel set up and ready to use.
First thing to do is we need to define the two images:
First thing to do is to define the two images:


Header:
Header:
<pre>
<pre>
public:
void VidInit(void);
private:
private:
CHudTexture *m_icon_rb; // right bracket, full
CHudTexture *m_icon_lb; // left bracket, full
CHudTexture *m_icon_lb; // left bracket, full
CHudTexture *m_icon_lbe; // left bracket, empty
</pre>
</pre>


Constructor:
Cpp File:
<pre>
<pre>
void CLASSNAME::VidInit( void )
{
m_icon_lb = gHUD.GetIcon( "health_full" );
m_icon_lb = gHUD.GetIcon( "health_full" );
m_icon_lbe = gHUD.GetIcon( "health_empty" );
m_icon_lbe = gHUD.GetIcon( "health_empty" );
BaseClass::VidInit();
}
</pre>
</pre>
The names here refer to the texture defined in mod_textures.txt
The names here refer to the textures defined in mod_textures.txt
<br><br>
<br><br>
Once we have this we need to add some code to the paint function:
Once we have this we need to add some code to the paint function:
<pre>
<pre>
int scaledW, scaledH, scaledDis, screenWide, screenTall, X1,Y1, X2, offset;
int scaledW, scaledH, scaledDis, screenWide, screenTall, X,Y, offset;


offset = scheme()->GetProportionalScaledValue(100);
offset = scheme()->GetProportionalScaledValue(100);
Line 50: Line 63:
</pre>
</pre>


This draws each element at pos X,Y with size scaledW, scaledH. Since these are health bars we have a health percent all ready defined.
This draws each element at pos X,Y with size scaledW, scaledH. Since these are health bars a health percentage is already defined.
The true false refers to which one they are (true for empty image and false for full) and the offset is the between the edge and the point (see pict above).
The true/false refers to which image they are (true for empty image and false for full) and the offset is the horizontal distance between the edge and the pivot point (see picture above).
<br><br>
<br><br>
We need to add the new functions into hud.cpp/hud.h
We need to add the new functions into hud.cpp/hud.h
Line 58: Line 71:
<pre>
<pre>
void DrawScew_Left(int x, int y, int w, int h, float per, bool isTop, int offset) const;
void DrawScew_Left(int x, int y, int w, int h, float per, bool isTop, int offset) const;
void DrawScew_Left(int x, int y, int w, int h, float per, bool isTop, int offset, float ang) const;
void DrawScew_Right(int x, int y, int w, int h, float per, bool isTop, int offset) const;
void DrawScew_Right(int x, int y, int w, int h, float per, bool isTop, int offset) const;
void DrawScew_Right(int x, int y, int w, int h, float per, bool isTop, int offset, float ang) const;
</pre>
</pre>


And the cpp file add:
And the cpp file add:
<pre>
<pre>
#include <maths.h>
#define PI 3.14159265
</pre>
Up the top after the other includes and the following after all the other functions:


void CHudTexture::DrawScew_Left(int tx, int ty, int tw, int th, float per, bool isTop, int offset) const
<pre>
void MatixMulti(float m1[][2], int a, int b, float m2[][2], int c, int d, float m3[][2], int e, int f)
{
{
per = max(0, min(1,per));
if (b!=c || a!=e || d!=f)
return;


vgui::surface()->DrawSetTexture( textureId );
for (int x=0; x<a; x++)
vgui::surface()->DrawSetColor( Color(125,125,125,125) );
 
float x = (float)(tx);
float y = (float)(ty);
float w = (float)(tw);
float h = (float)(th);
 
if (!(per > 99 || per < 0))
{
{
float sy = y+h-(per*h);
for (int y=0; y<d; y++)
float sx = x+w;
float qy = y+h/2;
float ydis_sq=qy-sy;
float ydis_ef = (offset+w)/offset*ydis_sq;
float ex = x;
float ey = y+h/2-ydis_ef;
float ratio_1 = (h/2.0-ydis_ef)/h;
float ratio_2 = 1-per;
 
if ( ey < y)
{
{
float q=x+w-(w*(sy-y))/(sy-ey);
int res =0;
float ratio_3 = (q-x)/w;
for (int z=0; z<b; z++)
 
if (isTop)
{
vgui::Vertex_t points[3] =
{
vgui::Vertex_t( Vector2D((int)(q), (int)(y)), Vector2D(ratio_3,0)),
vgui::Vertex_t( Vector2D((int)(x+w), (int)(y)), Vector2D(1,0) ),
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(1,ratio_2) )
};
vgui::surface()->DrawTexturedPolygon( 3, points);
}
else
{
{
vgui::Vertex_t points[5] =
res += m1[x][z]*m2[z][y];
{
vgui::Vertex_t( Vector2D((int)(x), (int)(y)), Vector2D(0,0) ), //top left
vgui::Vertex_t( Vector2D((int)(q), (int)(y)), Vector2D(ratio_3,0) ), //top right
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(1,ratio_2) ), //bottom right
vgui::Vertex_t( Vector2D((int)(w+x), (int)(y+h)), Vector2D(1,1) ), //bottom center
vgui::Vertex_t( Vector2D((int)(x), (int)(y+h)), Vector2D(0,1) ) //bottom left
};
vgui::surface()->DrawTexturedPolygon( 5, points);
}
}
}
else if ( ey > (y+h))
{
float o=ey-h-y;
float q=x+(w*o/((y+h-sy)+o));
float ratio_3=(q-x)/w;


if (isTop)
m3[x][y] = res;
{
vgui::Vertex_t points[5] =
{
vgui::Vertex_t( Vector2D((int)(x), (int)(y)), Vector2D(0,0) ), //top left
vgui::Vertex_t( Vector2D((int)(x+w), (int)(y)), Vector2D(1,0) ), //top right
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(1,ratio_2) ), //bottom right
vgui::Vertex_t( Vector2D((int)(q), (int)(y+h)), Vector2D(ratio_3,1) ), //bottom center
vgui::Vertex_t( Vector2D((int)(x), (int)(y+h)), Vector2D(0,1) ) //bottom left
};
vgui::surface()->DrawTexturedPolygon( 5, points);
}
else
{
vgui::Vertex_t points[3] =
{
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(1,ratio_2) ),
vgui::Vertex_t( Vector2D((int)(x+w), (int)(y+h)), Vector2D(1,1)),
vgui::Vertex_t( Vector2D((int)(q), (int)(y+h)), Vector2D(ratio_3,1) )
};
vgui::surface()->DrawTexturedPolygon( 3, points);
}
}
else
{
if (isTop)
{
vgui::Vertex_t points[4] =
{
vgui::Vertex_t( Vector2D((int)(x), (int)(y)), Vector2D(0,0) ),
vgui::Vertex_t( Vector2D((int)(x+w),(int)(y)), Vector2D(1,0) ),
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(1,ratio_2) ),
vgui::Vertex_t( Vector2D((int)(ex), (int)(ey)), Vector2D(0,ratio_1) )
};
vgui::surface()->DrawTexturedPolygon( 4, points);
}
else
{
vgui::Vertex_t points[4] =
{
vgui::Vertex_t( Vector2D((int)(ex), (int)(ey)), Vector2D(0,ratio_1)),
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(1,ratio_2)),
vgui::Vertex_t( Vector2D((int)(x+w),(int)(y+h)), Vector2D(1,1) ),
vgui::Vertex_t( Vector2D((int)(x), (int)(y+h)), Vector2D(0,1) )
};
vgui::surface()->DrawTexturedPolygon( 4, points);
}
}
}
}
else
{
vgui::Vertex_t points[4] =
{
vgui::Vertex_t( Vector2D(x,y), Vector2D(0,0) ),
vgui::Vertex_t( Vector2D(x+w, y), Vector2D(1,0) ),
vgui::Vertex_t( Vector2D(x+w, y+(h)), Vector2D(1,1) ),
vgui::Vertex_t( Vector2D(x, y+h), Vector2D(0,1) )
};
vgui::surface()->DrawTexturedPolygon( 4, points);
}
}
}
}


void CHudTexture::DrawScew_Right(int tx, int ty, int tw, int th, float per, bool isTop, int offset) const
void CHudTexture::DrawScew_Left(int tx, int ty, int tw, int th, float per, bool isTop, int offset) const
{
DrawScew_Left(tx, ty, tw, th, per, isTop, offset, 0);
};
 
void CHudTexture::DrawScew_Left(int tx, int ty, int tw, int th, float per, bool isTop, int offset, float ang) const
{
{
per = max(0, min(1,per));
per = max(0, min(1,per));
Line 196: Line 121:
float h = (float)(th);
float h = (float)(th);


if (!(per > 99 || per < 0))
float rotMat[2][2];
rotMat[0][0] =  cos(ang*PI/180);
rotMat[0][1] =  sin(ang*PI/180);
rotMat[1][0] = -sin(ang*PI/180);
rotMat[1][1] =  cos(ang*PI/180);
 
if (per > 0 && per < 1)
{
{
float sy = y+h-(per*h);
bool perCheck = false;
float sx = x;
 
float qy = y+h/2;
if (per > 0.5)
float ydis_sq=qy-sy;
{
float ydis_ef = (ydis_sq*(offset+w)/offset);
per = 1.0-per;
float ex = x+w;  
perCheck = true;
float ey = y+h/2-ydis_ef;
}
float ratio_1 = (h/2.0-ydis_ef)/h;
float ratio_2 = 1-per;
float sy = per*h;
float sx = w;
 
float dis_sp = h/2 - sy;
float dis_pq = offset;
float dis_oe = sy;
 
float dis_ds = dis_oe*dis_pq/dis_sp;
float ax = w-dis_ds;
float ay = 0;
 
float dis_gq = dis_pq + w;
float dis_eg = dis_sp * dis_gq / dis_pq;
 
float ex = 0;  
float ey = h/2-dis_eg;


if ( ey < y)
if (perCheck)
{
{
//float q=x+((w*ey)/(h/2));
ay = h-ay;
float q=x+(w-((w+offset)*(y-ey))/((y+h/2)-ey));
ey = h-ey;
float ratio_3 = (q-x)/w;
sy = h-sy;
per = 1.0 - per;
}


float ratio_1 = ey/h; //ratio of ey to height
float ratio_2 = per; //ratio of sy to height
float ratio_3 = ax/w; //ratio of ax to width
if ( ey < 0)
{
if (isTop)
if (isTop)
{
{
float pMat[10][2];
pMat[0][0] = ax;
pMat[0][1] = ay;
pMat[1][0] = w;
pMat[1][1] = 0;
pMat[2][0] = sx;
pMat[2][1] = sy;
float rMat[10][2];
MatixMulti(pMat,3,2, rotMat, 2,2, rMat, 3,2);
vgui::Vertex_t points[3] =
vgui::Vertex_t points[3] =
{
{
vgui::Vertex_t( Vector2D((int)(q), (int)(y)), Vector2D(ratio_3,0)),
vgui::Vertex_t( Vector2D((rMat[0][0]+x), (rMat[0][1])+y), Vector2D(ratio_3,0)),
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(0,ratio_2) ),
vgui::Vertex_t( Vector2D((rMat[1][0]+x), (rMat[1][1])+y), Vector2D(1,0) ),
vgui::Vertex_t( Vector2D((int)(x), (int)(y)), Vector2D(0,0) )
vgui::Vertex_t( Vector2D((rMat[2][0]+x), (rMat[2][1])+y), Vector2D(1,ratio_2) )
};
};
vgui::surface()->DrawTexturedPolygon( 3, points);
vgui::surface()->DrawTexturedPolygon( 3, points);
Line 226: Line 191:
else
else
{
{
float pMat[10][2];
pMat[0][0] = 0;
pMat[0][1] = 0;
pMat[1][0] = ax;
pMat[1][1] = ay;
pMat[2][0] = sx;
pMat[2][1] = sy;
pMat[3][0] = w;
pMat[3][1] = h;
pMat[4][0] = 0;
pMat[4][1] = h;
float rMat[10][2];
MatixMulti(pMat,5,2, rotMat, 2,2, rMat, 5,2);
vgui::Vertex_t points[5] =
vgui::Vertex_t points[5] =
{
{
vgui::Vertex_t( Vector2D((int)(q), (int)(y)), Vector2D(ratio_3,0) ), //top center
vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x), (int)(rMat[0][1]+y)), Vector2D(0,0) ), //top left
vgui::Vertex_t( Vector2D((int)(x+w), (int)(y)), Vector2D(1,0) ), //top right
vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x), (int)(rMat[1][1]+y)), Vector2D(ratio_3,0) ), //top right
vgui::Vertex_t( Vector2D((int)(w+x), (int)(y+h)), Vector2D(1,1) ), //bottom right
vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x), (int)(rMat[2][1]+y)), Vector2D(1,ratio_2) ), //bottom right
vgui::Vertex_t( Vector2D((int)(x), (int)(y+h)), Vector2D(0,1) ), //bottom left
vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x), (int)(rMat[3][1]+y)), Vector2D(1,1) ), //bottom center
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(0,ratio_2) ) //top right
vgui::Vertex_t( Vector2D((int)(rMat[4][0]+x), (int)(rMat[4][1]+y)), Vector2D(0,1) ) //bottom left
};
};
vgui::surface()->DrawTexturedPolygon( 5, points);
vgui::surface()->DrawTexturedPolygon( 5, points);
}
}
}
}
else if ( ey > (y+h))
else if ( ey > h)
{
{
float q=x+w+((offset+w)*((y+h)-ey)/(ey-(h/2+y)));
float ratio_3=(q-x)/w;


if (isTop)
if (isTop)
{
{
float pMat[10][2];
pMat[0][0] = 0;
pMat[0][1] = 0;
pMat[1][0] = w;
pMat[1][1] = 0;
pMat[2][0] = sx;
pMat[2][1] = sy;
pMat[3][0] = ax;
pMat[3][1] = ay;
pMat[4][0] = 0;
pMat[4][1] = h;
float rMat[10][2];
MatixMulti(pMat,5,2, rotMat, 2,2, rMat, 5,2);
vgui::Vertex_t points[5] =
vgui::Vertex_t points[5] =
{
{
vgui::Vertex_t( Vector2D((int)(x), (int)(y)), Vector2D(0,0) ), //top left
vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x), (int)(rMat[0][1]+y)), Vector2D(0,0) ), //top left
vgui::Vertex_t( Vector2D((int)(x+w), (int)(y)), Vector2D(1,0) ), //top right
vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x), (int)(rMat[1][1]+y)), Vector2D(1,0) ), //top right
vgui::Vertex_t( Vector2D((int)(x+w), (int)(y+h)), Vector2D(1,1) ), //bottom right
vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x), (int)(rMat[2][1]+y)), Vector2D(1,ratio_2) ), //bottom right
vgui::Vertex_t( Vector2D((int)(q), (int)(y+h)), Vector2D(ratio_3,1) ), //bottom center
vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x), (int)(rMat[3][1]+y)), Vector2D(ratio_3,1) ), //bottom center
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(0,ratio_2) ) //bottom left
vgui::Vertex_t( Vector2D((int)(rMat[4][0]+x), (int)(rMat[4][1]+y)), Vector2D(0,1) ) //bottom left
};
};
vgui::surface()->DrawTexturedPolygon( 5, points);
vgui::surface()->DrawTexturedPolygon( 5, points);
Line 258: Line 250:
else
else
{
{
float pMat[10][2];
pMat[0][0] = sx;
pMat[0][1] = sy;
pMat[1][0] = w;
pMat[1][1] = h;
pMat[2][0] = ax;
pMat[2][1] = ay;
float rMat[10][2];
MatixMulti(pMat,3,2, rotMat, 2,2, rMat, 3,2);
vgui::Vertex_t points[3] =
vgui::Vertex_t points[3] =
{
{
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(0,ratio_2) ),
vgui::Vertex_t( Vector2D((rMat[0][0]+x), (rMat[0][1])+y), Vector2D(1,ratio_2)),
vgui::Vertex_t( Vector2D((int)(q), (int)(y+h)), Vector2D(ratio_3,1) ),
vgui::Vertex_t( Vector2D((rMat[1][0]+x), (rMat[1][1])+y), Vector2D(1,1)),
vgui::Vertex_t( Vector2D((int)(x), (int)(y+h)), Vector2D(0,1))
vgui::Vertex_t( Vector2D((rMat[2][0]+x), (rMat[2][1])+y), Vector2D(ratio_3,1))
};
};
vgui::surface()->DrawTexturedPolygon( 3, points);
vgui::surface()->DrawTexturedPolygon( 3, points);
Line 272: Line 274:
if (isTop)
if (isTop)
{
{
float pMat[4][2];
pMat[0][0] = 0;
pMat[0][1] = 0;
pMat[1][0] = w;
pMat[1][1] = 0;
pMat[2][0] = sx;
pMat[2][1] = sy;
pMat[3][0] = ex;
pMat[3][1] = ey;
float rMat[4][2];
MatixMulti(pMat,4,2, rotMat, 2,2, rMat, 4,2);
vgui::Vertex_t points[4] =
vgui::Vertex_t points[4] =
{
{
vgui::Vertex_t( Vector2D((int)(x), (int)(y)), Vector2D(0,0) ),
vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x), (int)(rMat[0][1]+y)), Vector2D(0,0) ),
vgui::Vertex_t( Vector2D((int)(x+w),(int)(y)), Vector2D(1,0) ),
vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x), (int)(rMat[1][1]+y)), Vector2D(1,0) ),
vgui::Vertex_t( Vector2D((int)(ex), (int)(ey)), Vector2D(1,ratio_1) ),
vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x), (int)(rMat[2][1]+y)), Vector2D(1,ratio_2) ),
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(0,ratio_2) )
vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x), (int)(rMat[3][1]+y)), Vector2D(0,ratio_1) )
};
};
vgui::surface()->DrawTexturedPolygon( 4, points);
vgui::surface()->DrawTexturedPolygon( 4, points);
Line 283: Line 298:
else
else
{
{
float pMat[4][2];
pMat[0][0] = ex;
pMat[0][1] = ey;
pMat[1][0] = sx;
pMat[1][1] = sy;
pMat[2][0] = w;
pMat[2][1] = h;
pMat[3][0] = 0;
pMat[3][1] = h;
float rMat[4][2];
MatixMulti(pMat,4,2, rotMat, 2,2, rMat, 4,2);
vgui::Vertex_t points[4] =
vgui::Vertex_t points[4] =
{
{
vgui::Vertex_t( Vector2D((int)(sx), (int)(sy)), Vector2D(0,ratio_2)),
vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x), (int)(rMat[0][1]+y)), Vector2D(0,ratio_1)),
vgui::Vertex_t( Vector2D((int)(ex), (int)(ey)), Vector2D(1,ratio_1)),
vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x), (int)(rMat[1][1]+y)), Vector2D(1,ratio_2)),
vgui::Vertex_t( Vector2D((int)(x+w),(int)(y+h)), Vector2D(1,1) ),
vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x), (int)(rMat[2][1]+y)), Vector2D(1,1) ),
vgui::Vertex_t( Vector2D((int)(x), (int)(y+h)), Vector2D(0,1) )
vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x), (int)(rMat[3][1]+y)), Vector2D(0,1) )
};
};
vgui::surface()->DrawTexturedPolygon( 4, points);
vgui::surface()->DrawTexturedPolygon( 4, points);
Line 296: Line 324:
else
else
{
{
float pMat[4][2];
pMat[0][0] = 0;
pMat[0][1] = 0;
pMat[1][0] = w;
pMat[1][1] = 0;
pMat[2][0] = w;
pMat[2][1] = h;
pMat[3][0] = 0;
pMat[3][1] = h;
float rMat[4][2];
MatixMulti(pMat,4,2, rotMat, 2,2, rMat, 4,2);
vgui::Vertex_t points[4] =
vgui::Vertex_t points[4] =
{
{
vgui::Vertex_t( Vector2D(x,y), Vector2D(0,0) ),
vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x), (int)(rMat[0][1]+y)), Vector2D(0,0) ),
vgui::Vertex_t( Vector2D(x+w, y), Vector2D(1,0) ),
vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x), (int)(rMat[1][1]+y)), Vector2D(1,0) ),
vgui::Vertex_t( Vector2D(x+w, y+(h)), Vector2D(1,1) ),
vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x), (int)(rMat[2][1]+y)), Vector2D(1,1) ),
vgui::Vertex_t( Vector2D(x, y+h), Vector2D(0,1) )
vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x), (int)(rMat[3][1]+y)), Vector2D(0,1) )
};
};
vgui::surface()->DrawTexturedPolygon( 4, points);
vgui::surface()->DrawTexturedPolygon( 4, points);
}
}
}


void CHudTexture::DrawScew_Right(int tx, int ty, int tw, int th, float per, bool isTop, int offset) const
{
DrawScew_Right(tx, ty, tw, th, per, isTop, offset, 0.0);
}
void CHudTexture::DrawScew_Right(int tx, int ty, int tw, int th, float per, bool isTop, int offset, float ang) const
{
DrawScew_Left(tx+tw, ty+th, tw, th, 1.0-per, !isTop, offset, ang+180.0);
}
}
</pre>
</pre>


[[Category:Hud]]
[[Category:Hud]]
[[Category:Free source code]]
[[Category:Free source code]]

Latest revision as of 10:04, 21 January 2024

Wikipedia - Letter.png
This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these template messages)
Dead End - Icon.png
This article has no Wikipedia icon links to other VDC articles. Please help improve this article by adding links Wikipedia icon that are relevant to the context within the existing text.
January 2024

This code is like the two image split for the ammo and health icons in ep1 (near the cross hair) but does it on an angle both on the left side and right side and allows for them to be rotated.
This uses a lot of trig and the code could be simplified a bit.

How it works

Angle split working.jpg

Result

Angle split.jpg

Code

This assumes you already have a HUD panel set up and ready to use. First thing to do is to define the two images:

Header:

public:
	void VidInit(void);

private:
	CHudTexture	*m_icon_lb;		// left bracket, full
	CHudTexture	*m_icon_lbe;		// left bracket, empty

Cpp File:

void CLASSNAME::VidInit( void )
{
	m_icon_lb = gHUD.GetIcon( "health_full" );
	m_icon_lbe = gHUD.GetIcon( "health_empty" );

	BaseClass::VidInit();
}

The names here refer to the textures defined in mod_textures.txt

Once we have this we need to add some code to the paint function:

	int scaledW, scaledH, scaledDis, screenWide, screenTall, X,Y, offset;

	offset = scheme()->GetProportionalScaledValue(100);
		
	//image width
	scaledW = scheme()->GetProportionalScaledValue(25);

	//image height
	scaledH = scheme()->GetProportionalScaledValue(100);

	//image indentation
	scaledDis = scheme()->GetProportionalScaledValue(200);

	GetHudSize(screenWide, screenTall);

	X = screenWide/2 - scaledDis - scaledW;
	Y = screenTall/2 - scaledH/2;

	m_icon_lbe->DrawScew_Left(X, Y, scaledW, scaledH, 1-HealthPer, true, offset);
	m_icon_lb->DrawScew_Left(X, Y, scaledW, scaledH, 1-HealthPer, false, offset);

This draws each element at pos X,Y with size scaledW, scaledH. Since these are health bars a health percentage is already defined. The true/false refers to which image they are (true for empty image and false for full) and the offset is the horizontal distance between the edge and the pivot point (see picture above).

We need to add the new functions into hud.cpp/hud.h
For the header add:

	void DrawScew_Left(int x, int y, int w, int h, float per, bool isTop, int offset) const;
	void DrawScew_Left(int x, int y, int w, int h, float per, bool isTop, int offset, float ang) const;
	void DrawScew_Right(int x, int y, int w, int h, float per, bool isTop, int offset) const;
	void DrawScew_Right(int x, int y, int w, int h, float per, bool isTop, int offset, float ang) const;

And the cpp file add:

#include <maths.h>
#define PI 3.14159265

Up the top after the other includes and the following after all the other functions:

void MatixMulti(float m1[][2], int a, int b, float m2[][2], int c, int d, float m3[][2], int e, int f)
{
	if (b!=c || a!=e || d!=f)
		return;

	for (int x=0; x<a; x++)
	{
		for (int y=0; y<d; y++)
		{
			int res =0;
			for (int z=0; z<b; z++)
			{
				res += m1[x][z]*m2[z][y];
			}

			m3[x][y] = res;
		}
	}
}

void CHudTexture::DrawScew_Left(int tx, int ty, int tw, int th, float per, bool isTop, int offset) const
{
	DrawScew_Left(tx, ty, tw, th, per, isTop, offset, 0);
};

void CHudTexture::DrawScew_Left(int tx, int ty, int tw, int th, float per, bool isTop, int offset, float ang) const
{
	per = max(0, min(1,per));

	vgui::surface()->DrawSetTexture( textureId );
	vgui::surface()->DrawSetColor( Color(125,125,125,125) );

	float x = (float)(tx);
	float y = (float)(ty);
	float w = (float)(tw);
	float h = (float)(th);

	float rotMat[2][2];
	rotMat[0][0] =  cos(ang*PI/180);
	rotMat[0][1] =  sin(ang*PI/180);
	rotMat[1][0] = -sin(ang*PI/180);
	rotMat[1][1] =  cos(ang*PI/180);

	if (per > 0 && per < 1)
	{
		bool perCheck = false;

		if (per > 0.5)
		{
			per = 1.0-per;
			perCheck = true;
		}
	
		float sy = per*h;
		float sx = w;

		float dis_sp = h/2 - sy;
		float dis_pq = offset;
		float dis_oe = sy;

		float dis_ds = dis_oe*dis_pq/dis_sp;
		float ax = w-dis_ds;
		float ay = 0;

		float dis_gq = dis_pq + w;
		float dis_eg = dis_sp * dis_gq / dis_pq;

		float ex = 0; 
		float ey = h/2-dis_eg;

		if (perCheck)
		{
			ay = h-ay;
			ey = h-ey;
			sy = h-sy;
			per = 1.0 - per;
		}

		float ratio_1 = ey/h;	//ratio of ey to height
		float ratio_2 =	per;	//ratio of sy to height
		float ratio_3 = ax/w;	//ratio of ax to width

		if ( ey < 0)
		{
			if (isTop)
			{
				float pMat[10][2];
				pMat[0][0] = ax;
				pMat[0][1] = ay;
				pMat[1][0] = w;
				pMat[1][1] = 0;
				pMat[2][0] = sx;
				pMat[2][1] = sy;

				float rMat[10][2];
				MatixMulti(pMat,3,2, rotMat, 2,2, rMat, 3,2);

				vgui::Vertex_t points[3] =
				{
					vgui::Vertex_t( Vector2D((rMat[0][0]+x), (rMat[0][1])+y), Vector2D(ratio_3,0)),
					vgui::Vertex_t( Vector2D((rMat[1][0]+x), (rMat[1][1])+y), Vector2D(1,0) ),
					vgui::Vertex_t( Vector2D((rMat[2][0]+x), (rMat[2][1])+y), Vector2D(1,ratio_2) )
				};
				vgui::surface()->DrawTexturedPolygon( 3, points);
			}
			else
			{
				float pMat[10][2];
				pMat[0][0] = 0;
				pMat[0][1] = 0;
				pMat[1][0] = ax;
				pMat[1][1] = ay;
				pMat[2][0] = sx;
				pMat[2][1] = sy;
				pMat[3][0] = w;
				pMat[3][1] = h;
				pMat[4][0] = 0;
				pMat[4][1] = h;

				float rMat[10][2];
				MatixMulti(pMat,5,2, rotMat, 2,2, rMat, 5,2);

				vgui::Vertex_t points[5] =
				{
					vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x),	(int)(rMat[0][1]+y)), Vector2D(0,0) ),			//top left
					vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x),	(int)(rMat[1][1]+y)), Vector2D(ratio_3,0) ),	//top right
					vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x),	(int)(rMat[2][1]+y)), Vector2D(1,ratio_2) ),	//bottom right
					vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x),	(int)(rMat[3][1]+y)), Vector2D(1,1) ),		//bottom center
					vgui::Vertex_t( Vector2D((int)(rMat[4][0]+x),	(int)(rMat[4][1]+y)), Vector2D(0,1) )		//bottom left
				};

				vgui::surface()->DrawTexturedPolygon( 5, points);
			}
		}
		else if ( ey > h)
		{

			if (isTop)
			{
				float pMat[10][2];
				pMat[0][0] = 0;
				pMat[0][1] = 0;
				pMat[1][0] = w;
				pMat[1][1] = 0;
				pMat[2][0] = sx;
				pMat[2][1] = sy;
				pMat[3][0] = ax;
				pMat[3][1] = ay;
				pMat[4][0] = 0;
				pMat[4][1] = h;

				float rMat[10][2];
				MatixMulti(pMat,5,2, rotMat, 2,2, rMat, 5,2);

				vgui::Vertex_t points[5] =
				{
					vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x),	(int)(rMat[0][1]+y)), Vector2D(0,0) ),			//top left
					vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x),	(int)(rMat[1][1]+y)), Vector2D(1,0) ),			//top right
					vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x),	(int)(rMat[2][1]+y)), Vector2D(1,ratio_2) ),	//bottom right
					vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x),	(int)(rMat[3][1]+y)), Vector2D(ratio_3,1) ),	//bottom center
					vgui::Vertex_t( Vector2D((int)(rMat[4][0]+x),	(int)(rMat[4][1]+y)), Vector2D(0,1) )		//bottom left
				};
				vgui::surface()->DrawTexturedPolygon( 5, points);
			}
			else
			{
				float pMat[10][2];
				pMat[0][0] = sx;
				pMat[0][1] = sy;
				pMat[1][0] = w;
				pMat[1][1] = h;
				pMat[2][0] = ax;
				pMat[2][1] = ay;

				float rMat[10][2];
				MatixMulti(pMat,3,2, rotMat, 2,2, rMat, 3,2);

				vgui::Vertex_t points[3] =
				{
					vgui::Vertex_t( Vector2D((rMat[0][0]+x), (rMat[0][1])+y), Vector2D(1,ratio_2)),
					vgui::Vertex_t( Vector2D((rMat[1][0]+x), (rMat[1][1])+y), Vector2D(1,1)),
					vgui::Vertex_t( Vector2D((rMat[2][0]+x), (rMat[2][1])+y), Vector2D(ratio_3,1))
				};
				vgui::surface()->DrawTexturedPolygon( 3, points);
			}
		}
		else
		{
			if (isTop)
			{
				float pMat[4][2];
				pMat[0][0] = 0;
				pMat[0][1] = 0;
				pMat[1][0] = w;
				pMat[1][1] = 0;
				pMat[2][0] = sx;
				pMat[2][1] = sy;
				pMat[3][0] = ex;
				pMat[3][1] = ey;

				float rMat[4][2];
				MatixMulti(pMat,4,2, rotMat, 2,2, rMat, 4,2);

				vgui::Vertex_t points[4] =
				{
					vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x),	(int)(rMat[0][1]+y)), Vector2D(0,0) ),
					vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x),	(int)(rMat[1][1]+y)), Vector2D(1,0) ),
					vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x),	(int)(rMat[2][1]+y)), Vector2D(1,ratio_2) ),
					vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x),	(int)(rMat[3][1]+y)), Vector2D(0,ratio_1) )
				};
				vgui::surface()->DrawTexturedPolygon( 4, points);
			}
			else
			{
				float pMat[4][2];
				pMat[0][0] = ex;
				pMat[0][1] = ey;
				pMat[1][0] = sx;
				pMat[1][1] = sy;
				pMat[2][0] = w;
				pMat[2][1] = h;
				pMat[3][0] = 0;
				pMat[3][1] = h;

				float rMat[4][2];
				MatixMulti(pMat,4,2, rotMat, 2,2, rMat, 4,2);

				vgui::Vertex_t points[4] =
				{
					vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x),	(int)(rMat[0][1]+y)), Vector2D(0,ratio_1)),
					vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x),	(int)(rMat[1][1]+y)), Vector2D(1,ratio_2)),
					vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x),	(int)(rMat[2][1]+y)), Vector2D(1,1) ),
					vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x),	(int)(rMat[3][1]+y)), Vector2D(0,1) )
				};
				vgui::surface()->DrawTexturedPolygon( 4, points);
			}
		}
	}
	else
	{
		float pMat[4][2];
		pMat[0][0] = 0;
		pMat[0][1] = 0;
		pMat[1][0] = w;
		pMat[1][1] = 0;
		pMat[2][0] = w;
		pMat[2][1] = h;
		pMat[3][0] = 0;
		pMat[3][1] = h;

		float rMat[4][2];
		MatixMulti(pMat,4,2, rotMat, 2,2, rMat, 4,2);

		vgui::Vertex_t points[4] =
		{
			vgui::Vertex_t( Vector2D((int)(rMat[0][0]+x), (int)(rMat[0][1]+y)), Vector2D(0,0) ),
			vgui::Vertex_t( Vector2D((int)(rMat[1][0]+x), (int)(rMat[1][1]+y)), Vector2D(1,0) ),
			vgui::Vertex_t( Vector2D((int)(rMat[2][0]+x), (int)(rMat[2][1]+y)), Vector2D(1,1) ),
			vgui::Vertex_t( Vector2D((int)(rMat[3][0]+x), (int)(rMat[3][1]+y)), Vector2D(0,1) )
		};
		vgui::surface()->DrawTexturedPolygon( 4, points);
	}
}

void CHudTexture::DrawScew_Right(int tx, int ty, int tw, int th, float per, bool isTop, int offset) const
{
	DrawScew_Right(tx, ty, tw, th, per, isTop, offset, 0.0);
}

void CHudTexture::DrawScew_Right(int tx, int ty, int tw, int th, float per, bool isTop, int offset, float ang) const
{
	DrawScew_Left(tx+tw, ty+th, tw, th, 1.0-per, !isTop, offset, ang+180.0);
}