You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1086 lines
35 KiB
1086 lines
35 KiB
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//===========================================================================//
|
|
#include "istudiorender.h"
|
|
#include "materialsystem/imesh.h"
|
|
#include "mathlib/mathlib.h"
|
|
#include "matsyswin.h"
|
|
#include "viewersettings.h"
|
|
#include "materialsystem/imaterialvar.h"
|
|
#include "tier1/UtlSortVector.h"
|
|
#include "tier2/tier2.h"
|
|
|
|
#define NORMAL_LENGTH .5f
|
|
#define NORMAL_OFFSET_FROM_MESH 0.1f
|
|
|
|
int DebugDrawModel( IStudioRender *pStudioRender, DrawModelInfo_t& info,
|
|
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
CMeshBuilder meshBuilder;
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
pRenderContext->Bind( materialBatch.m_pMaterial );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
|
|
int indexStart;
|
|
for (indexStart = 0; indexStart < materialBatch.m_TriListIndices.Count(); )
|
|
{
|
|
// FIXME: this shouldn't be needed, models shouldn't be built that can't fit
|
|
int nClampedIndices = MIN( materialBatch.m_TriListIndices.Count(), 32766 );
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(), nClampedIndices );
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &pos = vert.m_Position;
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
|
|
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
|
|
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
|
|
int k;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
|
|
Vector tmp;
|
|
VectorTransform( pos, poseToWorld, tmp );
|
|
skinnedPos += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( normal, poseToWorld, tmp );
|
|
skinnedNormal += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
|
|
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
|
|
}
|
|
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Normal3fv( &skinnedNormal.x );
|
|
meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
|
|
meshBuilder.UserData( &skinnedTangentS.x );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
int i;
|
|
// Set the indices down to the hardware.
|
|
// Each triplet of indices is a triangle.
|
|
for( i = indexStart; i < indexStart + nClampedIndices; i++ )
|
|
{
|
|
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
|
|
}
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
|
|
indexStart += nClampedIndices;
|
|
}
|
|
}
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DebugDrawModelNormals( IStudioRender *pStudioRender, DrawModelInfo_t& info,
|
|
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
CMeshBuilder meshBuilder;
|
|
pRenderContext->Bind( g_materialVertexColor );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh();
|
|
|
|
int vertID;
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); )
|
|
{
|
|
int nClamped = MIN( materialBatch.m_Verts.Count() - vertID, 32768 / 2 );
|
|
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_LINES, nClamped );
|
|
|
|
// Send the vertices down to the hardware.
|
|
for( ; nClamped > 0; vertID++, nClamped-- )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &pos = vert.m_Position;
|
|
const Vector &normal = vert.m_Normal;
|
|
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
|
|
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
|
|
int k;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
|
|
Vector tmp;
|
|
VectorTransform( pos, poseToWorld, tmp );
|
|
skinnedPos += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( normal, poseToWorld, tmp );
|
|
skinnedNormal += vert.m_BoneWeight[k] * tmp;
|
|
}
|
|
|
|
// skinnedPos += skinnedNormal * NORMAL_OFFSET_FROM_MESH;
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Color3f( 0.0f, 0.0f, 1.0f );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
skinnedPos += skinnedNormal * NORMAL_LENGTH;
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Color3f( 0.0f, 0.0f, 1.0f );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
}
|
|
}
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DebugDrawModelTangentS( IStudioRender *pStudioRender, DrawModelInfo_t& info,
|
|
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
CMeshBuilder meshBuilder;
|
|
pRenderContext->Bind( g_materialVertexColor );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh();
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_LINES, materialBatch.m_Verts.Count() );
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &pos = vert.m_Position;
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
|
|
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
|
|
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
|
|
int k;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
|
|
Vector tmp;
|
|
VectorTransform( pos, poseToWorld, tmp );
|
|
skinnedPos += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( normal, poseToWorld, tmp );
|
|
skinnedNormal += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
|
|
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
|
|
}
|
|
|
|
// skinnedPos += skinnedNormal * NORMAL_OFFSET_FROM_MESH;
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
skinnedPos += skinnedTangentS.AsVector3D() * NORMAL_LENGTH;
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
}
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DebugDrawModelTangentT( IStudioRender *pStudioRender, DrawModelInfo_t& info,
|
|
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
CMeshBuilder meshBuilder;
|
|
pRenderContext->Bind( g_materialVertexColor );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh();
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_LINES, materialBatch.m_Verts.Count() );
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &pos = vert.m_Position;
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
|
|
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
|
|
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
|
|
int k;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
|
|
Vector tmp;
|
|
VectorTransform( pos, poseToWorld, tmp );
|
|
skinnedPos += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( normal, poseToWorld, tmp );
|
|
skinnedNormal += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
|
|
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
|
|
}
|
|
|
|
Vector skinnedTangentT = CrossProduct( skinnedNormal, skinnedTangentS.AsVector3D() ) * skinnedTangentS.w;
|
|
|
|
// skinnedPos += skinnedNormal * NORMAL_OFFSET_FROM_MESH;
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
skinnedPos += skinnedTangentT * NORMAL_LENGTH;
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
}
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DebugDrawModelBadVerts( IStudioRender *pStudioRender, DrawModelInfo_t& info,
|
|
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
CMeshBuilder meshBuilder;
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
pRenderContext->Bind( g_materialVertexColor );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
|
|
int indexStart;
|
|
for (indexStart = 0; indexStart < materialBatch.m_TriListIndices.Count(); )
|
|
{
|
|
// FIXME: this shouldn't be needed, models shouldn't be built that can't fit
|
|
int nClampedIndices = MIN( materialBatch.m_TriListIndices.Count(), 32766 );
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(), nClampedIndices );
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &pos = vert.m_Position;
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
|
|
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
|
|
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
|
|
int k;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
|
|
Vector tmp;
|
|
VectorTransform( pos, poseToWorld, tmp );
|
|
skinnedPos += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( normal, poseToWorld, tmp );
|
|
skinnedNormal += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
|
|
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
|
|
}
|
|
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Normal3fv( &skinnedNormal.x );
|
|
meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
|
|
meshBuilder.UserData( &skinnedTangentS.x );
|
|
|
|
Vector color( 0.0f, 0.0f, 0.0f );
|
|
float len;
|
|
|
|
// check the length of the tangent S vector.
|
|
len = tangentS.AsVector3D().Length();
|
|
if( len < .9f || len > 1.1f )
|
|
{
|
|
color.Init( 1.0f, 0.0f, 0.0f );
|
|
}
|
|
|
|
// check the length of the normal.
|
|
len = normal.Length();
|
|
if( len < .9f || len > 1.1f )
|
|
{
|
|
color.Init( 1.0f, 0.0f, 0.0f );
|
|
}
|
|
|
|
// check the dot of tangent s and normal
|
|
float dot = DotProduct( tangentS.AsVector3D(), normal );
|
|
if( dot > .95 || dot < -.95 )
|
|
{
|
|
color.Init( 1.0f, 0.0f, 0.0f );
|
|
}
|
|
|
|
meshBuilder.Color3fv( color.Base() );
|
|
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
int i;
|
|
// Set the indices down to the hardware.
|
|
// Each triplet of indices is a triangle.
|
|
for( i = indexStart; i < indexStart + nClampedIndices; i++ )
|
|
{
|
|
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
|
|
}
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
|
|
indexStart += nClampedIndices;
|
|
}
|
|
}
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DebugDrawModelWireframe( IStudioRender *pStudioRender, DrawModelInfo_t& info,
|
|
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, const Vector &color, int flags )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
CMeshBuilder meshBuilder;
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
pRenderContext->Bind( g_materialWireframeVertexColor );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
|
|
|
|
int indexStart;
|
|
for (indexStart = 0; indexStart < materialBatch.m_TriListIndices.Count(); )
|
|
{
|
|
// FIXME: this shouldn't be needed, models shouldn't be built that can't fit
|
|
int nClampedIndices = MIN( materialBatch.m_TriListIndices.Count() - indexStart, 32766 );
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(), nClampedIndices );
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &pos = vert.m_Position;
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
|
|
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
|
|
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
|
|
int k;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
|
|
Vector tmp;
|
|
VectorTransform( pos, poseToWorld, tmp );
|
|
skinnedPos += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( normal, poseToWorld, tmp );
|
|
skinnedNormal += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
|
|
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
|
|
}
|
|
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Normal3fv( &skinnedNormal.x );
|
|
meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
|
|
meshBuilder.UserData( &skinnedTangentS.x );
|
|
meshBuilder.Color3fv( color.Base() );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
int i;
|
|
// Set the indices down to the hardware.
|
|
// Each triplet of indices is a triangle.
|
|
for( i = indexStart; i < indexStart + nClampedIndices; i++ )
|
|
{
|
|
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
|
|
}
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
|
|
indexStart += nClampedIndices;
|
|
}
|
|
}
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void drawWeightIdentifier( matrix3x4_t& m, float flLength )
|
|
{
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
IMesh* pMesh = pRenderContext->GetDynamicMesh( );
|
|
CMeshBuilder meshBuilder;
|
|
|
|
const unsigned char white[3] = { 255, 255, 255 };
|
|
const unsigned char black[3] = { 0, 0, 0 };
|
|
|
|
Vector vecPoint;
|
|
MatrixPosition( m, vecPoint );
|
|
|
|
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, 2 );
|
|
|
|
meshBuilder.Color3ubv( black );
|
|
meshBuilder.Position3f( vecPoint.x, vecPoint.y, vecPoint.z );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
meshBuilder.Color3ubv( black );
|
|
meshBuilder.Position3f( vecPoint.x + flLength * 0.9f, vecPoint.y - flLength * 0.2f, vecPoint.z + flLength );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
meshBuilder.Color3ubv( black );
|
|
meshBuilder.Position3f( vecPoint.x + flLength * 0.9f, vecPoint.y + flLength * 0.2f, vecPoint.z + flLength );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
meshBuilder.Color3ubv( white );
|
|
meshBuilder.Position3f( vecPoint.x, vecPoint.y, vecPoint.z );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
meshBuilder.Color3ubv( white );
|
|
meshBuilder.Position3f( vecPoint.x + flLength, vecPoint.y - flLength * 0.1f, vecPoint.z + flLength * 0.9f );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
meshBuilder.Color3ubv( white );
|
|
meshBuilder.Position3f( vecPoint.x + flLength, vecPoint.y + flLength * 0.1f, vecPoint.z + flLength * 0.9f );
|
|
meshBuilder.AdvanceVertex();
|
|
|
|
meshBuilder.End();
|
|
pMesh->Draw();
|
|
}
|
|
|
|
int g_BoneWeightInspectVert;
|
|
debug_vert_weight_t g_BoneWeightInspectResults[3];
|
|
|
|
int DebugDrawModelBoneWeights( IStudioRender *pStudioRender, DrawModelInfo_t& info,
|
|
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
CMeshBuilder meshBuilder;
|
|
|
|
Vector vecDebugPos;
|
|
vecDebugPos.Init();
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
pRenderContext->Bind( g_materialVertexColor );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
|
|
|
|
int indexStart;
|
|
for (indexStart = 0; indexStart < materialBatch.m_TriListIndices.Count(); )
|
|
{
|
|
// FIXME: this shouldn't be needed, models shouldn't be built that can't fit
|
|
int nClampedIndices = MIN( materialBatch.m_TriListIndices.Count(), 32766 );
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(), nClampedIndices );
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &pos = vert.m_Position;
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
|
|
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
|
|
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
|
|
|
|
if ( vertID == g_BoneWeightInspectVert )
|
|
{
|
|
g_BoneWeightInspectResults[0].index = 0;
|
|
g_BoneWeightInspectResults[0].flweight = 0;
|
|
g_BoneWeightInspectResults[1].index = 0;
|
|
g_BoneWeightInspectResults[1].flweight = 0;
|
|
g_BoneWeightInspectResults[2].index = 0;
|
|
g_BoneWeightInspectResults[2].flweight = 0;
|
|
}
|
|
|
|
int k;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
|
|
Vector tmp;
|
|
VectorTransform( pos, poseToWorld, tmp );
|
|
skinnedPos += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( normal, poseToWorld, tmp );
|
|
skinnedNormal += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
|
|
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
|
|
|
|
if ( vertID == g_BoneWeightInspectVert && k < 3 )
|
|
{
|
|
g_BoneWeightInspectResults[k].index = vert.m_BoneIndex[k];
|
|
g_BoneWeightInspectResults[k].flweight = vert.m_BoneWeight[k];
|
|
}
|
|
|
|
}
|
|
|
|
if ( vertID == g_BoneWeightInspectVert )
|
|
{
|
|
VectorCopy( skinnedPos, vecDebugPos );
|
|
}
|
|
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Normal3fv( &skinnedNormal.x );
|
|
meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
|
|
meshBuilder.UserData( &skinnedTangentS.x );
|
|
|
|
if (g_viewerSettings.highlightBone >= 0)
|
|
{
|
|
float v = 0.0;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
if (vert.m_BoneIndex[k] == g_viewerSettings.highlightBone)
|
|
{
|
|
v = vert.m_BoneWeight[k];
|
|
}
|
|
}
|
|
v = clamp( v, 0.0f, 1.0f );
|
|
meshBuilder.Color4f( 1.0f - v, 1.0f, 1.0f - v, 0.5 );
|
|
}
|
|
else
|
|
{
|
|
switch( vert.m_NumBones )
|
|
{
|
|
case 0:
|
|
meshBuilder.Color3f( 0.0f, 0.0f, 0.0f );
|
|
break;
|
|
case 1:
|
|
meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
|
|
break;
|
|
case 2:
|
|
meshBuilder.Color3f( 1.0f, 1.0f, 0.0f );
|
|
break;
|
|
case 3:
|
|
meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
|
|
break;
|
|
default:
|
|
meshBuilder.Color3f( 1.0f, 1.0f, 1.0f );
|
|
break;
|
|
}
|
|
}
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
int i;
|
|
// Set the indices down to the hardware.
|
|
// Each triplet of indices is a triangle.
|
|
for( i = indexStart; i < indexStart + nClampedIndices; i++ )
|
|
{
|
|
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
|
|
}
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
|
|
indexStart += nClampedIndices;
|
|
}
|
|
}
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
matrix3x4_t temp;
|
|
temp.SetToIdentity();
|
|
PositionMatrix( vecDebugPos, temp );
|
|
drawWeightIdentifier( temp, 8 );
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
class CMatchedVert
|
|
{
|
|
public:
|
|
CMatchedVert( const GetTriangles_Vertex_t &vert )
|
|
{
|
|
m_pos = vert.m_Position;
|
|
m_bones = (vert.m_BoneIndex[0])
|
|
+ ((vert.m_BoneIndex[1] > 0 ? vert.m_BoneIndex[1] : 0 )<< 8)
|
|
+ ((vert.m_BoneIndex[2] > 0 ? vert.m_BoneIndex[1] : 0 )<< 16);
|
|
m_count = 1;
|
|
}
|
|
|
|
class CMatchedVertLessFunc
|
|
{
|
|
public:
|
|
bool Less( CMatchedVert const & lhs, CMatchedVert const & rhs, void *pContext )
|
|
{
|
|
float i1 = lhs.m_pos.x + lhs.m_pos.y + lhs.m_pos.z + lhs.m_bones;
|
|
float i2 = rhs.m_pos.x + rhs.m_pos.y + rhs.m_pos.z + rhs.m_bones;
|
|
|
|
return (i1 < i2);
|
|
}
|
|
};
|
|
|
|
Vector m_pos;
|
|
int m_bones;
|
|
int m_count;
|
|
};
|
|
|
|
|
|
int DebugDrawModelVertColocation( IStudioRender *pStudioRender, DrawModelInfo_t& info,
|
|
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
static DrawModelInfo_t cached_info;
|
|
static CUtlSortVector< CMatchedVert, CMatchedVert::CMatchedVertLessFunc > sortedVector;
|
|
|
|
if ( memcmp( &info, &cached_info, sizeof( DrawModelInfo_t ) ) )
|
|
{
|
|
sortedVector.RemoveAll( );
|
|
cached_info = info;
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
|
|
CMatchedVert mv( vert );
|
|
|
|
int i = sortedVector.Find( mv );
|
|
if (i == -1)
|
|
{
|
|
sortedVector.Insert( mv );
|
|
}
|
|
else
|
|
{
|
|
sortedVector[i].m_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
CMeshBuilder meshBuilder;
|
|
|
|
// pRenderContext->DrawScreenSpaceRectangle( g_materialVertexColor, 0, 0, 64, 64, 0, 0, 1, 1, 1, 1 );
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
pRenderContext->Bind( g_materialVertexColor );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
|
|
|
|
int indexStart;
|
|
for (indexStart = 0; indexStart < materialBatch.m_TriListIndices.Count(); )
|
|
{
|
|
// FIXME: this shouldn't be needed, models shouldn't be built that can't fit
|
|
int nClampedIndices = MIN( materialBatch.m_TriListIndices.Count() - indexStart, 32766 );
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(), nClampedIndices );
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
CMatchedVert mv( vert );
|
|
|
|
const Vector &pos = vert.m_Position;
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
|
|
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
|
|
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
|
|
int k;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
|
|
Vector tmp;
|
|
VectorTransform( pos, poseToWorld, tmp );
|
|
skinnedPos += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( normal, poseToWorld, tmp );
|
|
skinnedNormal += vert.m_BoneWeight[k] * tmp;
|
|
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
|
|
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
|
|
}
|
|
|
|
meshBuilder.Position3fv( &skinnedPos.x );
|
|
meshBuilder.Normal3fv( &skinnedNormal.x );
|
|
meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
|
|
meshBuilder.UserData( &skinnedTangentS.x );
|
|
|
|
int i = sortedVector.Find( mv );
|
|
switch( i >= 0 ? sortedVector[i].m_count : 0 )
|
|
{
|
|
case 0:
|
|
meshBuilder.Color3f( 0.0f, 0.0f, 0.0f );
|
|
break;
|
|
case 1:
|
|
meshBuilder.Color3f( 0.0f, 0.0f, 1.0f );
|
|
break;
|
|
case 2:
|
|
meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
|
|
break;
|
|
case 3:
|
|
meshBuilder.Color3f( 1.0f, 1.0f, 0.0f );
|
|
break;
|
|
default:
|
|
meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
|
|
break;
|
|
}
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
int i;
|
|
// Set the indices down to the hardware.
|
|
// Each triplet of indices is a triangle.
|
|
for( i = indexStart; i < indexStart + nClampedIndices; i++ )
|
|
{
|
|
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
|
|
}
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
|
|
indexStart += nClampedIndices;
|
|
}
|
|
}
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DebugDrawModelTexCoord( IStudioRender *pStudioRender, const char *pMaterialName, const DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, float w, float h )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
CUtlVector<int> batchList;
|
|
for( int batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
if ( !materialBatch.m_Verts.Count() || V_stricmp(materialBatch.m_pMaterial->GetName(), pMaterialName) )
|
|
continue;
|
|
batchList.AddToTail(batchID);
|
|
}
|
|
if ( !batchList.Count() )
|
|
return 0;
|
|
|
|
bool bFound = false;
|
|
IMaterialVar *pBaseVar = g_materialDebugCopyBaseTexture->FindVar( "$basetexture", &bFound, true );
|
|
if ( !bFound )
|
|
return 0;
|
|
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[0]];
|
|
IMaterialVar *pVar = materialBatch.m_pMaterial->FindVar( "$basetexture", &bFound, true );
|
|
if ( !bFound )
|
|
return 0;
|
|
pBaseVar->SetTextureValue( pVar->GetTextureValue() );
|
|
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->OverrideDepthEnable( false, false );
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
pRenderContext->Ortho( 0, h, w, 0, -1, 1 );
|
|
|
|
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
|
pRenderContext->PushMatrix();
|
|
pRenderContext->LoadIdentity();
|
|
|
|
CMeshBuilder meshBuilder;
|
|
|
|
// now render a single quad with the base texture on it
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[0]];
|
|
//pRenderContext->Bind( materialBatch.m_pMaterial );
|
|
pRenderContext->Bind( g_materialDebugCopyBaseTexture );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, 4, 6 );
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[0];
|
|
//const Vector &pos = vert.m_Position;
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
|
|
Vector uv0(0,0,0), uv1(1,0,0), uv2(1, 1, 0), uv3(0,1,0);
|
|
Vector *pUV[] = {&uv0, &uv1, &uv2, &uv3};
|
|
|
|
for ( int i = 0;i < 4; i++ )
|
|
{
|
|
Vector p = *pUV[i];
|
|
p.x *= w;
|
|
p.y *= h;
|
|
meshBuilder.Position3fv( &p.x );
|
|
meshBuilder.Normal3fv( &normal.x );
|
|
meshBuilder.TexCoord2fv( 0, pUV[i]->Base() );
|
|
meshBuilder.UserData( &tangentS.x );
|
|
|
|
meshBuilder.Color3f( 1.0f, 1.0f, 1.0f );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
meshBuilder.FastIndex( 0 );
|
|
meshBuilder.FastIndex( 1 );
|
|
meshBuilder.FastIndex( 2 );
|
|
|
|
meshBuilder.FastIndex( 0 );
|
|
meshBuilder.FastIndex( 2 );
|
|
meshBuilder.FastIndex( 3 );
|
|
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
}
|
|
|
|
// now draw coverage - show which UV space is used more than once
|
|
#if 0
|
|
for( int i = 0; i < batchList.Count(); i++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[i]];
|
|
//pRenderContext->Bind( g_materialWireframeVertexColorNoCull );
|
|
pRenderContext->Bind( g_materialVertexColorAdditive );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
|
|
// FIXME: this shouldn't be needed, models shouldn't be built that can't fit
|
|
int nClampedIndices = MIN( materialBatch.m_TriListIndices.Count(), 32766 );
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(), nClampedIndices );
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
|
|
Vector p;
|
|
p.x = vert.m_TexCoord.x * w;
|
|
p.y = vert.m_TexCoord.y * h;
|
|
p.z = 0;
|
|
|
|
meshBuilder.Position3fv( &p.x );
|
|
meshBuilder.Normal3fv( &normal.x );
|
|
meshBuilder.UserData( &tangentS.x );
|
|
|
|
|
|
meshBuilder.Color3f( 0.25f, 0.0f, 0.0f );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
int i;
|
|
// Set the indices down to the hardware.
|
|
// Each triplet of indices is a triangle.
|
|
for( i = 0; i < nClampedIndices; i++ )
|
|
{
|
|
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
|
|
}
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
}
|
|
#endif
|
|
|
|
const color32 batchColor = {0,255,255,0};
|
|
// now draw all batches with the matching material in wireframe over the render of the base texture
|
|
for( int i = 0; i < batchList.Count(); i++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[i]];
|
|
|
|
pRenderContext->Bind( g_materialWireframeVertexColorNoCull );
|
|
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
|
|
// FIXME: this shouldn't be needed, models shouldn't be built that can't fit
|
|
int nClampedIndices = MIN( materialBatch.m_TriListIndices.Count(), 32766 );
|
|
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(), nClampedIndices );
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &normal = vert.m_Normal;
|
|
const Vector4D &tangentS = vert.m_TangentS;
|
|
|
|
Vector p;
|
|
p.x = vert.m_TexCoord.x * w;
|
|
p.y = vert.m_TexCoord.y * h;
|
|
p.z = 0;
|
|
|
|
meshBuilder.Position3fv( &p.x );
|
|
meshBuilder.Normal3fv( &normal.x );
|
|
meshBuilder.UserData( &tangentS.x );
|
|
|
|
|
|
meshBuilder.Color4ubv( &batchColor.r );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
|
|
// Set the indices down to the hardware.
|
|
// Each triplet of indices is a triangle.
|
|
for(int j = 0; j < nClampedIndices; j++ )
|
|
{
|
|
meshBuilder.FastIndex( materialBatch.m_TriListIndices[j] );
|
|
}
|
|
meshBuilder.End();
|
|
pBuildMesh->Draw();
|
|
}
|
|
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
|
pRenderContext->PopMatrix();
|
|
|
|
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
|
pRenderContext->PopMatrix();
|
|
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
|
pRenderContext->PopMatrix();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int DebugModelVertExtents( IStudioRender *pStudioRender, DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, Vector &vecMin, Vector &vecMax )
|
|
{
|
|
// Make static so that we aren't reallocating everything all the time.
|
|
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
|
|
static GetTriangles_Output_t tris;
|
|
|
|
vecMin.Init( 999999,999999,999999);
|
|
vecMax.Init( -999999,-999999,-999999);
|
|
|
|
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
|
|
|
|
int batchID;
|
|
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
|
|
{
|
|
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
|
|
|
|
int vertID;
|
|
// Send the vertices down to the hardware.
|
|
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
|
|
{
|
|
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
|
|
const Vector &pos = vert.m_Position;
|
|
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
|
|
int k;
|
|
for( k = 0; k < vert.m_NumBones; k++ )
|
|
{
|
|
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
|
|
Vector tmp;
|
|
VectorTransform( pos, poseToWorld, tmp );
|
|
skinnedPos += vert.m_BoneWeight[k] * tmp;
|
|
}
|
|
|
|
VectorMin( skinnedPos, vecMin, vecMin );
|
|
VectorMax( skinnedPos, vecMax, vecMax );
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|