#include "stdafx.h" #include "MeshViewer.hpp" #include "aux_Bitmap.hpp" //========================================================================= // FUNCTIONS //========================================================================= //========================================================================= void mesh_viewer::CleanUp( void ) { for (s32 j = 0; j < MAX_MESHES; j++) { for( s32 i=0; i= MAX_MESHES) { return; } m_Mesh[m_nCurrentMeshCount].Load( pFileName ); m_Anim[m_nCurrentMeshCount].Load( pFileName ); m_Mesh[m_nCurrentMeshCount].ApplyNewSkeleton( m_Anim[m_nCurrentMeshCount] ); m_L2W[m_nCurrentMeshCount].Identity(); m_L2W[m_nCurrentMeshCount].Rotate(Rot); m_L2W[m_nCurrentMeshCount].Translate(Pos); m_Frame = 0; m_bPlayAnim = FALSE; m_BBox += m_Mesh[m_nCurrentMeshCount].GetBBox(); m_LightDir.Set( -0.5f, 1, -0.5f ); m_LightDir.Normalize(); if( m_Mesh[m_nCurrentMeshCount].m_nFacets <= 0 ) { CleanUp(); x_throw( "The mesh didn't have any facets" ); } m_Mesh[m_nCurrentMeshCount].SortFacetsByMaterialAndBone(); for( s32 i=0; iSetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TEXTURE ); g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); if( m_bBackFacets ) { g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); } else { g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ); } for (s32 j = 0; j < m_nCurrentMeshCount; j++) { if( m_Mesh[j].m_nBones == 1 ) { RenderSolid(j); } else { RenderSoftSkin(j); } } } //========================================================================= void mesh_viewer::SetBackFacets( xbool bFaceFacets ) { m_bBackFacets = bFaceFacets; } //========================================================================= void mesh_viewer::RenderSolid( s32 nMesh ) { g_pd3dDevice->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 ); struct lovert { vector3p P; xcolor C; vector2 UV; }; s32 iLastTex = -1; for( s32 i=0; i= 0 ); vector3 Amb( m_Ambient ); Amb += vector3( I, I, I ); Amb.Min( 1.0f ); V[j].C.SetfRGBA( Amb.GetX(), Amb.GetY(), Amb.GetZ(), 1 ); } } g_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, 1, V, sizeof(lovert) ); } } //========================================================================= void mesh_viewer::RenderSoftSkin( s32 nMesh ) { struct lovert { vector3p P; xcolor C; vector2 UV; }; s32 i; vector3 LightDir(1,0,0); // Check whether we have something to do if( m_Anim[nMesh].m_nBones == 0 ) return; g_pd3dDevice->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 ); // Allocate all the matrices smem_StackPushMarker(); matrix4* pMatrix = (matrix4*)smem_StackAlloc( m_Anim[nMesh].m_nBones * sizeof(matrix4) ); if( pMatrix == NULL ) return; // Compute the frame if( m_bPlayAnim ) { f32 Time = m_Timer.TripSec(); m_Frame += Time*m_AnimFrameRate; } m_Anim[nMesh].ComputeBonesL2W( pMatrix, m_Frame ); // Compute final matrices for( i=0; i MaxWeight ) { MaxWeight = W.Weight; iBone = W.iBone; } vector3 P = V[j].P + (pMatrix[ W.iBone ] * Vert.Position) * W.Weight; V[j].P = P; N[j] += pMatrix[ W.iBone ].RotateVector( Vert.Normal[0] ) * W.Weight; } N[j].Normalize(); V[j].UV.X = Vert.UV[0].X; V[j].UV.Y = Vert.UV[0].Y; f32 I = fMax( 0, LightDir.Dot( N[j] ) ); I = fMin( 1, I ); //ASSERT( I >= 0 ); vector3 Amb = m_Ambient; Amb += vector3( I, I, I ); Amb.Min( 1.0f ); V[j].C.SetfRGBA( Amb.GetX(), Amb.GetY(), Amb.GetZ(), 1 ); } } // Render the triangle g_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, 1, V, sizeof(lovert) ); } // Free alloced memory smem_StackPopToMarker(); } //========================================================================= void mesh_viewer::PlayAnimation( xbool bPlayInPlace ) { m_bPlayInPlace = bPlayInPlace; // Nothing to do if( m_Mesh[0].m_nBones == 0 ) return; if( m_Anim[0].m_nFrames == 0 ) x_throw( "Mesh doesn't have animation" ); m_bPlayAnim = TRUE; m_Timer.Start(); } //========================================================================= void mesh_viewer::PauseAnimation ( void ) { m_bPlayAnim = FALSE; m_Timer.Stop(); }