/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include namespace AZ { namespace SceneAPI { namespace FbxSceneBuilder { const char* AssImpBitangentStreamImporter::m_defaultNodeName = "Bitangent"; AssImpBitangentStreamImporter::AssImpBitangentStreamImporter() { BindToCall(&AssImpBitangentStreamImporter::ImportBitangentStreams); } void AssImpBitangentStreamImporter::Reflect(ReflectContext* context) { SerializeContext* serializeContext = azrtti_cast(context); if (serializeContext) { serializeContext->Class()->Version(2); // LYN-2576 } } Events::ProcessingResult AssImpBitangentStreamImporter::ImportBitangentStreams(AssImpSceneNodeAppendedContext& context) { AZ_TraceContext("Importer", m_defaultNodeName); if (!context.m_sourceNode.ContainsMesh()) { return Events::ProcessingResult::Ignored; } aiNode* currentNode = context.m_sourceNode.GetAssImpNode(); const aiScene* scene = context.m_sourceScene.GetAssImpScene(); GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context)); if (!meshDataResult.IsSuccess()) { return meshDataResult.GetError(); } const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue()); size_t vertexCount = parentMeshData->GetVertexCount(); int sdkMeshIndex = parentMeshData->GetSdkMeshIndex(); if (sdkMeshIndex < 0 || sdkMeshIndex >= currentNode->mNumMeshes) { AZ_Error(Utilities::ErrorWindow, false, "Tried to construct bitangent stream attribute for invalid or non-mesh parent data, mesh index is invalid"); return Events::ProcessingResult::Failure; } aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]]; if (!mesh->HasTangentsAndBitangents()) { return Events::ProcessingResult::Ignored; } AZStd::shared_ptr bitangentStream = AZStd::make_shared(); // AssImp only has one bitangentStream per mesh. bitangentStream->SetBitangentSetIndex(0); bitangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromFbx); bitangentStream->ReserveContainerSpace(vertexCount); for (int v = 0; v < mesh->mNumVertices; ++v) { const Vector3 bitangent( AssImpSDKWrapper::AssImpTypeConverter::ToVector3(mesh->mBitangents[v])); bitangentStream->AppendBitangent(bitangent); } AZStd::string nodeName(AZStd::string::format("%s",m_defaultNodeName)); Containers::SceneGraph::NodeIndex newIndex = context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str()); Events::ProcessingResult bitangentResults; AssImpSceneAttributeDataPopulatedContext dataPopulated(context, bitangentStream, newIndex, nodeName.c_str()); bitangentResults = Events::Process(dataPopulated); if (bitangentResults != Events::ProcessingResult::Failure) { bitangentResults = AddAttributeDataNodeWithContexts(dataPopulated); } return bitangentResults; } } // namespace FbxSceneBuilder } // namespace SceneAPI } // namespace AZ