Team Fortress 2 Source Code as on 22/4/2020
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.

761 lines
25 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #include "istudiorender.h"
  9. #include "materialsystem/imesh.h"
  10. #include "mathlib/mathlib.h"
  11. #include "matsyswin.h"
  12. #include "viewersettings.h"
  13. #include "materialsystem/imaterialvar.h"
  14. extern IMaterialSystem *g_pMaterialSystem;
  15. #define NORMAL_LENGTH .5f
  16. #define NORMAL_OFFSET_FROM_MESH 0.1f
  17. int DebugDrawModel( IStudioRender *pStudioRender, DrawModelInfo_t& info,
  18. matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
  19. {
  20. // Make static so that we aren't reallocating everything all the time.
  21. // TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
  22. static GetTriangles_Output_t tris;
  23. pStudioRender->GetTriangles( info, pBoneToWorld, tris );
  24. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  25. pRenderContext->MatrixMode( MATERIAL_MODEL );
  26. pRenderContext->PushMatrix();
  27. pRenderContext->LoadIdentity();
  28. CMeshBuilder meshBuilder;
  29. int batchID;
  30. for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
  31. {
  32. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
  33. pRenderContext->Bind( materialBatch.m_pMaterial );
  34. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
  35. meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
  36. materialBatch.m_TriListIndices.Count() );
  37. int vertID;
  38. // Send the vertices down to the hardware.
  39. for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
  40. {
  41. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
  42. const Vector &pos = vert.m_Position;
  43. const Vector &normal = vert.m_Normal;
  44. const Vector4D &tangentS = vert.m_TangentS;
  45. Vector skinnedPos( 0.0f, 0.0f, 0.0f );
  46. Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
  47. Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
  48. int k;
  49. for( k = 0; k < vert.m_NumBones; k++ )
  50. {
  51. const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
  52. Vector tmp;
  53. VectorTransform( pos, poseToWorld, tmp );
  54. skinnedPos += vert.m_BoneWeight[k] * tmp;
  55. VectorRotate( normal, poseToWorld, tmp );
  56. skinnedNormal += vert.m_BoneWeight[k] * tmp;
  57. VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
  58. skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
  59. }
  60. meshBuilder.Position3fv( &skinnedPos.x );
  61. meshBuilder.Normal3fv( &skinnedNormal.x );
  62. meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
  63. meshBuilder.UserData( &skinnedTangentS.x );
  64. meshBuilder.AdvanceVertex();
  65. }
  66. int i;
  67. // Set the indices down to the hardware.
  68. // Each triplet of indices is a triangle.
  69. for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
  70. {
  71. meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
  72. }
  73. meshBuilder.End();
  74. pBuildMesh->Draw();
  75. }
  76. pRenderContext->MatrixMode( MATERIAL_MODEL );
  77. pRenderContext->PopMatrix();
  78. return 0;
  79. }
  80. int DebugDrawModelNormals( IStudioRender *pStudioRender, DrawModelInfo_t& info,
  81. matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
  82. {
  83. // Make static so that we aren't reallocating everything all the time.
  84. // TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
  85. static GetTriangles_Output_t tris;
  86. pStudioRender->GetTriangles( info, pBoneToWorld, tris );
  87. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  88. pRenderContext->MatrixMode( MATERIAL_MODEL );
  89. pRenderContext->PushMatrix();
  90. pRenderContext->LoadIdentity();
  91. int batchID;
  92. for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
  93. {
  94. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
  95. CMeshBuilder meshBuilder;
  96. pRenderContext->Bind( g_materialVertexColor );
  97. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh();
  98. meshBuilder.Begin( pBuildMesh, MATERIAL_LINES, materialBatch.m_Verts.Count() );
  99. int vertID;
  100. // Send the vertices down to the hardware.
  101. for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
  102. {
  103. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
  104. const Vector &pos = vert.m_Position;
  105. const Vector &normal = vert.m_Normal;
  106. Vector skinnedPos( 0.0f, 0.0f, 0.0f );
  107. Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
  108. int k;
  109. for( k = 0; k < vert.m_NumBones; k++ )
  110. {
  111. const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
  112. Vector tmp;
  113. VectorTransform( pos, poseToWorld, tmp );
  114. skinnedPos += vert.m_BoneWeight[k] * tmp;
  115. VectorRotate( normal, poseToWorld, tmp );
  116. skinnedNormal += vert.m_BoneWeight[k] * tmp;
  117. }
  118. // skinnedPos += skinnedNormal * NORMAL_OFFSET_FROM_MESH;
  119. meshBuilder.Position3fv( &skinnedPos.x );
  120. meshBuilder.Color3f( 0.0f, 0.0f, 1.0f );
  121. meshBuilder.AdvanceVertex();
  122. skinnedPos += skinnedNormal * NORMAL_LENGTH;
  123. meshBuilder.Position3fv( &skinnedPos.x );
  124. meshBuilder.Color3f( 0.0f, 0.0f, 1.0f );
  125. meshBuilder.AdvanceVertex();
  126. }
  127. meshBuilder.End();
  128. pBuildMesh->Draw();
  129. }
  130. pRenderContext->MatrixMode( MATERIAL_MODEL );
  131. pRenderContext->PopMatrix();
  132. return 0;
  133. }
  134. int DebugDrawModelTangentS( IStudioRender *pStudioRender, DrawModelInfo_t& info,
  135. matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
  136. {
  137. // Make static so that we aren't reallocating everything all the time.
  138. // TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
  139. static GetTriangles_Output_t tris;
  140. pStudioRender->GetTriangles( info, pBoneToWorld, tris );
  141. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  142. pRenderContext->MatrixMode( MATERIAL_MODEL );
  143. pRenderContext->PushMatrix();
  144. pRenderContext->LoadIdentity();
  145. int batchID;
  146. for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
  147. {
  148. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
  149. CMeshBuilder meshBuilder;
  150. pRenderContext->Bind( g_materialVertexColor );
  151. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh();
  152. meshBuilder.Begin( pBuildMesh, MATERIAL_LINES, materialBatch.m_Verts.Count() );
  153. int vertID;
  154. // Send the vertices down to the hardware.
  155. for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
  156. {
  157. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
  158. const Vector &pos = vert.m_Position;
  159. const Vector &normal = vert.m_Normal;
  160. const Vector4D &tangentS = vert.m_TangentS;
  161. Vector skinnedPos( 0.0f, 0.0f, 0.0f );
  162. Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
  163. Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
  164. int k;
  165. for( k = 0; k < vert.m_NumBones; k++ )
  166. {
  167. const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
  168. Vector tmp;
  169. VectorTransform( pos, poseToWorld, tmp );
  170. skinnedPos += vert.m_BoneWeight[k] * tmp;
  171. VectorRotate( normal, poseToWorld, tmp );
  172. skinnedNormal += vert.m_BoneWeight[k] * tmp;
  173. VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
  174. skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
  175. }
  176. // skinnedPos += skinnedNormal * NORMAL_OFFSET_FROM_MESH;
  177. meshBuilder.Position3fv( &skinnedPos.x );
  178. meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
  179. meshBuilder.AdvanceVertex();
  180. skinnedPos += skinnedTangentS.AsVector3D() * NORMAL_LENGTH;
  181. meshBuilder.Position3fv( &skinnedPos.x );
  182. meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
  183. meshBuilder.AdvanceVertex();
  184. }
  185. meshBuilder.End();
  186. pBuildMesh->Draw();
  187. }
  188. pRenderContext->MatrixMode( MATERIAL_MODEL );
  189. pRenderContext->PopMatrix();
  190. return 0;
  191. }
  192. int DebugDrawModelTangentT( IStudioRender *pStudioRender, DrawModelInfo_t& info,
  193. matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
  194. {
  195. // Make static so that we aren't reallocating everything all the time.
  196. // TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
  197. static GetTriangles_Output_t tris;
  198. pStudioRender->GetTriangles( info, pBoneToWorld, tris );
  199. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  200. pRenderContext->MatrixMode( MATERIAL_MODEL );
  201. pRenderContext->PushMatrix();
  202. pRenderContext->LoadIdentity();
  203. int batchID;
  204. for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
  205. {
  206. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
  207. CMeshBuilder meshBuilder;
  208. pRenderContext->Bind( g_materialVertexColor );
  209. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh();
  210. meshBuilder.Begin( pBuildMesh, MATERIAL_LINES, materialBatch.m_Verts.Count() );
  211. int vertID;
  212. // Send the vertices down to the hardware.
  213. for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
  214. {
  215. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
  216. const Vector &pos = vert.m_Position;
  217. const Vector &normal = vert.m_Normal;
  218. const Vector4D &tangentS = vert.m_TangentS;
  219. Vector skinnedPos( 0.0f, 0.0f, 0.0f );
  220. Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
  221. Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
  222. int k;
  223. for( k = 0; k < vert.m_NumBones; k++ )
  224. {
  225. const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
  226. Vector tmp;
  227. VectorTransform( pos, poseToWorld, tmp );
  228. skinnedPos += vert.m_BoneWeight[k] * tmp;
  229. VectorRotate( normal, poseToWorld, tmp );
  230. skinnedNormal += vert.m_BoneWeight[k] * tmp;
  231. VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
  232. skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
  233. }
  234. Vector skinnedTangentT = CrossProduct( skinnedNormal, skinnedTangentS.AsVector3D() ) * skinnedTangentS.w;
  235. // skinnedPos += skinnedNormal * NORMAL_OFFSET_FROM_MESH;
  236. meshBuilder.Position3fv( &skinnedPos.x );
  237. meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
  238. meshBuilder.AdvanceVertex();
  239. skinnedPos += skinnedTangentT * NORMAL_LENGTH;
  240. meshBuilder.Position3fv( &skinnedPos.x );
  241. meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
  242. meshBuilder.AdvanceVertex();
  243. }
  244. meshBuilder.End();
  245. pBuildMesh->Draw();
  246. }
  247. pRenderContext->MatrixMode( MATERIAL_MODEL );
  248. pRenderContext->PopMatrix();
  249. return 0;
  250. }
  251. int DebugDrawModelBadVerts( IStudioRender *pStudioRender, DrawModelInfo_t& info,
  252. matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
  253. {
  254. // Make static so that we aren't reallocating everything all the time.
  255. // TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
  256. static GetTriangles_Output_t tris;
  257. pStudioRender->GetTriangles( info, pBoneToWorld, tris );
  258. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  259. pRenderContext->MatrixMode( MATERIAL_MODEL );
  260. pRenderContext->PushMatrix();
  261. pRenderContext->LoadIdentity();
  262. CMeshBuilder meshBuilder;
  263. int batchID;
  264. for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
  265. {
  266. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
  267. pRenderContext->Bind( g_materialVertexColor );
  268. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
  269. meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
  270. materialBatch.m_TriListIndices.Count() );
  271. int vertID;
  272. // Send the vertices down to the hardware.
  273. for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
  274. {
  275. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
  276. const Vector &pos = vert.m_Position;
  277. const Vector &normal = vert.m_Normal;
  278. const Vector4D &tangentS = vert.m_TangentS;
  279. Vector skinnedPos( 0.0f, 0.0f, 0.0f );
  280. Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
  281. Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
  282. int k;
  283. for( k = 0; k < vert.m_NumBones; k++ )
  284. {
  285. const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
  286. Vector tmp;
  287. VectorTransform( pos, poseToWorld, tmp );
  288. skinnedPos += vert.m_BoneWeight[k] * tmp;
  289. VectorRotate( normal, poseToWorld, tmp );
  290. skinnedNormal += vert.m_BoneWeight[k] * tmp;
  291. VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
  292. skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
  293. }
  294. meshBuilder.Position3fv( &skinnedPos.x );
  295. meshBuilder.Normal3fv( &skinnedNormal.x );
  296. meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
  297. meshBuilder.UserData( &skinnedTangentS.x );
  298. Vector color( 0.0f, 0.0f, 0.0f );
  299. float len;
  300. // check the length of the tangent S vector.
  301. len = tangentS.AsVector3D().Length();
  302. if( len < .9f || len > 1.1f )
  303. {
  304. color.Init( 1.0f, 0.0f, 0.0f );
  305. }
  306. // check the length of the normal.
  307. len = normal.Length();
  308. if( len < .9f || len > 1.1f )
  309. {
  310. color.Init( 1.0f, 0.0f, 0.0f );
  311. }
  312. // check the dot of tangent s and normal
  313. float dot = DotProduct( tangentS.AsVector3D(), normal );
  314. if( dot > .95 || dot < -.95 )
  315. {
  316. color.Init( 1.0f, 0.0f, 0.0f );
  317. }
  318. meshBuilder.Color3fv( color.Base() );
  319. meshBuilder.AdvanceVertex();
  320. }
  321. int i;
  322. // Set the indices down to the hardware.
  323. // Each triplet of indices is a triangle.
  324. for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
  325. {
  326. meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
  327. }
  328. meshBuilder.End();
  329. pBuildMesh->Draw();
  330. }
  331. pRenderContext->MatrixMode( MATERIAL_MODEL );
  332. pRenderContext->PopMatrix();
  333. return 0;
  334. }
  335. int DebugDrawModelWireframe( IStudioRender *pStudioRender, DrawModelInfo_t& info,
  336. matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, const Vector &color, int flags )
  337. {
  338. // Make static so that we aren't reallocating everything all the time.
  339. // TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
  340. static GetTriangles_Output_t tris;
  341. pStudioRender->GetTriangles( info, pBoneToWorld, tris );
  342. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  343. pRenderContext->MatrixMode( MATERIAL_MODEL );
  344. pRenderContext->PushMatrix();
  345. pRenderContext->LoadIdentity();
  346. CMeshBuilder meshBuilder;
  347. int batchID;
  348. for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
  349. {
  350. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
  351. pRenderContext->Bind( g_materialWireframeVertexColor );
  352. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
  353. meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
  354. materialBatch.m_TriListIndices.Count() );
  355. int vertID;
  356. // Send the vertices down to the hardware.
  357. for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
  358. {
  359. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
  360. const Vector &pos = vert.m_Position;
  361. const Vector &normal = vert.m_Normal;
  362. const Vector4D &tangentS = vert.m_TangentS;
  363. Vector skinnedPos( 0.0f, 0.0f, 0.0f );
  364. Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
  365. Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
  366. int k;
  367. for( k = 0; k < vert.m_NumBones; k++ )
  368. {
  369. const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
  370. Vector tmp;
  371. VectorTransform( pos, poseToWorld, tmp );
  372. skinnedPos += vert.m_BoneWeight[k] * tmp;
  373. VectorRotate( normal, poseToWorld, tmp );
  374. skinnedNormal += vert.m_BoneWeight[k] * tmp;
  375. VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
  376. skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
  377. }
  378. meshBuilder.Position3fv( &skinnedPos.x );
  379. meshBuilder.Normal3fv( &skinnedNormal.x );
  380. meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
  381. meshBuilder.UserData( &skinnedTangentS.x );
  382. meshBuilder.Color3fv( color.Base() );
  383. meshBuilder.AdvanceVertex();
  384. }
  385. int i;
  386. // Set the indices down to the hardware.
  387. // Each triplet of indices is a triangle.
  388. for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
  389. {
  390. meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
  391. }
  392. meshBuilder.End();
  393. pBuildMesh->Draw();
  394. }
  395. pRenderContext->MatrixMode( MATERIAL_MODEL );
  396. pRenderContext->PopMatrix();
  397. return 0;
  398. }
  399. int DebugDrawModelBoneWeights( IStudioRender *pStudioRender, DrawModelInfo_t& info,
  400. matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
  401. {
  402. // Make static so that we aren't reallocating everything all the time.
  403. // TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
  404. static GetTriangles_Output_t tris;
  405. pStudioRender->GetTriangles( info, pBoneToWorld, tris );
  406. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  407. pRenderContext->MatrixMode( MATERIAL_MODEL );
  408. pRenderContext->PushMatrix();
  409. pRenderContext->LoadIdentity();
  410. CMeshBuilder meshBuilder;
  411. int batchID;
  412. for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
  413. {
  414. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
  415. pRenderContext->Bind( g_materialVertexColor );
  416. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
  417. meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
  418. materialBatch.m_TriListIndices.Count() );
  419. int vertID;
  420. // Send the vertices down to the hardware.
  421. for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
  422. {
  423. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
  424. const Vector &pos = vert.m_Position;
  425. const Vector &normal = vert.m_Normal;
  426. const Vector4D &tangentS = vert.m_TangentS;
  427. Vector skinnedPos( 0.0f, 0.0f, 0.0f );
  428. Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
  429. Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
  430. int k;
  431. for( k = 0; k < vert.m_NumBones; k++ )
  432. {
  433. const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
  434. Vector tmp;
  435. VectorTransform( pos, poseToWorld, tmp );
  436. skinnedPos += vert.m_BoneWeight[k] * tmp;
  437. VectorRotate( normal, poseToWorld, tmp );
  438. skinnedNormal += vert.m_BoneWeight[k] * tmp;
  439. VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
  440. skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
  441. }
  442. meshBuilder.Position3fv( &skinnedPos.x );
  443. meshBuilder.Normal3fv( &skinnedNormal.x );
  444. meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
  445. meshBuilder.UserData( &skinnedTangentS.x );
  446. if (g_viewerSettings.highlightBone >= 0)
  447. {
  448. float v = 0.0;
  449. for( k = 0; k < vert.m_NumBones; k++ )
  450. {
  451. if (vert.m_BoneIndex[k] == g_viewerSettings.highlightBone)
  452. {
  453. v = vert.m_BoneWeight[k];
  454. }
  455. }
  456. v = clamp( v, 0.0f, 1.0f );
  457. meshBuilder.Color4f( 1.0f - v, 1.0f, 1.0f - v, 0.5 );
  458. }
  459. else
  460. {
  461. switch( vert.m_NumBones )
  462. {
  463. case 0:
  464. meshBuilder.Color3f( 0.0f, 0.0f, 0.0f );
  465. break;
  466. case 1:
  467. meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
  468. break;
  469. case 2:
  470. meshBuilder.Color3f( 1.0f, 1.0f, 0.0f );
  471. break;
  472. case 3:
  473. meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
  474. break;
  475. default:
  476. meshBuilder.Color3f( 1.0f, 1.0f, 1.0f );
  477. break;
  478. }
  479. }
  480. meshBuilder.AdvanceVertex();
  481. }
  482. int i;
  483. // Set the indices down to the hardware.
  484. // Each triplet of indices is a triangle.
  485. for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
  486. {
  487. meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
  488. }
  489. meshBuilder.End();
  490. pBuildMesh->Draw();
  491. }
  492. pRenderContext->MatrixMode( MATERIAL_MODEL );
  493. pRenderContext->PopMatrix();
  494. return 0;
  495. }
  496. int DebugDrawModelTexCoord( IStudioRender *pStudioRender, const char *pMaterialName, const DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, float w, float h )
  497. {
  498. // Make static so that we aren't reallocating everything all the time.
  499. // TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
  500. static GetTriangles_Output_t tris;
  501. pStudioRender->GetTriangles( info, pBoneToWorld, tris );
  502. CUtlVector<int> batchList;
  503. for( int batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
  504. {
  505. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
  506. if ( !materialBatch.m_Verts.Count() || V_stricmp(materialBatch.m_pMaterial->GetName(), pMaterialName) )
  507. continue;
  508. batchList.AddToTail(batchID);
  509. }
  510. if ( !batchList.Count() )
  511. return 0;
  512. bool bFound = false;
  513. IMaterialVar *pBaseVar = g_materialDebugCopyBaseTexture->FindVar( "$basetexture", &bFound, true );
  514. if ( !bFound )
  515. return 0;
  516. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[0]];
  517. IMaterialVar *pVar = materialBatch.m_pMaterial->FindVar( "$basetexture", &bFound, true );
  518. if ( !bFound )
  519. return 0;
  520. pBaseVar->SetTextureValue( pVar->GetTextureValue() );
  521. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  522. pRenderContext->OverrideDepthEnable( false, false );
  523. pRenderContext->MatrixMode( MATERIAL_MODEL );
  524. pRenderContext->PushMatrix();
  525. pRenderContext->LoadIdentity();
  526. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  527. pRenderContext->PushMatrix();
  528. pRenderContext->LoadIdentity();
  529. pRenderContext->Ortho( 0, h, w, 0, -1, 1 );
  530. pRenderContext->MatrixMode( MATERIAL_VIEW );
  531. pRenderContext->PushMatrix();
  532. pRenderContext->LoadIdentity();
  533. CMeshBuilder meshBuilder;
  534. // now render a single quad with the base texture on it
  535. {
  536. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[0]];
  537. //pRenderContext->Bind( materialBatch.m_pMaterial );
  538. pRenderContext->Bind( g_materialDebugCopyBaseTexture );
  539. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
  540. meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, 4, 6 );
  541. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[0];
  542. //const Vector &pos = vert.m_Position;
  543. const Vector &normal = vert.m_Normal;
  544. const Vector4D &tangentS = vert.m_TangentS;
  545. Vector uv0(0,0,0), uv1(1,0,0), uv2(1, 1, 0), uv3(0,1,0);
  546. Vector *pUV[] = {&uv0, &uv1, &uv2, &uv3};
  547. for ( int i = 0;i < 4; i++ )
  548. {
  549. Vector p = *pUV[i];
  550. p.x *= w;
  551. p.y *= h;
  552. meshBuilder.Position3fv( &p.x );
  553. meshBuilder.Normal3fv( &normal.x );
  554. meshBuilder.TexCoord2fv( 0, pUV[i]->Base() );
  555. meshBuilder.UserData( &tangentS.x );
  556. meshBuilder.Color3f( 1.0f, 1.0f, 1.0f );
  557. meshBuilder.AdvanceVertex();
  558. }
  559. meshBuilder.FastIndex( 0 );
  560. meshBuilder.FastIndex( 1 );
  561. meshBuilder.FastIndex( 2 );
  562. meshBuilder.FastIndex( 0 );
  563. meshBuilder.FastIndex( 2 );
  564. meshBuilder.FastIndex( 3 );
  565. meshBuilder.End();
  566. pBuildMesh->Draw();
  567. }
  568. // now draw coverage - show which UV space is used more than once
  569. #if 0
  570. for( int i = 0; i < batchList.Count(); i++ )
  571. {
  572. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[i]];
  573. //pRenderContext->Bind( g_materialWireframeVertexColorNoCull );
  574. pRenderContext->Bind( g_materialVertexColorAdditive );
  575. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
  576. meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
  577. materialBatch.m_TriListIndices.Count() );
  578. int vertID;
  579. // Send the vertices down to the hardware.
  580. for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
  581. {
  582. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
  583. const Vector &normal = vert.m_Normal;
  584. const Vector4D &tangentS = vert.m_TangentS;
  585. Vector p;
  586. p.x = vert.m_TexCoord.x * w;
  587. p.y = vert.m_TexCoord.y * h;
  588. p.z = 0;
  589. meshBuilder.Position3fv( &p.x );
  590. meshBuilder.Normal3fv( &normal.x );
  591. meshBuilder.UserData( &tangentS.x );
  592. meshBuilder.Color3f( 0.25f, 0.0f, 0.0f );
  593. meshBuilder.AdvanceVertex();
  594. }
  595. int i;
  596. // Set the indices down to the hardware.
  597. // Each triplet of indices is a triangle.
  598. for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
  599. {
  600. meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
  601. }
  602. meshBuilder.End();
  603. pBuildMesh->Draw();
  604. }
  605. #endif
  606. const color32 batchColor = {0,255,255,0};
  607. // now draw all batches with the matching material in wireframe over the render of the base texture
  608. for( int i = 0; i < batchList.Count(); i++ )
  609. {
  610. GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[i]];
  611. pRenderContext->Bind( g_materialWireframeVertexColorNoCull );
  612. IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
  613. meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
  614. materialBatch.m_TriListIndices.Count() );
  615. // Send the vertices down to the hardware.
  616. for( int vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
  617. {
  618. GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
  619. const Vector &normal = vert.m_Normal;
  620. const Vector4D &tangentS = vert.m_TangentS;
  621. Vector p;
  622. p.x = vert.m_TexCoord.x * w;
  623. p.y = vert.m_TexCoord.y * h;
  624. p.z = 0;
  625. meshBuilder.Position3fv( &p.x );
  626. meshBuilder.Normal3fv( &normal.x );
  627. meshBuilder.UserData( &tangentS.x );
  628. meshBuilder.Color4ubv( &batchColor.r );
  629. meshBuilder.AdvanceVertex();
  630. }
  631. // Set the indices down to the hardware.
  632. // Each triplet of indices is a triangle.
  633. for( int j = 0; j < materialBatch.m_TriListIndices.Count(); j++ )
  634. {
  635. meshBuilder.FastIndex( materialBatch.m_TriListIndices[j] );
  636. }
  637. meshBuilder.End();
  638. pBuildMesh->Draw();
  639. }
  640. pRenderContext->MatrixMode( MATERIAL_VIEW );
  641. pRenderContext->PopMatrix();
  642. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  643. pRenderContext->PopMatrix();
  644. pRenderContext->MatrixMode( MATERIAL_MODEL );
  645. pRenderContext->PopMatrix();
  646. return 0;
  647. }