diff options
| author | Marijn Tamis <[email protected]> | 2018-05-03 18:22:48 +0200 |
|---|---|---|
| committer | Marijn Tamis <[email protected]> | 2018-05-03 18:22:48 +0200 |
| commit | ca32c59a58d37c1822e185a2d5f3d0d3e8943593 (patch) | |
| tree | b06b9eec03f34344ef8fc31aa147b2714d3962ee /NvCloth/samples/SampleBase/renderer/WeightedSkinRenderMesh.cpp | |
| parent | Forced rename of platform folders in cmake dir. Git didn't pick this up before. (diff) | |
| download | nvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.tar.xz nvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.zip | |
NvCloth 1.1.4 Release. (24070740)
Diffstat (limited to 'NvCloth/samples/SampleBase/renderer/WeightedSkinRenderMesh.cpp')
| -rw-r--r-- | NvCloth/samples/SampleBase/renderer/WeightedSkinRenderMesh.cpp | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/NvCloth/samples/SampleBase/renderer/WeightedSkinRenderMesh.cpp b/NvCloth/samples/SampleBase/renderer/WeightedSkinRenderMesh.cpp new file mode 100644 index 0000000..b0fc4f1 --- /dev/null +++ b/NvCloth/samples/SampleBase/renderer/WeightedSkinRenderMesh.cpp @@ -0,0 +1,219 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + + +#include "WeightedSkinRenderMesh.h" +#include "Renderer.h" +#include "Model.h" + +WeightedSkinRenderMesh::WeightedSkinRenderMesh(const Model* model) +{ + PX_ASSERT_WITH_MESSAGE(meshes.size() <= MeshesCountMax, "meshes.size() have to be <= WeightedSkinRenderMesh::MeshesCountMax"); + + m_model = model; + m_modelInstance.mAnimationIndex = 0; + m_modelInstance.mAnimationTime = 0.0f; + + m_device = GetDeviceManager()->GetDevice(); + + // input element desc setup + m_inputDesc.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + m_inputDesc.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + m_inputDesc.push_back({ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }); //uv + m_inputDesc.push_back({ "TEXCOORD", 1, DXGI_FORMAT_R32G32B32A32_UINT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0 }); //bone Indices + m_inputDesc.push_back({ "TEXCOORD", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0}); //bone weights + + ID3D11DeviceContext* context; + m_device->GetImmediateContext(&context); + + // reserve VB + uint32_t verticesTotal = model->getTotalVertexCount(); + std::vector<SkinnedMesh::Vertex> vertexBuffer; + vertexBuffer.reserve(verticesTotal); + + // reserve IB + uint32_t indicesTotal = model->getTotalIndexCount(); + m_indices.reserve(indicesTotal); + + // fill VB, IB, MeshInfo + m_meshesInfo.resize(model->getSubMeshCount()); + m_submeshCount = model->getTotalSubmeshInstanceCount(); + for (int meshIndex = 0; meshIndex < m_submeshCount; ++meshIndex) + { + const SkinnedMesh* mesh = &model->getSubMesh(meshIndex); + MeshInfo& meshInfo = m_meshesInfo[meshIndex]; + + meshInfo.firstVertex = (uint32_t)vertexBuffer.size(); + vertexBuffer.insert(vertexBuffer.end(), mesh->vertices.begin(), mesh->vertices.end()); + meshInfo.verticesCount = (uint32_t)mesh->vertices.size(); + + meshInfo.firstIndex = (uint32_t)m_indices.size(); + uint32_t indexOffset = meshInfo.firstVertex; + for (uint32_t index : mesh->indices) + { + m_indices.push_back((uint32_t)index); + } + meshInfo.indicesCount = (uint32_t)mesh->indices.size(); + } + + // vertex buffer + { + D3D11_SUBRESOURCE_DATA vertexBufferData; + + ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); + vertexBufferData.pSysMem = vertexBuffer.data(); + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (uint32_t)(sizeof(SkinnedMesh::Vertex) * vertexBuffer.size()); + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + + V(m_device->CreateBuffer(&bufferDesc, &vertexBufferData, &m_vertexBuffer)); + } + + // index buffer + { + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc.ByteWidth = (uint32_t)(sizeof(uint32_t) * m_indices.size()); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(m_device->CreateBuffer(&bufferDesc, nullptr, &m_indexBuffer)); + } + + // bone texture + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = 4; + desc.Height = (uint32_t)model->getNodeCount()*(1+model->getSubMeshCount()); //transforms and bind pose transforms + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + V(m_device->CreateTexture2D(&desc, nullptr, &m_boneTexture)); + } + + // bone texture SRV + { + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipLevels = 1; + desc.Texture2D.MostDetailedMip = 0; + V(m_device->CreateShaderResourceView(m_boneTexture, &desc, &m_boneTextureSRV)); + } + + // update index buffer + { + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + uint32_t* indexBuffer = (uint32_t*)mappedRead.pData; + uint32_t indexCount = 0; + for(const MeshInfo& info : m_meshesInfo) + { + memcpy(indexBuffer + indexCount, &m_indices[info.firstIndex], info.indicesCount * sizeof(uint32_t)); + indexCount += info.indicesCount; + } + context->Unmap(m_indexBuffer, 0); + m_indexCount = indexCount; + PX_ASSERT(m_indexCount % 3 == 0); + } +} + +WeightedSkinRenderMesh::~WeightedSkinRenderMesh() +{ + SAFE_RELEASE(m_vertexBuffer); + SAFE_RELEASE(m_indexBuffer); + SAFE_RELEASE(m_boneTexture); + SAFE_RELEASE(m_boneTextureSRV); +} + +void WeightedSkinRenderMesh::updateVisibleMeshTransforms(float deltatime, physx::PxMat44 transform) +{ + m_modelInstance.mAnimationTime += deltatime; + m_model->updateModelInstance(m_modelInstance, transform); + + + ID3D11DeviceContext* context; + m_device->GetImmediateContext(&context); + + // update bone transform texture + { + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(m_boneTexture, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + for (uint32_t i = 0; i < m_modelInstance.mNodes.size(); ++i) + { + std::memcpy((uint8_t*)mappedRead.pData + i * mappedRead.RowPitch, &m_modelInstance.mNodes[i].mTransform, sizeof(PxMat44)); + } + + //probably should separate this in to a different texture as it doesn't change + for(int submeshId = 0; submeshId < m_model->getSubMeshCount(); submeshId++) + { + auto& submesh = m_model->getSubMesh(submeshId); + int offset = (1 + submeshId) * (int)m_modelInstance.mNodes.size(); + for(int i = 0; i < m_model->getNodeCount(); ++i) + { + std::memcpy((uint8_t*)mappedRead.pData + (i+offset) * mappedRead.RowPitch, &submesh.mBoneOffsets[i], sizeof(PxMat44)); + } + } + context->Unmap(m_boneTexture, 0); + } +} + +int WeightedSkinRenderMesh::getBoneCount() const +{ + return (int)m_modelInstance.mNodes.size(); +} + +void WeightedSkinRenderMesh::render(ID3D11DeviceContext& context, int submesh) const +{ + Model::SubmeshInstance submeshInstance = m_model->getSubMeshInstance(submesh); + + context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + UINT strides[1] = { sizeof(SkinnedMesh::Vertex)}; + UINT offsets[1] = { 0 }; + ID3D11Buffer* buffers[1] = { m_vertexBuffer }; + context.IASetVertexBuffers(0, 1, buffers, strides, offsets); + + context.IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0); + + context.VSSetShaderResources(1, 1, &m_boneTextureSRV); + + context.DrawIndexed(m_meshesInfo[submeshInstance.mSubmeshId].indicesCount, m_meshesInfo[submeshInstance.mSubmeshId].firstIndex, m_meshesInfo[submeshInstance.mSubmeshId].firstVertex); +} + +physx::PxMat44 WeightedSkinRenderMesh::getRenderSubmeshTransform(int submesh) +{ + Model::SubmeshInstance submeshInstance = m_model->getSubMeshInstance(submesh); + return m_modelInstance.mNodes[submeshInstance.mParrentNodeId].mTransform; +} + +bool WeightedSkinRenderMesh::isRenderSubmeshHidden(int submesh) +{ + Model::SubmeshInstance submeshInstance = m_model->getSubMeshInstance(submesh); + return m_modelInstance.mNodes[submeshInstance.mParrentNodeId].mHidden; +}
\ No newline at end of file |