complete animation
							parent
							
								
									3532369f08
								
							
						
					
					
						commit
						c08f144680
					
				| 
						 | 
					@ -149,4 +149,5 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_subdirectory(base)
 | 
					add_subdirectory(base)
 | 
				
			||||||
add_subdirectory(homework)
 | 
					add_subdirectory(homework)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# add_subdirectory(examples)
 | 
					# add_subdirectory(examples)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,10 +20,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "homework1.h"
 | 
					#include "homework1.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
glm::mat4 VulkanglTFModel::Node::getLocalMatrix()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return glm::translate(glm::mat4(1.0f), translation) * glm::mat4(rotation) * glm::scale(glm::mat4(1.0f), scale) * matrix;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
VulkanglTFModel::~VulkanglTFModel()
 | 
					VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -113,39 +109,7 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//glTF nodes loading helper function
 | 
						
 | 
				
			||||||
	//rewrite node loader,simplify logic
 | 
					 | 
				
			||||||
	//Search node from parent to children by index
 | 
					 | 
				
			||||||
	VulkanglTFModel::Node* VulkanglTFModel::findNode(Node* parent, uint32_t index)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		Node* nodeFound = nullptr;
 | 
					 | 
				
			||||||
		if (parent->index == index)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return parent;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		for (auto &child : parent->children)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			nodeFound = findNode(child, index);
 | 
					 | 
				
			||||||
			if (nodeFound)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nodeFound;
 | 
					 | 
				
			||||||
}	//iterate vector of nodes to check weather nodes exist or not
 | 
					 | 
				
			||||||
	VulkanglTFModel::Node* VulkanglTFModel::nodeFromIndex(uint32_t index)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		Node* nodeFound = nullptr;
 | 
					 | 
				
			||||||
		for (auto& node : nodes)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			nodeFound = findNode(node, index);
 | 
					 | 
				
			||||||
			if (nodeFound)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nodeFound;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	//animation loader
 | 
						//animation loader
 | 
				
			||||||
	void VulkanglTFModel::loadAnimations(tinygltf::Model& input)
 | 
						void VulkanglTFModel::loadAnimations(tinygltf::Model& input)
 | 
				
			||||||
