Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,177 @@
/*
* 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 <Exporting/Components/TangentGenerators/MikkTGenerator.h>
#include <Exporting/Components/TangentGenerateComponent.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshVertexUVData.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshVertexTangentData.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshVertexBitangentData.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexBitangentData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexTangentData.h>
#include <SceneAPI/SceneData/Rules/TangentsRule.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Vector4.h>
#include <mikkelsen/mikktspace.h>
namespace AZ
{
namespace TangentGeneration
{
namespace 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_meshData->GetFaceCount();
}
int GetNumVerticesOfFace(const SMikkTSpaceContext* context, const int face)
{
AZ_UNUSED(context);
AZ_UNUSED(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_meshData->GetVertexIndex(face, vert);
const AZ::Vector3& pos = customData->m_meshData->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_meshData->GetVertexIndex(face, vert);
const AZ::Vector3 normal = customData->m_meshData->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_meshData->GetVertexIndex(face, vert);
const AZ::Vector2& uv = customData->m_uvData->GetUV(vertexIndex);
texOut[0] = uv.GetX();
texOut[1] = uv.GetY();
}
// This function is used to return the tangent and signValue to the application.
// tangent is a unit length vector.
// For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
// bitangent = signValue * cross(vN, tangent);
// Note that the results are returned unindexed. It is possible to generate a new index list
void SetTSpaceBasic(const SMikkTSpaceContext* context, const float tangent[], const float signValue, const int face, const int vert)
{
MikktCustomData* customData = static_cast<MikktCustomData*>(context->m_pUserData);
const AZ::u32 vertexIndex = customData->m_meshData->GetVertexIndex(face, vert);
AZ::Vector3 tangentVec3(tangent[0], tangent[1], tangent[2]);
tangentVec3.NormalizeSafe();
AZ::Vector3 normal = customData->m_meshData->GetNormal(vertexIndex);
normal.NormalizeSafe();
const AZ::Vector3 bitangent = normal.Cross(tangentVec3) * signValue;
customData->m_tangentData->SetTangent(vertexIndex, AZ::Vector4(tangentVec3.GetX(), tangentVec3.GetY(), tangentVec3.GetZ(), signValue));
customData->m_bitangentData->SetBitangent(vertexIndex, bitangent);
}
// 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_meshData->GetVertexIndex(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);
customData->m_tangentData->SetTangent(vertexIndex, tangentVec);
customData->m_bitangentData->SetBitangent(vertexIndex, bitangentVec);
}
bool GenerateTangents(AZ::SceneAPI::Containers::SceneManifest& manifest, AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::SceneAPI::DataTypes::IMeshData* meshData, size_t uvSet)
{
// Create tangent and bitangent data sets and relate them to the given UV set.
AZ::SceneAPI::DataTypes::IMeshVertexUVData* uvData = AZ::SceneAPI::SceneData::TangentsRule::FindUVData(graph, nodeIndex, uvSet);
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* tangentData = nullptr;
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* bitangentData = nullptr;
if (!uvData)
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Cannot find UV data (set index=%d) to generate tangents and bitangents from in MikkT generator!\n", uvSet);
return false;
}
if (!AZ::SceneExportingComponents::TangentGenerateComponent::CreateTangentBitangentLayers(manifest, nodeIndex, meshData->GetVertexCount(), uvSet, AZ::SceneAPI::DataTypes::TangentSpace::MikkT, "MikkT", graph, &tangentData, &bitangentData))
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Failed to create tangents and bitangents data sets inside MikkT generator!\n");
return false;
}
//----------------------------------
// 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;//SetTSpaceBasic;
mikkInterface.m_getNumVerticesOfFace= GetNumVerticesOfFace;
// Set the MikkT custom data.
MikktCustomData customData;
customData.m_meshData = meshData;
customData.m_uvData = uvData;
customData.m_tangentData = tangentData;
customData.m_bitangentData = bitangentData;
// 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, because MikkT reported failure!\n");
return false;
}
return true;
}
} // namespace MikkT
} // namespace TangentGenerators
} // namespace AZ
@@ -0,0 +1,47 @@
/*
* 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
{
namespace SceneAPI
{
namespace DataTypes
{
class IMeshData;
class IMeshVertexUVData;
class IMeshVertexTangentData;
class IMeshVertexBitangentData;
enum class TangentSpace;
}
}
namespace TangentGeneration
{
namespace MikkT
{
struct MikktCustomData
{
AZ::SceneAPI::DataTypes::IMeshData* m_meshData;
AZ::SceneAPI::DataTypes::IMeshVertexUVData* m_uvData;
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* m_tangentData;
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* m_bitangentData;
};
// The main generation method.
bool GenerateTangents(AZ::SceneAPI::Containers::SceneManifest& manifest, AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::SceneAPI::DataTypes::IMeshData* meshData, size_t uvSet);
}
}
}