MeshFactory.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Tests/TestAssetCode/MeshFactory.h>
  9. #include <EMotionFX/Source/Mesh.h>
  10. #include <EMotionFX/Source/SubMesh.h>
  11. #include <EMotionFX/Source/SkinningInfoVertexAttributeLayer.h>
  12. #include <EMotionFX/Source/VertexAttributeLayerAbstractData.h>
  13. namespace EMotionFX
  14. {
  15. EMotionFX::Mesh* MeshFactory::Create(
  16. const AZStd::vector<AZ::u32>& indices,
  17. const AZStd::vector<AZ::Vector3>& vertices,
  18. const AZStd::vector<AZ::Vector3>& normals,
  19. const AZStd::vector<AZ::Vector2>& uvs,
  20. const AZStd::vector<VertexSkinInfluences>& skinningInfo
  21. ) {
  22. const AZ::u32 vertCount = aznumeric_cast<AZ::u32>(vertices.size());
  23. const AZ::u32 faceCount = aznumeric_cast<AZ::u32>(indices.size()) / 3;
  24. auto* mesh = EMotionFX::Mesh::Create(vertCount, aznumeric_caster(indices.size()), faceCount, vertCount, false);
  25. // Skinning info
  26. if (!skinningInfo.empty() && skinningInfo.size() == vertices.size())
  27. {
  28. auto* skinningLayer = EMotionFX::SkinningInfoVertexAttributeLayer::Create(vertCount);
  29. for (size_t vertex = 0; vertex < skinningInfo.size(); ++vertex)
  30. {
  31. for (const auto& [nodeNr, weight] : skinningInfo[vertex])
  32. {
  33. skinningLayer->AddInfluence(static_cast<AZ::u32>(vertex), aznumeric_caster(nodeNr), weight, 0);
  34. }
  35. }
  36. mesh->AddSharedVertexAttributeLayer(skinningLayer);
  37. }
  38. // Original vertex numbers
  39. auto* orgVtxLayer = EMotionFX::VertexAttributeLayerAbstractData::Create(
  40. vertCount,
  41. EMotionFX::Mesh::ATTRIB_ORGVTXNUMBERS,
  42. sizeof(AZ::u32),
  43. true
  44. );
  45. mesh->AddVertexAttributeLayer(orgVtxLayer);
  46. AZStd::copy(indices.begin(), indices.end(), static_cast<AZ::u32*>(orgVtxLayer->GetOriginalData()));
  47. orgVtxLayer->ResetToOriginalData();
  48. // The positions layer
  49. auto* posLayer = EMotionFX::VertexAttributeLayerAbstractData::Create(
  50. vertCount,
  51. EMotionFX::Mesh::ATTRIB_POSITIONS,
  52. sizeof(AZ::Vector3),
  53. true
  54. );
  55. mesh->AddVertexAttributeLayer(posLayer);
  56. AZStd::copy(vertices.begin(), vertices.end(), static_cast<AZ::Vector3*>(posLayer->GetOriginalData()));
  57. posLayer->ResetToOriginalData();
  58. // The normals layer
  59. auto* normalsLayer = EMotionFX::VertexAttributeLayerAbstractData::Create(
  60. vertCount,
  61. EMotionFX::Mesh::ATTRIB_NORMALS,
  62. sizeof(AZ::Vector3),
  63. true
  64. );
  65. mesh->AddVertexAttributeLayer(normalsLayer);
  66. AZStd::copy(normals.begin(), normals.end(), static_cast<AZ::Vector3*>(normalsLayer->GetOriginalData()));
  67. normalsLayer->ResetToOriginalData();
  68. // The UVs layer.
  69. EMotionFX::VertexAttributeLayerAbstractData* uvsLayer = nullptr;
  70. if (!uvs.empty() && uvs.size() == vertices.size())
  71. {
  72. uvsLayer = EMotionFX::VertexAttributeLayerAbstractData::Create(vertCount, EMotionFX::Mesh::ATTRIB_UVCOORDS, sizeof(AZ::Vector2), true);
  73. mesh->AddVertexAttributeLayer(uvsLayer);
  74. AZStd::copy(uvs.begin(), uvs.end(), static_cast<AZ::Vector2*>(uvsLayer->GetOriginalData()));
  75. uvsLayer->ResetToOriginalData();
  76. }
  77. auto* subMesh = EMotionFX::SubMesh::Create(
  78. /*parentMesh=*/ mesh,
  79. /*startVertex=*/ 0,
  80. /*startIndex=*/ 0,
  81. /*startPolygon=*/ 0,
  82. /*numVerts=*/ mesh->GetNumVertices(),
  83. /*numIndices=*/ mesh->GetNumIndices(),
  84. /*numPolygons=*/ mesh->GetNumPolygons(),
  85. /*numBones=*/ aznumeric_caster(skinningInfo.size())
  86. );
  87. mesh->AddSubMesh(subMesh);
  88. if (!skinningInfo.empty() && skinningInfo.size() == vertices.size())
  89. {
  90. for (size_t vertex = 0; vertex < skinningInfo.size(); ++vertex)
  91. {
  92. subMesh->SetBone(aznumeric_caster(vertex), aznumeric_caster(vertex));
  93. }
  94. }
  95. AZ_PUSH_DISABLE_WARNING_MSVC(4244); // warning C4244: '=': conversion from 'const int' to 'uint8', possible loss of data
  96. AZStd::fill(mesh->GetPolygonVertexCounts(), mesh->GetPolygonVertexCounts() + faceCount, 3);
  97. AZ_POP_DISABLE_WARNING_MSVC
  98. AZStd::copy(indices.begin(), indices.end(), mesh->GetIndices());
  99. return mesh;
  100. }
  101. } // namespace EMotionFX