9 #include <ThirdParty/assimp/include/assimp/types.h> 14 VulkanRenderer* VulkanMesh::renderer =
nullptr;
15 VulkanLogicalDevice* VulkanMesh::device =
nullptr;
16 VulkanDescriptorPool* VulkanMesh::descriptorPool =
nullptr;
17 VkCommandPool VulkanMesh::commandPool = VK_NULL_HANDLE;
18 VmaAllocator VulkanMesh::allocator = VK_NULL_HANDLE;
20 void VulkanMesh::InitMeshes(VulkanRenderer * renderer, VulkanLogicalDevice * device, VulkanDescriptorPool* descriptorPool, VkCommandPool commandPool)
22 VulkanMesh::renderer = renderer;
23 VulkanMesh::device = device;
24 VulkanMesh::descriptorPool = descriptorPool;
25 VulkanMesh::commandPool = commandPool;
26 VulkanMesh::allocator = renderer->GetVmaAllocator();
29 VulkanMesh::VulkanMesh(aiMesh * mesh, eastl::shared_ptr<Skeleton> skeleton, eastl::vector<Vertex> vertices, eastl::vector<unsigned> indices) : Mesh(vertices, indices)
32 this->skeleton = skeleton;
37 VulkanMesh::~VulkanMesh()
43 void VulkanMesh::SetUpMesh()
59 boneOffsets.resize(255, glm::mat4());
61 if (mesh->HasBones() && skeleton !=
nullptr) {
63 eastl::map<eastl::string, Skeleton::Bone_t*> boneMap = skeleton->GetBoneMap();
65 for (
size_t i = 0, size = mesh->mNumBones; i < size; ++i) {
66 if (boneMap.find(eastl::string(mesh->mBones[i]->mName.C_Str())) == boneMap.end()) {
67 eastl::string s =
"Mesh references bone " +
68 eastl::string(mesh->mBones[i]->mName.C_Str()) +
69 " Which isn't found in skeleton " +
73 int index = boneMap[eastl::string(mesh->mBones[i]->mName.C_Str())]->boneDataIndex;
74 aiBone* bone = mesh->mBones[i];
76 boneOffsets[index] = glm::mat4(bone->mOffsetMatrix.a1, bone->mOffsetMatrix.b1, bone->mOffsetMatrix.c1, bone->mOffsetMatrix.d1,
77 bone->mOffsetMatrix.a2, bone->mOffsetMatrix.b2, bone->mOffsetMatrix.c2, bone->mOffsetMatrix.d2,
78 bone->mOffsetMatrix.a3, bone->mOffsetMatrix.b3, bone->mOffsetMatrix.c3, bone->mOffsetMatrix.d3,
79 bone->mOffsetMatrix.a4, bone->mOffsetMatrix.b4, bone->mOffsetMatrix.c4, bone->mOffsetMatrix.d4);
81 for (
size_t j = 0; j < bone->mNumWeights; ++j) {
83 float smallestWeight =
vertices[bone->mWeights[j].mVertexId].boneWeights[id];
85 for (
size_t k = 0; k < 4; ++k) {
86 if (
vertices[bone->mWeights[j].mVertexId].boneWeights[k] < smallestWeight) {
88 smallestWeight =
vertices[bone->mWeights[j].mVertexId].boneWeights[k];
92 if (smallestWeight < bone->mWeights[j].mWeight) {
93 vertices[bone->mWeights[j].mVertexId].boneIds[id] = index;
94 vertices[bone->mWeights[j].mVertexId].boneWeights[id] = bone->mWeights[j].mWeight;
103 vertexBuffer = eastl::unique_ptr<VulkanBuffer>(
new VulkanBuffer(device, allocator,
104 static_cast<uint32_t>(
sizeof(
Vertex)*
vertices.size()), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
true, commandPool));
106 indexBuffer = eastl::unique_ptr<VulkanBuffer>(
new VulkanBuffer(device, allocator,
107 static_cast<uint32_t>(
sizeof(uint32_t)*
indices.size()), VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
true, commandPool));
109 offsetBuffer = eastl::unique_ptr <VulkanBuffer>(
new VulkanBuffer(device, allocator,
110 static_cast<uint32_t>(
sizeof(glm::mat4) * 255), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
true, commandPool));
112 eastl::map<aiVector3D, uint32_t> positionMap;
113 eastl::map<Edge, eastl::vector<Face>> neighbors;
115 eastl::vector<Face> uniqueFaces;
118 for (
unsigned int i = 0; i < mesh->mNumFaces; ++i) {
119 const aiFace& face = mesh->mFaces[i];
123 for (
int j = 0; j < 3; ++j) {
124 uint32_t index =
static_cast<uint32_t
>(face.mIndices[j]);
126 aiVector3D v = mesh->mVertices[index];
128 if (positionMap.find(v) == positionMap.end()) {
129 positionMap[v] = index;
132 index = positionMap[v];
135 unique.indices[j] = index;
139 uniqueFaces.push_back(unique);
141 Edge edge1(unique.indices[0], unique.indices[1]);
142 Edge edge2(unique.indices[1], unique.indices[2]);
143 Edge edge3(unique.indices[2], unique.indices[0]);
145 neighbors[edge1].push_back(unique);
146 neighbors[edge2].push_back(unique);
147 neighbors[edge3].push_back(unique);
150 eastl::vector<uint32_t> intIndices(
indices.size());
152 for (
size_t i = 0, size =
indices.size(); i < size; ++i) {
153 intIndices[i] =
static_cast<uint32_t
>(
indices[i]);
156 eastl::vector<uint32_t> shadowIndices(uniqueFaces.size() * 6);
158 shadowIndicesCount =
static_cast<uint32_t
>(uniqueFaces.size() * 6);
160 for (
size_t i = 0, size = uniqueFaces.size(); i < size; ++i) {
161 Face face = uniqueFaces[i];
163 Edge edge1(face.indices[0], face.indices[1]);
164 Edge edge2(face.indices[1], face.indices[2]);
165 Edge edge3(face.indices[2], face.indices[0]);
171 eastl::vector<Face> edge1Neighbors = neighbors[edge1];
172 eastl::vector<Face> edge2Neighbors = neighbors[edge2];
173 eastl::vector<Face> edge3Neighbors = neighbors[edge3];
175 if (edge1Neighbors.size() < 2)
178 neighbor1 = edge1Neighbors[0] == face ? edge1Neighbors[1] : edge1Neighbors[0];
179 if (edge2Neighbors.size() < 2)
182 neighbor2 = edge2Neighbors[0] == face ? edge2Neighbors[1] : edge2Neighbors[0];
183 if (edge3Neighbors.size() < 2)
186 neighbor3 = edge3Neighbors[0] == face ? edge3Neighbors[1] : edge3Neighbors[0];
188 shadowIndices[i * 6 + 0] =
static_cast<uint32_t
>(face.indices[0]);
190 if (neighbor1 == face)
191 shadowIndices[i * 6 + 1] = face.indices[2];
193 shadowIndices[i * 6 + 1] = neighbor1.FindOpposingIndex(edge1);
195 shadowIndices[i * 6 + 2] =
static_cast<uint32_t
>(face.indices[1]);
197 if (neighbor2 == face)
198 shadowIndices[i * 6 + 3] = face.indices[0];
200 shadowIndices[i * 6 + 3] = neighbor2.FindOpposingIndex(edge2);
202 shadowIndices[i * 6 + 4] =
static_cast<uint32_t
>(face.indices[2]);
204 if (neighbor3 == face)
205 shadowIndices[i * 6 + 5] = face.indices[1];
207 shadowIndices[i * 6 + 5] = neighbor3.FindOpposingIndex(edge3);
210 shadowIndexBuffer = eastl::unique_ptr<VulkanBuffer>(
new VulkanBuffer(device, allocator,
211 static_cast<uint32_t>(
sizeof(uint32_t)*shadowIndicesCount),
212 VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
true, commandPool));
215 indexBuffer->UpdateBuffer(intIndices.data(), 0,
static_cast<uint32_t
>(
sizeof(uint32_t)*intIndices.size()));
216 offsetBuffer->UpdateBuffer(boneOffsets.data(), 0,
static_cast<uint32_t
>(
sizeof(glm::mat4) * 255));
218 shadowIndexBuffer->UpdateBuffer(shadowIndices.data(), 0,
219 static_cast<uint32_t
>(
sizeof(uint32_t)*shadowIndicesCount));
223 VkBuffer VulkanMesh::GetVertexBuffer()
const 225 return vertexBuffer->GetBuffer();
228 VkBuffer VulkanMesh::GetIndexBuffer()
const 230 return indexBuffer->GetBuffer();
233 VkBuffer VulkanMesh::GetShadowIndexBuffer()
const 235 return shadowIndexBuffer->GetBuffer();
238 uint32_t VulkanMesh::GetShadowIndexCount()
const 240 return shadowIndicesCount;
243 uint32_t VulkanMesh::GetIndexCount()
245 return static_cast<uint32_t
>(
indices.size());
248 bool VulkanMesh::IsAnimated()
const 253 VkDescriptorSet VulkanMesh::CreateBoneOffsetDescriptorSet(
size_t threadID,
size_t pipelineID,
size_t set, VkDescriptorSetLayout layout)
255 if (offsetDescriptorSets.size() <= pipelineID) {
256 offsetDescriptorSets.resize(pipelineID + 1);
258 if (offsetDescriptorSets[pipelineID].size() <=
set) {
259 offsetDescriptorSets[pipelineID].resize(
set + 1);
261 if (offsetDescriptorSets[pipelineID][
set].size() <= threadID) {
262 offsetDescriptorSets[pipelineID][
set].resize(threadID + 1, VK_NULL_HANDLE);
265 VkDescriptorSetLayout layouts[] = { layout };
266 renderer->GetDescriptorPool(threadID)->AllocateDescriptorSet(1, layouts, &offsetDescriptorSets[pipelineID][
set][threadID]);
268 renderer->GetDescriptorPool(threadID)->DescriptorSetBindToBuffer(offsetDescriptorSets[pipelineID][
set][threadID], offsetBuffer->GetBuffer(),
269 0,
static_cast<VkDeviceSize
>(
sizeof(glm::mat4) * 255), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
271 return offsetDescriptorSets[pipelineID][
set][threadID];
274 VkDescriptorSet VulkanMesh::GetBoneOffsetDescriptorSet(
size_t threadID,
size_t pipelineID,
size_t set)
276 if (pipelineID >= offsetDescriptorSets.size())
277 return VK_NULL_HANDLE;
278 if (
set >= offsetDescriptorSets[pipelineID].size())
279 return VK_NULL_HANDLE;
280 if (threadID >= offsetDescriptorSets[pipelineID][
set].size())
281 return VK_NULL_HANDLE;
282 return offsetDescriptorSets[pipelineID][
set][threadID];
eastl::vector< unsigned > indices
The indices of this mesh.
eastl::vector< Vertex > vertices
The vertices of this mesh.
#define debug_warning(debug_class, function, value)
This functions logs a debug warning to the log and console.
This object is used to store general data for a vertex.