mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-04 18:09:53 +03:00
1
This commit is contained in:
152
game/client/c_tracer.cpp
Normal file
152
game/client/c_tracer.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "particledraw.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sees if the tracer is behind the camera or should be culled
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static bool ClipTracer( const Vector &start, const Vector &delta, Vector &clippedStart, Vector &clippedDelta )
|
||||
{
|
||||
// dist1 = start dot forward - origin dot forward
|
||||
// dist2 = (start + delta ) dot forward - origin dot forward
|
||||
// in camera space this is -start[2] since origin = 0 and vecForward = (0, 0, -1)
|
||||
float dist1 = -start[2];
|
||||
float dist2 = dist1 - delta[2];
|
||||
|
||||
// Clipped, skip this tracer
|
||||
if ( dist1 <= 0 && dist2 <= 0 )
|
||||
return true;
|
||||
|
||||
clippedStart = start;
|
||||
clippedDelta = delta;
|
||||
|
||||
// Needs to be clipped
|
||||
if ( dist1 <= 0 || dist2 <= 0 )
|
||||
{
|
||||
float fraction = dist2 - dist1;
|
||||
|
||||
// Too close to clipping plane
|
||||
if ( fraction < 1e-3 && fraction > -1e-3 )
|
||||
return true;
|
||||
|
||||
fraction = -dist1 / fraction;
|
||||
|
||||
if ( dist1 <= 0 )
|
||||
{
|
||||
VectorMA( start, fraction, delta, clippedStart );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorMultiply( delta, fraction, clippedDelta );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Computes the four verts to draw the tracer with
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Tracer_ComputeVerts( const Vector &start, const Vector &delta, float width, Vector *pVerts )
|
||||
{
|
||||
Vector clippedStart, clippedDelta;
|
||||
|
||||
// Clip the tracer
|
||||
if ( ClipTracer( start, delta, clippedStart, clippedDelta ) )
|
||||
return false;
|
||||
|
||||
// Figure out direction in camera space of the normal
|
||||
Vector normal;
|
||||
CrossProduct( clippedDelta, clippedStart, normal );
|
||||
|
||||
// don't draw if they are parallel
|
||||
float sqLength = DotProduct( normal, normal );
|
||||
if (sqLength < 1e-3)
|
||||
return false;
|
||||
|
||||
// Resize the normal to be appropriate based on the width
|
||||
VectorScale( normal, 0.5f * width / sqrt(sqLength), normal );
|
||||
|
||||
VectorSubtract( clippedStart, normal, pVerts[0] );
|
||||
VectorAdd( clippedStart, normal, pVerts[1] );
|
||||
|
||||
VectorAdd( pVerts[0], clippedDelta, pVerts[2] );
|
||||
VectorAdd( pVerts[1], clippedDelta, pVerts[3] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Tracer_Draw( CMeshBuilder *pMeshBuilder, Vector& start, Vector& delta, float width, float* color, float startV, float endV )
|
||||
{
|
||||
// Clip the tracer
|
||||
Vector verts[4];
|
||||
if (!Tracer_ComputeVerts( start, delta, width, verts ))
|
||||
return;
|
||||
|
||||
// NOTE: Gotta get the winding right so it's not backface culled
|
||||
// (we need to turn of backface culling for these bad boys)
|
||||
pMeshBuilder->Position3f( verts[0].x, verts[0].y, verts[0].z );
|
||||
pMeshBuilder->TexCoord2f( 0, 0.0f, startV );
|
||||
if (color)
|
||||
{
|
||||
pMeshBuilder->Color4fv( color );
|
||||
}
|
||||
else
|
||||
{
|
||||
pMeshBuilder->Color4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
pMeshBuilder->AdvanceVertex();
|
||||
|
||||
pMeshBuilder->Position3f( verts[1].x, verts[1].y, verts[1].z );
|
||||
pMeshBuilder->TexCoord2f( 0, 1.0f, startV );
|
||||
if (color)
|
||||
{
|
||||
pMeshBuilder->Color4fv( color );
|
||||
}
|
||||
else
|
||||
{
|
||||
pMeshBuilder->Color4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
pMeshBuilder->AdvanceVertex();
|
||||
|
||||
pMeshBuilder->Position3f( verts[3].x, verts[3].y, verts[3].z );
|
||||
pMeshBuilder->TexCoord2f( 0, 1.0f, endV );
|
||||
if (color)
|
||||
pMeshBuilder->Color4fv( color );
|
||||
else
|
||||
pMeshBuilder->Color4ub( 255, 255, 255, 255 );
|
||||
pMeshBuilder->AdvanceVertex();
|
||||
|
||||
pMeshBuilder->Position3f( verts[2].x, verts[2].y, verts[2].z );
|
||||
pMeshBuilder->TexCoord2f( 0, 0.0f, endV );
|
||||
if (color)
|
||||
pMeshBuilder->Color4fv( color );
|
||||
else
|
||||
pMeshBuilder->Color4ub( 255, 255, 255, 255 );
|
||||
pMeshBuilder->AdvanceVertex();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// draw a tracer.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Tracer_Draw( ParticleDraw* pDraw, Vector& start, Vector& delta, float width, float* color, float startV, float endV )
|
||||
{
|
||||
if( !pDraw->GetMeshBuilder() )
|
||||
return;
|
||||
|
||||
Tracer_Draw( pDraw->GetMeshBuilder(), start, delta, width, color, startV, endV );
|
||||
}
|
||||
Reference in New Issue
Block a user