void ScratchPad_DrawLitCone( IScratchPad3D *pPad, const Vector &vBaseCenter, const Vector &vTip, const Vector &vBrightColor, const Vector &vDarkColor, const Vector &vLightDir, float baseWidth, int nSegments ) { // Make orthogonal vectors. Vector vDir = vTip - vBaseCenter; VectorNormalize( vDir ); Vector vRight, vUp; VectorVectors( vDir, vRight, vUp ); vRight *= baseWidth; vUp *= baseWidth; // Setup the top and bottom caps. CSPVertList bottomCap, tri; bottomCap.m_Verts.SetSize( nSegments ); tri.m_Verts.SetSize( 3 ); float flDot = -vLightDir.Dot( vDir ); Vector topColor, bottomColor; VectorLerp( vDarkColor, vBrightColor, RemapVal( -flDot, -1, 1, 0, 1 ), bottomColor ); // Draw each quad. Vector vPrevBottom = vBaseCenter + vRight; for ( int i=0; i < nSegments; i++ ) { float flAngle = (float)(i+1) * M_PI * 2.0 / nSegments; Vector vOffset = vRight * cos( flAngle ) + vUp * sin( flAngle ); Vector vCurBottom = vBaseCenter + vOffset; const Vector &v1 = vTip; const Vector &v2 = vPrevBottom; const Vector &v3 = vCurBottom; Vector vFaceNormal = (v2 - v1).Cross( v3 - v1 ); VectorNormalize( vFaceNormal ); // Now light it. flDot = -vLightDir.Dot( vFaceNormal ); Vector vColor; VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), vColor ); // Draw the quad. tri.m_Verts[0] = CSPVert( v1, vColor ); tri.m_Verts[1] = CSPVert( v2, vColor ); tri.m_Verts[2] = CSPVert( v3, vColor ); pPad->DrawPolygon( tri ); bottomCap.m_Verts[i] = CSPVert( vCurBottom, bottomColor ); } pPad->DrawPolygon( bottomCap ); }
void ScratchPad_DrawOriginalNormals( const CCoreDispInfo *pListBase, int listSize ) { for ( int i=0; i < listSize; i++ ) { const CCoreDispInfo *pDisp = &pListBase[i]; const CPowerInfo *pPowerInfo = pDisp->GetPowerInfo(); // Draw the triangles. for ( int iTri=0; iTri < pPowerInfo->GetNumTriInfos(); iTri++ ) { const CTriInfo *pTriInfo = pPowerInfo->GetTriInfo( iTri ); for ( int iLine=0; iLine < 3; iLine++ ) { const Vector &v1 = pDisp->GetVert( pTriInfo->m_Indices[iLine] ); const Vector &v2 = pDisp->GetVert( pTriInfo->m_Indices[(iLine+1)%3] ); g_pPad->DrawLine( CSPVert( v1 ), CSPVert( v2 ) ); } } // Draw the normals. CDispCircumferenceIterator it( pPowerInfo->GetSideLength() ); while ( it.Next() ) { ScratchPad_DrawArrowSimple( g_pPad, pDisp->GetVert( it.GetVertIndex() ), pDisp->GetNormal( it.GetVertIndex() ), Vector( 0, 1, 0 ), 15 ); } } }
void CScratchPadGraph::AddVerticalLine( float flTime, float flMinValue, float flMaxValue, const CSPColor &vColor ) { Vector v1 = GetSamplePosition( flTime, flMinValue ); Vector v2 = GetSamplePosition( flTime, flMaxValue ); m_pPad->DrawLine( CSPVert( v1, vColor ), CSPVert( v2, vColor ) ); }
void ScratchPad_DrawSphere( IScratchPad3D *pPad, const Vector &vCenter, float flRadius, const Vector &vColor, int nSubDivs ) { CUtlVector<Vector> prevPoints; prevPoints.SetSize( nSubDivs ); // For each vertical slice.. (the top and bottom ones are just a single point). for ( int iSlice=0; iSlice < nSubDivs; iSlice++ ) { float flHalfSliceAngle = M_PI * (float)iSlice / (nSubDivs - 1); if ( iSlice == 0 ) { prevPoints[0] = vCenter + Vector( 0, 0, flRadius ); for ( int z=1; z < prevPoints.Count(); z++ ) prevPoints[z] = prevPoints[0]; } else { for ( int iSubPt=0; iSubPt < nSubDivs; iSubPt++ ) { float flHalfAngle = M_PI * (float)iSubPt / (nSubDivs - 1); float flAngle = flHalfAngle * 2; Vector pt; if ( iSlice == (nSubDivs - 1) ) { pt = vCenter - Vector( 0, 0, flRadius ); } else { pt.x = cos( flAngle ) * sin( flHalfSliceAngle ); pt.y = sin( flAngle ) * sin( flHalfSliceAngle ); pt.z = cos( flHalfSliceAngle ); pt *= flRadius; pt += vCenter; } pPad->DrawLine( CSPVert( pt, vColor ), CSPVert( prevPoints[iSubPt], vColor ) ); prevPoints[iSubPt] = pt; } if ( iSlice != (nSubDivs - 1) ) { for ( int i=0; i < nSubDivs; i++ ) pPad->DrawLine( CSPVert( prevPoints[i], vColor ), CSPVert( prevPoints[(i+1)%nSubDivs], vColor ) ); } } } }
void ScratchPad_DrawWinding( IScratchPad3D *pPad, int nPoints, Vector *pPoints, Vector vColor, Vector vOffset ) { for ( int i=0; i < nPoints; i++ ) { pPad->DrawLine( CSPVert( pPoints[i]+vOffset, vColor ), CSPVert( pPoints[(i+1)%nPoints]+vOffset, vColor ) ); } }
void ScratchPad_DrawFace( IScratchPad3D *pPad, dface_t *f, int iFaceNumber, const CSPColor &faceColor, const Vector &vOffset ) { // Draw the face's outline, then put text for its face index on it too. CUtlVector<Vector> points; for ( int iEdge = 0; iEdge < f->numedges; iEdge++ ) { int v; int se = dsurfedges[f->firstedge + iEdge]; if ( se < 0 ) v = dedges[-se].v[1]; else v = dedges[se].v[0]; dvertex_t *dv = &dvertexes[v]; points.AddToTail( dv->point ); } // Draw the outline. Vector vCenter( 0, 0, 0 ); for ( int iEdge=0; iEdge < points.Count(); iEdge++ ) { pPad->DrawLine( CSPVert( points[iEdge]+vOffset, faceColor ), CSPVert( points[(iEdge+1)%points.Count()]+vOffset, faceColor ) ); vCenter += points[iEdge]; } vCenter /= points.Count(); vCenter += vOffset; // Draw the text. if ( iFaceNumber != -1 ) { char str[64]; Q_snprintf( str, sizeof( str ), "%d", iFaceNumber ); CTextParams params; params.m_bCentered = true; params.m_bOutline = true; params.m_flLetterWidth = 2; params.m_vColor.Init( 1, 0, 0 ); VectorAngles( dplanes[f->planenum].normal, params.m_vAngles ); params.m_bTwoSided = true; params.m_vPos = vCenter; pPad->DrawText( str, params ); } }
void ScratchPad_DrawAABB( IScratchPad3D *pPad, const Vector &vMins, const Vector &vMaxs, const Vector &vColor ) { int vertOrder[4][2] = {{0,0},{1,0},{1,1},{0,1}}; const Vector *vecs[2] = {&vMins, &vMaxs}; Vector vTop, vBottom, vPrevTop, vPrevBottom; vTop.z = vPrevTop.z = vMaxs.z; vBottom.z = vPrevBottom.z = vMins.z; vPrevTop.x = vPrevBottom.x = vecs[vertOrder[3][0]]->x; vPrevTop.y = vPrevBottom.y = vecs[vertOrder[3][1]]->y; for ( int i=0; i < 4; i++ ) { vTop.x = vBottom.x = vecs[vertOrder[i][0]]->x; vTop.y = vBottom.y = vecs[vertOrder[i][1]]->y; // Draw the top line. pPad->DrawLine( CSPVert( vPrevTop, vColor ), CSPVert( vTop, vColor ) ); pPad->DrawLine( CSPVert( vPrevBottom, vColor ), CSPVert( vBottom, vColor ) ); pPad->DrawLine( CSPVert( vTop, vColor ), CSPVert( vBottom, vColor ) ); vPrevTop = vTop; vPrevBottom = vBottom; } }
void CScratchPadGraph::AddSample( LineID iLine, float flTime, float flValue ) { CScratchPadGraph::CLineInfo *pInfo = &m_LineInfos[iLine]; UpdateTicksAndStuff( flTime, flValue ); if ( !pInfo->m_bFirst ) { // Draw a line from the last value to the current one. Vector vStart = GetSamplePosition( pInfo->m_flLastTime, pInfo->m_flLastValue ); Vector vEnd = GetSamplePosition( flTime, flValue ); m_pPad->DrawLine( CSPVert( vStart, pInfo->m_vColor ), CSPVert( vEnd, pInfo->m_vColor ) ); } pInfo->m_flLastTime = flTime; pInfo->m_flLastValue = flValue; pInfo->m_bFirst = false; }
void ScratchPad_DrawLitCylinder( IScratchPad3D *pPad, const Vector &v1, const Vector &v2, const Vector &vBrightColor, const Vector &vDarkColor, const Vector &vLightDir, float width, int nSegments ) { // Make orthogonal vectors. Vector vDir = v2 - v1; VectorNormalize( vDir ); Vector vRight, vUp; VectorVectors( vDir, vRight, vUp ); vRight *= width; vUp *= width; // Setup the top and bottom caps. CSPVertList topCap, bottomCap, quad; topCap.m_Verts.SetSize( nSegments ); bottomCap.m_Verts.SetSize( nSegments ); quad.m_Verts.SetSize( 4 ); float flDot = -vLightDir.Dot( vDir ); Vector topColor, bottomColor; VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), topColor ); VectorLerp( vDarkColor, vBrightColor, RemapVal( -flDot, -1, 1, 0, 1 ), bottomColor ); // Draw each quad. Vector vPrevTop = v1 + vRight; Vector vPrevBottom = v2 + vRight; for ( int i=0; i < nSegments; i++ ) { float flAngle = (float)(i+1) * M_PI * 2.0 / nSegments; Vector vOffset = vRight * cos( flAngle ) + vUp * sin( flAngle ); Vector vCurTop = v1 + vOffset; Vector vCurBottom = v2 + vOffset; // Now light it. VectorNormalize( vOffset ); flDot = -vLightDir.Dot( vOffset ); Vector vColor; VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), vColor ); // Draw the quad. quad.m_Verts[0] = CSPVert( vPrevTop, vColor ); quad.m_Verts[1] = CSPVert( vPrevBottom, vColor ); quad.m_Verts[2] = CSPVert( vCurBottom, vColor ); quad.m_Verts[3] = CSPVert( vCurTop, vColor ); pPad->DrawPolygon( quad ); topCap.m_Verts[i] = CSPVert( vCurTop, topColor ); bottomCap.m_Verts[i] = CSPVert( vCurBottom, bottomColor ); } pPad->DrawPolygon( topCap ); pPad->DrawPolygon( bottomCap ); }
void CScratchPadGraph::UpdateTicksAndStuff( float flTime, float flValue ) { if ( flTime > m_flHighestTime ) { // Update the left part of the time axis. Vector vStart = GetSamplePosition( m_flHighestTime, m_flValueOrigin ); Vector vEnd = GetSamplePosition( flTime, m_flValueOrigin ); m_pPad->DrawLine( CSPVert( vStart, m_vTimeLineColor ), CSPVert( vEnd, m_vTimeLineColor ) ); m_flHighestTime = flTime; } if ( flValue > m_flHighestValue ) { // Update the left part of the time axis. Vector vStart = GetSamplePosition( m_flTimeOrigin, m_flHighestValue ); Vector vEnd = GetSamplePosition( m_flTimeOrigin, flValue ); m_pPad->DrawLine( CSPVert( vStart, m_vValueLineColor ), CSPVert( vEnd, m_vValueLineColor ) ); // Extend the lines attached to the time labels. for ( int i=0; i < m_nTimeLabelsDrawn; i++ ) { float flTime = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds; m_pPad->DrawLine( CSPVert((const Vector&) GetSamplePosition( flTime, m_flHighestValue )), CSPVert((const Vector&) GetSamplePosition( flTime, flValue ) ) ); } m_flHighestValue = flValue; } // More text labels? int iHighestTextLabel = (int)ceil( (flTime - m_flTimeOrigin) / m_flTimeLabelEveryNSeconds + 0.5f ); while ( m_nTimeLabelsDrawn < iHighestTextLabel ) { CTextParams params; float flTime = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds; params.m_bSolidBackground = true; params.m_vPos = GetSamplePosition( flTime, m_flValueOrigin-5 ); params.m_bTwoSided = true; char str[512]; Q_snprintf( str, sizeof( str ), "time: %.2f", flTime ); m_pPad->DrawText( str, params ); // Now draw the vertical line for the value.. m_pPad->DrawLine( CSPVert( (const Vector&)GetSamplePosition( flTime, m_flValueOrigin ) ), CSPVert( (const Vector&)GetSamplePosition( flTime, m_flHighestValue ) ) ); m_nTimeLabelsDrawn++; } }
void CScratchPad3D::DrawWireframeBox( const Vector &vMin, const Vector &vMax, const Vector &vColor ) { // Bottom 4. DrawLine( CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor) ); DrawLine( CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor) ); DrawLine( CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor), CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor) ); DrawLine( CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor), CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor) ); // Top 4. DrawLine( CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor), CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor) ); DrawLine( CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor), CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); DrawLine( CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor), CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor) ); DrawLine( CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor), CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); // Connecting 4. DrawLine( CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor) ); DrawLine( CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor), CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); DrawLine( CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor), CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor) ); DrawLine( CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor), CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor) ); }