| 
						 | 
					@ -236,6 +200,86 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// load skins from glTF model
 | 
				
			||||||
 | 
						void VulkanglTFModel::loadSkins(tinygltf::Model& input)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							skins.resize(input.skins.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (size_t i = 0; i < input.skins.size(); i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								tinygltf::Skin glTFSkin = input.skins[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								skins[i].name = glTFSkin.name;
 | 
				
			||||||
 | 
								//follow the tree structure,find the root node of skeleton by index
 | 
				
			||||||
 | 
								skins[i].skeletonRoot = nodeFromIndex(glTFSkin.skeleton);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								//join nodes
 | 
				
			||||||
 | 
								for (int jointIndex : glTFSkin.joints)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Node* node = nodeFromIndex(jointIndex);
 | 
				
			||||||
 | 
									if (node)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										skins[i].joints.push_back(node);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								//get the inverse bind matrices
 | 
				
			||||||
 | 
								if (glTFSkin.inverseBindMatrices > -1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									const tinygltf::Accessor& accessor = input.accessors[glTFSkin.inverseBindMatrices];
 | 
				
			||||||
 | 
									const tinygltf::BufferView& bufferview = input.bufferViews[accessor.bufferView];
 | 
				
			||||||
 | 
									const tinygltf::Buffer& buffer = input.buffers[bufferview.buffer];
 | 
				
			||||||
 | 
									skins[i].inverseBindMatrices.resize(accessor.count);
 | 
				
			||||||
 | 
									memcpy(skins[i].inverseBindMatrices.data(), &buffer.data[accessor.byteOffset + bufferview.byteOffset], accessor.count * sizeof(glm::mat4));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									//create a host visible shader buffer to store inverse bind matrices for this skin
 | 
				
			||||||
 | 
									VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
 | 
				
			||||||
 | 
										&skins[i].ssbo,
 | 
				
			||||||
 | 
										sizeof(glm::mat4) * skins[i].inverseBindMatrices.size(),
 | 
				
			||||||
 | 
										skins[i].inverseBindMatrices.data()));
 | 
				
			||||||
 | 
									VK_CHECK_RESULT(skins[i].ssbo.map());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//glTF nodes loading helper function
 | 
				
			||||||
 | 
						//rewrite node loader,simplify logic
 | 
				
			||||||
 | 
						//Search node from parent to children by index
 | 
				
			||||||
 | 
						VulkanglTFModel::Node* VulkanglTFModel::findNode(Node* parent, uint32_t index)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Node* nodeFound = nullptr;
 | 
				
			||||||
 | 
							if (parent->index == index)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return parent;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (auto& child : parent->children)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								nodeFound = findNode(child, index);
 | 
				
			||||||
 | 
								if (nodeFound)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nodeFound;
 | 
				
			||||||
 | 
						}	//iterate vector of nodes to check weather nodes exist or not
 | 
				
			||||||
 | 
						VulkanglTFModel::Node* VulkanglTFModel::nodeFromIndex(uint32_t index)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Node* nodeFound = nullptr;
 | 
				
			||||||
 | 
							for (auto& node : nodes)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								nodeFound = findNode(node, index);
 | 
				
			||||||
 | 
								if (nodeFound)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nodeFound;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//node loader
 | 
						//node loader
 | 
				
			||||||
	void VulkanglTFModel::loadNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, VulkanglTFModel::Node* parent, uint32_t nodeIndex, std::vector<uint32_t>& indexBuffer, std::vector<VulkanglTFModel::Vertex>& vertexBuffer)
 | 
						void VulkanglTFModel::loadNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, VulkanglTFModel::Node* parent, uint32_t nodeIndex, std::vector<uint32_t>& indexBuffer, std::vector<VulkanglTFModel::Vertex>& vertexBuffer)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -399,49 +443,7 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// load skins from glTF model
 | 
					 | 
				
			||||||
	void VulkanglTFModel::loadSkins(tinygltf::Model& input)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		skins.resize(input.skins.size());
 | 
					 | 
				
			||||||
		std::cout << input.skins.size() << std::endl;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (size_t i = 0; i < input.skins.size(); i++)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			tinygltf::Skin glTFSkin = input.skins[i];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			skins[i].name = glTFSkin.name;
 | 
					 | 
				
			||||||
			//follow the tree structure,find the root node of skeleton by index
 | 
					 | 
				
			||||||
			skins[i].skeletonRoot = nodeFromIndex(glTFSkin.skeleton);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			//join nodes
 | 
					 | 
				
			||||||
			for (int jointIndex : glTFSkin.joints)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				Node* node = nodeFromIndex(jointIndex);
 | 
					 | 
				
			||||||
				if (node)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					skins[i].joints.push_back(node);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			//get the inverse bind matrices
 | 
					 | 
				
			||||||
			if (glTFSkin.inverseBindMatrices > -1)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				const tinygltf::Accessor& accessor = input.accessors[glTFSkin.inverseBindMatrices];
 | 
					 | 
				
			||||||
				const tinygltf::BufferView& bufferview = input.bufferViews[accessor.bufferView];
 | 
					 | 
				
			||||||
				const tinygltf::Buffer& buffer = input.buffers[bufferview.buffer];
 | 
					 | 
				
			||||||
				skins[i].inverseBindMatrices.resize(accessor.count);
 | 
					 | 
				
			||||||
				memcpy(skins[i].inverseBindMatrices.data(), &buffer.data[accessor.byteOffset + bufferview.byteOffset], accessor.count * sizeof(glm::mat4));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				//create a host visible shader buffer to store inverse bind matrices for this skin
 | 
					 | 
				
			||||||
				VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
 | 
					 | 
				
			||||||
					&skins[i].ssbo,
 | 
					 | 
				
			||||||
					sizeof(glm::mat4) * skins[i].inverseBindMatrices.size(),
 | 
					 | 
				
			||||||
					skins[i].inverseBindMatrices.data()));
 | 
					 | 
				
			||||||
				VK_CHECK_RESULT(skins[i].ssbo.map());
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
		vertex skinning functions
 | 
							vertex skinning functions
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
| 
						 | 
					@ -456,6 +458,19 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nodeMatrix;
 | 
							return nodeMatrix;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						void VulkanglTFModel::updateNodeMatrix(Node* node, std::vector<glm::mat4>& nodeMatrics)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (node->skin <= -1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								nodeMatrics[node->index] = getNodeMatrix(node);
 | 
				
			||||||
 | 
								for (auto& child : node->children)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								updateNodeMatrix(child, nodeMatrics);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void VulkanglTFModel::updateJoints(VulkanglTFModel::Node* node)
 | 
						void VulkanglTFModel::updateJoints(VulkanglTFModel::Node* node)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -478,7 +493,7 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void VulkanglTFModel::updateAnimation(float deltaTime)
 | 
						void VulkanglTFModel::updateAnimation(float deltaTime,vks::Buffer buffer)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (activeAnimation > static_cast<uint32_t>(animations.size()) - 1)
 | 
							if (activeAnimation > static_cast<uint32_t>(animations.size()) - 1)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -495,7 +510,7 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
		for (auto& channel : animation.channels)
 | 
							for (auto& channel : animation.channels)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			AnimationSampler& sampler = animation.samplers[channel.samplerIndex];
 | 
								AnimationSampler& sampler = animation.samplers[channel.samplerIndex];
 | 
				
			||||||
			for (size_t i = 0; i < sampler.inputs.size() - 1; i++)
 | 
								for (size_t i = 0; i < sampler.inputs.size() - 1; ++i)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if (sampler.interpolation != "LINEAR")
 | 
									if (sampler.interpolation != "LINEAR")
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
| 
						 | 
					@ -506,10 +521,10 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
				// Get the input keyframe values for the current time stamp
 | 
									// Get the input keyframe values for the current time stamp
 | 
				
			||||||
				if ((animation.currentTime >= sampler.inputs[i]) && (animation.currentTime <= sampler.inputs[i + 1]))
 | 
									if ((animation.currentTime >= sampler.inputs[i]) && (animation.currentTime <= sampler.inputs[i + 1]))
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					float a = (animation.currentTime - sampler.inputs[i]) / (sampler.inputs[i + 1] - sampler.inputs[i]);
 | 
										float ratio = (animation.currentTime - sampler.inputs[i]) / (sampler.inputs[i + 1] - sampler.inputs[i]);
 | 
				
			||||||
					if (channel.path == "translation")
 | 
										if (channel.path == "translation")
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						channel.node->translation = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], a);
 | 
											channel.node->translation = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], ratio);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if (channel.path == "rotation")
 | 
										if (channel.path == "rotation")
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
| 
						 | 
					@ -525,19 +540,25 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
						q2.z = sampler.outputsVec4[i + 1].z;
 | 
											q2.z = sampler.outputsVec4[i + 1].z;
 | 
				
			||||||
						q2.w = sampler.outputsVec4[i + 1].w;
 | 
											q2.w = sampler.outputsVec4[i + 1].w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						channel.node->rotation = glm::normalize(glm::slerp(q1, q2, a));
 | 
											channel.node->rotation = glm::normalize(glm::slerp(q1, q2, ratio));
 | 
				
			||||||
 | 
											channel.node->bAnimateNode = true;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if (channel.path == "scale")
 | 
										if (channel.path == "scale")
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						channel.node->scale = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], a);
 | 
											channel.node->scale = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], ratio);
 | 
				
			||||||
 | 
											channel.node->bAnimateNode = true;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							//if no skin in model , update node matrix to update animation stage
 | 
				
			||||||
 | 
							std::vector<glm::mat4> nodeMatrics(nodeCount);
 | 
				
			||||||
		for (auto& node : nodes)
 | 
							for (auto& node : nodes)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			updateJoints(node);
 | 
								updateJoints(node);
 | 
				
			||||||
 | 
								updateNodeMatrix(node, nodeMatrics);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							buffer.copyTo(nodeMatrics.data(), nodeCount * sizeof(glm::mat4));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -558,8 +579,11 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// Pass the final matrix to the vertex shader using push constants
 | 
								// Pass the final matrix to the vertex shader using push constants
 | 
				
			||||||
			vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &nodeMatrix);
 | 
								vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &nodeMatrix);
 | 
				
			||||||
 | 
								if (skins.size() != 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &skins[node.skin].descriptorSet, 0, nullptr);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &skins[node.skin].descriptorSet, 0, nullptr);
 | 
					 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (VulkanglTFModel::Primitive& primitive : node.mesh.primitives) {
 | 
								for (VulkanglTFModel::Primitive& primitive : node.mesh.primitives) {
 | 
				
			||||||
| 
						 | 
					@ -693,6 +717,7 @@ void VulkanExample::getEnabledFeatures()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (fileLoaded) 
 | 
							if (fileLoaded) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								glTFModel.nodeCount = static_cast<uint32_t>(glTFInput.nodes.size());
 | 
				
			||||||
			glTFModel.loadImages(glTFInput);
 | 
								glTFModel.loadImages(glTFInput);
 | 
				
			||||||
			glTFModel.loadMaterials(glTFInput);
 | 
								glTFModel.loadMaterials(glTFInput);
 | 
				
			||||||
			glTFModel.loadTextures(glTFInput);
 | 
								glTFModel.loadTextures(glTFInput);
 | 
				
			||||||
| 
						 | 
					@ -791,7 +816,7 @@ void VulkanExample::getEnabledFeatures()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void VulkanExample::loadAssets()
 | 
						void VulkanExample::loadAssets()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		loadglTFFile(getAssetPath() + "models/CesiumMan/glTF/CesiumMan.gltf");
 | 
							loadglTFFile(getAssetPath() + "buster_drone/busterDrone.gltf");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void VulkanExample::setupDescriptors()
 | 
						void VulkanExample::setupDescriptors()
 | 
				
			||||||
| 
						 | 
					@ -972,7 +997,7 @@ void VulkanExample::getEnabledFeatures()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!paused)
 | 
							if (!paused)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			glTFModel.updateAnimation(frameTimer);
 | 
								glTFModel.updateAnimation(frameTimer,shaderData.buffer);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -988,6 +1013,10 @@ void VulkanExample::getEnabledFeatures()
 | 
				
			||||||
				buildCommandBuffers();
 | 
									buildCommandBuffers();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (overlay->header("Animation"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								overlay->checkBox("pause", &paused);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,7 @@ public:
 | 
				
			||||||
	// The class requires some Vulkan objects so it can create it's own resources
 | 
						// The class requires some Vulkan objects so it can create it's own resources
 | 
				
			||||||
	vks::VulkanDevice* vulkanDevice;
 | 
						vks::VulkanDevice* vulkanDevice;
 | 
				
			||||||
	VkQueue copyQueue;
 | 
						VkQueue copyQueue;
 | 
				
			||||||
 | 
						uint32_t nodeCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The vertex layout for the samples' model
 | 
						// The vertex layout for the samples' model
 | 
				
			||||||
	struct Vertex {
 | 
						struct Vertex {
 | 
				
			||||||
| 
						 | 
					@ -83,8 +84,22 @@ public:
 | 
				
			||||||
		glm::vec3 scale{ 1.0f };
 | 
							glm::vec3 scale{ 1.0f };
 | 
				
			||||||
		glm::quat rotation{};
 | 
							glm::quat rotation{};
 | 
				
			||||||
		int32_t             skin = -1;
 | 
							int32_t             skin = -1;
 | 
				
			||||||
		glm::mat4 getLocalMatrix();
 | 
							glm::mat4 getLocalMatrix()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return bAnimateNode ? glm::translate(glm::mat4(1.0f), translation) * glm::mat4(rotation) * glm::scale(glm::mat4(1.0f), scale) : matrix;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		glm::mat4 matrix;
 | 
							glm::mat4 matrix;
 | 
				
			||||||
 | 
							bool bAnimateNode = false;
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							~Node() {
 | 
				
			||||||
 | 
								for (auto& child : children) {
 | 
				
			||||||
 | 
									delete child;
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							*/
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,6 +131,7 @@ public:
 | 
				
			||||||
		std::vector<Node*> joints;
 | 
							std::vector<Node*> joints;
 | 
				
			||||||
		vks::Buffer ssbo;
 | 
							vks::Buffer ssbo;
 | 
				
			||||||
		VkDescriptorSet descriptorSet;
 | 
							VkDescriptorSet descriptorSet;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct AnimationSampler
 | 
						struct AnimationSampler
 | 
				
			||||||
| 
						 | 
					@ -170,8 +186,9 @@ public:
 | 
				
			||||||
	void      loadAnimations(tinygltf::Model& input);
 | 
						void      loadAnimations(tinygltf::Model& input);
 | 
				
			||||||
	void      loadNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, VulkanglTFModel::Node* parent, uint32_t nodeIndex, std::vector<uint32_t>& indexBuffer, std::vector<VulkanglTFModel::Vertex>& vertexBuffer);
 | 
						void      loadNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, VulkanglTFModel::Node* parent, uint32_t nodeIndex, std::vector<uint32_t>& indexBuffer, std::vector<VulkanglTFModel::Vertex>& vertexBuffer);
 | 
				
			||||||
	glm::mat4 getNodeMatrix(VulkanglTFModel::Node* node);
 | 
						glm::mat4 getNodeMatrix(VulkanglTFModel::Node* node);
 | 
				
			||||||
 | 
						void updateNodeMatrix(Node* node, std::vector<glm::mat4>& nodeMatrics);
 | 
				
			||||||
	void      updateJoints(VulkanglTFModel::Node* node);
 | 
						void      updateJoints(VulkanglTFModel::Node* node);
 | 
				
			||||||
	void      updateAnimation(float deltaTime);
 | 
						void      updateAnimation(float deltaTime,vks::Buffer buffer);
 | 
				
			||||||
	void drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFModel::Node node);
 | 
						void drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFModel::Node node);
 | 
				
			||||||
	void      draw(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout);
 | 
						void      draw(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue