void GadgetBeamWeapon::render( RenderContext &context, const Matrix33 & frame, const Vector3 & position ) { NounGadget::render( context, frame, position ); // render the beam if ( useActive() && m_Target.valid() && m_Duration > 0 ) { Vector3 positionVS( context.worldToView( position ) ); float fLength = length() * calculateModifier( MT_BEAM_RANGE ); if (! context.sphereVisible( positionVS, fLength ) ) return; Noun * pTarget = m_Target; Vector3 position2( pTarget->worldPosition() ); if ( ( ( position2 - worldPosition() ).magnitude() - pTarget->radius() ) > fLength ) return; if ( !checkFacing( position2 ) ) return; int tailAlpha = 32; if ( m_Hit.valid() ) tailAlpha = 128; Vector3 direction( pTarget->worldPosition() - position ); Vector3 head( position ); Vector3 tail( head + direction ); // calculate the material wrap float h = 0.05f; float w = 10.0f; Material * pTracerMaterial = tracerMaterial(); if ( pTracerMaterial != NULL ) { h = pTracerMaterial->height(); w = pTracerMaterial->width(); Material::push( context, pTracerMaterial ); } else Material::push( context, Color(255,0,0), true, PrimitiveMaterial::ADDITIVE ); float u = (head - tail).magnitude() / w; const Vector3 N( 0,0, 0); const Vector3 Y( 0, h, 0 ); const Vector3 X( h, 0, 0 ); const Color HC( 255,255,255,255 ); const Color TC( 255,255,255,tailAlpha ); VertexL beamY[4] = { VertexL( head + Y, N, HC, u, 0.0f ), VertexL( tail + Y, N, TC, 0.0f, 0.0f ), VertexL( tail - Y, N, TC, 0.0f, 1.0f ), VertexL( head - Y, N, HC, u, 1.0f ), }; VertexL beamX[4] = { VertexL( head + X, N, HC, u, 0.0f ), VertexL( tail + X, N, TC, 0.0f, 0.0f ), VertexL( tail - X, N, TC, 0.0f, 1.0f ), VertexL( head - X, N, HC, u, 1.0f ), }; DisplayDevice * pDisplay = context.device(); ASSERT( pDisplay ); context.pushIdentity(); PrimitiveTriangleFanDL::push( pDisplay, 4, beamY ); PrimitiveTriangleFanDL::push( pDisplay, 4, beamX ); } }