/* * 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 // Needed for CGFContent.h #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace AZ { namespace RC { namespace SceneUtil = AZ::SceneAPI::Utilities; namespace SceneDataTypes = AZ::SceneAPI::DataTypes; namespace SceneContainers = AZ::SceneAPI::Containers; const AZStd::string CgfLodExporter::s_fileExtension = "cgf"; CgfLodExporter::CgfLodExporter(IAssetWriter* writer) : m_assetWriter(writer) { BindToCall(&CgfLodExporter::ProcessContext); ActivateBindings(); } SceneEvents::ProcessingResult CgfLodExporter::ProcessContext(CgfGroupExportContext& context) const { if (context.m_phase != Phase::Filling) { return SceneEvents::ProcessingResult::Ignored; } AZStd::shared_ptr lodRule = context.m_group.GetRuleContainerConst().FindFirstByType(); if (!lodRule) { return SceneEvents::ProcessingResult::Ignored; } // Create the base CGF name AZStd::string baseCGFfilename = SceneUtil::FileUtilities::CreateOutputFileName(context.m_group.GetName(), context.m_outputDirectory, s_fileExtension); SceneEvents::ProcessingResultCombiner result; for (size_t index = 0; index < lodRule->GetLodCount(); ++index) { AZStd::string filename = SceneUtil::FileUtilities::CreateOutputFileName( context.m_group.GetName() + "_LOD" + AZStd::to_string(static_cast(index + 1)), context.m_outputDirectory, s_fileExtension); AZ_TraceContext("CGF Lod File Name", filename); if (filename.empty() || !SceneUtil::FileUtilities::EnsureTargetFolderExists(filename)) { AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Unable to write CGF Lod file. Filename is empty or target folder does not exist."); result += SceneEvents::ProcessingResult::Failure; break; } CContentCGF cgfContent(filename.c_str()); ConfigureCgfContent(cgfContent); const SceneContainers::SceneGraph& graph = context.m_scene.GetGraph(); AZStd::vector physTargetNodes; AZStd::vector targetNodes = SceneUtil::SceneGraphSelector::GenerateTargetNodes(graph, lodRule->GetSceneNodeSelectionList(index), SceneUtil::SceneGraphSelector::IsMesh); result += ProcessMeshes(context, cgfContent, targetNodes, physTargetNodes); if (cgfContent.GetNodeCount() == 0) { AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Empty LoD Detected at level %d.", index); result += SceneEvents::ProcessingResult::Failure; break; } if (m_assetWriter) { if (m_assetWriter->WriteCGF(&cgfContent)) { static const AZ::Data::AssetType staticMeshLodsAssetType("{9AAE4926-CB6A-4C60-9948-A1A22F51DB23}"); // Using the same guid as the parent group/cgf as this needs to be a lod of that cgf. // Setting the lod to index+1 as 0 means the base mesh and 1-6 are lod levels 0-5. AZ::SceneAPI::Events::ExportProduct& lodProduct = context.m_products.AddProduct(AZStd::move(filename), context.m_group.GetId(), staticMeshLodsAssetType, index + 1, AZStd::nullopt); // Add this LOD as a dependency to the base CGF context.m_products.AddDependencyToProduct(baseCGFfilename, lodProduct); } else { AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Unable to write CGF LoD file at level %d.", index); result += SceneEvents::ProcessingResult::Failure; break; } } else { AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "No asset writer found. Unable to write cgf to disk"); result += SceneEvents::ProcessingResult::Failure; break; } } return result.GetResult(); } } // namespace RC } // namespace AZ