BVB Source Codes

CRYENGINE Show AttachmentSkin.cpp Source code

Return Download CRYENGINE: download AttachmentSkin.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "stdafx.h"
  4. #include "AttachmentSkin.h"
  5.  
  6. #include <CryRenderer/IRenderAuxGeom.h>
  7. #include <CryRenderer/IShader.h>
  8. #include <CryAnimation/IAttachment.h>
  9. #include "ModelMesh.h"
  10. #include "AttachmentManager.h"
  11. #include "CharacterInstance.h"
  12. #include <CryMath/QTangent.h>
  13. #include "CharacterManager.h"
  14. #include <CryRenderer/IRenderAuxGeom.h>
  15. #include <CryMath/QTangent.h>
  16. #include <CryThreading/IJobManager_JobDelegator.h>
  17. #include "Vertex/VertexAnimation.h"
  18. #include "Vertex/VertexData.h"
  19. #include "Vertex/VertexCommand.h"
  20. #include "Vertex/VertexCommandBuffer.h"
  21.  
  22. void CAttachmentSKIN::ReleaseSoftwareRenderMeshes()
  23. {
  24.         m_pRenderMeshsSW[0] = NULL;
  25.         m_pRenderMeshsSW[1] = NULL;
  26. }
  27.  
  28. uint32 CAttachmentSKIN::Immediate_AddBinding( IAttachmentObject* pIAttachmentObject,ISkin* pISkin,uint32 nLoadingFlags )
  29. {
  30.         if (pIAttachmentObject==0)
  31.                 return 0; //no attachment objects
  32.  
  33.         if (pISkin==0)
  34.                 CryFatalError("CryAnimation: if you create the binding for a Skin-Attachment, then you have to pass the pointer to an ISkin as well");
  35.  
  36.         uint32 nLogWarnings = (nLoadingFlags&CA_DisableLogWarnings)==0;
  37.         CSkin* pCSkinModel = (CSkin*)pISkin;
  38.  
  39.         //only the SKIN-Instance is allowed to keep a smart-ptr CSkin object
  40.         //this should prevent ptr-hijacking in the future
  41.         if (m_pModelSkin!=pCSkinModel)
  42.         {
  43.                 ReleaseModelSkin();
  44.                 g_pCharacterManager->RegisterInstanceSkin(pCSkinModel,this); //register this CAttachmentSKIN instance in CSkin.
  45.                 m_pModelSkin=pCSkinModel;            //increase the Ref-Counter                
  46.         }
  47.  
  48.         CCharInstance* pInstanceSkel = m_pAttachmentManager->m_pSkelInstance;
  49.         CDefaultSkeleton* pDefaultSkeleton = pInstanceSkel->m_pDefaultSkeleton;
  50.  
  51.         const char* pSkelFilePath = pDefaultSkeleton->GetModelFilePath();
  52.         const char* pSkinFilePath = m_pModelSkin->GetModelFilePath();
  53.  
  54.         uint32 numJointsSkel = pDefaultSkeleton->m_arrModelJoints.size();
  55.         uint32 numJointsSkin = m_pModelSkin->m_arrModelJoints.size();
  56.  
  57.         uint32 NotMatchingNames=0;
  58.         m_arrRemapTable.resize(numJointsSkin, 0);
  59.         for(uint32 js=0; js<numJointsSkin; js++)
  60.         {
  61.                 int32 nID;
  62.                 if (m_pModelSkin->m_arrModelJoints[js].m_nJointCRC32Lower == -1)
  63.                         nID = m_pModelSkin->m_arrModelJoints[js].m_nExtraJointID + numJointsSkel;
  64.                 else
  65.                         nID = pDefaultSkeleton->GetJointIDByCRC32(m_pModelSkin->m_arrModelJoints[js].m_nJointCRC32Lower);
  66.  
  67.                 if (nID>=0)
  68.                         m_arrRemapTable[js]=nID;
  69. #ifdef EDITOR_PCDEBUGCODE
  70.                 else
  71.                         NotMatchingNames++,g_pILog->LogWarning ("Extending Skeleton, because the joint-name (%s) of SKIN (%s) was not found in SKEL:  %s",m_pModelSkin->m_arrModelJoints[js].m_NameModelSkin.c_str(),pSkinFilePath,pSkelFilePath);
  72. #endif
  73.         } //for loop
  74.  
  75.         if (NotMatchingNames)
  76.         {
  77.                 if (pInstanceSkel->m_CharEditMode)
  78.                 {
  79.                   //for now limited to CharEdit
  80.                         RecreateDefaultSkeleton(pInstanceSkel,nLoadingFlags);
  81.                 }
  82.                 else
  83.                 {
  84.                         if (nLogWarnings)
  85.                         {
  86.                                 CryLogAlways("SKEL: %s",pDefaultSkeleton->GetModelFilePath() );
  87.                                 CryLogAlways("SKIN: %s",m_pModelSkin->GetModelFilePath() );
  88.                                 uint32 numJointCount = pDefaultSkeleton->GetJointCount();
  89.                                 for (uint32 i=0; i<numJointCount; i++)
  90.                                 {
  91.                                         const char* pJointName = pDefaultSkeleton->GetJointNameByID(i);
  92.                                         CryLogAlways("%03d JointName: %s",i,pJointName );
  93.                                 }
  94.                         }
  95.  
  96.                         // Free the new attachment as we cannot use it
  97.                         SAFE_RELEASE(pIAttachmentObject);
  98.                         return 0; //critical! incompatible skeletons. cant create skin-attachment
  99.                 }
  100.         }
  101.  
  102.         // Patch the remapping
  103.         if (!(nLoadingFlags & CA_SkipBoneRemapping))
  104.         {
  105.                 for (size_t i=0; i<m_pModelSkin->GetNumLODs(); i++)
  106.                 {
  107.                         CModelMesh* pModelMesh = m_pModelSkin->GetModelMesh(i);
  108.                         IRenderMesh* pRenderMesh = pModelMesh->m_pIRenderMesh;
  109.                         if (!pRenderMesh)
  110.                                 continue;
  111.                         pRenderMesh->CreateRemappedBoneIndicesPair(m_arrRemapTable, pDefaultSkeleton->GetGuid(), this);
  112.                 }
  113.         }
  114.        
  115.         SAFE_RELEASE(m_pIAttachmentObject);
  116.         m_pIAttachmentObject=pIAttachmentObject;
  117.         return 1;
  118. }
  119.  
  120. void CAttachmentSKIN::Immediate_ClearBinding(uint32 nLoadingFlags)
  121. {
  122.         if (m_pIAttachmentObject)
  123.         {
  124.                 m_pIAttachmentObject->Release();
  125.                 m_pIAttachmentObject = 0;
  126.                 ReleaseModelSkin();
  127.  
  128.                 if (nLoadingFlags&CA_SkipSkelRecreation)
  129.                         return;
  130.                 //for now limited to CharEdit
  131.                 CCharInstance* pInstanceSkel = m_pAttachmentManager->m_pSkelInstance;
  132.                 if (pInstanceSkel->m_CharEditMode)
  133.                         RecreateDefaultSkeleton(pInstanceSkel,CA_CharEditModel|nLoadingFlags);
  134.         }
  135. };
  136.  
  137. void CAttachmentSKIN::RecreateDefaultSkeleton(CCharInstance* pInstanceSkel, uint32 nLoadingFlags)
  138. {
  139.         const CDefaultSkeleton* const pDefaultSkeleton = pInstanceSkel->m_pDefaultSkeleton;
  140.  
  141.         const char* pOriginalFilePath = pDefaultSkeleton->GetModelFilePath();
  142.         if (pDefaultSkeleton->GetModelFilePathCRC64() && pOriginalFilePath[0]=='_')
  143.         {
  144.                 pOriginalFilePath++; // All extended skeletons have an '_' in front of the filepath to not confuse them with regular skeletons.
  145.         }
  146.  
  147.         CDefaultSkeleton* pOrigDefaultSkeleton = g_pCharacterManager->CheckIfModelSKELLoaded(pOriginalFilePath,nLoadingFlags);
  148.         if (!pOrigDefaultSkeleton)
  149.         {
  150.                 return;
  151.         }
  152.  
  153.         pOrigDefaultSkeleton->SetKeepInMemory(true);
  154.  
  155.         std::vector<const char*> mismatchingSkins;
  156.         uint64 nExtendedCRC64 = CCrc32::ComputeLowercase(pOriginalFilePath);
  157.         for (auto&& pAttachment : m_pAttachmentManager->m_arrAttachments)
  158.         {
  159.                 if (pAttachment->GetType() != CA_SKIN)
  160.                 {
  161.                         continue;
  162.                 }
  163.  
  164.                 const CSkin* const pSkin  = static_cast<CAttachmentSKIN*>(pAttachment.get())->m_pModelSkin;
  165.                 if (!pSkin)
  166.                 {
  167.                         continue;
  168.                 }
  169.  
  170.                 const char* pSkinFilename = pSkin->GetModelFilePath();
  171.                 mismatchingSkins.push_back(pSkinFilename);
  172.                 nExtendedCRC64 += CCrc32::ComputeLowercase(pSkinFilename);
  173.         }
  174.  
  175.         CDefaultSkeleton* const pExtDefaultSkeleton = g_pCharacterManager->CreateExtendedSkel(pInstanceSkel, pOrigDefaultSkeleton, nExtendedCRC64, mismatchingSkins, nLoadingFlags);
  176.         if (pExtDefaultSkeleton)
  177.         {
  178.                 pInstanceSkel->RuntimeInit(pExtDefaultSkeleton);
  179.                 m_pAttachmentManager->m_TypeSortingRequired++;
  180.                 m_pAttachmentManager->UpdateAllRemapTables();
  181.         }
  182. }
  183.  
  184. void CAttachmentSKIN::UpdateRemapTable()
  185. {
  186.         if (m_pModelSkin==0)
  187.                 return;
  188.  
  189.         ReleaseRemapTablePair();
  190.         CCharInstance* pInstanceSkel = m_pAttachmentManager->m_pSkelInstance;
  191.         CDefaultSkeleton* pDefaultSkeleton = pInstanceSkel->m_pDefaultSkeleton;
  192.  
  193.         const char* pSkelFilePath = pDefaultSkeleton->GetModelFilePath();
  194.         const char* pSkinFilePath = m_pModelSkin->GetModelFilePath();
  195.  
  196.         uint32 numJointsSkel = pDefaultSkeleton->m_arrModelJoints.size();
  197.         uint32 numJointsSkin = m_pModelSkin->m_arrModelJoints.size();
  198.  
  199.         m_arrRemapTable.resize(numJointsSkin, 0);
  200.         for(uint32 js=0; js<numJointsSkin; js++)
  201.         {
  202.                 const int32 nID = pDefaultSkeleton->GetJointIDByCRC32(m_pModelSkin->m_arrModelJoints[js].m_nJointCRC32Lower);
  203.                 if (nID>=0)
  204.                         m_arrRemapTable[js]=nID;
  205.                 else
  206.                         CryFatalError("ModelError: data-corruption when executing UpdateRemapTable for SKEL (%s) and SKIN (%s) ",pSkelFilePath,pSkinFilePath); //a fail in this case is virtually impossible, because the SKINs are alread attached
  207.         }
  208.        
  209.         // Patch the remapping
  210.         for (size_t i=0; i<m_pModelSkin->GetNumLODs(); i++)
  211.         {
  212.                 CModelMesh* pModelMesh = m_pModelSkin->GetModelMesh(i);
  213.                 IRenderMesh* pRenderMesh = pModelMesh->m_pIRenderMesh;
  214.                 if (!pRenderMesh)
  215.                         continue;
  216.                 pRenderMesh->CreateRemappedBoneIndicesPair(m_arrRemapTable, pDefaultSkeleton->GetGuid(), this);
  217.         }
  218. }
  219.  
  220. void CAttachmentSKIN::ReleaseRemapTablePair()
  221. {
  222.         if (!m_pModelSkin)
  223.                 return;
  224.         CCharInstance* pInstanceSkel = m_pAttachmentManager->m_pSkelInstance;
  225.         CDefaultSkeleton* pModelSkel = pInstanceSkel->m_pDefaultSkeleton;
  226.         const uint skeletonGuid = pModelSkel->GetGuid();
  227.         for (size_t i=0; i<m_pModelSkin->GetNumLODs(); i++)
  228.         {
  229.                 CModelMesh* pModelMesh = m_pModelSkin->GetModelMesh(i);
  230.                 IRenderMesh* pRenderMesh = pModelMesh->m_pIRenderMesh;
  231.                 if (!pRenderMesh)
  232.                         continue;
  233.                 pRenderMesh->ReleaseRemappedBoneIndicesPair(skeletonGuid);
  234.         }
  235. }
  236.  
  237. uint32 CAttachmentSKIN::Immediate_SwapBinding(IAttachment* pNewAttachment)
  238. {
  239.         CryWarning(VALIDATOR_MODULE_ANIMATION, VALIDATOR_WARNING, "CAttachmentSKIN::SwapBinding attempting to swap skin attachment bindings this is not supported");
  240.         return 0;
  241. }
  242.  
  243. float CAttachmentSKIN::GetExtent(EGeomForm eForm)
  244. {
  245.         if (m_pModelSkin)
  246.         {
  247.                 int nLOD = m_pModelSkin->SelectNearestLoadedLOD(0);
  248.                 if (IRenderMesh* pMesh = m_pModelSkin->GetIRenderMesh(nLOD))
  249.                         return pMesh->GetExtent(eForm);
  250.         }
  251.         return 0.f;
  252. }
  253.  
  254. void CAttachmentSKIN::GetRandomPos(PosNorm& ran, CRndGen& seed, EGeomForm eForm) const
  255. {
  256.         int nLOD = m_pModelSkin->SelectNearestLoadedLOD(0);
  257.         IRenderMesh* pMesh = m_pModelSkin->GetIRenderMesh(nLOD);
  258.  
  259.         SSkinningData* pSkinningData = NULL;
  260.         int nFrameID = gEnv->pRenderer->EF_GetSkinningPoolID();
  261.         for (int n = 0; n < 3; n++)
  262.         {
  263.                 int nList = (nFrameID-n) % 3;
  264.                 if (m_arrSkinningRendererData[nList].nFrameID == nFrameID-n)
  265.                 {
  266.                         pSkinningData = m_arrSkinningRendererData[nList].pSkinningData;
  267.                         break;
  268.                 }
  269.         }
  270.  
  271.         pMesh->GetRandomPos(ran, seed, eForm, pSkinningData);
  272. }
  273.  
  274. const QuatTS CAttachmentSKIN::GetAttWorldAbsolute() const
  275. {
  276.         QuatTS rPhysLocation = m_pAttachmentManager->m_pSkelInstance->m_location;
  277.         return rPhysLocation;
  278. };
  279.  
  280. void CAttachmentSKIN::UpdateAttModelRelative()
  281. {
  282. }
  283.  
  284. int CAttachmentSKIN::GetGuid() const
  285. {
  286.         return m_pAttachmentManager->m_pSkelInstance->m_pDefaultSkeleton->GetGuid();
  287. }
  288.  
  289. void CAttachmentSKIN::ReleaseModelSkin()
  290. {
  291.         if (m_pModelSkin)
  292.         {
  293.                 g_pCharacterManager->UnregisterInstanceSkin(m_pModelSkin,this);
  294.                 ReleaseRemapTablePair();
  295.                 m_pModelSkin = 0;
  296.         }
  297. }
  298.  
  299. CAttachmentSKIN::~CAttachmentSKIN()
  300. {
  301.         if (m_AttFlags & FLAGS_ATTACH_SW_SKINNING)
  302.         {
  303.                 int nFrameID = gEnv->pRenderer ? gEnv->pRenderer->EF_GetSkinningPoolID() : 0;
  304.                 int nList = nFrameID % 3;
  305.                 if(m_arrSkinningRendererData[nList].nFrameID == nFrameID && m_arrSkinningRendererData[nList].pSkinningData)
  306.                 {                              
  307.                         if(m_arrSkinningRendererData[nList].pSkinningData->pAsyncJobs)
  308.                                 gEnv->pJobManager->WaitForJob( *m_arrSkinningRendererData[nList].pSkinningData->pAsyncJobs );
  309.                 }
  310.         }
  311.  
  312.         ReleaseModelSkin();
  313.  
  314.         CVertexAnimation::RemoveSoftwareRenderMesh(this);
  315.         for (uint32 j=0; j<2; ++j)
  316.                         m_pRenderMeshsSW[j] = NULL;
  317. }
  318.  
  319. void CAttachmentSKIN::Serialize(TSerialize ser)
  320. {
  321.         if (ser.GetSerializationTarget() != eST_Network)
  322.         {
  323.                 ser.BeginGroup("CAttachmentSKIN");
  324.  
  325.                 bool bHideInMainPass;
  326.  
  327.                 if (ser.IsWriting())
  328.                 {
  329.                         bHideInMainPass = ((m_AttFlags & FLAGS_ATTACH_HIDE_MAIN_PASS) == FLAGS_ATTACH_HIDE_MAIN_PASS);
  330.                 }
  331.  
  332.                 ser.Value("HideInMainPass", bHideInMainPass);
  333.                
  334.                 if (ser.IsReading())
  335.                 {
  336.                         HideAttachment(bHideInMainPass);
  337.                 }
  338.  
  339.                 ser.EndGroup();
  340.         }
  341. }
  342.  
  343. size_t CAttachmentSKIN::SizeOfThis() const
  344. {
  345.         size_t nSize = sizeof(CAttachmentSKIN) + sizeofVector(m_strSocketName);
  346.         nSize += m_arrRemapTable.get_alloc_size();
  347.         return nSize;
  348. }
  349.  
  350. void CAttachmentSKIN::GetMemoryUsage( ICrySizer *pSizer ) const
  351. {
  352.         pSizer->AddObject(this, sizeof(*this));
  353.         pSizer->AddObject( m_strSocketName );
  354.         pSizer->AddObject( m_arrRemapTable );  
  355. }
  356.  
  357. _smart_ptr<IRenderMesh> CAttachmentSKIN::CreateVertexAnimationRenderMesh(uint lod, uint id)
  358. {
  359.         m_pRenderMeshsSW[id] = NULL; // smart pointer release
  360.  
  361.         if ((m_AttFlags & FLAGS_ATTACH_SW_SKINNING) == 0)
  362.                 return _smart_ptr<IRenderMesh>(NULL);
  363.         if (m_pModelSkin == 0)
  364.                 return _smart_ptr<IRenderMesh>(NULL);
  365.  
  366.         uint32 numModelMeshes = m_pModelSkin->m_arrModelMeshes.size();
  367.         if (lod >= numModelMeshes)
  368.                 return _smart_ptr<IRenderMesh>(NULL);
  369.  
  370.         _smart_ptr<IRenderMesh> pIStaticRenderMesh = m_pModelSkin->m_arrModelMeshes[lod].m_pIRenderMesh;
  371.         if (pIStaticRenderMesh==0)
  372.                 return _smart_ptr<IRenderMesh>(NULL);
  373.         ;
  374.  
  375.         CModelMesh* pModelMesh = m_pModelSkin->GetModelMesh(lod);
  376.         uint32 success = pModelMesh->InitSWSkinBuffer();
  377.         if (success==0)
  378.                 return _smart_ptr<IRenderMesh>(NULL);
  379.         ;
  380.  
  381.         if (m_sSoftwareMeshName.empty() && pIStaticRenderMesh->GetSourceName() != NULL)
  382.         {
  383.                 m_sSoftwareMeshName.reserve(strlen(pIStaticRenderMesh->GetSourceName()) + 3);
  384.                 m_sSoftwareMeshName = pIStaticRenderMesh->GetSourceName();
  385.                 m_sSoftwareMeshName += "_SW";
  386.         }
  387.  
  388.         m_pRenderMeshsSW[id] = g_pIRenderer->CreateRenderMeshInitialized(
  389.                 NULL
  390.                 , pIStaticRenderMesh->GetVerticesCount()
  391.                 , eVF_P3F_C4B_T2F
  392.                 , NULL
  393.                 , pIStaticRenderMesh->GetIndicesCount()
  394.                 , prtTriangleList
  395.                 , "Character"
  396.                 , m_sSoftwareMeshName.c_str()
  397.                 , eRMT_Transient);
  398.  
  399.         m_pRenderMeshsSW[id]->SetMeshLod(lod);
  400.  
  401.         TRenderChunkArray& chunks = pIStaticRenderMesh->GetChunks();
  402.         TRenderChunkArray  nchunks;
  403.         nchunks.resize(chunks.size());
  404.         for (size_t i=0; i<size_t(chunks.size()); ++i)
  405.         {
  406.                 nchunks[i].m_texelAreaDensity = chunks[i].m_texelAreaDensity;
  407.                 nchunks[i].nFirstIndexId = chunks[i].nFirstIndexId;
  408.                 nchunks[i].nNumIndices = chunks[i].nNumIndices;
  409.                 nchunks[i].nFirstVertId = chunks[i].nFirstVertId;
  410.                 nchunks[i].nNumVerts = chunks[i].nNumVerts;
  411. #ifdef SUBDIVISION_ACC_ENGINE
  412.                 nchunks[i].nFirstFaceId = chunks[i].nFirstFaceId;
  413.                 nchunks[i].nNumFaces = chunks[i].nNumFaces;
  414.                 nchunks[i].nPrimitiveType = chunks[i].nPrimitiveType;
  415. #endif
  416.                 nchunks[i].m_nMatFlags = chunks[i].m_nMatFlags;
  417.                 nchunks[i].m_nMatID = chunks[i].m_nMatID;
  418.                 nchunks[i].nSubObjectIndex = chunks[i].nSubObjectIndex;
  419.         }
  420.         m_pRenderMeshsSW[id]->SetRenderChunks(&nchunks[0], nchunks.size(), false);
  421.  
  422. #ifndef _RELEASE
  423.         m_vertexAnimation.m_vertexAnimationStats.sCharInstanceName = m_pAttachmentManager->m_pSkelInstance->GetFilePath();
  424.         m_vertexAnimation.m_vertexAnimationStats.sAttachmentName = "";//m_Name; TODO fix
  425.         m_vertexAnimation.m_vertexAnimationStats.pCharInstance = m_pAttachmentManager->m_pSkelInstance;
  426. #endif
  427.         return m_pRenderMeshsSW[id];
  428. }
  429.  
  430. void CAttachmentSKIN::CullVertexFrames(const SRenderingPassInfo& passInfo, float fDistance)
  431. {
  432.         DynArray<SVertexFrameState>& frameStates = m_vertexAnimation.GetFrameStates();
  433.         const uint stateCount = uint(frameStates.size());
  434.  
  435.         const CCamera& camera = passInfo.GetCamera();
  436.         float fDeltaSize = 1.f / tan(camera.GetFov()/2.0f);
  437.         float fPixelThreshold = Console::GetInst().ca_vaBlendCullingThreshold / camera.GetViewSurfaceZ();
  438.  
  439.         const float fNearPlane = camera.GetNearPlane();
  440.         fDistance *= passInfo.GetInverseZoomFactor();
  441.         fDistance = fDistance < fNearPlane ? fNearPlane : fDistance;
  442.         fDeltaSize /= fDistance;
  443.  
  444.         for (uint i=0; i<stateCount; ++i)
  445.         {
  446.                 SVertexFrameState& frameState = frameStates[i];
  447.                 if (const SSoftwareVertexFrame* const pMorphTarget = frameState.pFrame)
  448.                 {
  449.                         if (std::abs(frameState.weight * pMorphTarget->vertexMaxLength * fDeltaSize) < fPixelThreshold)
  450.                         {
  451.                                 frameState.flags |= VA_FRAME_CULLED;
  452.                         }
  453.                 }
  454.         }
  455. }
  456.  
  457. void CAttachmentSKIN::DrawAttachment(SRendParams& RendParams, const SRenderingPassInfo &passInfo, const Matrix34& rWorldMat34, f32 fZoomFactor)
  458. {
  459.         //-----------------------------------------------------------------------------
  460.         //---              map logical LOD to render LOD                            ---
  461.         //-----------------------------------------------------------------------------
  462.         int32 numLODs = m_pModelSkin->m_arrModelMeshes.size();
  463.         if (numLODs==0)
  464.                 return;
  465.         int nDesiredRenderLOD = RendParams.lodValue.LodA();
  466.         if (nDesiredRenderLOD == -1)
  467.                 nDesiredRenderLOD = RendParams.lodValue.LodB();
  468.         if (nDesiredRenderLOD>=numLODs)
  469.         {
  470.                 if (m_AttFlags&FLAGS_ATTACH_RENDER_ONLY_EXISTING_LOD)
  471.                         return;  //early exit, if LOD-file doesn't exist
  472.                 nDesiredRenderLOD = numLODs-1; //render the last existing LOD-file
  473.         }
  474.         int nRenderLOD = m_pModelSkin->SelectNearestLoadedLOD(nDesiredRenderLOD);  //we can render only loaded LODs
  475.  
  476.         m_pModelSkin->m_arrModelMeshes[nRenderLOD].m_stream.nFrameId = passInfo.GetMainFrameID();
  477.  
  478. //      float fColor[4] = {1,0,1,1};
  479. //      extern f32 g_YLine;
  480. //      g_pAuxGeom->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false,"CSkin:  numLODs: %d  nLodLevel: %d   nRenderLOD: %d   Model: %s",numLODs, RendParams.nLod, nRenderLOD, m_pModelSkin->GetModelFilePath() ); g_YLine+=0x10;
  481.  
  482.         Matrix34 FinalMat34 = rWorldMat34;
  483.         RendParams.pMatrix = &FinalMat34;
  484.         RendParams.pInstance = this;
  485.         RendParams.pMaterial = (IMaterial*)m_pIAttachmentObject->GetReplacementMaterial(nRenderLOD); //the Replacement-Material has priority
  486.         if (RendParams.pMaterial==0)
  487.                 RendParams.pMaterial = (IMaterial*)m_pModelSkin->GetIMaterial(nRenderLOD); //as a fall back take the Base-Material from the model
  488.  
  489.         bool bNewFrame = false;
  490.         if (m_vertexAnimation.m_skinningPoolID != gEnv->pRenderer->EF_GetSkinningPoolID())
  491.         {
  492.                 m_vertexAnimation.m_skinningPoolID = gEnv->pRenderer->EF_GetSkinningPoolID();
  493.                 ++m_vertexAnimation.m_RenderMeshId;
  494.                 bNewFrame = true;
  495.         }
  496.  
  497.         //---------------------------------------------------------------------------------------------
  498.         //---------------------------------------------------------------------------------------------
  499.         //---------------------------------------------------------------------------------------------
  500.         CRenderObject* pObj = g_pIRenderer->EF_GetObject_Temp(passInfo.ThreadID());
  501.         if (!pObj)
  502.                 return;
  503.  
  504.         pObj->m_pRenderNode = RendParams.pRenderNode;
  505.         pObj->m_editorSelectionID = RendParams.nEditorSelectionID;
  506.         uint64 uLocalObjFlags = pObj->m_ObjFlags;
  507.  
  508.         //check if it should be drawn close to the player
  509.         CCharInstance* pMaster  =       m_pAttachmentManager->m_pSkelInstance;
  510.         if (pMaster->m_rpFlags & CS_FLAG_DRAW_NEAR)
  511.         {
  512.                 uLocalObjFlags |= FOB_NEAREST;
  513.         }
  514.         else
  515.         {
  516.                 uLocalObjFlags &= ~FOB_NEAREST;
  517.         }
  518.  
  519.         pObj->m_fAlpha = RendParams.fAlpha;
  520.         pObj->m_fDistance =     RendParams.fDistance;
  521.         pObj->m_II.m_AmbColor = RendParams.AmbientColor;
  522.  
  523.         uLocalObjFlags |= RendParams.dwFObjFlags;
  524.  
  525.         SRenderObjData* pD = pObj->GetObjData();
  526.  
  527.         // copy the shaderparams into the render object data from the render params
  528.         if (RendParams.pShaderParams && RendParams.pShaderParams->size() > 0)
  529.         {
  530.                 pD->SetShaderParams(RendParams.pShaderParams);
  531.         }
  532.        
  533.         pD->m_uniqueObjectId = reinterpret_cast<uintptr_t>(RendParams.pInstance);
  534.  
  535.         bool bCheckMotion = pMaster->MotionBlurMotionCheck(pObj->m_ObjFlags);
  536.         if (bCheckMotion)
  537.                 uLocalObjFlags |= FOB_MOTION_BLUR;
  538.  
  539.         assert(RendParams.pMatrix);
  540.         Matrix34 RenderMat34 = (*RendParams.pMatrix);
  541.         pObj->m_II.m_Matrix = RenderMat34;
  542.   pObj->m_nClipVolumeStencilRef = RendParams.nClipVolumeStencilRef;
  543.         pObj->m_nTextureID = RendParams.nTextureID;
  544.  
  545.         pObj->m_nMaterialLayers = RendParams.nMaterialLayersBlend;
  546.  
  547.         pD->m_nVisionParams = RendParams.nVisionParams;
  548.         pD->m_nHUDSilhouetteParams = RendParams.nHUDSilhouettesParams;
  549.        
  550.         pD->m_nCustomData = RendParams.nCustomData;
  551.         pD->m_nCustomFlags = RendParams.nCustomFlags;
  552.         if(RendParams.nCustomFlags & COB_CLOAK_HIGHLIGHT)
  553.         {
  554.                 pD->m_fTempVars[5] = RendParams.fCustomData[0];
  555.         }
  556.         else if(RendParams.nCustomFlags & COB_POST_3D_RENDER)
  557.         {
  558.                 memcpy(&pD->m_fTempVars[5],&RendParams.fCustomData[0],sizeof(float)*4);
  559.                 pObj->m_fAlpha = 1.0f; // Use the alpha in the post effect instead of here
  560.                 pD->m_fTempVars[9] = RendParams.fAlpha;
  561.         }
  562.   pObj->m_DissolveRef = RendParams.nDissolveRef;
  563.        
  564.         pObj->m_ObjFlags = uLocalObjFlags | FOB_INSHADOW | FOB_TRANS_MASK;
  565.  
  566.         if (g_pI3DEngine->IsTessellationAllowed(pObj, passInfo))
  567.         {
  568.                 // Allow this RO to be tessellated, however actual tessellation will be applied if enabled in material
  569.                 pObj->m_ObjFlags |= FOB_ALLOW_TESSELLATION;
  570.         }
  571.  
  572.         pObj->m_nSort = fastround_positive(RendParams.fDistance * 2.0f);
  573.  
  574.         const float SORT_BIAS_AMOUNT = 1.f;
  575.         if(pMaster->m_rpFlags & CS_FLAG_BIAS_SKIN_SORT_DIST)
  576.         {
  577.                 pObj->m_fSort = SORT_BIAS_AMOUNT;
  578.         }
  579.  
  580.         // get skinning data           
  581.         static ICVar* cvar_gdMorphs = gEnv->pConsole->GetCVar("r_ComputeSkinningMorphs");
  582.         static ICVar* cvar_gd = gEnv->pConsole->GetCVar("r_ComputeSkinning");
  583.         bool bUseGPUComputeDeformation = (nRenderLOD == 0) && (cvar_gd && cvar_gd->GetIVal()) && m_AttFlags & FLAGS_ATTACH_COMPUTE_SKINNING;
  584.         bool bUseCPUDeformation = !bUseGPUComputeDeformation && (nRenderLOD == 0) && ShouldSwSkin() && (Console::GetInst().ca_vaEnable != 0);
  585.  
  586.         IF (!bUseCPUDeformation, 1)
  587.                 pObj->m_ObjFlags |= FOB_SKINNED;
  588.  
  589.         if (bNewFrame)
  590.         {
  591.                 bool bUpdateActiveMorphs = (bUseGPUComputeDeformation && (cvar_gdMorphs && cvar_gdMorphs->GetIVal())) || (bUseCPUDeformation);
  592.                 if (bUpdateActiveMorphs && Console::GetInst().ca_vaBlendEnable && m_vertexAnimation.GetFrameStates().size())
  593.                 {
  594.                         m_vertexAnimation.UpdateFrameWeightsFromPose(m_pAttachmentManager->m_pSkelInstance->m_SkeletonPose.GetPoseData());
  595.                         CullVertexFrames(passInfo, pObj->m_fDistance);
  596.                 }
  597.         }
  598.  
  599.         pD->m_pSkinningData = GetVertexTransformationData(bUseCPUDeformation, nRenderLOD);
  600.  
  601.         Vec3 skinOffset = m_pModelSkin->m_arrModelMeshes[nRenderLOD].m_vRenderMeshOffset;
  602.         pD->m_pSkinningData->vecPrecisionOffset[0] = skinOffset.x;
  603.         pD->m_pSkinningData->vecPrecisionOffset[1] = skinOffset.y;
  604.         pD->m_pSkinningData->vecPrecisionOffset[2] = skinOffset.z;
  605.  
  606.         IRenderMesh* pRenderMesh = m_pModelSkin->GetIRenderMesh(nRenderLOD);
  607.  
  608.         if (pRenderMesh && bUseGPUComputeDeformation && bNewFrame)
  609.         {
  610.                 pObj->m_pCurrMaterial = RendParams.pMaterial;
  611.                 if(pObj->m_pCurrMaterial == 0)
  612.                         pObj->m_pCurrMaterial = m_pModelSkin->GetIMaterial(0);
  613.  
  614.                 pD->m_pSkinningData->nHWSkinningFlags |= eHWS_DC_deformation_Skinning;
  615.                 if (m_AttFlags & FLAGS_ATTACH_COMPUTE_SKINNING_PREMORPHS)
  616.                         pD->m_pSkinningData->nHWSkinningFlags |= eHWS_DC_Deformation_PreMorphs;
  617.                 if (m_AttFlags & FLAGS_ATTACH_COMPUTE_SKINNING_TANGENTS)
  618.                         pD->m_pSkinningData->nHWSkinningFlags |= eHWS_DC_Deformation_Tangents;
  619.        
  620.                 g_pIRenderer->EF_EnqueueComputeSkinningData(pD->m_pSkinningData);
  621.  
  622.                 pRenderMesh->Render(pObj,passInfo);
  623.                 return;
  624.         }
  625.  
  626.         if (ShouldSkinLinear())
  627.                 pD->m_pSkinningData->nHWSkinningFlags |= eHWS_SkinnedLinear;
  628.  
  629.         if(bUseCPUDeformation && pRenderMesh)
  630.         {
  631.         SVertexAnimationJob *pVertexAnimation = static_cast<SVertexAnimationJob*>(pD->m_pSkinningData->pCustomData);
  632.                 uint iCurrentRenderMeshID = m_vertexAnimation.m_RenderMeshId & 1;
  633.  
  634.                 if (bNewFrame)
  635.                 {
  636.                         CreateVertexAnimationRenderMesh(nRenderLOD, iCurrentRenderMeshID);
  637.                         CVertexAnimation::RegisterSoftwareRenderMesh(this);
  638.                 }
  639.  
  640.                 pRenderMesh = m_pRenderMeshsSW[iCurrentRenderMeshID];
  641.  
  642.                 IF (pRenderMesh && bNewFrame, 1)
  643.                 {
  644.                         CModelMesh* pModelMesh = m_pModelSkin->GetModelMesh(nRenderLOD);
  645.                         CSoftwareMesh& geometry = pModelMesh->m_softwareMesh;
  646.  
  647.                         SVertexSkinData vertexSkinData;
  648.                         vertexSkinData.pTransformations = pD->m_pSkinningData->pBoneQuatsS;
  649.                         vertexSkinData.pTransformationRemapTable = pD->m_pSkinningData->pRemapTable;
  650.                         vertexSkinData.transformationCount = pD->m_pSkinningData->nNumBones;
  651.                         vertexSkinData.pVertexPositions = geometry.GetPositions();
  652.                         vertexSkinData.pVertexColors = geometry.GetColors();
  653.                         vertexSkinData.pVertexCoords = geometry.GetCoords();
  654.                         vertexSkinData.pVertexQTangents = geometry.GetTangents();
  655.                         vertexSkinData.pVertexTransformIndices = geometry.GetBlendIndices();
  656.                         vertexSkinData.pVertexTransformWeights = geometry.GetBlendWeights();
  657.                         vertexSkinData.vertexTransformCount = geometry.GetBlendCount();
  658.                         vertexSkinData.pIndices = geometry.GetIndices();
  659.                         vertexSkinData.indexCount = geometry.GetIndexCount();
  660.                         vertexSkinData.pTangentUpdateTriangles = geometry.GetTangentUpdateData();
  661.                         vertexSkinData.tangetUpdateTriCount = geometry.GetTangentUpdateDataCount();
  662.                         vertexSkinData.pTangentUpdateVertIds = geometry.GetTangentUpdateVertIds();
  663.                         vertexSkinData.tangetUpdateVertIdsCount = geometry.GetTangentUpdateTriIdsCount();
  664.                         vertexSkinData.vertexCount = geometry.GetVertexCount();
  665.                         CRY_ASSERT(pRenderMesh->GetVerticesCount() == geometry.GetVertexCount());
  666.  
  667. #if CRY_PLATFORM_DURANGO
  668.                         const uint fslCreate = FSL_VIDEO_CREATE;
  669.                         const uint fslRead = FSL_READ|FSL_VIDEO;
  670. #else
  671.                         const uint fslCreate = FSL_SYSTEM_CREATE;
  672.                         const uint fslRead = FSL_READ;
  673. #endif
  674.  
  675.                         vertexSkinData.pVertexPositionsPrevious = strided_pointer<const Vec3>(NULL);
  676.                         if (pD->m_pSkinningData->pPreviousSkinningRenderData)
  677.                                 gEnv->pJobManager->WaitForJob(*pD->m_pSkinningData->pPreviousSkinningRenderData->pAsyncJobs);
  678.                         _smart_ptr<IRenderMesh>& pRenderMeshPrevious = m_pRenderMeshsSW[1 - iCurrentRenderMeshID];
  679.                         if (pRenderMeshPrevious != NULL)
  680.                         {
  681.                                 pRenderMeshPrevious->LockForThreadAccess();
  682.                                 Vec3* pPrevPositions = (Vec3*)pRenderMeshPrevious->GetPosPtrNoCache(vertexSkinData.pVertexPositionsPrevious.iStride, fslRead);
  683.                                 if (pPrevPositions)
  684.                                 {
  685.                                         vertexSkinData.pVertexPositionsPrevious.data = pPrevPositions;
  686.                                         pVertexAnimation->m_previousRenderMesh = pRenderMeshPrevious;
  687.                                 }
  688.                                 else
  689.                                 {
  690.                                         pRenderMeshPrevious->UnlockStream(VSF_GENERAL);
  691.                                         pRenderMeshPrevious->UnLockForThreadAccess();
  692.                                 }
  693.                         }
  694.                         m_vertexAnimation.SetSkinData(vertexSkinData);
  695.  
  696.                         pVertexAnimation->vertexData.m_vertexCount = pRenderMesh->GetVerticesCount();
  697.  
  698.                         pRenderMesh->LockForThreadAccess();
  699.  
  700.                         SVF_P3F_C4B_T2F *pGeneral = (SVF_P3F_C4B_T2F*)pRenderMesh->GetPosPtrNoCache(pVertexAnimation->vertexData.pPositions.iStride, fslCreate);
  701.  
  702.                         pVertexAnimation->vertexData.pPositions.data    = (Vec3*)(&pGeneral[0].xyz);
  703.                         pVertexAnimation->vertexData.pPositions.iStride = sizeof(pGeneral[0]);
  704.                         pVertexAnimation->vertexData.pColors.data       = (uint32*)(&pGeneral[0].color);
  705.                         pVertexAnimation->vertexData.pColors.iStride    = sizeof(pGeneral[0]);
  706.                         pVertexAnimation->vertexData.pCoords.data       = (Vec2*)(&pGeneral[0].st);
  707.                         pVertexAnimation->vertexData.pCoords.iStride    = sizeof(pGeneral[0]);
  708.                         pVertexAnimation->vertexData.pVelocities.data = (Vec3*)pRenderMesh->GetVelocityPtr(pVertexAnimation->vertexData.pVelocities.iStride, fslCreate);
  709.                         pVertexAnimation->vertexData.pTangents.data = (SPipTangents*)pRenderMesh->GetTangentPtr(pVertexAnimation->vertexData.pTangents.iStride, fslCreate);
  710.                         pVertexAnimation->vertexData.pIndices = pRenderMesh->GetIndexPtr(fslCreate);
  711.                         pVertexAnimation->vertexData.m_indexCount = geometry.GetIndexCount();
  712.  
  713.                         if (!pVertexAnimation->vertexData.pPositions ||
  714.                                 !pVertexAnimation->vertexData.pVelocities ||
  715.                                 !pVertexAnimation->vertexData.pTangents)
  716.                         {
  717.                                 pRenderMesh->UnlockStream(VSF_GENERAL);
  718.                                 pRenderMesh->UnlockStream(VSF_TANGENTS);
  719.                                 pRenderMesh->UnlockStream(VSF_VERTEX_VELOCITY);
  720. #if ENABLE_NORMALSTREAM_SUPPORT
  721.                                 pRenderMesh->UnlockStream(VSF_NORMALS);
  722. #endif
  723.                                 pRenderMesh->UnLockForThreadAccess();
  724.                                 return;
  725.                         }
  726.  
  727.                         // If memory was pre-allocated for the command buffer, recompile into it.
  728.                         if (pVertexAnimation->commandBufferLength)
  729.                         {
  730.                                 CVertexCommandBufferAllocatorStatic commandBufferAllocator(
  731.                                         (uint8*)pD->m_pSkinningData->pCustomData + sizeof(SVertexAnimationJob),
  732.                                         pVertexAnimation->commandBufferLength);
  733.                                 pVertexAnimation->commandBuffer.Initialize(commandBufferAllocator);
  734.                                 m_vertexAnimation.CompileCommands(pVertexAnimation->commandBuffer);
  735.  
  736. #ifndef _RELEASE
  737.                                 if (Console::GetInst().ca_vaProfile != 0)
  738.                                 {
  739.                                         m_vertexAnimation.m_vertexAnimationStats.vertexCount = geometry.GetVertexCount();
  740.                                         g_vertexAnimationProfiler.AddVertexAnimationStats(m_vertexAnimation.m_vertexAnimationStats);
  741.                                 }
  742. #endif
  743.                         }
  744.  
  745.                         pVertexAnimation->pRenderMeshSyncVariable = pRenderMesh->SetAsyncUpdateState();
  746.  
  747.                         SSkinningData *pCurrentJobSkinningData = *pD->m_pSkinningData->pMasterSkinningDataList;
  748.                         if(pCurrentJobSkinningData == NULL)
  749.                         {
  750.                                 pVertexAnimation->Begin(pD->m_pSkinningData->pAsyncJobs);
  751.                         }
  752.                         else
  753.                         {
  754.                                 // try to append to list
  755.                                 pD->m_pSkinningData->pNextSkinningData = pCurrentJobSkinningData;
  756.                                 void *pUpdatedJobSkinningData = CryInterlockedCompareExchangePointer( alias_cast<void *volatile *>(pD->m_pSkinningData->pMasterSkinningDataList), pD->m_pSkinningData, pCurrentJobSkinningData );
  757.  
  758.                                 // in case we failed (job has finished in the meantime), we need to start the job from the main thread
  759.                                 if(pUpdatedJobSkinningData == NULL )
  760.                                 {
  761.                                         pVertexAnimation->Begin(pD->m_pSkinningData->pAsyncJobs);
  762.                                 }
  763.                         }
  764.  
  765. #ifdef EDITOR_PCDEBUGCODE
  766.                         if (Console::GetInst().ca_DebugSWSkinning)
  767.                                 DrawVertexDebug(pRenderMesh, QuatT(RenderMat34), pVertexAnimation, vertexSkinData);
  768. #endif
  769.  
  770.                         pRenderMesh->UnLockForThreadAccess();
  771.                 }
  772.         }
  773.  
  774.         if(pRenderMesh)
  775.         {
  776.                 IMaterial* pMaterial = RendParams.pMaterial;
  777.                 if(pMaterial==0)
  778.                         pMaterial = m_pModelSkin->GetIMaterial(0);
  779.                 pObj->m_pCurrMaterial = pMaterial;
  780. #ifndef _RELEASE
  781.                 CModelMesh* pModelMesh = m_pModelSkin->GetModelMesh(nRenderLOD);
  782.                 static ICVar *p_e_debug_draw = gEnv->pConsole->GetCVar("e_DebugDraw");
  783.                 if(p_e_debug_draw && p_e_debug_draw->GetIVal() > 0)
  784.                         pModelMesh->DrawDebugInfo(pMaster->m_pDefaultSkeleton, nRenderLOD, RenderMat34, p_e_debug_draw->GetIVal(), pMaterial, pObj, RendParams, passInfo.IsGeneralPass(), (IRenderNode*)RendParams.pRenderNode, m_pAttachmentManager->m_pSkelInstance->m_SkeletonPose.GetAABB() );
  785. #endif
  786.                 pRenderMesh->Render(pObj, passInfo);
  787.  
  788.                 //------------------------------------------------------------------
  789.                 //---       render debug-output (only PC in CharEdit mode)       ---
  790.                 //------------------------------------------------------------------
  791. #if EDITOR_PCDEBUGCODE
  792.                 if (pMaster->m_CharEditMode&CA_CharacterTool)
  793.                 {
  794.                         const Console& rConsole = Console::GetInst();
  795.  
  796.                         uint32 tang = rConsole.ca_DrawTangents;
  797.                         uint32 bitang = rConsole.ca_DrawBinormals;
  798.                         uint32 norm = rConsole.ca_DrawNormals;
  799.                         uint32 wire = rConsole.ca_DrawWireframe;
  800.                         if (tang || bitang || norm || wire)
  801.                         {
  802.                                 CModelMesh* pModelMesh = m_pModelSkin->GetModelMesh(nRenderLOD);
  803.                                 gEnv->pJobManager->WaitForJob( *pD->m_pSkinningData->pAsyncJobs );
  804.                                 SoftwareSkinningDQ_VS_Emulator(pModelMesh, pObj->m_II.m_Matrix,   tang,bitang,norm,wire, pD->m_pSkinningData->pBoneQuatsS);
  805.                         }
  806.                 }
  807. #endif
  808.         }
  809.  
  810. }
  811.  
  812. //-----------------------------------------------------------------------------
  813. //---     trigger streaming of desired LODs (only need in CharEdit)         ---
  814. //-----------------------------------------------------------------------------
  815. void CAttachmentSKIN::TriggerMeshStreaming(uint32 nDesiredRenderLOD, const SRenderingPassInfo &passInfo)
  816. {
  817.         if (!m_pModelSkin)
  818.                 return;
  819.  
  820.         uint32 numLODs = m_pModelSkin->m_arrModelMeshes.size();
  821.         if (numLODs==0)
  822.                 return;
  823.         if (m_AttFlags&FLAGS_ATTACH_HIDE_ATTACHMENT)
  824.                 return;  //mesh not visible
  825.         if(nDesiredRenderLOD>=numLODs)
  826.         {
  827.                 if (m_AttFlags&FLAGS_ATTACH_RENDER_ONLY_EXISTING_LOD)
  828.                         return;  //early exit, if LOD-file doesn't exist
  829.                 nDesiredRenderLOD = numLODs-1; //render the last existing LOD-file
  830.         }
  831.         m_pModelSkin->m_arrModelMeshes[nDesiredRenderLOD].m_stream.nFrameId = passInfo.GetMainFrameID();
  832. }
  833.  
  834. SSkinningData* CAttachmentSKIN::GetVertexTransformationData(bool bVertexAnimation, uint8 nRenderLOD)
  835. {
  836.         DEFINE_PROFILER_FUNCTION();
  837.         CCharInstance* pMaster = m_pAttachmentManager->m_pSkelInstance;
  838.         if (pMaster==0)
  839.         {
  840.                 CryFatalError("CryAnimation: pMaster is zero");
  841.                 return NULL;
  842.         }
  843.  
  844.         // get data to fill
  845.         int nFrameID = gEnv->pRenderer->EF_GetSkinningPoolID();
  846.         int nList = nFrameID % 3;
  847.         int nPrevList = (nFrameID - 1 ) % 3;
  848.         // before allocating new skinning date, check if we already have for this frame
  849.         if(m_arrSkinningRendererData[nList].nFrameID == nFrameID && m_arrSkinningRendererData[nList].pSkinningData)
  850.         {
  851.                 return m_arrSkinningRendererData[nList].pSkinningData;
  852.         }
  853.  
  854.         if(pMaster->arrSkinningRendererData[nList].nFrameID != nFrameID )
  855.         {
  856.                 pMaster->GetSkinningData(); // force master to compute skinning data if not available
  857.                 assert(pMaster->arrSkinningRendererData[nList].nFrameID == nFrameID);
  858.                 assert(pMaster->arrSkinningRendererData[nList].pSkinningData);
  859.         }
  860.  
  861.         uint32 nCustomDataSize = 0;
  862.         uint commandBufferLength = 0;
  863.         if (bVertexAnimation)
  864.         {
  865.                 // Make sure the software skinning command gets compiled.
  866.                 SVertexSkinData vertexSkinData = SVertexSkinData();
  867.                 vertexSkinData.transformationCount = 1;
  868.                 vertexSkinData.vertexTransformCount = 4;
  869.                 vertexSkinData.tangetUpdateTriCount = 1;
  870.                 m_vertexAnimation.SetSkinData(vertexSkinData);
  871.  
  872.                 // Compile the command buffer without allocating the commands to
  873.                 // compute the buffer length.
  874.                 CVertexCommandBufferAllocationCounter commandBufferAllocationCounter;
  875.                 CVertexCommandBuffer commandBuffer;
  876.                 commandBuffer.Initialize(commandBufferAllocationCounter);
  877.                 m_vertexAnimation.CompileCommands(commandBuffer);
  878.                 commandBufferLength = commandBufferAllocationCounter.GetCount();
  879.  
  880.                 nCustomDataSize = sizeof(SVertexAnimationJob) + commandBufferLength;
  881.         }
  882.         else
  883.         {
  884.                 static ICVar* cvar_gd = gEnv->pConsole->GetCVar("r_ComputeSkinning");
  885.                 static ICVar* cvar_gdMorphs = gEnv->pConsole->GetCVar("r_ComputeSkinningMorphs");
  886.  
  887.                 bool bUpdateActiveMorphs = (cvar_gd && cvar_gd->GetIVal()) &&
  888.                                 (cvar_gdMorphs && cvar_gdMorphs->GetIVal()) &&
  889.                                 (m_AttFlags & FLAGS_ATTACH_COMPUTE_SKINNING) &&
  890.                                 (m_AttFlags & FLAGS_ATTACH_COMPUTE_SKINNING_PREMORPHS);
  891.  
  892.                 if (bUpdateActiveMorphs)
  893.                 {
  894.                         const bool bAllowCulling = Console::GetInst().ca_vaProfile != 1;
  895.                         const bool bDebugCulling = Console::GetInst().ca_vaBlendCullingDebug && gEnv->pRenderer->EF_GetSkinningPoolID() % 2;
  896.  
  897.                         SSkinningData* sd = pMaster->arrSkinningRendererData[nList].pSkinningData;
  898.  
  899.                         uint32 numActiveMorphs = 0;
  900.                         DynArray<SVertexFrameState>& frameStates = m_vertexAnimation.GetFrameStates();
  901.                         const uint frameCount = uint(frameStates.size());
  902.                         for (uint i=0; i<frameCount; ++i)
  903.                         {
  904.                                 const SVertexFrameState& frameState = frameStates[i];
  905.  
  906.                                 const bool bCullFrame = bAllowCulling && (frameState.flags == VA_FRAME_CULLED);
  907.                                 const bool bUseFrame = frameState.weight > 0.0f && !bCullFrame;
  908.  
  909.                                 if (bUseFrame || bDebugCulling)
  910.                                 {
  911.                                         sd->pActiveMorphs[numActiveMorphs].morphIndex = frameState.frameIndex;
  912.                                         sd->pActiveMorphs[numActiveMorphs].weight = frameState.weight;
  913.  
  914.                                         ++numActiveMorphs;
  915.                                 }
  916.                         }
  917.                         sd->nNumActiveMorphs = numActiveMorphs;
  918.                 }
  919.         }
  920.  
  921.         const uint32 skinningQuatCount = m_arrRemapTable.size();
  922.         const uint32 skinningQuatCountMax = pMaster->arrSkinningRendererData[nList].pSkinningData->nNumBones;
  923.         const uint32 nNumBones = std::min(skinningQuatCount, skinningQuatCountMax);
  924.  
  925.         SSkinningData *pSkinningData = gEnv->pRenderer->EF_CreateRemappedSkinningData(nNumBones, pMaster->arrSkinningRendererData[nList].pSkinningData, nCustomDataSize, pMaster->m_pDefaultSkeleton->GetGuid());      
  926.         pSkinningData->pCustomTag = this;
  927.         pSkinningData->pRenderMesh = m_pModelSkin->GetIRenderMesh(nRenderLOD);
  928.         if (nCustomDataSize)
  929.         {
  930.                 SVertexAnimationJob *pVertexAnimation = new (pSkinningData->pCustomData) SVertexAnimationJob();
  931.                 pVertexAnimation->commandBufferLength = commandBufferLength;
  932.         }
  933.         m_arrSkinningRendererData[nList].pSkinningData = pSkinningData;
  934.         m_arrSkinningRendererData[nList].nFrameID = nFrameID;
  935.         PREFAST_ASSUME(pSkinningData);
  936.  
  937.         // set data for motion blur    
  938.         if(m_arrSkinningRendererData[nPrevList].nFrameID == (nFrameID - 1) && m_arrSkinningRendererData[nPrevList].pSkinningData)
  939.         {              
  940.                 pSkinningData->nHWSkinningFlags |= eHWS_MotionBlured;
  941.                 pSkinningData->pPreviousSkinningRenderData = m_arrSkinningRendererData[nPrevList].pSkinningData;
  942.                 if(pSkinningData->pPreviousSkinningRenderData->pAsyncJobs)
  943.                         gEnv->pJobManager->WaitForJob( *pSkinningData->pPreviousSkinningRenderData->pAsyncJobs );
  944.         }      
  945.         else
  946.         {
  947.                 // if we don't have motion blur data, use the some as for the current frame
  948.                 pSkinningData->pPreviousSkinningRenderData = pSkinningData;
  949.         }
  950.  
  951.         pSkinningData->pRemapTable = &m_arrRemapTable[0];
  952.  
  953.         return pSkinningData;
  954. }
  955.  
  956. SMeshLodInfo CAttachmentSKIN::ComputeGeometricMean() const
  957. {
  958.         SMeshLodInfo lodInfo;
  959.         lodInfo.Clear();
  960.  
  961.         CModelMesh* pModelMesh = m_pModelSkin->GetModelMesh(0);
  962.         if (pModelMesh)
  963.         {
  964.                 lodInfo.fGeometricMean = pModelMesh->m_geometricMeanFaceArea;
  965.                 lodInfo.nFaceCount = pModelMesh->m_faceCount;
  966.         }
  967.  
  968.         return lodInfo;
  969. }
  970.  
  971. void CAttachmentSKIN::HideAttachment( uint32 x )
  972. {
  973.         m_pAttachmentManager->OnHideAttachment(this, FLAGS_ATTACH_HIDE_MAIN_PASS | FLAGS_ATTACH_HIDE_SHADOW_PASS | FLAGS_ATTACH_HIDE_RECURSION, x!=0);
  974.  
  975.         if(x)
  976.                 m_AttFlags |=  (FLAGS_ATTACH_HIDE_MAIN_PASS | FLAGS_ATTACH_HIDE_SHADOW_PASS | FLAGS_ATTACH_HIDE_RECURSION);
  977.         else
  978.                 m_AttFlags &= ~(FLAGS_ATTACH_HIDE_MAIN_PASS | FLAGS_ATTACH_HIDE_SHADOW_PASS | FLAGS_ATTACH_HIDE_RECURSION);
  979. }
  980.  
  981. void CAttachmentSKIN::HideInRecursion( uint32 x )
  982. {
  983.         m_pAttachmentManager->OnHideAttachment(this, FLAGS_ATTACH_HIDE_RECURSION, x!=0);
  984.  
  985.         if(x)
  986.                 m_AttFlags |= FLAGS_ATTACH_HIDE_RECURSION;
  987.         else
  988.                 m_AttFlags &= ~FLAGS_ATTACH_HIDE_RECURSION;
  989. }
  990.  
  991. void CAttachmentSKIN::HideInShadow( uint32 x )
  992. {
  993.         m_pAttachmentManager->OnHideAttachment(this, FLAGS_ATTACH_HIDE_SHADOW_PASS, x!=0);
  994.  
  995.         if(x)
  996.                 m_AttFlags |= FLAGS_ATTACH_HIDE_SHADOW_PASS;
  997.         else
  998.                 m_AttFlags &= ~FLAGS_ATTACH_HIDE_SHADOW_PASS;
  999. }
  1000.  
  1001. #ifdef EDITOR_PCDEBUGCODE
  1002. //These functions are need only for the Editor on PC
  1003.  
  1004. void CAttachmentSKIN::DrawVertexDebug(  IRenderMesh* pRenderMesh, const QuatT& location,        const SVertexAnimationJob* pVertexAnimation,    const SVertexSkinData& vertexSkinData)
  1005. {
  1006.         static const ColorB SKINNING_COLORS[8] =
  1007.         {
  1008.                 ColorB(0x40, 0x40, 0xff, 0xff),
  1009.                 ColorB(0x40, 0x80, 0xff, 0xff),
  1010.                 ColorB(0x40, 0xff, 0x40, 0xff),
  1011.                 ColorB(0x80, 0xff, 0x40, 0xff),
  1012.  
  1013.                 ColorB(0xff, 0x80, 0x40, 0xff),
  1014.                 ColorB(0xff, 0x80, 0x80, 0xff),
  1015.                 ColorB(0xff, 0xc0, 0xc0, 0xff),
  1016.                 ColorB(0xff, 0xff, 0xff, 0xff),
  1017.         };
  1018.  
  1019.         // wait till the SW-Skinning jobs have finished
  1020.         while(*pVertexAnimation->pRenderMeshSyncVariable)                              
  1021.                 CrySleep(1);                           
  1022.  
  1023.         IRenderMesh* pIRenderMesh = pRenderMesh;
  1024.         strided_pointer<Vec3> parrDstPositions = pVertexAnimation->vertexData.pPositions;
  1025.         strided_pointer<SPipTangents> parrDstTangents;
  1026.         parrDstTangents.data = (SPipTangents*)pVertexAnimation->vertexData.pTangents.data;
  1027.         parrDstTangents.iStride = sizeof(SPipTangents);
  1028.  
  1029.         uint32 numExtVertices = pIRenderMesh->GetVerticesCount();
  1030.         if (parrDstPositions && parrDstTangents)
  1031.         {
  1032.                 static DynArray<Vec3>           arrDstPositions;
  1033.                 static DynArray<ColorB> arrDstColors;
  1034.                 uint32 numDstPositions=arrDstPositions.size();
  1035.                 if (numDstPositions<numExtVertices)
  1036.                 {
  1037.                         arrDstPositions.resize(numExtVertices);
  1038.                         arrDstColors.resize(numExtVertices);
  1039.                 }
  1040.  
  1041.                 //transform vertices by world-matrix
  1042.                 for (uint32 i=0; i<numExtVertices; ++i)
  1043.                         arrDstPositions[i]      = location*parrDstPositions[i];
  1044.  
  1045.                 //render faces as wireframe
  1046.                 if (Console::GetInst().ca_DebugSWSkinning == 1)
  1047.                 {
  1048.                         for (uint i=0; i<CRY_ARRAY_COUNT(SKINNING_COLORS); ++i)
  1049.                                 g_pAuxGeom->Draw2dLabel(32.0f+float(i*16), 32.0f, 2.0f, ColorF(SKINNING_COLORS[i].r/255.0f, SKINNING_COLORS[i].g/255.0f, SKINNING_COLORS[i].b/255.0f, 1.0f), false, "%d", i+1);
  1050.  
  1051.                         for (uint32 e=0; e<numExtVertices; e++)
  1052.                         {
  1053.                                 uint32 w=0;
  1054.                                 const SoftwareVertexBlendWeight* pBlendWeights = &vertexSkinData.pVertexTransformWeights[e];
  1055.                                 for (uint c=0; c<vertexSkinData.vertexTransformCount; ++c)
  1056.                                 {
  1057.                                         if (pBlendWeights[c] > 0.0f)
  1058.                                                 w++;
  1059.                                 }
  1060.  
  1061.                                 if (w) --w;
  1062.                                 arrDstColors[e] = w < 8 ? SKINNING_COLORS[w] : ColorB(0x00, 0x00, 0x00, 0xff);
  1063.                         }
  1064.  
  1065.                         pIRenderMesh->LockForThreadAccess();
  1066.                         uint32  numIndices = pIRenderMesh->GetIndicesCount();
  1067.                         vtx_idx* pIndices = pIRenderMesh->GetIndexPtr(FSL_READ);
  1068.  
  1069.                         IRenderAuxGeom* pAuxGeom =      gEnv->pRenderer->GetIRenderAuxGeom();
  1070.                         SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
  1071.                         renderFlags.SetFillMode( e_FillModeWireframe );
  1072.                         //              renderFlags.SetAlphaBlendMode(e_AlphaAdditive);
  1073.                         renderFlags.SetDrawInFrontMode( e_DrawInFrontOn );
  1074.                         pAuxGeom->SetRenderFlags( renderFlags );
  1075.                         //      pAuxGeom->DrawTriangles(&arrDstPositions[0],numExtVertices, pIndices,numIndices,RGBA8(0x00,0x17,0x00,0x00));           
  1076.                         pAuxGeom->DrawTriangles(&arrDstPositions[0],numExtVertices, pIndices,numIndices,&arrDstColors[0]);             
  1077.  
  1078.                         pIRenderMesh->UnLockForThreadAccess();
  1079.                 }      
  1080.  
  1081.                 //render the Normals
  1082.                 if (Console::GetInst().ca_DebugSWSkinning == 2)
  1083.                 {
  1084.                         IRenderAuxGeom* pAuxGeom =      gEnv->pRenderer->GetIRenderAuxGeom();
  1085.                         static std::vector<ColorB> arrExtVColors;
  1086.                         uint32 csize = arrExtVColors.size();
  1087.                         if (csize<(numExtVertices*2)) arrExtVColors.resize( numExtVertices*2 );
  1088.                         for(uint32 i=0; i<numExtVertices*2; i=i+2)     
  1089.                         {
  1090.                                 arrExtVColors[i+0] = RGBA8(0x00,0x00,0x3f,0x1f);
  1091.                                 arrExtVColors[i+1] = RGBA8(0x7f,0x7f,0xff,0xff);
  1092.                         }
  1093.  
  1094.                         Matrix33 WMat33 = Matrix33(location.q);
  1095.                         static std::vector<Vec3> arrExtSkinnedStream;
  1096.                         uint32 numExtSkinnedStream = arrExtSkinnedStream.size();
  1097.                         if (numExtSkinnedStream<(numExtVertices*2)) arrExtSkinnedStream.resize( numExtVertices*2 );    
  1098.                         for(uint32 i=0,t=0; i<numExtVertices; i++)     
  1099.                         {
  1100.                                 Vec3 vNormal = parrDstTangents[i].GetN().GetNormalized() * 0.03f;
  1101.  
  1102.                                 arrExtSkinnedStream[t+0] = arrDstPositions[i];
  1103.                                 arrExtSkinnedStream[t+1] = WMat33*vNormal + arrExtSkinnedStream[t];
  1104.                                 t=t+2;
  1105.                         }
  1106.                         SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
  1107.                         pAuxGeom->SetRenderFlags( renderFlags );
  1108.                         pAuxGeom->DrawLines( &arrExtSkinnedStream[0],numExtVertices*2, &arrExtVColors[0]);             
  1109.                 }
  1110.         }
  1111.  
  1112.         if (Console::GetInst().ca_DebugSWSkinning == 3)
  1113.         {
  1114.                 if (!vertexSkinData.tangetUpdateVertIdsCount)
  1115.                         return;
  1116.  
  1117.                 uint numVertices = pRenderMesh->GetVerticesCount();
  1118.                 uint numIndices = vertexSkinData.tangetUpdateTriCount*3;
  1119.  
  1120.                 static DynArray<vtx_idx> indices;
  1121.                 static DynArray<Vec3> positions;
  1122.                 static DynArray<ColorB> colors;
  1123.  
  1124.                 indices.resize(numIndices);
  1125.                 for (uint i=0; i<vertexSkinData.tangetUpdateTriCount; ++i)
  1126.                 {
  1127.                         const uint base = i * 3;
  1128.                         indices[base+0] = vertexSkinData.pTangentUpdateTriangles[i].idx1;
  1129.                         indices[base+1] = vertexSkinData.pTangentUpdateTriangles[i].idx2;
  1130.                         indices[base+2] = vertexSkinData.pTangentUpdateTriangles[i].idx3;
  1131.                 }
  1132.  
  1133.                 positions.resize(numVertices);
  1134.                 colors.resize(numVertices);
  1135.                 for (uint i=0; i<numVertices; ++i)
  1136.                 {
  1137.                         positions[i] = location * pVertexAnimation->vertexData.pPositions[i];
  1138.                         colors[i] = ColorB(0x00, 0x00, 0xff, 0xff);
  1139.                 }
  1140.  
  1141.                 IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();
  1142.                 SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
  1143.                 renderFlags.SetFillMode( e_FillModeWireframe );
  1144.                 renderFlags.SetDrawInFrontMode( e_DrawInFrontOn );
  1145.                 pAuxGeom->SetRenderFlags( renderFlags );
  1146.                 pAuxGeom->DrawTriangles(&positions[0], numVertices, &indices[0], numIndices, &colors[0]);
  1147.         }
  1148. }
  1149.  
  1150. void CAttachmentSKIN::DrawWireframeStatic( const Matrix34& m34, int nLOD, uint32 color)
  1151. {
  1152.         CModelMesh* pModelMesh = m_pModelSkin->GetModelMesh(nLOD);
  1153.         if (pModelMesh)
  1154.                 pModelMesh->DrawWireframeStatic(m34,color);
  1155. }
  1156.  
  1157. //////////////////////////////////////////////////////////////////////////
  1158. // skinning of external Vertices and QTangents
  1159. //////////////////////////////////////////////////////////////////////////
  1160. void CAttachmentSKIN::SoftwareSkinningDQ_VS_Emulator( CModelMesh* pModelMesh, Matrix34 rRenderMat34, uint8 tang,uint8 binorm,uint8 norm,uint8 wire, const DualQuat* const pSkinningTransformations)
  1161. {
  1162. #ifdef DEFINE_PROFILER_FUNCTION
  1163.         DEFINE_PROFILER_FUNCTION();
  1164. #endif
  1165.  
  1166.         CRenderAuxGeomRenderFlagsRestore _renderFlagsRestore(g_pAuxGeom);
  1167.  
  1168.         if (pModelMesh->m_pIRenderMesh==0)
  1169.                 return;
  1170.  
  1171.         static DynArray<Vec3> g_arrExtSkinnedStream;
  1172.         static DynArray<Quat> g_arrQTangents;
  1173.         static DynArray<uint8> arrSkinned;
  1174.  
  1175.         uint32 numExtIndices    = pModelMesh->m_pIRenderMesh->GetIndicesCount();
  1176.         uint32 numExtVertices   = pModelMesh->m_pIRenderMesh->GetVerticesCount();
  1177.         assert(numExtVertices && numExtIndices);
  1178.  
  1179.         uint32 ssize=g_arrExtSkinnedStream.size();
  1180.         if (ssize<numExtVertices)
  1181.         {
  1182.                 g_arrExtSkinnedStream.resize(numExtVertices);
  1183.                 g_arrQTangents.resize(numExtVertices);
  1184.                 arrSkinned.resize(numExtVertices);
  1185.         }
  1186.         memset(&arrSkinned[0],0,numExtVertices);
  1187.  
  1188.         pModelMesh->m_pIRenderMesh->LockForThreadAccess();
  1189.         ++pModelMesh->m_iThreadMeshAccessCounter;
  1190.  
  1191.         vtx_idx* pIndices                               = pModelMesh->m_pIRenderMesh->GetIndexPtr(FSL_READ);
  1192.         if (pIndices==0)
  1193.                 return;
  1194.         int32           nPositionStride;
  1195.         uint8*  pPositions                      = pModelMesh->m_pIRenderMesh->GetPosPtr(nPositionStride, FSL_READ);
  1196.         if (pPositions==0)
  1197.                 return;
  1198.         int32           nQTangentStride;
  1199.         uint8*  pQTangents                      = pModelMesh->m_pIRenderMesh->GetQTangentPtr(nQTangentStride, FSL_READ);
  1200.         if (pQTangents==0)
  1201.                 return;
  1202.         int32           nSkinningStride;
  1203.         uint8 * pSkinningInfo                           = pModelMesh->m_pIRenderMesh->GetHWSkinPtr(nSkinningStride, FSL_READ); //pointer to weights and bone-id
  1204.         if (pSkinningInfo==0)
  1205.                 return;
  1206.  
  1207.         DualQuat arrRemapSkinQuat[MAX_JOINT_AMOUNT];    //dual quaternions for skinning
  1208.         for (size_t b = 0; b < m_arrRemapTable.size(); ++b)
  1209.         {
  1210.                 const uint16 sidx = m_arrRemapTable[b]; //is array can be different for every skin-attachment
  1211.                 arrRemapSkinQuat[b] = pSkinningTransformations[sidx];
  1212.         }
  1213.  
  1214.         const uint32 numSubsets = pModelMesh->m_arrRenderChunks.size();
  1215.         if (numSubsets)
  1216.                 g_pAuxGeom->Draw2dLabel( 1,g_YLine, 1.5f, ColorF(1.0f,0.9f,1.0f,1.0f), false,"FilePath: %s",this->GetISkin()->GetModelFilePath()),g_YLine+=0x17;
  1217.  
  1218.         for (uint32 s=0; s<numSubsets; s++)
  1219.         {
  1220.                 uint32 startIndex               = pModelMesh->m_arrRenderChunks[s].m_nFirstIndexId;
  1221.                 uint32 endIndex                 = pModelMesh->m_arrRenderChunks[s].m_nFirstIndexId+pModelMesh->m_arrRenderChunks[s].m_nNumIndices;
  1222.                 g_pAuxGeom->Draw2dLabel(1, g_YLine, 1.3f, ColorF(1.0f, 0.0f, 1.0f, 1.0f), false, "subset: %d  startIndex: %d  endIndex: %d", s, startIndex, endIndex);
  1223.                 g_YLine += 0x10;
  1224.  
  1225.                 for (uint32 idx=startIndex; idx<endIndex; ++idx)
  1226.                 {
  1227.                         uint32 e = pIndices[idx];
  1228.                         if (arrSkinned[e])
  1229.                                 continue;
  1230.  
  1231.                         arrSkinned[e]=1;
  1232.                         Vec3            hwPosition      = *(Vec3*)(pPositions + e * nPositionStride) + pModelMesh->m_vRenderMeshOffset;
  1233.                         SMeshQTangents  hwQTangent      = *(SMeshQTangents*)(pQTangents + e * nQTangentStride);
  1234.                         uint16* hwIndices   = ((SVF_W4B_I4S*)(pSkinningInfo + e*nSkinningStride))->indices;
  1235.                         ColorB  hwWeights               = *(ColorB*)&((SVF_W4B_I4S*)(pSkinningInfo + e*nSkinningStride))->weights;
  1236.  
  1237.                         //---------------------------------------------------------------------
  1238.                         //---     this is CPU emulation of Dual-Quat skinning              ---
  1239.                         //---------------------------------------------------------------------
  1240.                         //get indices for bones (always 4 indices per vertex)
  1241.                         uint32 id0 = hwIndices[0];
  1242.                         assert(id0 < m_arrRemapTable.size());
  1243.                         uint32 id1 = hwIndices[1];
  1244.                         assert(id1 < m_arrRemapTable.size());
  1245.                         uint32 id2 = hwIndices[2];
  1246.                         assert(id2 < m_arrRemapTable.size());
  1247.                         uint32 id3 = hwIndices[3];
  1248.                         assert(id3 < m_arrRemapTable.size());
  1249.  
  1250.                         //get weights for vertices (always 4 weights per vertex)
  1251.                         f32 w0 = hwWeights[0]/255.0f;
  1252.                         f32 w1 = hwWeights[1]/255.0f;
  1253.                         f32 w2 = hwWeights[2]/255.0f;
  1254.                         f32 w3 = hwWeights[3]/255.0f;
  1255.                         assert(fabsf((w0+w1+w2+w3)-1.0f)<0.0001f);
  1256.  
  1257.                         const DualQuat& q0=arrRemapSkinQuat[id0];
  1258.                         const DualQuat& q1=arrRemapSkinQuat[id1];
  1259.                         const DualQuat& q2=arrRemapSkinQuat[id2];
  1260.                         const DualQuat& q3=arrRemapSkinQuat[id3];
  1261.                         DualQuat wquat          =       q0*w0 +  q1*w1 + q2*w2 +        q3*w3;
  1262.  
  1263.                         f32 l=1.0f/wquat.nq.GetLength();
  1264.                         wquat.nq*=l;
  1265.                         wquat.dq*=l;
  1266.                         g_arrExtSkinnedStream[e] = rRenderMat34*(wquat*hwPosition);  //transform position by dual-quaternion
  1267.  
  1268.                         Quat QTangent = hwQTangent.GetQ();
  1269.                         assert( QTangent.IsUnit() );
  1270.  
  1271.                         g_arrQTangents[e] = wquat.nq*QTangent;
  1272.                         if (g_arrQTangents[e].w<0.0f)
  1273.                                 g_arrQTangents[e]=-g_arrQTangents[e]; //make it positive
  1274.                         f32 flip = QTangent.w<0 ? -1.0f : 1.0f;
  1275.                         if (flip<0)
  1276.                                 g_arrQTangents[e]=-g_arrQTangents[e]; //make it negative
  1277.                 }
  1278.         }
  1279.         g_YLine+=0x10;
  1280.  
  1281.         pModelMesh->m_pIRenderMesh->UnLockForThreadAccess();
  1282.         --pModelMesh->m_iThreadMeshAccessCounter;
  1283.         if (pModelMesh->m_iThreadMeshAccessCounter==0)
  1284.         {
  1285.                 pModelMesh->m_pIRenderMesh->UnlockStream(VSF_GENERAL);
  1286.                 pModelMesh->m_pIRenderMesh->UnlockStream(VSF_TANGENTS);
  1287.                 pModelMesh->m_pIRenderMesh->UnlockStream(VSF_HWSKIN_INFO);
  1288.         }
  1289.  
  1290.         //---------------------------------------------------------------------------
  1291.         //---------------------------------------------------------------------------
  1292.         //---------------------------------------------------------------------------
  1293.  
  1294.         uint32 numBuffer        =       g_arrExtSkinnedStream.size();
  1295.         if (numBuffer<numExtVertices)
  1296.                 return;
  1297.         const f32 VLENGTH=0.03f;
  1298.  
  1299.         if (tang)
  1300.         {
  1301.                 static std::vector<ColorB> arrExtVColors;
  1302.                 uint32 csize = arrExtVColors.size();
  1303.                 if (csize<(numExtVertices*2)) arrExtVColors.resize( numExtVertices*2 );
  1304.                 for(uint32 i=0; i<numExtVertices*2; i=i+2)     
  1305.                 {
  1306.                         arrExtVColors[i+0] = RGBA8(0x3f,0x00,0x00,0x00);
  1307.                         arrExtVColors[i+1] = RGBA8(0xff,0x7f,0x7f,0x00);
  1308.                 }
  1309.  
  1310.                 Matrix33 WMat33 = Matrix33(rRenderMat34);
  1311.                 static std::vector<Vec3> arrExtSkinnedStream;
  1312.                 uint32 vsize = arrExtSkinnedStream.size();
  1313.                 if (vsize<(numExtVertices*2)) arrExtSkinnedStream.resize( numExtVertices*2 );  
  1314.                 for(uint32 i=0,t=0; i<numExtVertices; i++)     
  1315.                 {
  1316.                         Vec3 vTangent  = g_arrQTangents[i].GetColumn0()*VLENGTH;
  1317.                         arrExtSkinnedStream[t+0] = g_arrExtSkinnedStream[i];
  1318.                         arrExtSkinnedStream[t+1] = WMat33*vTangent+arrExtSkinnedStream[t];
  1319.                         t=t+2;
  1320.                 }
  1321.  
  1322.                 SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
  1323.                 g_pAuxGeom->SetRenderFlags( renderFlags );
  1324.                 g_pAuxGeom->DrawLines( &arrExtSkinnedStream[0],numExtVertices*2, &arrExtVColors[0]);           
  1325.         }
  1326.  
  1327.         if (binorm)
  1328.         {
  1329.                 static std::vector<ColorB> arrExtVColors;
  1330.                 uint32 csize = arrExtVColors.size();
  1331.                 if (csize<(numExtVertices*2)) arrExtVColors.resize( numExtVertices*2 );
  1332.                 for(uint32 i=0; i<numExtVertices*2; i=i+2)     
  1333.                 {
  1334.                         arrExtVColors[i+0] = RGBA8(0x00,0x3f,0x00,0x00);
  1335.                         arrExtVColors[i+1] = RGBA8(0x7f,0xff,0x7f,0x00);
  1336.                 }
  1337.  
  1338.                 Matrix33 WMat33 = Matrix33(rRenderMat34);
  1339.                 static std::vector<Vec3> arrExtSkinnedStream;
  1340.                 uint32 vsize = arrExtSkinnedStream.size();
  1341.                 if (vsize<(numExtVertices*2)) arrExtSkinnedStream.resize( numExtVertices*2 );  
  1342.                 for(uint32 i=0,t=0; i<numExtVertices; i++)     
  1343.                 {
  1344.                         Vec3 vBitangent = g_arrQTangents[i].GetColumn1()*VLENGTH;
  1345.                         arrExtSkinnedStream[t+0] = g_arrExtSkinnedStream[i];
  1346.                         arrExtSkinnedStream[t+1] = WMat33*vBitangent+arrExtSkinnedStream[t];
  1347.                         t=t+2;
  1348.                 }
  1349.  
  1350.                 SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
  1351.                 g_pAuxGeom->SetRenderFlags( renderFlags );
  1352.                 g_pAuxGeom->DrawLines( &arrExtSkinnedStream[0],numExtVertices*2, &arrExtVColors[0]);           
  1353.         }
  1354.  
  1355.         if (norm)
  1356.         {
  1357.                 static std::vector<ColorB> arrExtVColors;
  1358.                 uint32 csize = arrExtVColors.size();
  1359.                 if (csize<(numExtVertices*2)) arrExtVColors.resize( numExtVertices*2 );
  1360.                 for(uint32 i=0; i<numExtVertices*2; i=i+2)     
  1361.                 {
  1362.                         arrExtVColors[i+0] = RGBA8(0x00,0x00,0x3f,0x00);
  1363.                         arrExtVColors[i+1] = RGBA8(0x7f,0x7f,0xff,0x00);
  1364.                 }
  1365.  
  1366.                 Matrix33 WMat33 = Matrix33(rRenderMat34);
  1367.                 static std::vector<Vec3> arrExtSkinnedStream;
  1368.                 uint32 vsize = arrExtSkinnedStream.size();
  1369.                 if (vsize<(numExtVertices*2)) arrExtSkinnedStream.resize( numExtVertices*2 );  
  1370.                 for(uint32 i=0,t=0; i<numExtVertices; i++)     
  1371.                 {
  1372.                         f32 flip = (g_arrQTangents[i].w<0) ? -VLENGTH : VLENGTH;
  1373.                         Vec3 vNormal = g_arrQTangents[i].GetColumn2()*flip;
  1374.                         arrExtSkinnedStream[t+0] = g_arrExtSkinnedStream[i];
  1375.                         arrExtSkinnedStream[t+1] = WMat33*vNormal + arrExtSkinnedStream[t];
  1376.                         t=t+2;
  1377.                 }
  1378.                 SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
  1379.                 g_pAuxGeom->SetRenderFlags( renderFlags );
  1380.                 g_pAuxGeom->DrawLines( &arrExtSkinnedStream[0],numExtVertices*2, &arrExtVColors[0]);           
  1381.         }
  1382.  
  1383.         if (wire)
  1384.         {
  1385.                 uint32 color = RGBA8(0x00,0xff,0x00,0x00);
  1386.                 SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
  1387.                 renderFlags.SetFillMode( e_FillModeWireframe );
  1388.                 renderFlags.SetDrawInFrontMode( e_DrawInFrontOn );
  1389.                 renderFlags.SetAlphaBlendMode(e_AlphaAdditive);
  1390.                 g_pAuxGeom->SetRenderFlags( renderFlags );
  1391.                 g_pAuxGeom->DrawTriangles(&g_arrExtSkinnedStream[0],numExtVertices, pIndices,numExtIndices,color);             
  1392.         }
  1393. }
  1394.  
  1395. #endif
downloadAttachmentSkin.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top