Integrating up through commit 90f050496
This commit is contained in:
+30
-1
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <Generation/Components/TangentGenerator/TangentGenerateComponent.h>
|
||||
#include <Generation/Components/TangentGenerator/TangentGenerators/MikkTGenerator.h>
|
||||
#include <Generation/Components/TangentGenerator/TangentGenerators/BlendShapeMikkTGenerator.h>
|
||||
|
||||
#include <SceneAPI/SceneCore/DataTypes/Groups/IGroup.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshVertexUVData.h>
|
||||
@@ -28,6 +29,7 @@
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/DataTypeUtilities.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshVertexBitangentData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshVertexTangentData.h>
|
||||
|
||||
@@ -169,6 +171,24 @@ namespace AZ::SceneGenerationComponents
|
||||
}
|
||||
}
|
||||
|
||||
void TangentGenerateComponent::FindBlendShapes(
|
||||
AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex,
|
||||
AZStd::vector<AZ::SceneData::GraphData::BlendShapeData*>& outBlendShapes) const
|
||||
{
|
||||
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
|
||||
|
||||
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(
|
||||
graph, nodeIndex, nameContentView.begin(), true);
|
||||
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
|
||||
{
|
||||
AZ::SceneData::GraphData::BlendShapeData* blendShape =
|
||||
azrtti_cast<AZ::SceneData::GraphData::BlendShapeData*>(child->second.get());
|
||||
if (blendShape)
|
||||
{
|
||||
outBlendShapes.emplace_back(blendShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TangentGenerateComponent::GenerateTangentsForMesh(AZ::SceneAPI::Containers::Scene& scene, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::SceneAPI::DataTypes::IMeshData* meshData)
|
||||
{
|
||||
@@ -202,6 +222,10 @@ namespace AZ::SceneGenerationComponents
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find all blend shape data under the mesh. We need to generate the tangent and bitangent for blend shape as well.
|
||||
AZStd::vector<AZ::SceneData::GraphData::BlendShapeData*> blendShapes;
|
||||
FindBlendShapes(graph, nodeIndex, blendShapes);
|
||||
|
||||
// Generate all the tangent spaces we need.
|
||||
// Do this for every UV set.
|
||||
bool allSuccess = true;
|
||||
@@ -222,7 +246,12 @@ namespace AZ::SceneGenerationComponents
|
||||
// Generate using MikkT space.
|
||||
case AZ::SceneAPI::DataTypes::TangentSpace::MikkT:
|
||||
{
|
||||
allSuccess &= AZ::TangentGeneration::MikkT::GenerateTangents(scene.GetManifest(), graph, nodeIndex, const_cast<AZ::SceneAPI::DataTypes::IMeshData*>(meshData), uvSetIndex);
|
||||
allSuccess &= AZ::TangentGeneration::Mesh::MikkT::GenerateTangents(
|
||||
scene.GetManifest(), graph, nodeIndex, const_cast<AZ::SceneAPI::DataTypes::IMeshData*>(meshData), uvSetIndex);
|
||||
for (AZ::SceneData::GraphData::BlendShapeData* blendShape : blendShapes)
|
||||
{
|
||||
allSuccess &= AZ::TangentGeneration::BlendShape::MikkT::GenerateTangents(blendShape, uvSetIndex);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+7
@@ -21,6 +21,10 @@ namespace AZ::SceneAPI::DataTypes { class IMeshVertexUVData; }
|
||||
namespace AZ::SceneAPI::DataTypes { class IMeshVertexTangentData; }
|
||||
namespace AZ::SceneAPI::DataTypes { class IMeshVertexBitangentData; }
|
||||
namespace AZ::SceneAPI::DataTypes { enum class TangentSpace; }
|
||||
namespace AZ::SceneData::GraphData
|
||||
{
|
||||
class BlendShapeData;
|
||||
}
|
||||
|
||||
namespace AZ::SceneGenerationComponents
|
||||
{
|
||||
@@ -56,6 +60,9 @@ namespace AZ::SceneGenerationComponents
|
||||
AZ::SceneAPI::Events::ProcessingResult GenerateTangentData(TangentGenerateContext& context);
|
||||
|
||||
private:
|
||||
void FindBlendShapes(
|
||||
AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex,
|
||||
AZStd::vector<AZ::SceneData::GraphData::BlendShapeData*>& outBlendShapes) const;
|
||||
bool GenerateTangentsForMesh(AZ::SceneAPI::Containers::Scene& scene, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::SceneAPI::DataTypes::IMeshData* meshData);
|
||||
void UpdateFbxTangentWValues(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, const AZ::SceneAPI::DataTypes::IMeshData* meshData);
|
||||
AZStd::vector<AZ::SceneAPI::DataTypes::TangentSpace> CollectRequiredTangentSpaces(const AZ::SceneAPI::Containers::Scene& scene) const;
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Generation/Components/TangentGenerator/TangentGenerators/BlendShapeMikkTGenerator.h>
|
||||
#include <Generation/Components/TangentGenerator/TangentGenerateComponent.h>
|
||||
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
|
||||
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Vector4.h>
|
||||
|
||||
#include <mikkelsen/mikktspace.h>
|
||||
|
||||
namespace AZ::TangentGeneration::BlendShape::MikkT
|
||||
{
|
||||
// Returns the number of triangles in the mesh.
|
||||
int GetNumFaces(const SMikkTSpaceContext* context)
|
||||
{
|
||||
MikktCustomData* customData = static_cast<MikktCustomData*>(context->m_pUserData);
|
||||
return customData->m_blendShapeData->GetFaceCount();
|
||||
}
|
||||
|
||||
int GetNumVerticesOfFace([[maybe_unused]] const SMikkTSpaceContext* context, [[maybe_unused]] const int face)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
void GetPosition(const SMikkTSpaceContext* context, float posOut[], const int face, const int vert)
|
||||
{
|
||||
MikktCustomData* customData = static_cast<MikktCustomData*>(context->m_pUserData);
|
||||
const AZ::u32 vertexIndex = customData->m_blendShapeData->GetFaceVertexIndex(face, vert);
|
||||
const AZ::Vector3& pos = customData->m_blendShapeData->GetPosition(vertexIndex);
|
||||
posOut[0] = pos.GetX();
|
||||
posOut[1] = pos.GetY();
|
||||
posOut[2] = pos.GetZ();
|
||||
}
|
||||
|
||||
void GetNormal(const SMikkTSpaceContext* context, float normOut[], const int face, const int vert)
|
||||
{
|
||||
MikktCustomData* customData = static_cast<MikktCustomData*>(context->m_pUserData);
|
||||
const AZ::u32 vertexIndex = customData->m_blendShapeData->GetFaceVertexIndex(face, vert);
|
||||
const AZ::Vector3 normal = customData->m_blendShapeData->GetNormal(vertexIndex).GetNormalizedSafe();
|
||||
normOut[0] = normal.GetX();
|
||||
normOut[1] = normal.GetY();
|
||||
normOut[2] = normal.GetZ();
|
||||
}
|
||||
|
||||
void GetTexCoord(const SMikkTSpaceContext* context, float texOut[], const int face, const int vert)
|
||||
{
|
||||
MikktCustomData* customData = static_cast<MikktCustomData*>(context->m_pUserData);
|
||||
const AZ::u32 vertexIndex = customData->m_blendShapeData->GetFaceVertexIndex(face, vert);
|
||||
const AZ::Vector2& uv = customData->m_blendShapeData->GetUV(vertexIndex, customData->m_uvSetIndex);
|
||||
texOut[0] = uv.GetX();
|
||||
texOut[1] = uv.GetY();
|
||||
}
|
||||
|
||||
// This function is used to return tangent space results to the application.
|
||||
// tangent and bitangent are unit length vectors and magS and magT are their
|
||||
// true magnitudes which can be used for relief mapping effects.
|
||||
// bitangent is the "real" bitangent and thus may not be perpendicular to tangent.
|
||||
// However, both are perpendicular to the vertex normal.
|
||||
// For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
|
||||
// signValue = isOrientationPreserving ? 1.0f : -1.0f;
|
||||
// bitangent = signValue * cross(vN, tangent);
|
||||
void SetTSpace(const SMikkTSpaceContext* context, const float tangent[], const float bitangent[], const float magS, const float magT, const tbool isOrientationPreserving, const int face, const int vert)
|
||||
{
|
||||
MikktCustomData* customData = static_cast<MikktCustomData*>(context->m_pUserData);
|
||||
const AZ::u32 vertexIndex = customData->m_blendShapeData->GetFaceVertexIndex(face, vert);
|
||||
const float flipSign = isOrientationPreserving ? 1.0f : -1.0f;
|
||||
const AZ::Vector4 tangentVec(tangent[0]*magS, tangent[1]*magS, tangent[2]*magS, flipSign);
|
||||
const AZ::Vector3 bitangentVec(bitangent[0]*magT, bitangent[1]*magT, bitangent[2]*magT);
|
||||
|
||||
// Set the tangent and bitangent back to the blendshape
|
||||
AZStd::vector<AZ::Vector4>& tangents = customData->m_blendShapeData->GetTangents();
|
||||
AZStd::vector<AZ::Vector3>& bitangents = customData->m_blendShapeData->GetBitangents();
|
||||
tangents[vertexIndex] = tangentVec;
|
||||
bitangents[vertexIndex] = bitangentVec;
|
||||
}
|
||||
|
||||
bool GenerateTangents(AZ::SceneData::GraphData::BlendShapeData* blendShapeData, size_t uvSetIndex)
|
||||
{
|
||||
// Create tangent and bitangent data sets and relate them to the given UV set.
|
||||
const AZStd::vector<AZ::Vector2>& uvSet = blendShapeData->GetUVs(uvSetIndex);
|
||||
if (uvSet.empty())
|
||||
{
|
||||
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Cannot find UV data (set index=%d) to generate tangents and bitangents from in MikkT generator!\n", uvSetIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::Vector4>& tangents = blendShapeData->GetTangents();
|
||||
AZStd::vector<AZ::Vector3>& bitangents = blendShapeData->GetBitangents();
|
||||
if (!tangents.empty() || !bitangents.empty())
|
||||
{
|
||||
AZ_TracePrintf(
|
||||
AZ::SceneAPI::Utilities::WarningWindow, "Cannot generate tangents and bitangents because existing tangent or bitangent data has been found.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pre-allocate the tangent and bitangent data.
|
||||
tangents.resize(blendShapeData->GetVertexCount());
|
||||
bitangents.resize(blendShapeData->GetVertexCount());
|
||||
|
||||
//----------------------------------
|
||||
|
||||
// Provide the MikkT interface.
|
||||
SMikkTSpaceInterface mikkInterface;
|
||||
mikkInterface.m_getNumFaces = GetNumFaces;
|
||||
mikkInterface.m_getNormal = GetNormal;
|
||||
mikkInterface.m_getPosition = GetPosition;
|
||||
mikkInterface.m_getTexCoord = GetTexCoord;
|
||||
mikkInterface.m_setTSpace = SetTSpace;
|
||||
mikkInterface.m_setTSpaceBasic = nullptr;
|
||||
mikkInterface.m_getNumVerticesOfFace= GetNumVerticesOfFace;
|
||||
|
||||
// Set the MikkT custom data.
|
||||
MikktCustomData customData;
|
||||
customData.m_blendShapeData = blendShapeData;
|
||||
customData.m_uvSetIndex = uvSetIndex;
|
||||
|
||||
// Generate the tangents.
|
||||
SMikkTSpaceContext mikkContext;
|
||||
mikkContext.m_pInterface = &mikkInterface;
|
||||
mikkContext.m_pUserData = &customData;
|
||||
if (genTangSpaceDefault(&mikkContext) == 0)
|
||||
{
|
||||
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Failed to generate tangents and bitangents using MikkT for blend shape, because MikkT reported failure!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace AZ::TangentGeneration::MikkT
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
|
||||
namespace AZ::SceneData::GraphData
|
||||
{
|
||||
class BlendShapeData;
|
||||
}
|
||||
|
||||
namespace AZ::TangentGeneration::BlendShape::MikkT
|
||||
{
|
||||
struct MikktCustomData
|
||||
{
|
||||
AZ::SceneData::GraphData::BlendShapeData* m_blendShapeData;
|
||||
size_t m_uvSetIndex;
|
||||
};
|
||||
|
||||
// The main generation method.
|
||||
bool GenerateTangents(AZ::SceneData::GraphData::BlendShapeData* blendShapeData, size_t uvSetIndex);
|
||||
} // namespace AZ::TangentGeneration::MikkT
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <mikkelsen/mikktspace.h>
|
||||
|
||||
namespace AZ::TangentGeneration::MikkT
|
||||
namespace AZ::TangentGeneration::Mesh::MikkT
|
||||
{
|
||||
// Returns the number of triangles in the mesh.
|
||||
int GetNumFaces(const SMikkTSpaceContext* context)
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ namespace AZ::SceneAPI::DataTypes { class IMeshVertexUVData; }
|
||||
namespace AZ::SceneAPI::DataTypes { class IMeshVertexTangentData; }
|
||||
namespace AZ::SceneAPI::DataTypes { class IMeshVertexBitangentData; }
|
||||
|
||||
namespace AZ::TangentGeneration::MikkT
|
||||
namespace AZ::TangentGeneration::Mesh::MikkT
|
||||
{
|
||||
struct MikktCustomData
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace SceneBuilder
|
||||
builderDescriptor.m_createJobFunction = AZStd::bind(&SceneBuilderWorker::CreateJobs, &m_sceneBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||
builderDescriptor.m_processJobFunction = AZStd::bind(&SceneBuilderWorker::ProcessJob, &m_sceneBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||
|
||||
builderDescriptor.m_version = 4; // bump this to rebuild everything.
|
||||
builderDescriptor.m_version = 5; // bump this to rebuild everything.
|
||||
builderDescriptor.m_analysisFingerprint = m_sceneBuilder.GetFingerprint(); // bump this to at least re-analyze everything.
|
||||
|
||||
m_sceneBuilder.BusConnect(builderDescriptor.m_busId);
|
||||
|
||||
Reference in New Issue
Block a user