bug fix
							parent
							
								
									2aa0ab76d1
								
							
						
					
					
						commit
						3532369f08
					
				| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
{
 | 
			
		||||
  "configurations": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "x64-Debug",
 | 
			
		||||
      "generator": "Ninja",
 | 
			
		||||
      "configurationType": "Debug",
 | 
			
		||||
      "inheritEnvironments": [ "msvc_x64_x64" ],
 | 
			
		||||
      "buildRoot": "${projectDir}\\out\\build\\${name}",
 | 
			
		||||
      "installRoot": "${projectDir}\\out\\install\\${name}",
 | 
			
		||||
      "cmakeCommandArgs": "",
 | 
			
		||||
      "buildCommandArgs": "",
 | 
			
		||||
      "ctestCommandArgs": ""
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "x64-Clang-Debug",
 | 
			
		||||
      "generator": "Ninja",
 | 
			
		||||
      "configurationType": "Debug",
 | 
			
		||||
      "buildRoot": "${projectDir}\\out\\build\\${name}",
 | 
			
		||||
      "installRoot": "${projectDir}\\out\\install\\${name}",
 | 
			
		||||
      "cmakeCommandArgs": "",
 | 
			
		||||
      "buildCommandArgs": "",
 | 
			
		||||
      "ctestCommandArgs": "",
 | 
			
		||||
      "inheritEnvironments": [ "clang_cl_x64_x64" ],
 | 
			
		||||
      "variables": []
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -157,26 +157,26 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
			
		|||
			tinygltf::Animation glTFAnimation = input.animations[i];
 | 
			
		||||
			animations[i].name = glTFAnimation.name;
 | 
			
		||||
 | 
			
		||||
			// Samplers
 | 
			
		||||
			animations[i].samplers.resize(glTFAnimation.samplers.size());
 | 
			
		||||
			for (size_t j = 0; j < glTFAnimation.samplers.size(); j++)
 | 
			
		||||
			{
 | 
			
		||||
				tinygltf::AnimationSampler glTFSampler = glTFAnimation.samplers[j];
 | 
			
		||||
				AnimationSampler& dstSampler = animations[i].samplers[j];
 | 
			
		||||
				dstSampler.interpolation = glTFSampler.interpolation;
 | 
			
		||||
				//sample keyframes to input
 | 
			
		||||
 | 
			
		||||
				// Read sampler keyframe input time values
 | 
			
		||||
				{
 | 
			
		||||
					const tinygltf::Accessor& accessor = input.accessors[glTFSampler.input];
 | 
			
		||||
					const tinygltf::BufferView& bufferView = input.bufferViews[accessor.bufferView];
 | 
			
		||||
					const tinygltf::Buffer& buffer = input.buffers[bufferView.buffer];
 | 
			
		||||
					//data pointer
 | 
			
		||||
					const void* dataptr = &buffer.data[accessor.byteOffset + bufferView.byteOffset];
 | 
			
		||||
					const float* buf = static_cast<const float*>(dataptr);
 | 
			
		||||
 | 
			
		||||
					const void* dataPtr = &buffer.data[accessor.byteOffset + bufferView.byteOffset];
 | 
			
		||||
					const float* buf = static_cast<const float*>(dataPtr);
 | 
			
		||||
					for (size_t index = 0; index < accessor.count; index++)
 | 
			
		||||
					{
 | 
			
		||||
						dstSampler.inputs.push_back(buf[index]);
 | 
			
		||||
					}
 | 
			
		||||
					//switch value for correct start and end time
 | 
			
		||||
					// Adjust animation's start and end times
 | 
			
		||||
					for (auto input : animations[i].samplers[j].inputs)
 | 
			
		||||
					{
 | 
			
		||||
						if (input < animations[i].start)
 | 
			
		||||
| 
						 | 
				
			
			@ -189,43 +189,40 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
			
		|||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				//identify accessor type for keyframes to output translate/rotate/scale values
 | 
			
		||||
 | 
			
		||||
				// Read sampler keyframe output translate/rotate/scale values
 | 
			
		||||
				{
 | 
			
		||||
					const tinygltf::Accessor& accessor = input.accessors[glTFSampler.input];
 | 
			
		||||
					const tinygltf::Accessor& accessor = input.accessors[glTFSampler.output];
 | 
			
		||||
					const tinygltf::BufferView& bufferView = input.bufferViews[accessor.bufferView];
 | 
			
		||||
					const tinygltf::Buffer& buffer = input.buffers[bufferView.buffer];
 | 
			
		||||
					//data pointer
 | 
			
		||||
					const void* dataptr = &buffer.data[accessor.byteOffset + bufferView.byteOffset];
 | 
			
		||||
					
 | 
			
		||||
					const void* dataPtr = &buffer.data[accessor.byteOffset + bufferView.byteOffset];
 | 
			
		||||
					switch (accessor.type)
 | 
			
		||||
					{
 | 
			
		||||
					case TINYGLTF_TYPE_VEC3:
 | 
			
		||||
					{
 | 
			
		||||
						const glm::vec3* buf = static_cast<const glm::vec3*> (dataptr);
 | 
			
		||||
					case TINYGLTF_TYPE_VEC3: {
 | 
			
		||||
						const glm::vec3* buf = static_cast<const glm::vec3*>(dataPtr);
 | 
			
		||||
						for (size_t index = 0; index < accessor.count; index++)
 | 
			
		||||
						{
 | 
			
		||||
							dstSampler.outputsVec4.push_back(glm::vec4(buf[index], 0.0f));
 | 
			
		||||
 | 
			
		||||
						}
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					case TINYGLTF_TYPE_VEC4:
 | 
			
		||||
					{
 | 
			
		||||
						const glm::vec4* buf = static_cast<const glm::vec4*>(dataptr);
 | 
			
		||||
					case TINYGLTF_TYPE_VEC4: {
 | 
			
		||||
						const glm::vec4* buf = static_cast<const glm::vec4*>(dataPtr);
 | 
			
		||||
						for (size_t index = 0; index < accessor.count; index++)
 | 
			
		||||
						{
 | 
			
		||||
							dstSampler.outputsVec4.push_back(buf[index]);
 | 
			
		||||
						}
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					default:
 | 
			
		||||
					{
 | 
			
		||||
						std::cout << "unknown type in accessor" << std::endl;
 | 
			
		||||
					}
 | 
			
		||||
					default: {
 | 
			
		||||
						std::cout << "unknown type" << std::endl;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Channels
 | 
			
		||||
			animations[i].channels.resize(glTFAnimation.channels.size());
 | 
			
		||||
			for (size_t j = 0; j < glTFAnimation.channels.size(); j++)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -235,7 +232,6 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
			
		|||
				dstChannel.samplerIndex = glTFChannel.sampler;
 | 
			
		||||
				dstChannel.node = nodeFromIndex(glTFChannel.target_node);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
| 
						 | 
				
			
			@ -273,7 +269,7 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
			
		|||
		{
 | 
			
		||||
			for (size_t i = 0; i < inputNode.children.size(); i++)
 | 
			
		||||
			{
 | 
			
		||||
				VulkanglTFModel::loadNode(input.nodes[inputNode.children[i]], input, node, inputNode.children[i], indexBuffer, vertexBuffer);
 | 
			
		||||
				loadNode(input.nodes[inputNode.children[i]], input, node, inputNode.children[i], indexBuffer, vertexBuffer);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -486,7 +482,7 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
			
		|||
	{
 | 
			
		||||
		if (activeAnimation > static_cast<uint32_t>(animations.size()) - 1)
 | 
			
		||||
		{
 | 
			
		||||
			std::cout << "no animation with index" << activeAnimation << std::endl;
 | 
			
		||||
			std::cout << "No animation with index " << activeAnimation << std::endl;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		Animation& animation = animations[activeAnimation];
 | 
			
		||||
| 
						 | 
				
			
			@ -495,17 +491,19 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
			
		|||
		{
 | 
			
		||||
			animation.currentTime -= animation.end;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto& channel : animation.channels)
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
			AnimationSampler& sampler = animation.samplers[channel.samplerIndex];
 | 
			
		||||
			for (size_t i = 0; i < sampler.inputs.size() - 1; i++)
 | 
			
		||||
			{
 | 
			
		||||
				if (sampler.interpolation != "LINEAR")
 | 
			
		||||
				{
 | 
			
		||||
					std::cout << "sample only supports linear interpolaton" << std::endl;
 | 
			
		||||
					std::cout << "This sample only supports linear interpolations\n";
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Get the input keyframe values for the current time stamp
 | 
			
		||||
				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]);
 | 
			
		||||
| 
						 | 
				
			
			@ -515,7 +513,6 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
			
		|||
					}
 | 
			
		||||
					if (channel.path == "rotation")
 | 
			
		||||
					{
 | 
			
		||||
						//quaternion
 | 
			
		||||
						glm::quat q1;
 | 
			
		||||
						q1.x = sampler.outputsVec4[i].x;
 | 
			
		||||
						q1.y = sampler.outputsVec4[i].y;
 | 
			
		||||
| 
						 | 
				
			
			@ -523,13 +520,12 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
			
		|||
						q1.w = sampler.outputsVec4[i].w;
 | 
			
		||||
 | 
			
		||||
						glm::quat q2;
 | 
			
		||||
						q2.x = sampler.outputsVec4[i].x;
 | 
			
		||||
						q2.y = sampler.outputsVec4[i].y;
 | 
			
		||||
						q2.z = sampler.outputsVec4[i].z;
 | 
			
		||||
						q2.w = sampler.outputsVec4[i].w;
 | 
			
		||||
						q2.x = sampler.outputsVec4[i + 1].x;
 | 
			
		||||
						q2.y = sampler.outputsVec4[i + 1].y;
 | 
			
		||||
						q2.z = sampler.outputsVec4[i + 1].z;
 | 
			
		||||
						q2.w = sampler.outputsVec4[i + 1].w;
 | 
			
		||||
 | 
			
		||||
						channel.node->rotation = glm::normalize(glm::slerp(q1, q2, a));
 | 
			
		||||
 | 
			
		||||
					}
 | 
			
		||||
					if (channel.path == "scale")
 | 
			
		||||
					{
 | 
			
		||||
| 
						 | 
				
			
			@ -563,8 +559,7 @@ VulkanglTFModel::~VulkanglTFModel()
 | 
			
		|||
			// Pass the final matrix to the vertex shader using push constants
 | 
			
		||||
			vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &nodeMatrix);
 | 
			
		||||
			
 | 
			
		||||
			//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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -807,13 +802,12 @@ void VulkanExample::getEnabledFeatures()
 | 
			
		|||
 | 
			
		||||
		std::vector<VkDescriptorPoolSize> poolSizes = {
 | 
			
		||||
		vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1),
 | 
			
		||||
			// One combined image sampler per model image/texture
 | 
			
		||||
		// One combined image sampler per material image/texture
 | 
			
		||||
		vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, static_cast<uint32_t>(glTFModel.images.size())),
 | 
			
		||||
			//initialize descriptor pool size for skin
 | 
			
		||||
		// One ssbo per skin
 | 
			
		||||
		vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, static_cast<uint32_t>(glTFModel.skins.size())),
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		// One set for matrices and one per model image/texture
 | 
			
		||||
		// Number of descriptor sets = One for the scene ubo + one per image + one per skin
 | 
			
		||||
		const uint32_t             maxSetCount = static_cast<uint32_t>(glTFModel.images.size()) + static_cast<uint32_t>(glTFModel.skins.size()) + 1;
 | 
			
		||||
		VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, maxSetCount);
 | 
			
		||||
		VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
 | 
			
		||||
| 
						 | 
				
			
			@ -834,18 +828,18 @@ void VulkanExample::getEnabledFeatures()
 | 
			
		|||
		setLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0);
 | 
			
		||||
		VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.jointMatrices));
 | 
			
		||||
 | 
			
		||||
		// Pipeline layout using three descriptor sets (set 0 = matrices, set 1 = joint matrices, set 3 = material)
 | 
			
		||||
		std::array<VkDescriptorSetLayout, 3> setLayouts = 
 | 
			
		||||
		{ 
 | 
			
		||||
		// The pipeline layout uses three sets:
 | 
			
		||||
		// Set 0 = Scene matrices (VS)
 | 
			
		||||
		// Set 1 = Joint matrices (VS)
 | 
			
		||||
		// Set 2 = Material texture (FS)
 | 
			
		||||
		std::array<VkDescriptorSetLayout, 3> setLayouts = {
 | 
			
		||||
			descriptorSetLayouts.matrices,
 | 
			
		||||
			descriptorSetLayouts.jointMatrices,
 | 
			
		||||
			descriptorSetLayouts.textures 
 | 
			
		||||
		};
 | 
			
		||||
			descriptorSetLayouts.textures };
 | 
			
		||||
		VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast<uint32_t>(setLayouts.size()));
 | 
			
		||||
 | 
			
		||||
		// We will use push constants to push the local matrices of a primitive to the vertex shader
 | 
			
		||||
		VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(glm::mat4), 0);
 | 
			
		||||
 | 
			
		||||
		// Push constant ranges are part of the pipeline layout
 | 
			
		||||
		pipelineLayoutCI.pushConstantRangeCount = 1;
 | 
			
		||||
		pipelineLayoutCI.pPushConstantRanges = &pushConstantRange;
 | 
			
		||||
| 
						 | 
				
			
			@ -857,7 +851,7 @@ void VulkanExample::getEnabledFeatures()
 | 
			
		|||
		VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &shaderData.buffer.descriptor);
 | 
			
		||||
		vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
 | 
			
		||||
 | 
			
		||||
		//Descriptor sets for skin joint matrices
 | 
			
		||||
		// Descriptor set for glTF model skin joint matrices
 | 
			
		||||
		for (auto& skin : glTFModel.skins)
 | 
			
		||||
		{
 | 
			
		||||
			const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.jointMatrices, 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -866,15 +860,15 @@ void VulkanExample::getEnabledFeatures()
 | 
			
		|||
			vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Descriptor sets for materials
 | 
			
		||||
		for (auto& image : glTFModel.images) {
 | 
			
		||||
		// Descriptor sets for glTF model materials
 | 
			
		||||
		for (auto& image : glTFModel.images)
 | 
			
		||||
		{
 | 
			
		||||
			const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.textures, 1);
 | 
			
		||||
			VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &image.descriptorSet));
 | 
			
		||||
			VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(image.descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0, &image.texture.descriptor);
 | 
			
		||||
			vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void VulkanExample::preparePipelines()
 | 
			
		||||
| 
						 | 
				
			
			@ -893,13 +887,13 @@ void VulkanExample::getEnabledFeatures()
 | 
			
		|||
			vks::initializers::vertexInputBindingDescription(0, sizeof(VulkanglTFModel::Vertex), VK_VERTEX_INPUT_RATE_VERTEX),
 | 
			
		||||
		};
 | 
			
		||||
		const std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = {
 | 
			
		||||
			vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, pos)),	// Location 0: Position
 | 
			
		||||
			vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, normal)),// Location 1: Normal
 | 
			
		||||
			vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, uv)),	// Location 2: Texture coordinates
 | 
			
		||||
			vks::initializers::vertexInputAttributeDescription(0, 3, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, color)),	// Location 3: Color
 | 
			
		||||
			vks::initializers::vertexInputAttributeDescription(0, 4, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex,jointIndices)), // Location 4 : jointIndices
 | 
			
		||||
			vks::initializers::vertexInputAttributeDescription(0, 5, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex,jointWeights)), //Location 5 : jointWeights
 | 
			
		||||
 | 
			
		||||
		{0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, pos)},
 | 
			
		||||
		{1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, normal)},
 | 
			
		||||
		{2, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, uv)},
 | 
			
		||||
		{3, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, color)},
 | 
			
		||||
		// POI: Per-Vertex Joint indices and weights are passed to the vertex shader
 | 
			
		||||
		{4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(VulkanglTFModel::Vertex, jointIndices)},
 | 
			
		||||
		{5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(VulkanglTFModel::Vertex, jointWeights)},
 | 
			
		||||
		};
 | 
			
		||||
		VkPipelineVertexInputStateCreateInfo vertexInputStateCI = vks::initializers::pipelineVertexInputStateCreateInfo();
 | 
			
		||||
		vertexInputStateCI.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue