BVB Source Codes

CRYENGINE Show AttachmentManager.cpp Source code

Return Download CRYENGINE: download AttachmentManager.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 "AttachmentManager.h"
  5.  
  6. #include <CryRenderer/IRenderAuxGeom.h>
  7. #include "ModelMesh.h"
  8. #include "SocketSimulation.h"
  9. #include "AttachmentPRow.h"
  10. #include "AttachmentVCloth.h"
  11. #include "CharacterInstance.h"
  12. #include "CharacterManager.h"
  13. #include "AttachmentMerger.h"
  14. #include <memory>
  15. #include "Command_Commands.h"
  16. #include "Command_Buffer.h"
  17.  
  18. uint32 CAttachmentManager::LoadAttachmentList(const char* pathname)
  19. {
  20.  
  21.         XmlNodeRef nodeAttachList = g_pISystem->LoadXmlFromFile(pathname);
  22.         if (nodeAttachList == 0)
  23.                 return 0;
  24.  
  25.         const char* AttachListTag = nodeAttachList->getTag();
  26.         if (strcmp(AttachListTag, "AttachmentList"))
  27.                 return 0;
  28.  
  29.         RemoveAllAttachments();
  30.  
  31.         DynArray<CharacterAttachment> arrAttachments;
  32.         uint32 numChildren = nodeAttachList->getChildCount();
  33.         arrAttachments.resize(numChildren);
  34.         uint32 numValidAttachments = ParseXMLAttachmentList(&arrAttachments[0], numChildren, nodeAttachList);
  35.         if (numValidAttachments)
  36.         {
  37.                 arrAttachments.resize(numValidAttachments);
  38.                 InitAttachmentList(&arrAttachments[0], arrAttachments.size(), m_pSkelInstance->GetFilePath(), 0, -1);
  39.         }
  40.         return 1;
  41. };
  42.  
  43. //-----------------------------------------------------------
  44. //parse attachment-list
  45. //-----------------------------------------------------------
  46. uint32 CAttachmentManager::ParseXMLAttachmentList(CharacterAttachment* parrAttachments, uint32 numAttachments, XmlNodeRef nodeAttachements)
  47. {
  48.         uint32 numValidAttachments = 0;
  49.         for (uint32 i = 0; i < numAttachments; i++)
  50.         {
  51.                 CharacterAttachment attach;
  52.                 XmlNodeRef nodeAttach = nodeAttachements->getChild(i);
  53.                 const char* AttachTag = nodeAttach->getTag();
  54.                 if (strcmp(AttachTag, "Attachment"))
  55.                         continue;                                                     //invalid
  56.  
  57.                 stack_string Type = nodeAttach->getAttr("Type");
  58.                 if (Type == "CA_BONE")
  59.                         attach.m_Type = CA_BONE;
  60.                 if (Type == "CA_FACE")
  61.                         attach.m_Type = CA_FACE;
  62.                 if (Type == "CA_SKIN")
  63.                         attach.m_Type = CA_SKIN;
  64.                 if (Type == "CA_PROX")
  65.                         attach.m_Type = CA_PROX;
  66.                 if (Type == "CA_PROW")
  67.                         attach.m_Type = CA_PROW;
  68.                 if (Type == "CA_VCLOTH")
  69.                         attach.m_Type = CA_VCLOTH;
  70.                 if (attach.m_Type == 0xDeadBeef)
  71.                         continue;                                                     //invalid
  72.  
  73.                 string AName = nodeAttach->getAttr("AName");
  74.                 PathUtil::UnifyFilePath(AName);
  75.                 attach.m_strAttachmentName = AName;
  76.  
  77.                 nodeAttach->getAttr("Rotation", attach.m_AbsoluteDefault.q);
  78.                 nodeAttach->getAttr("Position", attach.m_AbsoluteDefault.t);
  79.  
  80.                 attach.m_relRotation = nodeAttach->getAttr("RelRotation", attach.m_RelativeDefault.q);
  81.                 attach.m_relPosition = nodeAttach->getAttr("RelPosition", attach.m_RelativeDefault.t);
  82.  
  83.                 attach.m_strJointName = nodeAttach->getAttr("BoneName");
  84.                 attach.m_strBindingPath = nodeAttach->getAttr("Binding");
  85.                 PathUtil::UnifyFilePath(attach.m_strBindingPath);
  86.                 attach.m_strSimBindingPath = nodeAttach->getAttr("simBinding");   //only used for the cloth simulation mesh
  87.  
  88.                 nodeAttach->getAttr("ProxyParams", attach.m_ProxyParams);
  89.                 nodeAttach->getAttr("ProxyPurpose", attach.m_ProxyPurpose);
  90.  
  91.                 const char* fileExt = PathUtil::GetExt(attach.m_strBindingPath);
  92.                 const bool isCGF = (0 == stricmp(fileExt, CRY_GEOMETRY_FILE_EXT));
  93.                 if (isCGF)
  94.                         attach.m_pStaticObject = gEnv->p3DEngine->LoadStatObj(attach.m_strBindingPath.c_str(), 0, 0, true);
  95.  
  96.                 if (nodeAttach->haveAttr("Material"))
  97.                 {
  98.                         const char* material = nodeAttach->getAttr("Material");
  99.                         attach.m_pMaterial = g_pISystem->GetI3DEngine()->GetMaterialManager()->LoadMaterial(material, false);
  100.                 }
  101.                 if (nodeAttach->haveAttr("MaterialLOD0"))
  102.                 {
  103.                         const char* material0 = nodeAttach->getAttr("MaterialLOD0");
  104.                         attach.m_parrMaterial[0] = g_pISystem->GetI3DEngine()->GetMaterialManager()->LoadMaterial(material0, false);
  105.                 }
  106.                 if (nodeAttach->haveAttr("MaterialLOD1"))
  107.                 {
  108.                         const char* material1 = nodeAttach->getAttr("MaterialLOD1");
  109.                         attach.m_parrMaterial[1] = g_pISystem->GetI3DEngine()->GetMaterialManager()->LoadMaterial(material1, false);
  110.                 }
  111.                 if (nodeAttach->haveAttr("MaterialLOD2"))
  112.                 {
  113.                         const char* material2 = nodeAttach->getAttr("MaterialLOD2");
  114.                         attach.m_parrMaterial[2] = g_pISystem->GetI3DEngine()->GetMaterialManager()->LoadMaterial(material2, false);
  115.                 }
  116.                 if (nodeAttach->haveAttr("MaterialLOD3"))
  117.                 {
  118.                         const char* material3 = nodeAttach->getAttr("MaterialLOD3");
  119.                         attach.m_parrMaterial[3] = g_pISystem->GetI3DEngine()->GetMaterialManager()->LoadMaterial(material3, false);
  120.                 }
  121.                 if (nodeAttach->haveAttr("MaterialLOD4"))
  122.                 {
  123.                         const char* material4 = nodeAttach->getAttr("MaterialLOD4");
  124.                         attach.m_parrMaterial[4] = g_pISystem->GetI3DEngine()->GetMaterialManager()->LoadMaterial(material4, false);
  125.                 }
  126.                 if (nodeAttach->haveAttr("MaterialLOD5"))
  127.                 {
  128.                         const char* material5 = nodeAttach->getAttr("MaterialLOD5");
  129.                         attach.m_parrMaterial[5] = g_pISystem->GetI3DEngine()->GetMaterialManager()->LoadMaterial(material5, false);
  130.                 }
  131.  
  132.                 uint32 isPendulum = 0;
  133.                 nodeAttach->getAttr("PA_PendulumType", isPendulum);
  134.                 if (isPendulum == SimulationParams::PENDULUM_CONE || isPendulum == SimulationParams::PENDULUM_HINGE_PLANE || isPendulum == SimulationParams::PENDULUM_HALF_CONE)
  135.                 {
  136.                         attach.ap.m_nClampType = SimulationParams::ClampType(isPendulum);
  137.                         nodeAttach->getAttr("PA_FPS", attach.ap.m_nSimFPS);
  138.                         nodeAttach->getAttr("PA_Redirect", attach.ap.m_useRedirect);
  139.                         nodeAttach->getAttr("PA_MaxAngle", attach.ap.m_fMaxAngle);
  140.                         nodeAttach->getAttr("PA_HRotation", attach.ap.m_vDiskRotation.x);
  141.  
  142.                         nodeAttach->getAttr("PA_Mass", attach.ap.m_fMass);
  143.                         nodeAttach->getAttr("PA_Gravity", attach.ap.m_fGravity);
  144.                         nodeAttach->getAttr("PA_Damping", attach.ap.m_fDamping);
  145.                         nodeAttach->getAttr("PA_Stiffness", attach.ap.m_fStiffness);
  146.  
  147.                         nodeAttach->getAttr("PA_PivotOffset", attach.ap.m_vPivotOffset);
  148.                         nodeAttach->getAttr("PA_PendulumOffset", attach.ap.m_vSimulationAxis);
  149.                         nodeAttach->getAttr("PA_SimulationAxis", attach.ap.m_vSimulationAxis);
  150.                         nodeAttach->getAttr("PA_StiffnessTarget", attach.ap.m_vStiffnessTarget);
  151.  
  152.                         nodeAttach->getAttr("PA_CapsuleX", attach.ap.m_vCapsule.x);
  153.                         nodeAttach->getAttr("PA_CapsuleY", attach.ap.m_vCapsule.y);
  154.                         nodeAttach->getAttr("PA_ProjectionType", attach.ap.m_nProjectionType);
  155.                         attach.ap.m_strDirTransJoint = nodeAttach->getAttr("PA_DirTransJointName");
  156.                         uint32 IsIdentical = stricmp(attach.ap.m_strDirTransJoint.c_str(), attach.m_strJointName.c_str()) == 0;
  157.                         if (attach.ap.m_strDirTransJoint.length() && IsIdentical)
  158.                                 attach.ap.m_strDirTransJoint.reset();
  159.  
  160.                         char proxytag[] = "PA_Proxy00";
  161.                         for (uint32 i = 0; i < SimulationParams::MaxCollisionProxies; i++)
  162.                         {
  163.                                 CCryName strProxyName = CCryName(nodeAttach->getAttr(proxytag));
  164.                                 proxytag[9]++;
  165.                                 if (strProxyName.empty())
  166.                                         continue;
  167.                                 attach.ap.m_arrProxyNames.push_back(strProxyName);
  168.                         }
  169.                 }
  170.  
  171.                 uint32 isSpring = 0;
  172.                 nodeAttach->getAttr("SA_SpringType", isSpring);
  173.                 if (isSpring)
  174.                 {
  175.                         attach.ap.m_nClampType = SimulationParams::SPRING_ELLIPSOID;
  176.                         nodeAttach->getAttr("SA_FPS", attach.ap.m_nSimFPS);
  177.                         nodeAttach->getAttr("SA_Radius", attach.ap.m_fRadius);
  178.                         nodeAttach->getAttr("SA_ScaleZP", attach.ap.m_vSphereScale.x);
  179.                         nodeAttach->getAttr("SA_ScaleZN", attach.ap.m_vSphereScale.y);
  180.                         nodeAttach->getAttr("SA_DiskRotX", attach.ap.m_vDiskRotation.x);
  181.                         nodeAttach->getAttr("SA_DiskRotZ", attach.ap.m_vDiskRotation.y);
  182.                         nodeAttach->getAttr("SA_HRotation", attach.ap.m_vDiskRotation.x);   //just for backwards compatibility
  183.  
  184.                         nodeAttach->getAttr("SA_Redirect", attach.ap.m_useRedirect);
  185.  
  186.                         nodeAttach->getAttr("SA_Mass", attach.ap.m_fMass);
  187.                         nodeAttach->getAttr("SA_Gravity", attach.ap.m_fGravity);
  188.                         nodeAttach->getAttr("SA_Damping", attach.ap.m_fDamping);
  189.                         nodeAttach->getAttr("SA_Stiffness", attach.ap.m_fStiffness);
  190.  
  191.                         nodeAttach->getAttr("SA_PivotOffset", attach.ap.m_vPivotOffset);
  192.                         nodeAttach->getAttr("SA_StiffnessTarget", attach.ap.m_vStiffnessTarget);
  193.  
  194.                         attach.ap.m_vCapsule.x = 0;
  195.                         nodeAttach->getAttr("SA_CapsuleY", attach.ap.m_vCapsule.y);
  196.                         nodeAttach->getAttr("SA_ProjectionType", attach.ap.m_nProjectionType);
  197.  
  198.                         char proxytag[] = "SA_Proxy00";
  199.                         for (uint32 i = 0; i < SimulationParams::MaxCollisionProxies; i++)
  200.                         {
  201.                                 CCryName strProxyName = CCryName(nodeAttach->getAttr(proxytag));
  202.                                 proxytag[9]++;
  203.                                 if (strProxyName.empty())
  204.                                         continue;
  205.                                 attach.ap.m_arrProxyNames.push_back(strProxyName);
  206.                         }
  207.                 }
  208.  
  209.                 uint32 IsProjection = 0;
  210.                 nodeAttach->getAttr("P_Projection", IsProjection);
  211.                 if (IsProjection)
  212.                 {
  213.                         attach.ap.m_nClampType = SimulationParams::TRANSLATIONAL_PROJECTION;
  214.                         attach.ap.m_useRedirect = 1;
  215.                         nodeAttach->getAttr("P_ProjectionType", attach.ap.m_nProjectionType);
  216.                         attach.ap.m_strDirTransJoint = nodeAttach->getAttr("P_DirTransJointName");
  217.                         uint32 IsIdentical = stricmp(attach.ap.m_strDirTransJoint.c_str(), attach.m_strJointName.c_str()) == 0;
  218.                         if (attach.ap.m_strDirTransJoint.length() && IsIdentical)
  219.                                 attach.ap.m_strDirTransJoint.reset();
  220.  
  221.                         nodeAttach->getAttr("P_TranslationAxis", attach.ap.m_vSimulationAxis);
  222.  
  223.                         nodeAttach->getAttr("P_CapsuleX", attach.ap.m_vCapsule.x);
  224.                         nodeAttach->getAttr("P_CapsuleY", attach.ap.m_vCapsule.y);
  225.  
  226.                         nodeAttach->getAttr("P_PivotOffset", attach.ap.m_vPivotOffset);
  227.  
  228.                         char proxytag[] = "P_Proxy00";
  229.                         for (uint32 i = 0; i < SimulationParams::MaxCollisionProxies; i++)
  230.                         {
  231.                                 CCryName strProxyName = CCryName(nodeAttach->getAttr(proxytag));
  232.                                 proxytag[8]++;
  233.                                 if (strProxyName.empty())
  234.                                         continue;
  235.                                 attach.ap.m_arrProxyNames.push_back(strProxyName);
  236.                         }
  237.                 }
  238.  
  239.                 attach.ap.m_strProcFunction = nodeAttach->getAttr("ProcFunction");
  240.  
  241.                 if (nodeAttach->haveAttr("PhysPropType"))
  242.                 {
  243.                         memset(&attach.m_AttPhysInfo, 0, sizeof(attach.m_AttPhysInfo));
  244.                         stack_string propType = nodeAttach->getAttr("PhysPropType");
  245.  
  246.                         int32 nRopeOrGrid = !strcmp(propType, "Rope") ? 0 : (!strcmp(propType, "Cloth") ? 1 : -1);
  247.                         DynArray<SJointProperty> jp = CDefaultSkeleton::GetPhysInfoProperties_ROPE(attach.m_AttPhysInfo[0], nRopeOrGrid);             //just write the names into jp
  248.  
  249.                         for (int nLod = 0; nLod < 2; nLod++)
  250.                         {
  251.                                 bool lodUsed = false;
  252.                                 uint32 numRopeJoints = jp.size();
  253.                                 for (uint32 idx = 1; idx < numRopeJoints; idx++)
  254.                                 {
  255.                                         char buf[32];
  256.                                         cry_sprintf(buf, "lod%d_%s", nLod, jp[idx].name);
  257.                                         if (jp[idx].type == 0)
  258.                                                 lodUsed |= nodeAttach->getAttr(buf, jp[idx].fval);
  259.                                         else
  260.                                                 lodUsed |= nodeAttach->getAttr(buf, jp[idx].bval);
  261.                                 }
  262.                                 if (lodUsed)
  263.                                         CDefaultSkeleton::ParsePhysInfoProperties_ROPE(attach.m_AttPhysInfo[nLod], jp);                                         //just init m_PhysInfo from jp
  264.                         }
  265.                 }
  266.  
  267.                 uint32 flags;
  268.                 if (nodeAttach->getAttr("Flags", flags))
  269.                         attach.m_AttFlags = flags;
  270.  
  271.                 if (attach.m_Type == CA_VCLOTH)
  272.                 {
  273.                         // Animation Control
  274.                         nodeAttach->getAttr("forceSkinning", attach.clothParams.forceSkinning);
  275.                         nodeAttach->getAttr("forceSkinningFpsThreshold", attach.clothParams.forceSkinningFpsThreshold);
  276.                         nodeAttach->getAttr("forceSkinningTranslateThreshold", attach.clothParams.forceSkinningTranslateThreshold);
  277.                         nodeAttach->getAttr("checkAnimationRewind", attach.clothParams.checkAnimationRewind);
  278.                         nodeAttach->getAttr("disableSimulationAtDistance", attach.clothParams.disableSimulationAtDistance);
  279.                         nodeAttach->getAttr("disableSimulationTimeRange", attach.clothParams.disableSimulationTimeRange);
  280.  
  281.                         // Simulation and Collision
  282.                         nodeAttach->getAttr("timeStep", attach.clothParams.timeStep);
  283.                         nodeAttach->getAttr("timeStepMax", attach.clothParams.timeStepsMax);
  284.                         nodeAttach->getAttr("numIterations", attach.clothParams.numIterations);
  285.                         nodeAttach->getAttr("collideEveryNthStep", attach.clothParams.collideEveryNthStep);
  286.                         nodeAttach->getAttr("collisionMultipleShiftFactor", attach.clothParams.collisionMultipleShiftFactor);
  287.                         nodeAttach->getAttr("gravityFactor", attach.clothParams.gravityFactor);
  288.  
  289.                         // Stiffness and Elasticity
  290.                         nodeAttach->getAttr("stretchStiffness", attach.clothParams.stretchStiffness);
  291.                         nodeAttach->getAttr("shearStiffness", attach.clothParams.shearStiffness);
  292.                         nodeAttach->getAttr("bendStiffness", attach.clothParams.bendStiffness);
  293.                         nodeAttach->getAttr("bendStiffnessByTrianglesAngle", attach.clothParams.bendStiffnessByTrianglesAngle);
  294.                         nodeAttach->getAttr("pullStiffness", attach.clothParams.pullStiffness);
  295.  
  296.                         // Friction and Damping
  297.                         nodeAttach->getAttr("Friction", attach.clothParams.friction);
  298.                         nodeAttach->getAttr("rigidDamping", attach.clothParams.rigidDamping);
  299.                         nodeAttach->getAttr("springDamping", attach.clothParams.springDamping);
  300.                         nodeAttach->getAttr("springDampingPerSubstep", attach.clothParams.springDampingPerSubstep);
  301.                         nodeAttach->getAttr("collisionDampingTangential", attach.clothParams.collisionDampingTangential);
  302.  
  303.                         // Long Range Attachments
  304.                         nodeAttach->getAttr("longRangeAttachments", attach.clothParams.longRangeAttachments);
  305.                         nodeAttach->getAttr("longRangeAttachmentsAllowedExtension", attach.clothParams.longRangeAttachmentsAllowedExtension);
  306.                         nodeAttach->getAttr("longRangeAttachmentsMaximumShiftFactor", attach.clothParams.longRangeAttachmentsMaximumShiftFactor);
  307.                         nodeAttach->getAttr("longRangeAttachmentsShiftCollisionFactor", attach.clothParams.longRangeAttachmentsShiftCollisionFactor);
  308.  
  309.                         // Test Reset Damping
  310.                         nodeAttach->getAttr("resetDampingFactor", attach.clothParams.resetDampingFactor);
  311.                         nodeAttach->getAttr("resetDampingRange", attach.clothParams.resetDampingRange);
  312.  
  313.                         // Additional
  314.                         nodeAttach->getAttr("translationBlend", attach.clothParams.translationBlend);
  315.                         nodeAttach->getAttr("rotationBlend", attach.clothParams.rotationBlend);
  316.                         nodeAttach->getAttr("externalBlend", attach.clothParams.externalBlend);
  317.                         nodeAttach->getAttr("maxAnimDistance", attach.clothParams.maxAnimDistance);
  318.                         nodeAttach->getAttr("filterLaplace", attach.clothParams.filterLaplace);
  319.  
  320.                         // Debug
  321.                         nodeAttach->getAttr("isMainCharacter", attach.clothParams.isMainCharacter);
  322.                         attach.clothParams.renderMeshName = nodeAttach->getAttr("renderMeshName");
  323.                         //attach.clothParams.renderBinding = nodeAttach->getAttr( "Binding");
  324.                         attach.clothParams.renderBinding = attach.m_strBindingPath;
  325.                         attach.clothParams.simMeshName = nodeAttach->getAttr("simMeshName");
  326.                         //attach.clothParams.simBinding = nodeAttach->getAttr( "simBinding");
  327.                         attach.clothParams.simBinding = attach.m_strSimBindingPath;
  328.                         attach.clothParams.material = nodeAttach->getAttr("Material");
  329.                         nodeAttach->getAttr("debugDrawVerticesRadius", attach.clothParams.debugDrawVerticesRadius);
  330.                         nodeAttach->getAttr("debugDrawCloth", attach.clothParams.debugDrawCloth);
  331.                         nodeAttach->getAttr("debugDrawLRA", attach.clothParams.debugDrawLRA);
  332.                         nodeAttach->getAttr("debugPrint", attach.clothParams.debugPrint);
  333.                         // overwrite debug settings
  334.                         attach.clothParams.debugPrint = 0;
  335.  
  336.                         nodeAttach->getAttr("hide", attach.clothParams.hide);
  337.                 }
  338.  
  339.                 if (attach.m_Type == CA_PROW)
  340.                 {
  341.                         attach.m_strRowJointName = nodeAttach->getAttr("RowJointName");
  342.  
  343.                         uint32 nPendulumClampMode = 0;
  344.                         uint32 isPendulum = nodeAttach->getAttr("ROW_ClampMode", nPendulumClampMode);
  345.                         if (isPendulum)
  346.                         {
  347.                                 attach.rowap.m_nClampMode = RowSimulationParams::ClampMode(nPendulumClampMode);
  348.                                 nodeAttach->getAttr("ROW_FPS", attach.rowap.m_nSimFPS);
  349.                                 nodeAttach->getAttr("ROW_ConeAngle", attach.rowap.m_fConeAngle);
  350.                                 nodeAttach->getAttr("ROW_ConeRotation", attach.rowap.m_vConeRotation);
  351.  
  352.                                 nodeAttach->getAttr("ROW_Mass", attach.rowap.m_fMass);
  353.                                 nodeAttach->getAttr("ROW_Gravity", attach.rowap.m_fGravity);
  354.                                 nodeAttach->getAttr("ROW_Damping", attach.rowap.m_fDamping);
  355.                                 nodeAttach->getAttr("ROW_JointSpring", attach.rowap.m_fJointSpring);
  356.                                 nodeAttach->getAttr("ROW_RodLength", attach.rowap.m_fRodLength);
  357.                                 nodeAttach->getAttr("ROW_StiffnessTarget", attach.rowap.m_vStiffnessTarget);
  358.                                 nodeAttach->getAttr("ROW_Turbulence", attach.rowap.m_vTurbulence);
  359.                                 nodeAttach->getAttr("ROW_MaxVelocity", attach.rowap.m_fMaxVelocity);
  360.  
  361.                                 nodeAttach->getAttr("ROW_Cycle", attach.rowap.m_cycle);
  362.                                 nodeAttach->getAttr("ROW_RelaxLoops", attach.rowap.m_relaxationLoops);
  363.                                 nodeAttach->getAttr("ROW_Stretch", attach.rowap.m_fStretch);
  364.  
  365.                                 nodeAttach->getAttr("ROW_CapsuleX", attach.rowap.m_vCapsule.x);
  366.                                 nodeAttach->getAttr("ROW_CapsuleY", attach.rowap.m_vCapsule.y);
  367.                                 nodeAttach->getAttr("ROW_ProjectionType", attach.rowap.m_nProjectionType);
  368.  
  369.                                 char proxytag[] = "ROW_Proxy00";
  370.                                 for (uint32 i = 0; i < SimulationParams::MaxCollisionProxies; i++)
  371.                                 {
  372.                                         CCryName strProxyName = CCryName(nodeAttach->getAttr(proxytag));
  373.                                         proxytag[10]++;
  374.                                         if (strProxyName.empty())
  375.                                                 continue;
  376.                                         attach.rowap.m_arrProxyNames.push_back(strProxyName);
  377.                                 }
  378.                         }
  379.                 }
  380.                 parrAttachments[numValidAttachments++] = attach;
  381.         }
  382.         return numValidAttachments;
  383. }
  384.  
  385. //-----------------------------------------------------------
  386. //init attachment-list
  387. //-----------------------------------------------------------
  388. void CAttachmentManager::InitAttachmentList(const CharacterAttachment* parrAttachments, uint32 numAttachments, const string pathname, uint32 nLoadingFlags, int nKeepModelInMemory)
  389. {
  390.         uint32 nLogWarnings = (nLoadingFlags & CA_DisableLogWarnings) == 0;
  391.         CSkeletonPose& rSkelPose = (CSkeletonPose&)*m_pSkelInstance->GetISkeletonPose();
  392.         CDefaultSkeleton& rDefaultSkeleton = *m_pSkelInstance->m_pDefaultSkeleton;
  393.  
  394.         // flush once, because, here we will execute immediate commands
  395.         UpdateBindings();
  396.  
  397.         bool bHasVertexAnimation = false;
  398.         CCharInstance* pICharacter = m_pSkelInstance;
  399.         for (uint32 i = 0; i < numAttachments; i++)
  400.         {
  401.                 // copy attachment, so we don't rely on vector-s memory
  402.                 const CharacterAttachment& attach = parrAttachments[i];
  403.                 uint32 nSizeOfBindingFilePath = attach.m_strBindingPath.size();
  404.  
  405.                 const char* fileExt = PathUtil::GetExt(attach.m_strBindingPath);
  406.                 bool IsCDF = (0 == stricmp(fileExt, "cdf"));
  407.                 bool IsCGA = (0 == stricmp(fileExt, "cga"));
  408.                 bool IsCGF = (0 == stricmp(fileExt, "cgf"));
  409.  
  410.                 bool IsSKEL = (0 == stricmp(fileExt, CRY_SKEL_FILE_EXT));
  411.                 bool IsSKIN = (0 == stricmp(fileExt, CRY_SKIN_FILE_EXT));
  412.  
  413.                 if (attach.m_Type == CA_BONE)
  414.                 {
  415.                         CAttachmentBONE* pAttachment = (CAttachmentBONE*)CreateAttachment(attach.m_strAttachmentName, CA_BONE, attach.m_strJointName.c_str());
  416.                         if (pAttachment == 0)
  417.                                 continue;
  418.  
  419.                         QuatT defaultTransform;
  420.                         if (pAttachment->m_nJointID < 0)
  421.                         {
  422.                                 CryWarning(VALIDATOR_MODULE_ANIMATION, VALIDATOR_ERROR, "CryAnimation: Attachment '%s' cannot be attached to bone '%s' because it doesn't exist in skeleton '%s'",
  423.                                            attach.m_strAttachmentName.c_str(), attach.m_strJointName.c_str(), rDefaultSkeleton.GetModelFilePath());
  424.                                 defaultTransform.SetIdentity();
  425.                         }
  426.                         else
  427.                         {
  428.                                 defaultTransform = rDefaultSkeleton.GetDefaultAbsJointByID(pAttachment->m_nJointID);
  429.                         }
  430.  
  431.                         QuatT qt = attach.m_AbsoluteDefault;
  432.                         QuatT rel = defaultTransform.GetInverted() * qt;
  433.                         if (attach.m_relPosition)
  434.                                 rel.t = attach.m_RelativeDefault.t;
  435.                         if (attach.m_relRotation)
  436.                                 rel.q = attach.m_RelativeDefault.q;
  437.                         qt = defaultTransform * rel;
  438.                         pAttachment->SetAttAbsoluteDefault(qt);
  439.                         pAttachment->ProjectAttachment();
  440.  
  441.                         pAttachment->SetFlags(attach.m_AttFlags);
  442.                         pAttachment->HideAttachment(attach.m_AttFlags & FLAGS_ATTACH_HIDE_ATTACHMENT);
  443.                         SimulationParams& ap = pAttachment->GetSimulationParams();
  444.                         ap = attach.ap;
  445.                         CSkeletonPose& rSkelPose = (CSkeletonPose&)*m_pSkelInstance->GetISkeletonPose();
  446.  
  447.                         if (IsSKEL || IsCGA || IsCDF)
  448.                         {
  449.                                 ICharacterInstance* pIChildCharacter = g_pCharacterManager->CreateInstance(attach.m_strBindingPath, nLoadingFlags);
  450.                                 if (pIChildCharacter == 0 && nSizeOfBindingFilePath && nLogWarnings)
  451.                                         g_pILog->LogError("CryAnimation: no character as attachment created: %s", pathname.c_str());
  452.  
  453.                                 if (pIChildCharacter)
  454.                                 {
  455.                                         CSKELAttachment* pCharacterAttachment = new CSKELAttachment();
  456.                                         pCharacterAttachment->m_pCharInstance = pIChildCharacter;
  457.                                         IAttachmentObject* pIAttachmentObject = (IAttachmentObject*)pCharacterAttachment;
  458.                                         pAttachment->Immediate_AddBinding(pIAttachmentObject);
  459.                                         if (attach.m_pMaterial && pIAttachmentObject)
  460.                                                 pIAttachmentObject->SetReplacementMaterial(attach.m_pMaterial);
  461.                                         bHasVertexAnimation |= pIChildCharacter->HasVertexAnimation();
  462.                                 }
  463.                         }
  464.                         if (IsCGF)
  465.                         {
  466.                                 IStatObj* pIStatObj = g_pISystem->GetI3DEngine()->LoadStatObj(attach.m_strBindingPath, 0, 0, true, 0);
  467.                                 if (pIStatObj == 0 && nSizeOfBindingFilePath && nLogWarnings)
  468.                                         g_pILog->LogError("CryAnimation: no static object as attachment created: %s", pathname.c_str());
  469.  
  470.                                 if (pIStatObj)
  471.                                 {
  472.                                         CCGFAttachment* pStatAttachment = new CCGFAttachment();
  473.                                         pStatAttachment->pObj = pIStatObj;
  474.                                         IAttachmentObject* pIAttachmentObject = (IAttachmentObject*)pStatAttachment;
  475.                                         pAttachment->Immediate_AddBinding(pIAttachmentObject);
  476.                                         if (attach.m_pMaterial && pIAttachmentObject)
  477.                                                 pIAttachmentObject->SetReplacementMaterial(attach.m_pMaterial);
  478.                                 }
  479.                         }
  480.  
  481.                         //this should have its own type; its not really an attachment
  482.                         for (int nLod = 0; nLod < 2; nLod++)
  483.                         {
  484.                                 if (*(alias_cast<const int*>(attach.m_AttPhysInfo[nLod].spring_angle)) == 0x12345678)
  485.                                         pICharacter->m_SkeletonPose.m_physics.SetJointPhysInfo(pAttachment->GetJointID(), attach.m_AttPhysInfo[nLod], nLod);
  486.                         }
  487.                 }
  488.  
  489.                 //-----------------------------------------------------------------------------------
  490.  
  491.                 if (attach.m_Type == CA_FACE)
  492.                 {
  493.                         CAttachmentFACE* pAttachment = (CAttachmentFACE*)CreateAttachment(attach.m_strAttachmentName, CA_FACE, 0, 0);
  494.                         if (pAttachment == 0)
  495.                                 continue;
  496.  
  497.                         pAttachment->SetAttAbsoluteDefault(attach.m_AbsoluteDefault);
  498.                         pAttachment->SetFlags(attach.m_AttFlags);
  499.                         pAttachment->HideAttachment(attach.m_AttFlags & FLAGS_ATTACH_HIDE_ATTACHMENT);
  500.                         SimulationParams& ap = pAttachment->GetSimulationParams();
  501.                         ap = attach.ap;
  502.  
  503.                         if (IsSKEL || IsCGA || IsCDF)
  504.                         {
  505.                                 ICharacterInstance* pIChildCharacter = g_pCharacterManager->CreateInstance(attach.m_strBindingPath, nLoadingFlags);
  506.                                 if (pIChildCharacter == 0 && nSizeOfBindingFilePath && nLogWarnings)
  507.                                         g_pILog->LogError("CryAnimation: no character created: %s", pathname.c_str());
  508.  
  509.                                 if (pIChildCharacter)
  510.                                 {
  511.                                         CSKELAttachment* pCharacterAttachment = new CSKELAttachment();
  512.                                         pCharacterAttachment->m_pCharInstance = pIChildCharacter;
  513.                                         IAttachmentObject* pIAttachmentObject = (IAttachmentObject*)pCharacterAttachment;
  514.                                         pAttachment->Immediate_AddBinding(pIAttachmentObject);
  515.                                         if (attach.m_pMaterial && pIAttachmentObject)
  516.                                                 pIAttachmentObject->SetReplacementMaterial(attach.m_pMaterial);
  517.                                 }
  518.                         }
  519.                         if (IsCGF)
  520.                         {
  521.                                 IStatObj* pIStatObj = g_pISystem->GetI3DEngine()->LoadStatObj(attach.m_strBindingPath, 0, 0, true, 0);
  522.                                 if (pIStatObj == 0 && nSizeOfBindingFilePath && nLogWarnings)
  523.                                         g_pILog->LogError("CryAnimation: no static object as attachment created: %s", pathname.c_str());
  524.  
  525.                                 if (pIStatObj)
  526.                                 {
  527.                                         CCGFAttachment* pStatAttachment = new CCGFAttachment();
  528.                                         pStatAttachment->pObj = pIStatObj;
  529.                                         IAttachmentObject* pIAttachmentObject = (IAttachmentObject*)pStatAttachment;
  530.                                         pAttachment->Immediate_AddBinding(pIAttachmentObject);
  531.                                         if (attach.m_pMaterial && pIAttachmentObject)
  532.                                                 pIAttachmentObject->SetReplacementMaterial(attach.m_pMaterial);
  533.                                 }
  534.                         }
  535.  
  536.                 }
  537.  
  538.                 //-----------------------------------------------------------------------------------
  539.  
  540.                 if (attach.m_Type == CA_SKIN)
  541.                 {
  542.                         CAttachmentSKIN* pAttachment = (CAttachmentSKIN*)CreateAttachment(attach.m_strAttachmentName, CA_SKIN);
  543.                         if (pAttachment == 0)
  544.                                 continue;
  545.  
  546.                         if (IsSKIN == 0 && attach.m_strBindingPath.size() > 0)
  547.                                 g_pILog->LogError("CryAnimation: a skin-attachment must be a SKIN-file. You can't use this file: '%s' in attachment '%s'", attach.m_strBindingPath.c_str(), attach.m_strAttachmentName.c_str());
  548.  
  549.                         if (IsSKIN)
  550.                         {
  551.                                 ISkin* pIModelSKIN = g_pCharacterManager->LoadModelSKIN(attach.m_strBindingPath, nLoadingFlags);
  552.                                 if (pIModelSKIN == 0 && nLogWarnings)
  553.                                         g_pILog->LogError("CryAnimation: skin-attachment not created: CDF: %s  SKIN: %s", pathname.c_str(), attach.m_strBindingPath.c_str());
  554.  
  555.                                 if (pIModelSKIN)
  556.                                 {
  557.                                         CSKINAttachment* pSkinInstance = new CSKINAttachment();
  558.                                         pSkinInstance->m_pIAttachmentSkin = pAttachment;
  559.                                         IAttachmentObject* pIAttachmentObject = (IAttachmentObject*)pSkinInstance;
  560.                                         if (pAttachment->Immediate_AddBinding(pIAttachmentObject, pIModelSKIN, nLoadingFlags))
  561.                                         {
  562.                                                 pAttachment->SetFlags(attach.m_AttFlags);
  563.                                                 bHasVertexAnimation |= (attach.m_AttFlags & FLAGS_ATTACH_SW_SKINNING) != 0;
  564.                                                 pAttachment->HideAttachment(attach.m_AttFlags & FLAGS_ATTACH_HIDE_ATTACHMENT);
  565.  
  566.                                                 if (pIAttachmentObject)
  567.                                                 {
  568.                                                         if (attach.m_pMaterial)
  569.                                                         {
  570.                                                                 for (uint32 nLOD = 0; nLOD < g_nMaxGeomLodLevels; nLOD++)
  571.                                                                 {
  572.                                                                         pIAttachmentObject->SetReplacementMaterial(attach.m_pMaterial, nLOD);
  573.                                                                 }
  574.                                                         }
  575.                                                         for (uint32 nLOD = 0; nLOD < g_nMaxGeomLodLevels; nLOD++)
  576.                                                         {
  577.                                                                 if (attach.m_parrMaterial[nLOD])
  578.                                                                         pIAttachmentObject->SetReplacementMaterial(attach.m_parrMaterial[nLOD], nLOD);
  579.                                                         }
  580.  
  581.                                                         if (const CModelMesh* pModelMesh = ((CSkin*)pIModelSKIN)->GetModelMesh(0))
  582.                                                         {
  583.                                                                 pAttachment->m_vertexAnimation.CreateFrameStates(pModelMesh->m_softwareMesh.GetVertexFrames(), *(pICharacter->m_pDefaultSkeleton.get()));
  584.                                                         }
  585.                                                 }
  586.  
  587.                                         }
  588.  
  589.                                         if (nKeepModelInMemory == 0 || nKeepModelInMemory == 1)
  590.                                         {
  591.                                                 ISkin* pISKIN = pIModelSKIN;
  592.                                                 CSkin* pCSKIN = (CSkin*)pISKIN;
  593.                                                 if (nKeepModelInMemory)
  594.                                                         pCSKIN->SetKeepInMemory(true);
  595.                                                 else
  596.                                                         pCSKIN->SetKeepInMemory(false);
  597.                                         }
  598.                                 }
  599.                         }
  600.                 }
  601.  
  602.                 //-------------------------------------------------------------------------
  603.  
  604.                 if (attach.m_Type == CA_PROX)
  605.                 {
  606.                         QuatT qt = attach.m_AbsoluteDefault;
  607.                         int32 jointid = rDefaultSkeleton.GetJointIDByName(attach.m_strJointName);
  608.                         if (jointid >= 0)
  609.                         {
  610.                                 QuatT defaultTransform = rDefaultSkeleton.GetDefaultAbsJointByID(jointid);
  611.                                 QuatT rel = defaultTransform.GetInverted() * qt;
  612.                                 if (attach.m_relPosition)
  613.                                         rel.t = attach.m_RelativeDefault.t;
  614.                                 if (attach.m_relRotation)
  615.                                         rel.q = attach.m_RelativeDefault.q;
  616.                                 qt = defaultTransform * rel;
  617.                         }
  618.                         CProxy proxy;
  619.                         proxy.m_pAttachmentManager = this;
  620.                         proxy.m_strProxyName = attach.m_strAttachmentName;
  621.                         proxy.m_nProxyCRC32 = CCrc32::ComputeLowercase(proxy.m_strProxyName.c_str());
  622.                         proxy.m_strJointName = attach.m_strJointName;
  623.                         proxy.m_ProxyAbsoluteDefault = qt;
  624.                         proxy.m_params = attach.m_ProxyParams;
  625.                         proxy.m_nPurpose = attach.m_ProxyPurpose;
  626.                         m_arrProxies.push_back(proxy);
  627.                 }
  628.  
  629.                 //-------------------------------------------------------------------------
  630.                 if (attach.m_Type == CA_PROW)
  631.                 {
  632.                         CAttachmentPROW* pCAttachmentPROW = (CAttachmentPROW*)CreateAttachment(attach.m_strAttachmentName, CA_PROW, attach.m_strRowJointName.c_str());
  633.                         if (pCAttachmentPROW == 0)
  634.                                 continue;
  635.                         (RowSimulationParams&)pCAttachmentPROW->m_rowparams = attach.rowap;
  636.                 }
  637.                 //-------------------------------------------------------------------------
  638.                 if (attach.m_Type == CA_VCLOTH)
  639.                 {
  640.                         CAttachmentVCLOTH* pCAttachmentVCloth = (CAttachmentVCLOTH*)CreateAttachment(attach.m_strAttachmentName, CA_VCLOTH);
  641.                         if (pCAttachmentVCloth == 0)
  642.                                 continue;
  643.  
  644.                         if (IsSKIN == 0)
  645.                                 g_pILog->LogError("CryAnimation: a rendermesh for vertex-cloth must be a SKIN-file. You can't use this file: %s", pathname.c_str());
  646.  
  647.                         const char* fileExt = PathUtil::GetExt(attach.m_strSimBindingPath);
  648.                         bool IsSimSKIN = (0 == stricmp(fileExt, CRY_SKIN_FILE_EXT));
  649.                         if (IsSimSKIN == 0)
  650.                                 g_pILog->LogError("CryAnimation: a simulation-mesh must be a SKIN-file. You can't use this file: %s", pathname.c_str());
  651.  
  652.                         if (IsSKIN && IsSimSKIN)
  653.                         {
  654.                                 ISkin* pIModelSKIN = g_pCharacterManager->LoadModelSKIN(attach.m_strBindingPath, nLoadingFlags);
  655.                                 if (pIModelSKIN == 0 && nLogWarnings)
  656.                                         g_pILog->LogError("CryAnimation: skin-attachment not created: CDF: %s  SKIN: %s", pathname.c_str(), attach.m_strBindingPath.c_str());
  657.  
  658.                                 ISkin* pIModelSimSKIN = g_pCharacterManager->LoadModelSKIN(attach.m_strSimBindingPath, nLoadingFlags);
  659.                                 if (pIModelSimSKIN == 0 && nLogWarnings)
  660.                                         g_pILog->LogError("CryAnimation: skin-attachment not created: CDF: %s  SKIN: %s", pathname.c_str(), attach.m_strSimBindingPath.c_str());
  661.  
  662.                                 if (pIModelSKIN && pIModelSimSKIN)
  663.                                 {
  664.                                         CSKINAttachment* pSkinInstance = new CSKINAttachment();
  665.                                         pSkinInstance->m_pIAttachmentSkin = pCAttachmentVCloth;
  666.                                         IAttachmentObject* pIAttachmentObject = (IAttachmentObject*)pSkinInstance;
  667.                                         if (pCAttachmentVCloth->Immediate_AddBinding(pIAttachmentObject, pIModelSKIN, nLoadingFlags))
  668.                                         {
  669.                                                 pCAttachmentVCloth->SetFlags(attach.m_AttFlags | FLAGS_ATTACH_SW_SKINNING);
  670.                                                 bHasVertexAnimation = true;
  671.                                                 pCAttachmentVCloth->HideAttachment(attach.m_AttFlags & FLAGS_ATTACH_HIDE_ATTACHMENT);
  672.  
  673.                                                 if (pIAttachmentObject)
  674.                                                 {
  675.                                                         if (attach.m_pMaterial)
  676.                                                         {
  677.                                                                 for (uint32 nLOD = 0; nLOD < g_nMaxGeomLodLevels; nLOD++)
  678.                                                                 {
  679.                                                                         pIAttachmentObject->SetReplacementMaterial(attach.m_pMaterial, nLOD);
  680.                                                                 }
  681.                                                         }
  682.                                                         for (uint32 nLOD = 0; nLOD < g_nMaxGeomLodLevels; nLOD++)
  683.                                                         {
  684.                                                                 if (attach.m_parrMaterial[nLOD])
  685.                                                                         pIAttachmentObject->SetReplacementMaterial(attach.m_parrMaterial[nLOD], nLOD);
  686.                                                         }
  687.  
  688.                                                         if (const CModelMesh* pModelMesh = ((CSkin*)pIModelSKIN)->GetModelMesh(0))
  689.                                                                 pCAttachmentVCloth->m_vertexAnimation.CreateFrameStates(pModelMesh->m_softwareMesh.GetVertexFrames(), *(pICharacter->m_pDefaultSkeleton.get()));
  690.                                                 }
  691.                                                 pCAttachmentVCloth->AddSimBinding(*pIModelSimSKIN, nLoadingFlags);
  692.                                                 pCAttachmentVCloth->AddClothParams(attach.clothParams);
  693.                                                 pCAttachmentVCloth->ComputeClothCacheKey();
  694.                                         }
  695.  
  696.                                         if (nKeepModelInMemory == 0 || nKeepModelInMemory == 1)
  697.                                         {
  698.                                                 if (nKeepModelInMemory)
  699.                                                 {
  700.                                                         ((CSkin*)pIModelSKIN)->SetKeepInMemory(true);
  701.                                                         ((CSkin*)pIModelSimSKIN)->SetKeepInMemory(true);
  702.                                                 }
  703.                                                 else
  704.                                                 {
  705.                                                         ((CSkin*)pIModelSKIN)->SetKeepInMemory(false);
  706.                                                         ((CSkin*)pIModelSimSKIN)->SetKeepInMemory(false);
  707.                                                 }
  708.                                         }
  709.                                 }
  710.                         }
  711.                 }
  712.         }
  713.         pICharacter->SetHasVertexAnimation(bHasVertexAnimation);
  714.  
  715.         uint32 count = GetAttachmentCount();
  716.         ProjectAllAttachment();
  717.         VerifyProxyLinks();
  718.  
  719.         uint32 nproxies = m_arrProxies.size();
  720.         for (uint32 i = 0; i < nproxies; i++)
  721.         {
  722.                 int idx = m_arrProxies[i].m_nJointID;
  723.                 m_arrProxies[i].m_ProxyModelRelative = rDefaultSkeleton.GetDefaultAbsJointByID(idx) * m_arrProxies[i].m_ProxyRelativeDefault;
  724.                 m_arrProxies[i].m_ProxyModelRelativePrev = m_arrProxies[i].m_ProxyModelRelative;
  725.         }
  726.  
  727.         uint32 numAttachmnets = GetAttachmentCount();
  728.         for (uint32 i = 0; i < numAttachmnets; i++)
  729.         {
  730.                 IAttachment* pIAttachment = GetInterfaceByIndex(i);
  731.                 if (pIAttachment->GetType() == CA_BONE)
  732.                 {
  733.                         int32 id = pIAttachment->GetJointID();
  734.                         const char* jname = rDefaultSkeleton.GetJointNameByID(id);
  735.                         pIAttachment->PostUpdateSimulationParams(1, jname);
  736.                 }
  737.                 if (pIAttachment->GetType() == CA_FACE)
  738.                         pIAttachment->PostUpdateSimulationParams(1);
  739.                 if (pIAttachment->GetType() == CA_PROW)
  740.                         pIAttachment->PostUpdateSimulationParams(1);
  741.         }
  742.  
  743.         m_TypeSortingRequired++;
  744. }
  745.  
  746. void CAttachmentManager::MergeCharacterAttachments()
  747. {
  748.         DEFINE_PROFILER_FUNCTION();
  749.  
  750.         // check for invalidated bindings first
  751.         for (auto it = m_mergedAttachments.begin(); it < m_mergedAttachments.end(); )
  752.         {
  753.                 CAttachmentMerged* pAttachment = *it;
  754.                 if (!pAttachment->AreAttachmentBindingsValid())
  755.                 {
  756.                         pAttachment->Invalidate();
  757.                         it = m_mergedAttachments.erase(it);
  758.                 }
  759.                 else
  760.                         ++it;
  761.         }
  762.  
  763.         // try to merge anything that's not merged yet
  764.         CAttachmentMerger::Instance().MergeAttachments(m_arrAttachments, m_mergedAttachments, this);
  765.         m_attachmentMergingRequired = 0;
  766. }
  767.  
  768. int32 CAttachmentManager::FindExtraBone(IAttachment* pAttachment)
  769. {
  770.         auto it = std::find(m_extraBones.begin(), m_extraBones.end(), pAttachment);
  771.         return it != m_extraBones.end() ? int32(it - m_extraBones.begin()) : -1;
  772. }
  773.  
  774. void CAttachmentManager::UpdateBindings()
  775. {
  776.         m_modificationCommandBuffer.Execute();
  777. }
  778.  
  779. int32 CAttachmentManager::AddExtraBone(IAttachment* pAttachment)
  780. {
  781.         auto it = std::find(m_extraBones.begin(), m_extraBones.end(), static_cast<IAttachment*>(NULL));
  782.         if (it != m_extraBones.end())
  783.         {
  784.                 *it = pAttachment;
  785.         }
  786.         else
  787.         {
  788.                 it = m_extraBones.push_back(pAttachment);
  789.         }
  790.  
  791.         return int32(it - m_extraBones.begin());
  792. }
  793.  
  794. void CAttachmentManager::RemoveExtraBone(IAttachment* pAttachment)
  795. {
  796.         int32 extraBone = FindExtraBone(pAttachment);
  797.         if (extraBone != -1)
  798.                 m_extraBones[extraBone] = NULL;
  799. }
  800.  
  801. IAttachment* CAttachmentManager::CreateAttachment(const char* szAttName, uint32 type, const char* szJointName, bool bCallProject)
  802. {
  803.         string strAttachmentName = szAttName;
  804.         strAttachmentName.MakeLower();
  805.  
  806.         IAttachment* pIAttachmentName = GetInterfaceByName(strAttachmentName.c_str());
  807.         if (pIAttachmentName)
  808.         {
  809.                 CryWarning(VALIDATOR_MODULE_ANIMATION, VALIDATOR_ERROR, "CryAnimation: Attachment name '%s' is already in use, attachment will not be created", strAttachmentName.c_str());
  810.                 return 0;
  811.         }
  812.  
  813.         uint32 nameCRC = CCrc32::ComputeLowercase(strAttachmentName.c_str());
  814.         IAttachment* pIAttachmentCRC32 = GetInterfaceByNameCRC(nameCRC);
  815.         if (pIAttachmentCRC32)
  816.         {
  817.                 CryWarning(VALIDATOR_MODULE_ANIMATION, VALIDATOR_ERROR, "CryAnimation: Attachment CRC32 for '%s' clashes with attachment name '%s' (crc's are created using lower case only), attachment will not be created", strAttachmentName.c_str(), pIAttachmentCRC32->GetName());
  818.                 return 0;
  819.         }
  820.  
  821.         CDefaultSkeleton& rDefaultSkeleton = *m_pSkelInstance->m_pDefaultSkeleton;
  822.  
  823.         //----------------------------------------------------------------------------------
  824.         if (type == CA_BONE)
  825.         {
  826.                 if (szJointName == 0)
  827.                         return 0;
  828.  
  829.                 CAttachmentBONE* pAttachment = new CAttachmentBONE();
  830.                 pAttachment->m_pAttachmentManager = this;
  831.                 pAttachment->m_strSocketName = strAttachmentName.c_str();
  832.                 pAttachment->m_nSocketCRC32 = nameCRC;
  833.                 pAttachment->m_strJointName = szJointName;
  834.                 if (bCallProject)
  835.                         pAttachment->ProjectAttachment();
  836.                 m_arrAttachments.push_back(pAttachment);
  837.                 m_TypeSortingRequired++;
  838.                 return pAttachment;
  839.         }
  840.  
  841.         if (type == CA_FACE)
  842.         {
  843.                 CAttachmentFACE* pAttachment = new CAttachmentFACE();
  844.                 pAttachment->m_pAttachmentManager = this;
  845.                 pAttachment->m_strSocketName = strAttachmentName.c_str();
  846.                 pAttachment->m_nSocketCRC32 = nameCRC;
  847.                 //      if( bCallProject )
  848.                 //              pAttachment->ProjectAttachment();
  849.                 m_arrAttachments.push_back(pAttachment);
  850.                 m_TypeSortingRequired++;
  851.                 return pAttachment;
  852.         }
  853.  
  854.         if (type == CA_SKIN)
  855.         {
  856.                 CAttachmentSKIN* pAttachment = new CAttachmentSKIN();
  857.                 pAttachment->m_pAttachmentManager = this;
  858.                 pAttachment->m_strSocketName = strAttachmentName.c_str();
  859.                 pAttachment->m_nSocketCRC32 = nameCRC;
  860.                 m_arrAttachments.push_back(pAttachment);
  861.                 m_TypeSortingRequired++;
  862.                 return pAttachment;
  863.         }
  864.  
  865.         if (type == CA_PROW)
  866.         {
  867.                 if (szJointName == 0)
  868.                         return 0;
  869.                 CAttachmentPROW* pAttachment = new CAttachmentPROW();
  870.                 pAttachment->m_pAttachmentManager = this;
  871.                 pAttachment->m_strSocketName = strAttachmentName.c_str();
  872.                 pAttachment->m_nSocketCRC32 = nameCRC;
  873.                 pAttachment->m_strRowJointName = szJointName;
  874.                 m_arrAttachments.push_back(pAttachment);
  875.                 m_TypeSortingRequired++;
  876.                 return pAttachment;
  877.         }
  878.  
  879.         if (type == CA_VCLOTH)
  880.         {
  881.                 CAttachmentVCLOTH* pAttachment = new CAttachmentVCLOTH();
  882.                 pAttachment->m_pAttachmentManager = this;
  883.                 pAttachment->m_strSocketName = strAttachmentName.c_str();
  884.                 pAttachment->m_nSocketCRC32 = nameCRC;
  885.                 m_arrAttachments.push_back(pAttachment);
  886.                 m_TypeSortingRequired++;
  887.                 return pAttachment;
  888.         }
  889.  
  890.         m_TypeSortingRequired++;
  891.         return 0;
  892. };
  893.  
  894. ICharacterInstance* CAttachmentManager::GetSkelInstance() const
  895. {
  896.         return m_pSkelInstance;
  897. }
  898.  
  899. float CAttachmentManager::GetExtent(EGeomForm eForm)
  900. {
  901.         CGeomExtent& extent = m_Extents.Make(eForm);
  902.  
  903.         // Add attachments.
  904.         extent.Clear();
  905.         extent.ReserveParts(m_arrAttachments.size());
  906.  
  907.         // Add attachments.
  908.         for (const auto& pa : m_arrAttachments)
  909.         {
  910.                 float fExt = 0.f;
  911.                 if (pa)
  912.                 {
  913.                         if (IAttachmentObject* pAttachmentObject = pa->GetIAttachmentObject())
  914.                         {
  915.                                 if (ICharacterInstance* pSkinInstance = pAttachmentObject->GetICharacterInstance())
  916.                                         fExt = pSkinInstance->GetExtent(eForm);
  917.                                 else if (IStatObj* pStatObj = pAttachmentObject->GetIStatObj())
  918.                                         fExt = pStatObj->GetExtent(eForm);
  919.                                 else if (IAttachmentSkin* pSkin = pAttachmentObject->GetIAttachmentSkin())
  920.                                         fExt = pSkin->GetExtent(eForm);
  921.                         }
  922.                 }
  923.                 extent.AddPart(fExt);
  924.         }
  925.  
  926.         return extent.TotalExtent();
  927. }
  928.  
  929. void CAttachmentManager::GetRandomPos(PosNorm& ran, CRndGen& seed, EGeomForm eForm) const
  930. {
  931.         ran.zero();
  932.  
  933.         CGeomExtent const& ext = m_Extents[eForm];
  934.         int iPart = ext.RandomPart(seed);
  935.         if (iPart < m_arrAttachments.size())
  936.         {
  937.                 // Choose attachment.
  938.                 if (IAttachment* pAttachment = m_arrAttachments[iPart])
  939.                 {
  940.                         if (IAttachmentObject* pAttachmentObject = pAttachment->GetIAttachmentObject())
  941.                         {
  942.                                 if (ICharacterInstance* pCharInstance = pAttachmentObject->GetICharacterInstance())
  943.                                         pCharInstance->GetRandomPos(ran, seed, eForm);
  944.                                 else if (IStatObj* pStatObj = pAttachmentObject->GetIStatObj())
  945.                                         pStatObj->GetRandomPos(ran, seed, eForm);
  946.                                 else if (IAttachmentSkin* pSkin = pAttachmentObject->GetIAttachmentSkin())
  947.                                         pSkin->GetRandomPos(ran, seed, eForm);
  948.                         }
  949.                         ran <<= QuatTS(pAttachment->GetAttModelRelative());
  950.                 }
  951.         }
  952. }
  953.  
  954. void CAttachmentManager::PhysicalizeAttachment(int idx, IPhysicalEntity* pent, int nLod)
  955. {
  956.         if (!pent)
  957.                 if (!(pent = m_pSkelInstance->GetISkeletonPose()->GetCharacterPhysics()))
  958.                         return;
  959.         PhysicalizeAttachment(idx, nLod, pent, m_pSkelInstance->m_SkeletonPose.m_physics.GetOffset());
  960. }
  961.  
  962. const int idbit = ilog2(((FLAGS_ATTACH_ID_MASK ^ FLAGS_ATTACH_ID_MASK - 1) + 1) >> 1);           // bit shift for FLAG_ATTACH_ID_MASK
  963.  
  964. void CAttachmentManager::PhysicalizeAttachment(int idx, int nLod, IPhysicalEntity* pent, const Vec3& offset)
  965. {
  966.         IStatObj* pStatObj;
  967.         IAttachment* pIAttachment = GetInterfaceByIndex(idx);
  968.         if (pIAttachment == 0)
  969.                 return;
  970.  
  971.         bool bWasPhysicalized = false;
  972.         if ((pIAttachment->GetFlags() & FLAGS_ATTACH_PHYSICALIZED) == 0)
  973.         {
  974.                 if (pIAttachment->GetIAttachmentObject())
  975.                 {
  976.                         bWasPhysicalized = pIAttachment->GetIAttachmentObject()->PhysicalizeAttachment(this, idx, nLod, pent, offset);
  977.                 }
  978.         }
  979.         //
  980.         if (bWasPhysicalized)
  981.                 return;
  982.  
  983.         // old path
  984.         if (!(pIAttachment = GetInterfaceByIndex(idx)) || pIAttachment->GetType() != CA_BONE || !(pIAttachment->GetFlags() & FLAGS_ATTACH_PHYSICALIZED) ||
  985.             !pIAttachment->GetIAttachmentObject() || !(pStatObj = pIAttachment->GetIAttachmentObject()->GetIStatObj()) || !pStatObj->GetPhysGeom() ||
  986.             pIAttachment->IsAttachmentHidden())
  987.                 return;
  988.  
  989.         int iJoint = pIAttachment->GetJointID();
  990.         pe_articgeomparams gp;
  991.         const Skeleton::CPoseData& rPoseData = m_pSkelInstance->m_SkeletonPose.GetPoseData();
  992.         Matrix34 mtx = Matrix34(rPoseData.GetJointAbsolute(iJoint) * ((CAttachmentFACE*)pIAttachment)->m_AttRelativeDefault);
  993.         mtx.AddTranslation(offset);
  994.         gp.pMtx3x4 = &mtx;
  995.         //FIXME:
  996.         gp.idbody = m_pSkelInstance->GetISkeletonPose()->getBonePhysParentOrSelfIndex(iJoint, nLod);
  997.         if (gp.idbody >= 0)
  998.                 while ((iJoint = m_pSkelInstance->m_SkeletonPose.m_physics.getBonePhysParentIndex(gp.idbody, nLod)) >= 0 &&
  999.                        (m_pSkelInstance->m_SkeletonPose.m_physics.GetModelJointPointer(gp.idbody)->m_PhysInfo.flags & all_angles_locked) == all_angles_locked)
  1000.                         gp.idbody = iJoint;
  1001.         gp.flags = 0;
  1002.         if (pIAttachment->GetFlags() & FLAGS_ATTACH_PHYSICALIZED_COLLISIONS)
  1003.                 gp.flags = geom_colltype_solid | geom_colltype_solid | geom_floats | geom_colltype_explosion;
  1004.         if (pIAttachment->GetFlags() & FLAGS_ATTACH_PHYSICALIZED_RAYS)
  1005.                 gp.flags |= geom_colltype_ray;
  1006.         int id = (pIAttachment->GetFlags() & FLAGS_ATTACH_ID_MASK) >> idbit;
  1007.         if (!id)
  1008.         {
  1009.                 id = ilog2(((m_physAttachIds ^ m_physAttachIds + 1) + 1) >> 1);               // least significant 0 bit index
  1010.                 m_physAttachIds |= 1 << id;
  1011.                 pIAttachment->SetFlags(pIAttachment->GetFlags() | id << idbit);
  1012.         }
  1013.         pent->AddGeometry(pStatObj->GetPhysGeom(), &gp, m_pSkelInstance->m_pDefaultSkeleton->GetJointCount() + id);
  1014.         pIAttachment->SetFlags(pIAttachment->GetFlags() | FLAGS_ATTACH_WAS_PHYSICALIZED);
  1015. }
  1016.  
  1017. void CAttachmentManager::DephysicalizeAttachment(int idx, IPhysicalEntity* pent)
  1018. {
  1019.         if (!pent)
  1020.                 if (!(pent = m_pSkelInstance->GetISkeletonPose()->GetCharacterPhysics()))
  1021.                         return;
  1022.         IAttachment* pIAttachment = GetInterfaceByIndex(idx);
  1023.         int id = (pIAttachment->GetFlags() & FLAGS_ATTACH_ID_MASK) >> idbit;
  1024.         if (id)
  1025.         {
  1026.                 m_physAttachIds &= ~(1 << id);
  1027.                 pIAttachment->SetFlags(pIAttachment->GetFlags() & ~FLAGS_ATTACH_ID_MASK);
  1028.         }
  1029.         pent->RemoveGeometry(m_pSkelInstance->m_pDefaultSkeleton->GetJointCount() + id);
  1030.         if (pIAttachment)
  1031.                 pIAttachment->SetFlags(pIAttachment->GetFlags() & ~FLAGS_ATTACH_WAS_PHYSICALIZED);
  1032. }
  1033.  
  1034. int CAttachmentManager::UpdatePhysicalizedAttachment(int idx, IPhysicalEntity* pent, const QuatT& offset)
  1035. {
  1036.         IStatObj* pStatObj;
  1037.         IAttachment* pIAttachment;
  1038.  
  1039.         bool WasHandled = false;
  1040.         if (!(pIAttachment = GetInterfaceByIndex(idx)) || !(pIAttachment->GetFlags() & FLAGS_ATTACH_PHYSICALIZED) ||
  1041.             !pIAttachment->GetIAttachmentObject() /* || !(pStatObj=pIAttachment->GetIAttachmentObject()->GetIStatObj()) || !pStatObj->GetPhysGeom()*/)
  1042.         {
  1043.                 if (pIAttachment && pIAttachment->GetIAttachmentObject())
  1044.                 {
  1045.                         WasHandled = pIAttachment->GetIAttachmentObject()->UpdatePhysicalizedAttachment(this, idx, pent, offset);
  1046.                 }
  1047.         }
  1048.  
  1049.         if (WasHandled)
  1050.                 return 0;
  1051.  
  1052.         if (!(pIAttachment = GetInterfaceByIndex(idx)) || pIAttachment->GetType() != CA_BONE || !(pIAttachment->GetFlags() & FLAGS_ATTACH_PHYSICALIZED) ||
  1053.             !pIAttachment->GetIAttachmentObject() || !(pStatObj = pIAttachment->GetIAttachmentObject()->GetIStatObj()) || !pStatObj->GetPhysGeom())
  1054.                 return 0;
  1055.  
  1056.         int changed = 0;
  1057.         if (pIAttachment->IsAttachmentHidden() && pIAttachment->GetFlags() & FLAGS_ATTACH_WAS_PHYSICALIZED)
  1058.                 DephysicalizeAttachment(idx, pent), changed = 1;
  1059.         else if (!pIAttachment->IsAttachmentHidden() && !(pIAttachment->GetFlags() & FLAGS_ATTACH_WAS_PHYSICALIZED))
  1060.                 PhysicalizeAttachment(idx, 0, pent, offset.t), changed = 1;
  1061.  
  1062.         pe_status_awake sa;
  1063.         if (!pent->GetStatus(&sa))
  1064.         {
  1065.                 int iJoint = pIAttachment->GetJointID();
  1066.                 pe_params_part pp;
  1067.                 Matrix34 mtx = Matrix34(offset * pIAttachment->GetAttModelRelative());
  1068.                 int id = (pIAttachment->GetFlags() & FLAGS_ATTACH_ID_MASK) >> idbit;
  1069.                 pp.partid = m_pSkelInstance->m_pDefaultSkeleton->GetJointCount() + id;
  1070.                 pp.pMtx3x4 = &mtx;
  1071.                 const CDefaultSkeleton::SJoint* pJoint = m_pSkelInstance->m_SkeletonPose.m_physics.GetModelJointPointer(iJoint);
  1072.                 pp.bRecalcBBox = !pJoint->m_PhysInfo.pPhysGeom;
  1073.                 pent->SetParams(&pp);
  1074.         }
  1075.         return changed;
  1076. }
  1077.  
  1078. int CAttachmentManager::UpdatePhysAttachmentHideState(int idx, IPhysicalEntity* pent, const Vec3& offset)
  1079. {
  1080.         IStatObj* pStatObj;
  1081.         IAttachment* pIAttachment;
  1082.  
  1083.         if (!(pIAttachment = GetInterfaceByIndex(idx)) || pIAttachment->GetType() != CA_BONE || !(pIAttachment->GetFlags() & FLAGS_ATTACH_PHYSICALIZED) ||
  1084.             !pIAttachment->GetIAttachmentObject() || !(pStatObj = pIAttachment->GetIAttachmentObject()->GetIStatObj()) || !pStatObj->GetPhysGeom())
  1085.                 return 0;
  1086.  
  1087.         if (pIAttachment->IsAttachmentHidden() && pIAttachment->GetFlags() & FLAGS_ATTACH_WAS_PHYSICALIZED)
  1088.         {
  1089.                 DephysicalizeAttachment(idx, pent);
  1090.                 return 2;
  1091.         }
  1092.         if (!pIAttachment->IsAttachmentHidden() && !(pIAttachment->GetFlags() & FLAGS_ATTACH_WAS_PHYSICALIZED))
  1093.         {
  1094.                 PhysicalizeAttachment(idx, 0, pent, offset);
  1095.                 return 1;
  1096.         }
  1097.         return 3;
  1098. }
  1099.  
  1100. int32 CAttachmentManager::RemoveAttachmentByInterface(const IAttachment* pAttachment, uint32 loadingFlags)
  1101. {
  1102.         return RemoveAttachmentByName(pAttachment->GetName(), loadingFlags);
  1103. }
  1104.  
  1105. int32 CAttachmentManager::RemoveAttachmentByName(const char* szName, uint32 loadingFlags)
  1106. {
  1107.         const int32 index = GetIndexByName(szName);
  1108.         if (index == -1)
  1109.         {
  1110.                 return 0;
  1111.         }
  1112.  
  1113.         RemoveAttachmentByIndex(index, loadingFlags);
  1114.         return 1;
  1115. };
  1116.  
  1117. int32 CAttachmentManager::RemoveAttachmentByNameCRC(uint32 nameCRC, uint32 loadingFlags)
  1118. {
  1119.         const int32 index = GetIndexByNameCRC(nameCRC);
  1120.         if (index == -1)
  1121.         {
  1122.                 return 0;
  1123.         }
  1124.  
  1125.         RemoveAttachmentByIndex(index, loadingFlags);
  1126.         return 1;
  1127. };
  1128.  
  1129. void CAttachmentManager::RemoveAttachmentByIndex(uint32 index, uint32 loadingFlags)
  1130. {
  1131.         IAttachment* const pAttachment = GetInterfaceByIndex(index);
  1132.         assert(pAttachment);
  1133.         assert(pAttachment->GetType() == CA_BONE || pAttachment->GetType() == CA_FACE || pAttachment->GetType() == CA_SKIN || pAttachment->GetType() == CA_PROW || pAttachment->GetType() == CA_VCLOTH);
  1134.  
  1135.         if (pAttachment->GetIAttachmentObject())
  1136.         {
  1137.                 pAttachment->GetIAttachmentObject()->OnRemoveAttachment(this, index);
  1138.         }
  1139.  
  1140.         for (auto && pMergedAttachment : m_mergedAttachments)
  1141.         {
  1142.                 if (pMergedAttachment->HasAttachment(pAttachment))
  1143.                 {
  1144.                         pMergedAttachment->Invalidate();
  1145.                         break; // TODO: Why is there a break here?
  1146.                 }
  1147.         }
  1148.  
  1149.         pAttachment->ClearBinding(loadingFlags);
  1150.         m_arrAttachments.erase(index);
  1151.  
  1152.         m_Extents.Clear();
  1153.         m_TypeSortingRequired++;
  1154. }
  1155.  
  1156. uint32 CAttachmentManager::ProjectAllAttachment()
  1157. {
  1158.         uint32 numAttachments = m_arrAttachments.size();
  1159.         for (uint32 i = 0; i < numAttachments; i++)
  1160.         {
  1161.                 uint32 flags = m_arrAttachments[i]->GetFlags();
  1162.                 flags &= (~FLAGS_ATTACH_PROJECTED);
  1163.                 m_arrAttachments[i]->SetFlags(flags);
  1164.         }
  1165.         return 1;
  1166. }
  1167.  
  1168. IAttachment* CAttachmentManager::GetInterfaceByName(const char* szName) const
  1169. {
  1170.         int32 idx = GetIndexByName(szName);
  1171.         if (idx == -1) return 0;
  1172.         return GetInterfaceByIndex(idx);
  1173. };
  1174.  
  1175. IAttachment* CAttachmentManager::GetInterfaceByIndex(uint32 c) const
  1176. {
  1177.         size_t size = m_arrAttachments.size();
  1178.         if (size == 0) return 0;
  1179.         if (size <= c) return 0;
  1180.         return m_arrAttachments[c];
  1181. };
  1182.  
  1183. int32 CAttachmentManager::GetIndexByName(const char* szName) const
  1184. {
  1185.         const uint32 nameCRC = CCrc32::ComputeLowercase(szName);
  1186.         return GetIndexByNameCRC(nameCRC);
  1187. }
  1188.  
  1189. IAttachment* CAttachmentManager::GetInterfaceByNameCRC(uint32 nameCRC) const
  1190. {
  1191.         int32 idx = GetIndexByNameCRC(nameCRC);
  1192.         if (idx == -1) return 0;
  1193.         return GetInterfaceByIndex(idx);
  1194. };
  1195.  
  1196. int32 CAttachmentManager::GetIndexByNameCRC(uint32 nameCRC) const
  1197. {
  1198.         const int32 num = GetAttachmentCount();
  1199.         for (int32 i = 0; i < num; i++)
  1200.         {
  1201.                 const IAttachment* pA = m_arrAttachments[i];
  1202.                 if (pA->GetNameCRC() == nameCRC)
  1203.                         return i;
  1204.         }
  1205.         return -1;
  1206. }
  1207.  
  1208. IAttachment* CAttachmentManager::GetInterfaceByPhysId(int id) const
  1209. {
  1210.         if ((id -= m_pSkelInstance->m_pDefaultSkeleton->GetJointCount()) < 0)
  1211.                 return 0;
  1212.         for (int i = GetAttachmentCount() - 1; i >= 0; i--)
  1213.         {
  1214.                 if ((m_arrAttachments[i]->GetFlags() & FLAGS_ATTACH_ID_MASK) >> idbit == id)
  1215.                         return GetInterfaceByIndex(i);
  1216.         }
  1217.         return 0;
  1218. }
  1219.  
  1220. bool CAttachmentManager::NeedsHierarchicalUpdate()
  1221. {
  1222.         const uint32 numAttachments = GetAttachmentCount();
  1223.         for (uint32 i = 0; i < numAttachments; i++)
  1224.         {
  1225.                 IAttachmentObject* pIAttachmentObject = m_arrAttachments[i]->GetIAttachmentObject();
  1226.                 if (pIAttachmentObject == 0)
  1227.                         continue;
  1228.  
  1229.                 ICharacterInstance* pICharacterInstance = pIAttachmentObject->GetICharacterInstance();
  1230.                 if (pICharacterInstance == 0)
  1231.                         continue;
  1232.  
  1233.                 IAnimationSet* pIAnimationSet = pICharacterInstance->GetIAnimationSet();
  1234.                 uint32 numAnimations = pIAnimationSet->GetAnimationCount();
  1235.                 if (numAnimations == 0)
  1236.                         continue;
  1237.  
  1238.                 ISkeletonAnim* pISkeletonAnim = pICharacterInstance->GetISkeletonAnim();
  1239.                 uint32 numAnims = 0;
  1240.                 for (uint32 l = 0; l < numVIRTUALLAYERS; l++)
  1241.                 {
  1242.                         numAnims += pISkeletonAnim->GetNumAnimsInFIFO(l);
  1243.                 }
  1244.                 if (numAnims)
  1245.                         return 1;
  1246.         }
  1247.  
  1248.         return 0;
  1249. }
  1250.  
  1251. void CAttachmentManager::UpdateAllRemapTables()
  1252. {
  1253.         if (m_TypeSortingRequired)
  1254.                 SortByType();
  1255.  
  1256.         for (uint32 r = 0; r < m_sortedRanges[eRange_BoneExecuteUnsafe].end; r++)
  1257.         {
  1258.                 IAttachment* pIAttachment = m_arrAttachments[r];
  1259.                 CAttachmentBONE* pCAttachmentBone = (CAttachmentBONE*)pIAttachment;
  1260.                 pCAttachmentBone->m_nJointID = -1;   //request re-projection
  1261.                 pCAttachmentBone->m_Simulation.m_arrChildren.resize(0);
  1262.         }
  1263.         uint32 x = FLAGS_ATTACH_PROJECTED ^ -1;
  1264.         for (uint32 i = m_sortedRanges[0].begin; i < m_sortedRanges[eRange_SkinMesh].end; i++)
  1265.         {
  1266.                 m_arrAttachments[i]->SetFlags(m_arrAttachments[i]->GetFlags() & x);
  1267.         }
  1268.         for (uint32 i = m_sortedRanges[eRange_SkinMesh].begin; i < m_sortedRanges[eRange_SkinMesh].end; i++)
  1269.         {
  1270.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1271.                 CAttachmentSKIN* pCAttachmentSkin = (CAttachmentSKIN*)pIAttachment;
  1272.                 pCAttachmentSkin->UpdateRemapTable();
  1273.         }
  1274. }
  1275.  
  1276. void CAttachmentManager::VerifyProxyLinks()
  1277. {
  1278.         //verify and re-adjust proxy links
  1279.         uint32 numAttachmnets = GetAttachmentCount();
  1280.         for (uint32 a = 0; a < numAttachmnets; a++)
  1281.         {
  1282.                 IAttachment* pIAttachment = GetInterfaceByIndex(a);
  1283.  
  1284.                 if (pIAttachment->GetType() == CA_BONE)
  1285.                 {
  1286.                         CAttachmentBONE* pCAttachmentBone = (CAttachmentBONE*)pIAttachment;
  1287.                         uint32 numUsedProxies = pCAttachmentBone->m_Simulation.m_arrProxyNames.size();
  1288.                         if (numUsedProxies == 0)
  1289.                                 continue;
  1290.  
  1291.                         string arrProxyNames[100];
  1292.                         for (uint32 p = 0; p < numUsedProxies; p++)
  1293.                         {
  1294.                                 arrProxyNames[p] = pCAttachmentBone->m_Simulation.m_arrProxyNames[p].c_str();
  1295.                         }
  1296.  
  1297.                         pCAttachmentBone->m_Simulation.m_arrProxyNames.resize(0);
  1298.                         pCAttachmentBone->m_Simulation.m_arrProxyIndex.resize(0);
  1299.                         uint32 numAllProxies = m_arrProxies.size();
  1300.                         for (uint32 crc = 0; crc < numUsedProxies; crc++)
  1301.                         {
  1302.                                 uint32 nCRC32lower = CCrc32::ComputeLowercase(arrProxyNames[crc].c_str());
  1303.                                 for (uint32 p = 0; p < numAllProxies; p++)
  1304.                                 {
  1305.                                         if (nCRC32lower == m_arrProxies[p].m_nProxyCRC32)
  1306.                                         {
  1307.                                                 pCAttachmentBone->m_Simulation.m_arrProxyNames.push_back(CCryName(arrProxyNames[crc]));
  1308.                                                 pCAttachmentBone->m_Simulation.m_arrProxyIndex.push_back(p);
  1309.                                                 break;
  1310.                                         }
  1311.                                 }
  1312.                         }
  1313.                 }
  1314.  
  1315.                 if (pIAttachment->GetType() == CA_FACE)
  1316.                 {
  1317.                         CAttachmentFACE* pCAttachmentFace = (CAttachmentFACE*)pIAttachment;
  1318.                         uint32 numUsedProxies = pCAttachmentFace->m_Simulation.m_arrProxyNames.size();
  1319.                         if (numUsedProxies == 0)
  1320.                                 continue;
  1321.  
  1322.                         string arrProxyNames[100];
  1323.                         for (uint32 p = 0; p < numUsedProxies; p++)
  1324.                         {
  1325.                                 arrProxyNames[p] = pCAttachmentFace->m_Simulation.m_arrProxyNames[p].c_str();
  1326.                         }
  1327.  
  1328.                         pCAttachmentFace->m_Simulation.m_arrProxyNames.resize(0);
  1329.                         pCAttachmentFace->m_Simulation.m_arrProxyIndex.resize(0);
  1330.                         uint32 numAllProxies = m_arrProxies.size();
  1331.                         for (uint32 crc = 0; crc < numUsedProxies; crc++)
  1332.                         {
  1333.                                 uint32 nCRC32lower = CCrc32::ComputeLowercase(arrProxyNames[crc].c_str());
  1334.                                 for (uint32 p = 0; p < numAllProxies; p++)
  1335.                                 {
  1336.                                         if (nCRC32lower == m_arrProxies[p].m_nProxyCRC32)
  1337.                                         {
  1338.                                                 pCAttachmentFace->m_Simulation.m_arrProxyNames.push_back(CCryName(arrProxyNames[crc]));
  1339.                                                 pCAttachmentFace->m_Simulation.m_arrProxyIndex.push_back(p);
  1340.                                                 break;
  1341.                                         }
  1342.                                 }
  1343.                         }
  1344.                 }
  1345.  
  1346.         }
  1347.  
  1348.         const CDefaultSkeleton& rDefaultSkeleton = *m_pSkelInstance->m_pDefaultSkeleton;
  1349.         uint32 numProxies = m_arrProxies.size();
  1350.         for (uint32 i = 0; i < numProxies; i++)
  1351.         {
  1352.                 const char* strJointName = m_arrProxies[i].m_strJointName.c_str();
  1353.                 int16 nJointID = rDefaultSkeleton.GetJointIDByName(strJointName);
  1354.                 if (nJointID < 0)
  1355.                 {
  1356.                         CryWarning(VALIDATOR_MODULE_ANIMATION, VALIDATOR_ERROR, "CryAnimation: Proxy '%s' specified wrong joint name '%s'", m_arrProxies[i].m_strProxyName.c_str(), strJointName);
  1357.                         m_arrProxies.erase(m_arrProxies.begin() + i);
  1358.                         numProxies = m_arrProxies.size();
  1359.                         --i;
  1360.                         continue;
  1361.                 }
  1362.                 m_arrProxies[i].m_nJointID = nJointID;
  1363.                 QuatT jointQT = rDefaultSkeleton.GetDefaultAbsJointByID(nJointID);
  1364.                 m_arrProxies[i].m_ProxyRelativeDefault = jointQT.GetInverted() * m_arrProxies[i].m_ProxyAbsoluteDefault;
  1365.         }
  1366. }
  1367.  
  1368. void CAttachmentManager::PrepareAllRedirectedTransformations(Skeleton::CPoseData& rPoseData)
  1369. {
  1370.         const f32 fIPlaybackScale = m_pSkelInstance->GetPlaybackScale();
  1371.         const f32 fLPlaybackScale = m_pSkelInstance->m_SkeletonAnim.GetLayerPlaybackScale(0);
  1372.         const f32 fAverageFrameTime = g_AverageFrameTime * fIPlaybackScale * fLPlaybackScale ? g_AverageFrameTime * fIPlaybackScale * fLPlaybackScale : g_AverageFrameTime;
  1373.         m_fTurbulenceGlobal += gf_PI * fAverageFrameTime, m_fTurbulenceLocal = 0;
  1374.  
  1375.         DEFINE_PROFILER_FUNCTION();
  1376.         const QuatTS& rPhysLocation = m_pSkelInstance->m_location;
  1377.         uint32 nproxies = m_arrProxies.size();
  1378.         for (uint32 i = 0; i < nproxies; i++)
  1379.         {
  1380.                 int idx = m_arrProxies[i].m_nJointID;
  1381.                 m_arrProxies[i].m_ProxyModelRelative = rPoseData.GetJointAbsolute(idx) * m_arrProxies[i].m_ProxyRelativeDefault;
  1382. #ifndef _RELEASE
  1383.                 if (m_pSkelInstance->m_CharEditMode == 3)
  1384.                 {
  1385.                         const Vec3 pos = rPoseData.GetJointAbsolute(idx).t;
  1386.                         g_pAuxGeom->DrawLine(rPhysLocation * pos, RGBA8(0xff, 0x00, 0x00, 0xff), rPhysLocation * m_arrProxies[i].m_ProxyModelRelative.t, RGBA8(0x00, 0xff, 0x00, 0xff));
  1387.                 }
  1388. #endif
  1389.         }
  1390.  
  1391. #ifdef EDITOR_PCDEBUGCODE
  1392.         if (m_nDrawProxies)
  1393.         {
  1394.                 for (uint32 i = 0; i < nproxies; i++)
  1395.                 {
  1396.                         QuatTS wlocation = rPhysLocation * m_arrProxies[i].m_ProxyModelRelative;
  1397.                         if (m_nDrawProxies & 2 && m_arrProxies[i].m_nHideProxy == 0 && m_arrProxies[i].m_nPurpose == 0)
  1398.                                 m_arrProxies[i].Draw(wlocation, RGBA8(0xe7, 0xc0, 0xbc, 0xff), 16, m_pSkelInstance->m_Viewdir);
  1399.                         if (m_nDrawProxies & 4 && m_arrProxies[i].m_nHideProxy == 0 && m_arrProxies[i].m_nPurpose == 1)
  1400.                                 m_arrProxies[i].Draw(wlocation, RGBA8(0xa0, 0xe7, 0x80, 0xff), 16, m_pSkelInstance->m_Viewdir);
  1401.                         if (m_nDrawProxies & 8 && m_arrProxies[i].m_nHideProxy == 0 && m_arrProxies[i].m_nPurpose == 2)
  1402.                                 m_arrProxies[i].Draw(wlocation, RGBA8(0xff, 0xa0, 0x80, 0xff), 16, m_pSkelInstance->m_Viewdir);
  1403.                 }
  1404.         }
  1405. #endif
  1406.  
  1407. #ifdef EDITOR_PCDEBUGCODE
  1408.         //Verification();
  1409. #endif
  1410. }
  1411.  
  1412. void CAttachmentManager::GenerateProxyModelRelativeTransformations(Skeleton::CPoseData& rPoseData)
  1413. {
  1414.         const QuatTS& rPhysLocation = m_pSkelInstance->m_location;
  1415.         uint32 nproxies = m_arrProxies.size();
  1416.         for (uint32 i = 0; i < nproxies; i++)
  1417.         {
  1418.                 m_arrProxies[i].m_ProxyModelRelativePrev = m_arrProxies[i].m_ProxyModelRelative;
  1419.                 m_arrProxies[i].m_ProxyModelRelativePrev.q.Normalize();
  1420.         }
  1421. }
  1422.  
  1423. void CAttachmentManager::CreateCommands(Command::CBuffer& buffer)
  1424. {
  1425.         if (m_TypeSortingRequired)
  1426.                 SortByType();
  1427.  
  1428.         buffer.CreateCommand<Command::PrepareAllRedirectedTransformations>();
  1429.  
  1430.         uint32 m = GetRedirectedJointCount();
  1431.         for (uint32 i = 0; i < m; i++)
  1432.         {
  1433.                 Command::UpdateRedirectedJoint* cmd = buffer.CreateCommand<Command::UpdateRedirectedJoint>();
  1434.                 cmd->m_attachmentBone = static_cast<CAttachmentBONE*>(m_arrAttachments[i].get());
  1435.         }
  1436.  
  1437.         buffer.CreateCommand<Command::GenerateProxyModelRelativeTransformations>();
  1438.  
  1439.         for (uint32 i = m_sortedRanges[eRange_VertexClothOrPendulumRow].begin; i < m_sortedRanges[eRange_VertexClothOrPendulumRow].end; i++)
  1440.         {
  1441.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1442.                 if (pIAttachment->GetType() != CA_PROW)
  1443.                         continue;
  1444.                 Command::UpdatePendulumRow* cmd = buffer.CreateCommand<Command::UpdatePendulumRow>();
  1445.                 cmd->m_attachmentPendulumRow = static_cast<CAttachmentPROW*>(pIAttachment);
  1446.         }
  1447. }
  1448.  
  1449. int CAttachmentManager::GenerateAttachedInstanceContexts()
  1450. {
  1451.         if (m_TypeSortingRequired)
  1452.                 SortByType();
  1453.  
  1454.         auto& sc = g_pCharacterManager->GetContextSyncQueue();
  1455.  
  1456.         int result = 0;
  1457.  
  1458.         uint32 m =
  1459.           m_sortedRanges[eRange_BoneExecuteUnsafe].end - m_sortedRanges[eRange_BoneExecute].begin;
  1460.  
  1461.         for (uint32 i = m_sortedRanges[eRange_BoneExecute].begin;
  1462.              i < m_sortedRanges[eRange_BoneExecuteUnsafe].end; i++)
  1463.         {
  1464.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1465.                 CAttachmentBONE* pCAttachmentBone = static_cast<CAttachmentBONE*>(pIAttachment);
  1466.                 if (pCAttachmentBone->m_nJointID < 0)
  1467.                         continue;
  1468.                 IAttachmentObject* pIAttachmentObject = pCAttachmentBone->m_pIAttachmentObject;
  1469.                 CRY_ASSERT(pIAttachmentObject != nullptr);
  1470.                 if (pIAttachmentObject->GetAttachmentType() == IAttachmentObject::eAttachment_Skeleton)
  1471.                 {
  1472.                         CCharInstance* pChildInstance =
  1473.                           static_cast<CCharInstance*>(pIAttachmentObject->GetICharacterInstance());
  1474.                         if (pChildInstance)
  1475.                         {
  1476.                                 CharacterInstanceProcessing::CContextQueue& queue = g_pCharacterManager->GetContextSyncQueue();
  1477.                                 CharacterInstanceProcessing::SContext& ctx = queue.AppendContext();
  1478.                                 result += 1;
  1479.                                 int numChildren = pChildInstance->m_AttachmentManager.GenerateAttachedInstanceContexts();
  1480.                                 result += numChildren;
  1481.                                 ctx.Initialize(pChildInstance, pCAttachmentBone, m_pSkelInstance, numChildren);
  1482.                         }
  1483.                 }
  1484.         }
  1485.         return result;
  1486. }
  1487.  
  1488. void CAttachmentManager::UpdateLocationsExceptExecute(Skeleton::CPoseData& rPoseData)
  1489. {
  1490.         if (m_TypeSortingRequired)
  1491.                 SortByType();
  1492.  
  1493.         for (uint32 i = m_sortedRanges[eRange_BoneEmpty].begin; i < m_sortedRanges[eRange_BoneEmpty].end; i++)
  1494.         {
  1495.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1496.                 CAttachmentBONE* pCAttachmentBone = (CAttachmentBONE*)pIAttachment;
  1497.                 pCAttachmentBone->Update_Empty(rPoseData);
  1498.         }
  1499.         for (uint32 i = m_sortedRanges[eRange_BoneStatic].begin; i < m_sortedRanges[eRange_BoneStatic].end; i++)
  1500.         {
  1501.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1502.                 CAttachmentBONE* pCAttachmentBone = (CAttachmentBONE*)pIAttachment;
  1503.                 pCAttachmentBone->Update_Static(rPoseData);
  1504.         }
  1505.  
  1506.         if (m_pSkelInstance->GetAnimationLOD() < 1)
  1507.         {
  1508.                 for (uint32 i = m_sortedRanges[eRange_FaceEmpty].begin; i < m_sortedRanges[eRange_FaceEmpty].end; i++)
  1509.                 {
  1510.                         IAttachment* pIAttachment = m_arrAttachments[i];
  1511.                         CAttachmentFACE* pCAttachmentFace = (CAttachmentFACE*)pIAttachment;
  1512.                         pCAttachmentFace->Update_Empty(rPoseData);
  1513.                 }
  1514.         }
  1515.  
  1516.         for (uint32 i = m_sortedRanges[eRange_FaceStatic].begin; i < m_sortedRanges[eRange_FaceStatic].end; i++)
  1517.         {
  1518.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1519.                 CAttachmentFACE* pCAttachmentFace = (CAttachmentFACE*)pIAttachment;
  1520.                 pCAttachmentFace->Update_Static(rPoseData);
  1521.         }
  1522. }
  1523.  
  1524. void CAttachmentManager::UpdateLocationsExecute(Skeleton::CPoseData& rPoseData)
  1525. {
  1526.         if (m_TypeSortingRequired)
  1527.                 SortByType();
  1528.  
  1529.         for (uint32 i = m_sortedRanges[eRange_BoneExecute].begin; i < m_sortedRanges[eRange_BoneExecute].end; i++)
  1530.         {
  1531.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1532.                 CAttachmentBONE* pCAttachmentBone = static_cast<CAttachmentBONE*>(pIAttachment);
  1533.                 pCAttachmentBone->Update_Execute(rPoseData);
  1534.         }
  1535.  
  1536.         for (uint32 i = m_sortedRanges[eRange_FaceExecute].begin; i < m_sortedRanges[eRange_FaceExecute].end; i++)
  1537.         {
  1538.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1539.                 CAttachmentFACE* pCAttachmentFace = (CAttachmentFACE*)pIAttachment;
  1540.                 pCAttachmentFace->Update_Execute(rPoseData);
  1541.         }
  1542. }
  1543.  
  1544. void CAttachmentManager::UpdateLocationsExecuteUnsafe(Skeleton::CPoseData& rPoseData)
  1545. {
  1546.         if (m_TypeSortingRequired)
  1547.                 SortByType();
  1548.  
  1549.         for (uint32 i = m_sortedRanges[eRange_BoneExecuteUnsafe].begin; i < m_sortedRanges[eRange_BoneExecuteUnsafe].end; i++)
  1550.         {
  1551.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1552.                 CAttachmentBONE* pCAttachmentBone = (CAttachmentBONE*)pIAttachment;
  1553.                 pCAttachmentBone->Update_Execute(rPoseData);
  1554.         }
  1555.  
  1556.         for (uint32 i = m_sortedRanges[eRange_FaceExecuteUnsafe].begin; i < m_sortedRanges[eRange_FaceExecuteUnsafe].end; i++)
  1557.         {
  1558.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1559.                 CAttachmentFACE* pCAttachmentFace = (CAttachmentFACE*)pIAttachment;
  1560.                 pCAttachmentFace->Update_Execute(rPoseData);
  1561.         }
  1562.  
  1563. }
  1564.  
  1565. uint32 CAttachmentManager::RemoveAllAttachments()
  1566. {
  1567.         uint32 counter = GetAttachmentCount();
  1568.         for (uint32 i = 0; i < counter; i++)
  1569.         {
  1570.                 m_arrAttachments[i]->ClearBinding(CA_SkipSkelRecreation);
  1571.         }
  1572.         for (uint32 i = counter; i > 0; i--)
  1573.         {
  1574.                 RemoveAttachmentByIndex(i - 1);
  1575.         }
  1576.         return 1;
  1577. }
  1578.  
  1579. void CAttachmentManager::Serialize(TSerialize ser)
  1580. {
  1581.         if (ser.GetSerializationTarget() != eST_Network)
  1582.         {
  1583.                 ser.BeginGroup("CAttachmentManager");
  1584.                 int32 numAttachments = GetAttachmentCount();
  1585.                 for (int32 i = 0; i < numAttachments; i++)
  1586.                 {
  1587.                         GetInterfaceByIndex(i)->Serialize(ser);
  1588.                 }
  1589.                 ser.EndGroup();
  1590.         }
  1591. }
  1592.  
  1593. #if !defined(_RELEASE)
  1594. void VisualizeEmptySocket(const Matrix34& WorldMat34, const QuatT& rAttModelRelative, ColorB col)
  1595. {
  1596.         g_pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags);
  1597.         Matrix34 FinalMat34 = WorldMat34 * Matrix34(rAttModelRelative);
  1598.         Vec3 pos = FinalMat34.GetTranslation();
  1599.         static Ang3 angle1(0, 0, 0);
  1600.         static Ang3 angle2(0, 0, 0);
  1601.         static Ang3 angle3(0, 0, 0);
  1602.         angle1 += Ang3(0.01f, +0.02f, +0.03f);
  1603.         angle2 -= Ang3(0.01f, -0.02f, -0.03f);
  1604.         angle3 += Ang3(0.03f, -0.02f, +0.01f);
  1605.  
  1606.         AABB aabb1 = AABB(Vec3(-0.05f, -0.05f, -0.05f), Vec3(+0.05f, +0.05f, +0.05f));
  1607.         AABB aabb2 = AABB(Vec3(-0.005f, -0.005f, -0.005f), Vec3(+0.005f, +0.005f, +0.005f));
  1608.  
  1609.         Matrix33 m33;
  1610.         OBB obb;
  1611.         m33 = Matrix33::CreateRotationXYZ(angle1);
  1612.         obb = OBB::CreateOBBfromAABB(m33, aabb1);
  1613.         g_pAuxGeom->DrawOBB(obb, pos, 0, col, eBBD_Extremes_Color_Encoded);
  1614.         obb = OBB::CreateOBBfromAABB(m33, aabb1);
  1615.         g_pAuxGeom->DrawOBB(obb, pos, 0, col, eBBD_Extremes_Color_Encoded);
  1616.  
  1617.         m33 = Matrix33::CreateRotationXYZ(angle2);
  1618.         obb = OBB::CreateOBBfromAABB(m33, aabb1);
  1619.         g_pAuxGeom->DrawOBB(obb, pos, 0, col, eBBD_Extremes_Color_Encoded);
  1620.         obb = OBB::CreateOBBfromAABB(m33, aabb2);
  1621.         g_pAuxGeom->DrawOBB(obb, pos, 0, col, eBBD_Extremes_Color_Encoded);
  1622.  
  1623.         m33 = Matrix33::CreateRotationXYZ(angle3);
  1624.         obb = OBB::CreateOBBfromAABB(m33, aabb1);
  1625.         g_pAuxGeom->DrawOBB(obb, pos, 0, col, eBBD_Extremes_Color_Encoded);
  1626.         obb = OBB::CreateOBBfromAABB(m33, aabb2);
  1627.         g_pAuxGeom->DrawOBB(obb, pos, 0, col, eBBD_Extremes_Color_Encoded);
  1628.  
  1629.         obb = OBB::CreateOBBfromAABB(rAttModelRelative.q, aabb1);
  1630.         g_pAuxGeom->DrawOBB(obb, pos, 0, RGBA8(0xff, 0xff, 0xff, 0xff), eBBD_Extremes_Color_Encoded);
  1631. }
  1632. #endif
  1633.  
  1634. void CAttachmentManager::DrawAttachments(SRendParams& rParams, const Matrix34& rWorldMat34, const SRenderingPassInfo& passInfo, const f32 fZoomFactor, const f32 fZoomDistanceSq)
  1635. {
  1636. #ifdef DEFINE_PROFILER_FUNCTION
  1637.         DEFINE_PROFILER_FUNCTION();
  1638. #endif
  1639.         const uint32 numAttachments = m_arrAttachments.size();
  1640.         if (numAttachments == 0)
  1641.                 return;
  1642.  
  1643.         if (m_TypeSortingRequired)
  1644.                 SortByType();
  1645.  
  1646. #if !defined(_RELEASE)
  1647.         g_pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags);
  1648.         if (Console::GetInst().ca_DrawAttachments == 0)
  1649.                 return;
  1650. #endif
  1651.  
  1652.         uint32 InRecursion = passInfo.IsRecursivePass();
  1653.         const bool InShadow = passInfo.IsShadowPass();
  1654.  
  1655.         //Only save the zoom sq distance if not called from recursive render call
  1656.         //this is because zoom sq distance is used to cull attachments and zoom is modified for recursive calls (see e_RecursionViewDistRatio)
  1657.         if (InRecursion == 0)
  1658.                 m_fZoomDistanceSq = fZoomDistanceSq;
  1659.  
  1660.         uint32 uHideFlags = 0;
  1661.         if (InRecursion > 1)
  1662.                 uHideFlags |= FLAGS_ATTACH_HIDE_RECURSION;
  1663.         else if (InShadow)
  1664.                 uHideFlags |= FLAGS_ATTACH_HIDE_SHADOW_PASS;
  1665.         else
  1666.                 uHideFlags |= FLAGS_ATTACH_HIDE_MAIN_PASS;
  1667.  
  1668.         if (m_numRedirectionWithAttachment)
  1669.         {
  1670.                 for (uint32 i = 0; i < m_sortedRanges[eRange_BoneRedirect].end; i++)
  1671.                 {
  1672.                         IAttachment* pIAttachment = m_arrAttachments[i];
  1673.                         CAttachmentBONE* pCAttachmentBone = (CAttachmentBONE*)pIAttachment;
  1674.                         IAttachmentObject* pIAttachmentObject = pCAttachmentBone->m_pIAttachmentObject;
  1675.                         if (pIAttachmentObject == 0)
  1676.                                 continue;              //most likely all of them are 0
  1677.                         if (pCAttachmentBone->m_AttFlags & uHideFlags)
  1678.                                 continue;
  1679.                         if (pCAttachmentBone->m_nJointID < 0)
  1680.                                 continue;              //No success! Maybe next time
  1681.                         Matrix34 FinalMat34 = rWorldMat34 * Matrix34(pCAttachmentBone->m_AttModelRelative * pCAttachmentBone->m_addTransformation);
  1682.                         rParams.pMatrix = &FinalMat34;
  1683.                         pIAttachmentObject->RenderAttachment(rParams, passInfo);
  1684.                 }
  1685.         }
  1686.         const bool bDrawMergedAttachments = Console::GetInst().ca_DrawAttachmentsMergedForShadows != 0;
  1687.  
  1688.         for (uint32 i = m_sortedRanges[eRange_BoneStatic].begin; i < m_sortedRanges[eRange_BoneExecuteUnsafe].end; i++)
  1689.         {
  1690.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1691.                 CAttachmentBONE* pCAttachmentBone = (CAttachmentBONE*)pIAttachment;
  1692.                 if (pCAttachmentBone->m_AttFlags & uHideFlags)
  1693.                         continue;
  1694.                 if (pCAttachmentBone->m_nJointID < 0)
  1695.                         continue;                //No success! Maybe next time
  1696.                 if (bDrawMergedAttachments && (pIAttachment->GetFlags() & FLAGS_ATTACH_MERGED_FOR_SHADOWS) && (passInfo.IsShadowPass()))
  1697.                         continue;
  1698.                 if (!(rParams.nCustomFlags & COB_POST_3D_RENDER) && (pCAttachmentBone->m_AttFlags & FLAGS_ATTACH_VISIBLE) == 0)
  1699.                         continue;
  1700.                 Matrix34 FinalMat34 = rWorldMat34 * Matrix34(pCAttachmentBone->m_AttModelRelative * pCAttachmentBone->m_addTransformation);
  1701.                 rParams.pMatrix = &FinalMat34;
  1702.                 pCAttachmentBone->m_pIAttachmentObject->RenderAttachment(rParams, passInfo);
  1703.         }
  1704.         for (uint32 i = m_sortedRanges[eRange_FaceStatic].begin; i < m_sortedRanges[eRange_FaceExecute].end; i++)
  1705.         {
  1706.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1707.                 CAttachmentFACE* pCAttachmentFace = (CAttachmentFACE*)pIAttachment;
  1708.                 if (pCAttachmentFace->m_AttFlags & uHideFlags)
  1709.                         continue;
  1710.                 if ((pCAttachmentFace->m_AttFlags & FLAGS_ATTACH_PROJECTED) == 0)
  1711.                         continue;                //no success! maybe next time
  1712.                 if (bDrawMergedAttachments && (pIAttachment->GetFlags() & FLAGS_ATTACH_MERGED_FOR_SHADOWS) && (passInfo.IsShadowPass()))
  1713.                         continue;
  1714.                 if (!(rParams.nCustomFlags & COB_POST_3D_RENDER) && (pCAttachmentFace->m_AttFlags & FLAGS_ATTACH_VISIBLE) == 0)
  1715.                         continue;                //Distance culling. Object is too small for rendering
  1716.                 Matrix34 FinalMat34 = rWorldMat34 * Matrix34(pCAttachmentFace->m_AttModelRelative * pCAttachmentFace->m_addTransformation);
  1717.                 rParams.pMatrix = &FinalMat34;
  1718.                 pCAttachmentFace->m_pIAttachmentObject->RenderAttachment(rParams, passInfo);
  1719.         }
  1720.  
  1721. #if !defined(_RELEASE)
  1722.         // for debugdrawing - drawOffset prevents attachments from overdrawing each other, drawScale helps scaling depending on attachment count
  1723.         // used for Skin and Cloth Attachments for now
  1724.         static ICVar* p_e_debug_draw = gEnv->pConsole->GetCVar("e_DebugDraw");
  1725.         float drawOffset = 0.0f;
  1726.         float debugDrawScale = 1.0f;
  1727.  
  1728.         if (p_e_debug_draw->GetIVal() == 20)
  1729.         {
  1730.                 int attachmentCount = m_sortedRanges[eRange_SkinMesh].GetNumElements();
  1731.                 attachmentCount += m_sortedRanges[eRange_VertexClothOrPendulumRow].GetNumElements();
  1732.                 debugDrawScale = 0.5f + (10.0f / max(1.0f, (float)attachmentCount));
  1733.                 debugDrawScale = min(debugDrawScale, 1.5f);
  1734.         }
  1735. #endif
  1736.  
  1737.         for (uint32 i = m_sortedRanges[eRange_SkinMesh].begin; i < m_sortedRanges[eRange_SkinMesh].end; i++)
  1738.         {
  1739.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1740.                 CAttachmentSKIN* pCAttachmentSkin = (CAttachmentSKIN*)pIAttachment;
  1741.                 if (pCAttachmentSkin->m_AttFlags & uHideFlags)
  1742.                         continue;
  1743.                 if (bDrawMergedAttachments && (pIAttachment->GetFlags() & FLAGS_ATTACH_MERGED_FOR_SHADOWS) && passInfo.IsShadowPass())
  1744.                         continue;
  1745.                 if (pCAttachmentSkin->m_pIAttachmentObject == 0)
  1746.                         continue;
  1747.                 uint32 nDrawModel = m_pSkelInstance->m_rpFlags & CS_FLAG_DRAW_MODEL;
  1748.                 if (nDrawModel == 0)
  1749.                         continue;
  1750.                 const f32 fRadiusSqr = m_pSkelInstance->m_SkeletonPose.GetAABB().GetRadiusSqr();
  1751.                 if (fRadiusSqr == 0.0f)
  1752.                         continue;  //if radius is zero, then the object is most probably not visible and we can continue
  1753.                 if (!(rParams.nCustomFlags & COB_POST_3D_RENDER) && fZoomDistanceSq > fRadiusSqr)
  1754.                         continue;  //too small to render. cancel the update
  1755.                 pCAttachmentSkin->DrawAttachment(rParams, passInfo, rWorldMat34, fZoomFactor);
  1756.  
  1757. #if !defined(_RELEASE)
  1758.                 // pMaterial is set to NULL above, but restored in DrawAttachment with correct material
  1759.                 if (p_e_debug_draw->GetIVal() == 20)
  1760.                 {
  1761.                         Vec3 drawLoc = rWorldMat34.GetTranslation();
  1762.                         drawLoc.z += drawOffset;
  1763.                         drawOffset += DebugDrawAttachment(pCAttachmentSkin, pCAttachmentSkin->GetISkin(), drawLoc, rParams.pMaterial, debugDrawScale);
  1764.                 }
  1765. #endif
  1766.         }
  1767.  
  1768.         for (uint32 i = m_sortedRanges[eRange_VertexClothOrPendulumRow].begin; i < m_sortedRanges[eRange_VertexClothOrPendulumRow].end; i++)
  1769.         {
  1770.                 IAttachment* pIAttachment = m_arrAttachments[i];
  1771.                 if (pIAttachment->GetType() != CA_VCLOTH)
  1772.                         continue;
  1773.                 CAttachmentVCLOTH* pCAttachmentVCloth = (CAttachmentVCLOTH*)pIAttachment;
  1774.                 if (pCAttachmentVCloth->m_AttFlags & uHideFlags)
  1775.                         continue;
  1776.                 if (pCAttachmentVCloth->m_pIAttachmentObject == 0)
  1777.                         continue;
  1778.                 uint32 nDrawModel = m_pSkelInstance->m_rpFlags & CS_FLAG_DRAW_MODEL;
  1779.                 if (nDrawModel == 0)
  1780.                         continue;
  1781.                 const f32 fRadiusSqr = m_pSkelInstance->m_SkeletonPose.GetAABB().GetRadiusSqr();
  1782.                 if (fRadiusSqr == 0.0f)
  1783.                         continue;   //if radius is zero, then the object is most probably not visible and we can continue
  1784.                 if (!(rParams.nCustomFlags & COB_POST_3D_RENDER) && fZoomDistanceSq > fRadiusSqr)
  1785.                         continue;   //too small to render. cancel the update
  1786.  
  1787.                 pCAttachmentVCloth->InitializeCloth();
  1788.                 pCAttachmentVCloth->DrawAttachment(rParams, passInfo, rWorldMat34, fZoomFactor);
  1789.  
  1790. #if !defined(_RELEASE)
  1791.                 if (p_e_debug_draw->GetIVal() == 20)
  1792.                 {
  1793.                         Vec3 drawLoc = rWorldMat34.GetTranslation();
  1794.                         drawLoc.z += drawOffset;
  1795.                         drawOffset += DebugDrawAttachment(pCAttachmentVCloth, pCAttachmentVCloth->GetISkin(), drawLoc, rParams.pMaterial, debugDrawScale);
  1796.                 }
  1797. #endif
  1798.         }
  1799.  
  1800. #if !defined(_RELEASE)
  1801.         if (Console::GetInst().ca_DrawEmptyAttachments)
  1802.         {
  1803.                 for (uint32 i = m_sortedRanges[eRange_BoneEmpty].begin; i < m_sortedRanges[eRange_BoneEmpty].end; i++)
  1804.                 {
  1805.                         IAttachment* pIAttachment = m_arrAttachments[i];
  1806.                         CAttachmentBONE* pCAttachmentBone = (CAttachmentBONE*)pIAttachment;
  1807.                         if (pCAttachmentBone->m_AttFlags & uHideFlags)
  1808.                                 continue;
  1809.                         if (pCAttachmentBone->m_nJointID < 0)
  1810.                                 return;                                               //no success! maybe next time
  1811.                         VisualizeEmptySocket(rWorldMat34, QuatT(pCAttachmentBone->m_AttModelRelative.q, pCAttachmentBone->m_AttModelRelative.t), RGBA8(0xff, 0x00, 0x1f, 0xff));
  1812.                 }
  1813.                 for (uint32 i = m_sortedRanges[eRange_FaceEmpty].begin; i < m_sortedRanges[eRange_FaceEmpty].end; i++)
  1814.                 {
  1815.                         IAttachment* pIAttachment = m_arrAttachments[i];
  1816.                         CAttachmentFACE* pCAttachmentFace = (CAttachmentFACE*)pIAttachment;
  1817.                         if (pCAttachmentFace->m_AttFlags & uHideFlags)
  1818.                                 continue;
  1819.                         if ((pCAttachmentFace->m_AttFlags & FLAGS_ATTACH_PROJECTED) == 0)
  1820.                                 return;                                               //no success! maybe next time
  1821.                         VisualizeEmptySocket(rWorldMat34, pCAttachmentFace->m_AttModelRelative, RGBA8(0x1f, 0x00, 0xff, 0xff));
  1822.                 }
  1823.         }
  1824.  
  1825.         if (Console::GetInst().ca_DrawAttachmentOBB)
  1826.         {
  1827.                 g_pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags);
  1828.                 for (uint32 i = m_sortedRanges[eRange_BoneStatic].begin; i < m_sortedRanges[eRange_BoneExecuteUnsafe].end; i++)
  1829.                 {
  1830.                         IAttachment* pIAttachment = m_arrAttachments[i];
  1831.                         CAttachmentBONE* pCAttachmentBone = (CAttachmentBONE*)pIAttachment;
  1832.                         if (pCAttachmentBone->m_AttFlags & uHideFlags)
  1833.                                 continue;
  1834.                         if (pCAttachmentBone->m_nJointID < 0)
  1835.                                 continue;                                             //no success! maybe next time
  1836.                         if (!(rParams.nCustomFlags & COB_POST_3D_RENDER) && (pCAttachmentBone->m_AttFlags & FLAGS_ATTACH_VISIBLE) == 0)
  1837.                                 continue;                                             //Distance culling. Object is too small for rendering
  1838.                         Matrix34 FinalMat34 = rWorldMat34 * Matrix34(pCAttachmentBone->m_AttModelRelative);
  1839.                         Vec3 obbPos = FinalMat34.GetTranslation();
  1840.                         if (rParams.dwFObjFlags & FOB_NEAREST)
  1841.                                 obbPos += gEnv->pRenderer->GetCamera().GetPosition();   // Convert to world space
  1842.                         AABB caabb = pCAttachmentBone->m_pIAttachmentObject->GetAABB();
  1843.                         OBB obb2 = OBB::CreateOBBfromAABB(Matrix33(FinalMat34), caabb);
  1844.                         g_pAuxGeom->DrawOBB(obb2, obbPos, 0, RGBA8(0xff, 0x00, 0x1f, 0xff), eBBD_Extremes_Color_Encoded);
  1845.                 }
  1846.                 for (uint32 i = m_sortedRanges[eRange_FaceStatic].begin; i < m_sortedRanges[eRange_FaceExecute].end; i++)
  1847.                 {
  1848.                         IAttachment* pIAttachment = m_arrAttachments[i];
  1849.                         CAttachmentFACE* pCAttachmentFace = (CAttachmentFACE*)pIAttachment;
  1850.                         if (pCAttachmentFace->m_AttFlags & uHideFlags)
  1851.                                 continue;
  1852.                         if ((pCAttachmentFace->m_AttFlags & FLAGS_ATTACH_PROJECTED) == 0)
  1853.                                 continue;                                             //no success! maybe next time
  1854.                         if ((pCAttachmentFace->m_AttFlags & FLAGS_ATTACH_VISIBLE) == 0)
  1855.                                 continue;                                             //Distance culling. Object is too small for rendering
  1856.                         Matrix34 FinalMat34 = rWorldMat34 * Matrix34(pCAttachmentFace->m_AttModelRelative);
  1857.                         Vec3 obbPos = FinalMat34.GetTranslation();
  1858.                         if (rParams.dwFObjFlags & FOB_NEAREST)
  1859.                                 obbPos += gEnv->pRenderer->GetCamera().GetPosition();   // Convert to world space
  1860.                         AABB caabb = pCAttachmentFace->m_pIAttachmentObject->GetAABB();
  1861.                         OBB obb2 = OBB::CreateOBBfromAABB(Matrix33(FinalMat34), caabb);
  1862.                         g_pAuxGeom->DrawOBB(obb2, obbPos, 0, RGBA8(0x1f, 0x00, 0xff, 0xff), eBBD_Extremes_Color_Encoded);
  1863.                 }
  1864.         }
  1865. #endif
  1866.  
  1867. }
  1868.  
  1869. void CAttachmentManager::DrawMergedAttachments(SRendParams& rParams, const Matrix34& rWorldMat34, const SRenderingPassInfo& passInfo, const f32 fZoomFactor, const f32 fZoomDistanceSq)
  1870. {
  1871.         const bool bDrawMergedAttachments = Console::GetInst().ca_DrawAttachmentsMergedForShadows != 0;
  1872.         if (bDrawMergedAttachments)
  1873.         {
  1874.                 if (m_attachmentMergingRequired)
  1875.                         MergeCharacterAttachments();
  1876.  
  1877.                 if (passInfo.IsShadowPass())
  1878.                 {
  1879.                         for (uint32 i = 0; i < m_mergedAttachments.size(); i++)
  1880.                         {
  1881.                                 CAttachmentMerged* pCAttachmentMerged = static_cast<CAttachmentMerged*>(m_mergedAttachments[i].get());
  1882.                                 const f32 fRadiusSqr = m_pSkelInstance->m_SkeletonPose.GetAABB().GetRadiusSqr();
  1883.                                 if (fRadiusSqr == 0.0f)
  1884.                                         continue; //if radius is zero, then the object is most probably not visible and we can continue
  1885.                                 if (!(rParams.nCustomFlags & COB_POST_3D_RENDER) && fZoomDistanceSq > fRadiusSqr)
  1886.                                         continue; //too small to render. cancel the update
  1887.                                 pCAttachmentMerged->DrawAttachment(rParams, passInfo, rWorldMat34, fZoomFactor);
  1888.                         }
  1889.                 }
  1890.         }
  1891. }
  1892.  
  1893. //------------------------------------------------------------------------------------
  1894. //------------------------------------------------------------------------------------
  1895. //------------------------------------------------------------------------------------
  1896.  
  1897. IProxy* CAttachmentManager::CreateProxy(const char* szProxyName, const char* szJointName)
  1898. {
  1899.         string strProxyName = szProxyName;
  1900.         strProxyName.MakeLower();
  1901.         IProxy* pIProxyName = GetProxyInterfaceByName(strProxyName.c_str());
  1902.         if (pIProxyName)
  1903.         {
  1904.                 CryWarning(VALIDATOR_MODULE_ANIMATION, VALIDATOR_ERROR, "CryAnimation: Attachment name '%s' is already in use, attachment will not be created", strProxyName.c_str());
  1905.                 return 0;
  1906.         }
  1907.  
  1908.         uint32 nameCRC = CCrc32::ComputeLowercase(strProxyName.c_str());
  1909.         IAttachment* pIAttachmentCRC32 = GetInterfaceByNameCRC(nameCRC);
  1910.         if (pIAttachmentCRC32)
  1911.         {
  1912.                 CryWarning(VALIDATOR_MODULE_ANIMATION, VALIDATOR_ERROR, "CryAnimation: Attachment CRC32 for '%s' clashes with attachment name '%s' (crc's are created using lower case only), attachment will not be created", strProxyName.c_str(), pIAttachmentCRC32->GetName());
  1913.                 return 0;
  1914.         }
  1915.         CDefaultSkeleton& rDefaultSkeleton = *m_pSkelInstance->m_pDefaultSkeleton;
  1916.         if (szJointName == 0)
  1917.                 return 0;
  1918.  
  1919.         CProxy proxy;
  1920.         proxy.m_pAttachmentManager = this;
  1921.         proxy.m_strProxyName = strProxyName.c_str();
  1922.         proxy.m_nProxyCRC32 = CCrc32::ComputeLowercase(proxy.m_strProxyName.c_str());
  1923.         proxy.m_strJointName = szJointName;
  1924.         proxy.m_nJointID = rDefaultSkeleton.GetJointIDByName(proxy.m_strJointName.c_str());
  1925.         if (proxy.m_nJointID < 0)
  1926.         {
  1927.                 CryWarning(VALIDATOR_MODULE_ANIMATION, VALIDATOR_ERROR, "CryAnimation: Proxy '%s' specified wrong joint name '%s'", strProxyName.c_str(), proxy.m_strJointName.c_str());
  1928.                 return 0;
  1929.         }
  1930.         proxy.m_ProxyAbsoluteDefault = rDefaultSkeleton.GetDefaultAbsJointByID(proxy.m_nJointID);
  1931.         proxy.m_params = Vec4(0, 0, 0, 0.25f);
  1932.         QuatT jointQT = rDefaultSkeleton.GetDefaultAbsJointByID(proxy.m_nJointID);
  1933.         proxy.m_ProxyRelativeDefault = jointQT.GetInverted() * proxy.m_ProxyAbsoluteDefault;
  1934.         m_arrProxies.push_back(proxy);
  1935.         return GetProxyInterfaceByCRC(proxy.m_nProxyCRC32);
  1936. }
  1937.  
  1938. IProxy* CAttachmentManager::GetProxyInterfaceByIndex(uint32 c) const
  1939. {
  1940.         size_t size = m_arrProxies.size();
  1941.         if (size == 0) return 0;
  1942.         if (size <= c) return 0;
  1943.         IProxy* pIProxy = (IProxy*)&m_arrProxies[c];
  1944.         return pIProxy;
  1945. };
  1946.  
  1947. IProxy* CAttachmentManager::GetProxyInterfaceByName(const char* szName) const
  1948. {
  1949.         int32 idx = GetProxyIndexByName(szName);
  1950.         if (idx == -1) return 0;
  1951.         return GetProxyInterfaceByIndex(idx);
  1952. }
  1953.  
  1954. IProxy* CAttachmentManager::GetProxyInterfaceByCRC(uint32 nameCRC) const
  1955. {
  1956.         int32 idx = GetProxyIndexByCRC(nameCRC);
  1957.         if (idx == -1) return 0;
  1958.         return GetProxyInterfaceByIndex(idx);
  1959. };
  1960.  
  1961. int32 CAttachmentManager::GetProxyIndexByName(const char* szName) const
  1962. {
  1963.         int num = GetProxyCount();
  1964.         for (int i = 0; i < num; i++)
  1965.         {
  1966.                 IProxy* pA = GetProxyInterfaceByIndex(i);
  1967.                 if (stricmp(pA->GetName(), szName) == 0)
  1968.                         return i;
  1969.         }
  1970.         return -1;
  1971. }
  1972.  
  1973. int32 CAttachmentManager::GetProxyIndexByCRC(uint32 nameCRC) const
  1974. {
  1975.         int num = GetProxyCount();
  1976.         for (int i = 0; i < num; i++)
  1977.         {
  1978.                 IProxy* pA = GetProxyInterfaceByIndex(i);
  1979.                 if (pA->GetNameCRC() == nameCRC)
  1980.                         return i;
  1981.         }
  1982.         return -1;
  1983. }
  1984.  
  1985. int32 CAttachmentManager::RemoveProxyByInterface(const IProxy* pIProxy)
  1986. {
  1987.         const char* pName = pIProxy->GetName();
  1988.         return RemoveProxyByName(pName);
  1989. }
  1990.  
  1991. int32 CAttachmentManager::RemoveProxyByName(const char* szName)
  1992. {
  1993.         int32 index = GetProxyIndexByName(szName);
  1994.         if (index == -1)
  1995.                 return 0;
  1996.         RemoveProxyByIndex(index);
  1997.         return 1;
  1998. };
  1999.  
  2000. int32 CAttachmentManager::RemoveProxyByNameCRC(uint32 nameCRC)
  2001. {
  2002.         int32 index = GetIndexByNameCRC(nameCRC);
  2003.         if (index == -1)
  2004.                 return 0;
  2005.         RemoveProxyByIndex(index);
  2006.         return 1;
  2007. };
  2008.  
  2009. void CAttachmentManager::RemoveProxyByIndex(uint32 n)
  2010. {
  2011.         size_t size = m_arrProxies.size();
  2012.         if (size == 0)
  2013.                 return;
  2014.         if (size <= n)
  2015.                 return;
  2016.         IProxy* pIProxy = GetProxyInterfaceByIndex(n);
  2017.         if (pIProxy == 0)
  2018.                 return;
  2019.         m_arrProxies[n] = m_arrProxies[size - 1];
  2020.         m_arrProxies.pop_back();
  2021.         VerifyProxyLinks();
  2022. }
  2023.  
  2024. size_t CAttachmentManager::SizeOfAllAttachments() const
  2025. {
  2026.         if (ICrySizer* pSizer = gEnv->pSystem->CreateSizer())
  2027.         {
  2028.                 pSizer->AddObject(this);
  2029.                 pSizer->End();
  2030.  
  2031.                 const auto totalSize = pSizer->GetTotalSize();
  2032.  
  2033.                 pSizer->Release();
  2034.  
  2035.                 return totalSize;
  2036.         }
  2037.         else
  2038.         {
  2039.                 return 0;
  2040.         }
  2041. }
  2042.  
  2043. void CAttachmentManager::GetMemoryUsage(ICrySizer* pSizer) const
  2044. {
  2045.         pSizer->AddObject(m_arrAttachments);
  2046. }
  2047.  
  2048. void CAttachmentManager::SortByType()
  2049. {
  2050.         m_TypeSortingRequired = 0;
  2051.         CDefaultSkeleton& rDefaultSkeleton = *m_pSkelInstance->m_pDefaultSkeleton;
  2052.         memset(m_sortedRanges, 0, sizeof(m_sortedRanges));
  2053.         uint32 numAttachments = m_arrAttachments.size(), n = 0;
  2054.         if (numAttachments == 0)
  2055.                 return;
  2056.         VerifyProxyLinks();
  2057.         IAttachment** parr = (IAttachment**)&m_arrAttachments[0];
  2058.         STACK_ARRAY(IAttachment*, parr2, numAttachments);
  2059.         for (uint32 a = 0; a < numAttachments; a++)
  2060.         {
  2061.                 if (parr[a]->GetType() != CA_BONE)
  2062.                         continue;
  2063.                 CAttachmentBONE* pb = (CAttachmentBONE*)parr[a];
  2064.                 const char* strJointName = pb->m_strJointName.c_str();
  2065.                 if (pb->m_Simulation.m_useRedirect)
  2066.                         parr2[n++] = parr[a], pb->m_nJointID = rDefaultSkeleton.GetJointIDByName(strJointName);
  2067.         }
  2068.         m_sortedRanges[eRange_BoneRedirect].end = m_sortedRanges[eRange_BoneEmpty].begin = n;
  2069.  
  2070.         for (uint32 i = 0; i < numAttachments; i++)
  2071.         {
  2072.                 if (parr[i]->GetType() != CA_BONE)
  2073.                         continue;
  2074.                 CAttachmentBONE* pb = (CAttachmentBONE*)parr[i];
  2075.                 if (pb->m_Simulation.m_useRedirect)
  2076.                         continue;
  2077.                 if (parr[i]->GetIAttachmentObject() == 0)
  2078.                 {
  2079.                         parr2[n++] = parr[i];
  2080.                         pb->m_nJointID = rDefaultSkeleton.GetJointIDByName(pb->m_strJointName.c_str());
  2081.                 }
  2082.         }
  2083.         m_sortedRanges[eRange_BoneEmpty].end = m_sortedRanges[eRange_BoneStatic].begin = n;
  2084.  
  2085.         for (uint32 i = 0; i < numAttachments; i++)
  2086.         {
  2087.                 if (parr[i]->GetType() != CA_BONE)
  2088.                         continue;
  2089.                 CAttachmentBONE* pb = (CAttachmentBONE*)parr[i];
  2090.                 if (pb->m_Simulation.m_useRedirect)
  2091.                         continue;
  2092.                 IAttachmentObject* p = pb->m_pIAttachmentObject;
  2093.                 if (p && p->GetAttachmentType() == IAttachmentObject::eAttachment_StatObj)
  2094.                 {
  2095.                         parr2[n++] = parr[i];
  2096.                         pb->m_nJointID = rDefaultSkeleton.GetJointIDByName(pb->m_strJointName.c_str());
  2097.                 }
  2098.         }
  2099.         m_sortedRanges[eRange_BoneStatic].end = m_sortedRanges[eRange_BoneExecute].begin = n;
  2100.  
  2101.         for (uint32 i = 0; i < numAttachments; i++)
  2102.         {
  2103.                 if (parr[i]->GetType() != CA_BONE)
  2104.                         continue;
  2105.                 CAttachmentBONE* pb = (CAttachmentBONE*)parr[i];
  2106.                 if (pb->m_Simulation.m_useRedirect)
  2107.                         continue;
  2108.                 IAttachmentObject* p = pb->m_pIAttachmentObject;
  2109.                 if (p)
  2110.                 {
  2111.                         IAttachmentObject::EType t = p->GetAttachmentType();
  2112.                         uint32 isSkeleton = t == IAttachmentObject::eAttachment_Skeleton;
  2113.                         if (isSkeleton)
  2114.                         {
  2115.                                 parr2[n++] = parr[i];
  2116.                                 pb->m_nJointID = rDefaultSkeleton.GetJointIDByName(pb->m_strJointName.c_str());
  2117.                         }
  2118.                 }
  2119.         }
  2120.         m_sortedRanges[eRange_BoneExecute].end = m_sortedRanges[eRange_BoneExecuteUnsafe].begin = n;
  2121.  
  2122.         for (uint32 i = 0; i < numAttachments; i++)
  2123.         {
  2124.                 if (parr[i]->GetType() != CA_BONE)
  2125.                         continue;
  2126.                 CAttachmentBONE* pb = (CAttachmentBONE*)parr[i];
  2127.                 if (pb->m_Simulation.m_useRedirect)
  2128.                         continue;
  2129.                 IAttachmentObject* p = pb->m_pIAttachmentObject;
  2130.                 if (p)
  2131.                 {
  2132.                         IAttachmentObject::EType t = p->GetAttachmentType();
  2133.                         uint32 isEntity = t == IAttachmentObject::eAttachment_Entity;
  2134.                         uint32 isLight = t == IAttachmentObject::eAttachment_Light;
  2135.                         uint32 isEffect = t == IAttachmentObject::eAttachment_Effect;
  2136.                         if (isEntity + isLight + isEffect)
  2137.                         {
  2138.                                 parr2[n++] = parr[i];
  2139.                                 pb->m_nJointID = rDefaultSkeleton.GetJointIDByName(pb->m_strJointName.c_str());
  2140.                         }
  2141.                 }
  2142.         }
  2143.         m_sortedRanges[eRange_BoneExecuteUnsafe].end = m_sortedRanges[eRange_FaceEmpty].begin = n;
  2144.         for (uint32 i = 0; i < numAttachments; i++)
  2145.         {
  2146.                 if (parr[i]->GetType() != CA_FACE)
  2147.                         continue;
  2148.                 if (parr[i]->GetIAttachmentObject() == 0)
  2149.                         parr2[n++] = parr[i];
  2150.         }
  2151.         m_sortedRanges[eRange_FaceEmpty].end = m_sortedRanges[eRange_FaceStatic].begin = n;
  2152.  
  2153.         for (uint32 i = 0; i < numAttachments; i++)
  2154.         {
  2155.                 if (parr[i]->GetType() != CA_FACE)
  2156.                         continue;
  2157.                 IAttachmentObject* p = parr[i]->GetIAttachmentObject();
  2158.                 if (p && p->GetAttachmentType() == IAttachmentObject::eAttachment_StatObj)
  2159.                         parr2[n++] = parr[i];
  2160.         }
  2161.         m_sortedRanges[eRange_FaceStatic].end = m_sortedRanges[eRange_FaceExecute].begin = n;
  2162.  
  2163.         for (uint32 i = 0; i < numAttachments; i++)
  2164.         {
  2165.                 if (parr[i]->GetType() != CA_FACE)
  2166.                         continue;
  2167.                 if (parr[i]->GetIAttachmentObject())
  2168.                 {
  2169.                         IAttachmentObject::EType t = parr[i]->GetIAttachmentObject()->GetAttachmentType();
  2170.                         uint32 isSkeleton = t == IAttachmentObject::eAttachment_Skeleton;
  2171.                         if (isSkeleton)
  2172.                                 parr2[n++] = parr[i];
  2173.                 }
  2174.         }
  2175.         m_sortedRanges[eRange_FaceExecute].end = m_sortedRanges[eRange_FaceExecuteUnsafe].begin = n;
  2176.  
  2177.         for (uint32 i = 0; i < numAttachments; i++)
  2178.         {
  2179.                 if (parr[i]->GetType() != CA_FACE)
  2180.                         continue;
  2181.                 if (parr[i]->GetIAttachmentObject())
  2182.                 {
  2183.                         IAttachmentObject::EType t = parr[i]->GetIAttachmentObject()->GetAttachmentType();
  2184.                         uint32 isEntity = t == IAttachmentObject::eAttachment_Entity;
  2185.                         uint32 isLight = t == IAttachmentObject::eAttachment_Light;
  2186.                         uint32 isEffect = t == IAttachmentObject::eAttachment_Effect;
  2187.                         if (isEntity + isLight + isEffect)
  2188.                                 parr2[n++] = parr[i];
  2189.                 }
  2190.         }
  2191.         m_sortedRanges[eRange_FaceExecuteUnsafe].end = m_sortedRanges[eRange_SkinMesh].begin = n;
  2192.  
  2193.         for (uint32 i = 0; i < numAttachments; i++)
  2194.         {
  2195.                 if (parr[i]->GetType() == CA_SKIN)
  2196.                         PREFAST_SUPPRESS_WARNING(6386) parr2[n++] = parr[i];
  2197.         }
  2198.         m_sortedRanges[eRange_SkinMesh].end = m_sortedRanges[eRange_VertexClothOrPendulumRow].begin = n;
  2199.         for (uint32 i = 0; i < numAttachments; i++)
  2200.         {
  2201.                 if (parr[i]->GetType() == CA_PROW || parr[i]->GetType() == CA_VCLOTH)
  2202.                         PREFAST_SUPPRESS_WARNING(6386) parr2[n++] = parr[i];
  2203.         }
  2204.         m_sortedRanges[eRange_VertexClothOrPendulumRow].end = n;
  2205.  
  2206.         if (n != numAttachments)
  2207.                 CryFatalError("CryAnimation: sorting error: %s", m_pSkelInstance->GetFilePath());
  2208.         for (uint32 i = 0; i < numAttachments; i++)
  2209.         {
  2210.                 parr[i] = parr2[i];
  2211.         }
  2212.         if (m_sortedRanges[eRange_BoneRedirect].end)
  2213.         {
  2214.                 STACK_ARRAY(uint8, parrflags, m_sortedRanges[eRange_BoneRedirect].end);
  2215.                 memset(parrflags, 0, m_sortedRanges[eRange_BoneRedirect].end);
  2216.                 for (uint32 i = 0; i < m_sortedRanges[eRange_BoneRedirect].end; i++)
  2217.                 {
  2218.                         uint32 s = 0x7fff, t = 0;
  2219.                         for (uint32 r = 0; r < m_sortedRanges[eRange_BoneRedirect].end; r++)
  2220.                         {
  2221.                                 CAttachmentBONE* pb = (CAttachmentBONE*)parr[r];
  2222.                                 if (s > uint32((pb->m_nJointID + 1) | parrflags[r] << 0x10))
  2223.                                 {
  2224.                                         t = r;
  2225.                                         s = pb->m_nJointID + 1;
  2226.                                 }
  2227.                         }
  2228.                         parr2[i] = parr[t], parrflags[t] = 1;
  2229.                 }
  2230.                 m_numRedirectionWithAttachment = 0;
  2231.  
  2232.                 for (uint32 r = 0; r < m_sortedRanges[eRange_BoneRedirect].end; r++)
  2233.                 {
  2234.                         parr[r] = parr2[r];
  2235.                         CAttachmentBONE* pb = (CAttachmentBONE*)parr[r];
  2236.                         if (pb->m_pIAttachmentObject)
  2237.                                 m_numRedirectionWithAttachment++;
  2238.                         if (pb->m_Simulation.m_arrChildren.size())
  2239.                                 continue;
  2240.                         pb->m_Simulation.m_nAnimOverrideJoint =
  2241.                           rDefaultSkeleton.GetJointIDByName("all_blendWeightPendulum");
  2242.                         int32 parentid = pb->m_nJointID;
  2243.                         if (parentid < 0)
  2244.                                 continue;
  2245.                         bool arrChildren[MAX_JOINT_AMOUNT];
  2246.                         for (uint32 i = 0; i < MAX_JOINT_AMOUNT; i++)
  2247.                         {
  2248.                                 arrChildren[i] = 0;
  2249.                         }
  2250.                         pb->m_Simulation.m_arrChildren.resize(0);
  2251.                         pb->m_Simulation.m_arrChildren.reserve(16);
  2252.                         uint32 numJoints = rDefaultSkeleton.GetJointCount();
  2253.                         for (uint32 i = parentid + 1; i < numJoints; i++)
  2254.                         {
  2255.                                 if (rDefaultSkeleton.GetJointParentIDByID(i) == parentid)
  2256.                                         arrChildren[i] = 1;
  2257.                         }
  2258.                         for (uint32 pid = 0; pid < MAX_JOINT_AMOUNT; pid++)
  2259.                         {
  2260.                                 if (arrChildren[pid] == 0)
  2261.                                         continue;
  2262.                                 for (uint32 i = pid + 1; i < numJoints; i++)
  2263.                                 {
  2264.                                         if (rDefaultSkeleton.GetJointParentIDByID(i) == pid)
  2265.                                                 arrChildren[i] = 1;
  2266.                                 }
  2267.                         }
  2268.                         for (uint32 i = 0; i < MAX_JOINT_AMOUNT; i++)
  2269.                         {
  2270.                                 if (arrChildren[i])
  2271.                                         pb->m_Simulation.m_arrChildren.push_back(i);
  2272.                         }
  2273.                 }
  2274.         }
  2275.  
  2276.         for (uint32 r = m_sortedRanges[eRange_VertexClothOrPendulumRow].begin;
  2277.              r < m_sortedRanges[eRange_VertexClothOrPendulumRow].end; r++)
  2278.         {
  2279.                 if (parr[r]->GetType() != CA_PROW)
  2280.                         continue;
  2281.                 CAttachmentPROW* pb = (CAttachmentPROW*)parr[r];
  2282.                 pb->m_nRowJointID = rDefaultSkeleton.GetJointIDByName(pb->m_strRowJointName.c_str());
  2283.                 if (pb->m_nRowJointID < 0)
  2284.                         continue;
  2285.                 const char* psrc = pb->m_strRowJointName.c_str();
  2286.                 const char* pstr = CryStringUtils::stristr(psrc, "_x00_");
  2287.                 if (pstr == 0)
  2288.                         continue;                                                                                                // invalid name
  2289.                 char pJointName[256];
  2290.                 cry_strcpy(pJointName, psrc);
  2291.                 JointIdType jindices[MAX_JOINT_AMOUNT];
  2292.                 uint16& numParticles = pb->m_rowparams.m_nParticlesPerRow;
  2293.                 numParticles = 0;
  2294.                 for (int idx = int(pstr - psrc) + 2; numParticles < MAX_JOINTS_PER_ROW; numParticles++)
  2295.                 {
  2296.                         if ((jindices[numParticles] = rDefaultSkeleton.GetJointIDByName(pJointName)) == JointIdType(-1))
  2297.                                 break;
  2298.                         if (++pJointName[idx + 1] == 0x3a)
  2299.                                 pJointName[idx]++, pJointName[idx + 1] = 0x30;
  2300.                 }
  2301.                 pb->m_rowparams.m_arrParticles.resize(numParticles);
  2302.                 uint32 numJoints = rDefaultSkeleton.GetJointCount();
  2303.                 for (uint32 r = 0; r < numParticles; r++)
  2304.                 {
  2305.                         pb->m_rowparams.m_arrParticles[r].m_childID = JointIdType(-1);
  2306.                         JointIdType parentid = jindices[r];
  2307.                         if (parentid == JointIdType(-1))
  2308.                                 continue;                                                                                              // invalid
  2309.                         for (uint32 i = parentid + 1; i < numJoints; i++)
  2310.                         {
  2311.                                 if (rDefaultSkeleton.GetJointParentIDByID(i) == parentid)
  2312.                                 {
  2313.                                         pb->m_rowparams.m_arrParticles[r].m_childID = i;
  2314.                                         break;
  2315.                                 }
  2316.                         }
  2317.                 }
  2318.                 for (uint32 i = 0; i < numParticles; i++)
  2319.                 {
  2320.                         pb->m_rowparams.m_arrParticles[i].m_vDistance.y = 0.07f;                                                   // use 7cm by default
  2321.                         if (pb->m_rowparams.