/* * 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 #include #include #include #include #include #include #include #include namespace PhysX { namespace Pipeline { void MeshBehavior::Activate() { AZ::SceneAPI::Events::ManifestMetaInfoBus::Handler::BusConnect(); AZ::SceneAPI::Events::AssetImportRequestBus::Handler::BusConnect(); } void MeshBehavior::Deactivate() { AZ::SceneAPI::Events::AssetImportRequestBus::Handler::BusDisconnect(); AZ::SceneAPI::Events::ManifestMetaInfoBus::Handler::BusDisconnect(); } void MeshBehavior::Reflect(AZ::ReflectContext* context) { MeshGroup::Reflect(context); AZ::SerializeContext* serializeContext = azrtti_cast(context); if (serializeContext) { serializeContext->Class()->Version(1); } } void MeshBehavior::GetCategoryAssignments(CategoryRegistrationList& categories, const AZ::SceneAPI::Containers::Scene& scene) { if (AZ::SceneAPI::Utilities::DoesSceneGraphContainDataLike(scene, false)) { categories.emplace_back("PhysX", MeshGroup::TYPEINFO_Uuid()); } } void MeshBehavior::InitializeObject(const AZ::SceneAPI::Containers::Scene& scene, AZ::SceneAPI::DataTypes::IManifestObject& target) { if (!target.RTTI_IsTypeOf(MeshGroup::TYPEINFO_Uuid())) { return; } MeshGroup* group = azrtti_cast(&target); group->SetName(AZ::SceneAPI::DataTypes::Utilities::CreateUniqueName(scene.GetName(), scene.GetManifest())); const AZ::SceneAPI::Containers::SceneGraph& graph = scene.GetGraph(); // Gather the nodes that should be selected by default AZ::SceneAPI::DataTypes::ISceneNodeSelectionList& nodeSelectionList = group->GetSceneNodeSelectionList(); AZ::SceneAPI::Utilities::SceneGraphSelector::UnselectAll(graph, nodeSelectionList); AZ::SceneAPI::Containers::SceneGraph::ContentStorageConstData graphContent = graph.GetContentStorage(); auto view = AZ::SceneAPI::Containers::Views::MakeFilterView(graphContent, AZ::SceneAPI::Containers::DerivedTypeFilter()); for (auto iter = view.begin(), iterEnd = view.end(); iter != iterEnd; ++iter) { AZ::SceneAPI::Containers::SceneGraph::NodeIndex nodeIndex = graph.ConvertToNodeIndex(iter.GetBaseIterator()); AZStd::set types; AZ::SceneAPI::Events::GraphMetaInfoBus::Broadcast(&AZ::SceneAPI::Events::GraphMetaInfoBus::Events::GetVirtualTypes, types, scene, nodeIndex); if (types.count(AZ_CRC("PhysicsMesh", 0xc75d4ff1)) == 1) { nodeSelectionList.AddSelectedNode(graph.GetNodeName(nodeIndex).GetPath()); } } } AZ::SceneAPI::Events::ProcessingResult MeshBehavior::UpdateManifest(AZ::SceneAPI::Containers::Scene& scene, ManifestAction action, RequestingApplication /*requester*/) { if (action == ManifestAction::ConstructDefault) { return BuildDefault(scene); } else if (action == ManifestAction::Update) { return UpdatePhysXMeshGroups(scene); } else { return AZ::SceneAPI::Events::ProcessingResult::Ignored; } } AZ::SceneAPI::Events::ProcessingResult MeshBehavior::BuildDefault(AZ::SceneAPI::Containers::Scene& scene) const { if (!AZ::SceneAPI::Utilities::DoesSceneGraphContainDataLike(scene, true)) { return AZ::SceneAPI::Events::ProcessingResult::Ignored; } AZStd::shared_ptr group = AZStd::make_shared(); // This is a group that's generated automatically so may not be saved to disk but would need to be recreated // in the same way again. To guarantee the same uuid, generate a stable one instead. group->OverrideId(AZ::SceneAPI::DataTypes::Utilities::CreateStableUuid(scene, MeshGroup::TYPEINFO_Uuid())); EBUS_EVENT(AZ::SceneAPI::Events::ManifestMetaInfoBus, InitializeObject, scene, *group); scene.GetManifest().AddEntry(AZStd::move(group)); return AZ::SceneAPI::Events::ProcessingResult::Success; } void MeshBehavior::GetAvailableModifiers(AZ::SceneAPI::Events::ManifestMetaInfo::ModifiersList& modifiers, const AZ::SceneAPI::Containers::Scene& /*scene*/, const AZ::SceneAPI::DataTypes::IManifestObject& target) { if (!target.RTTI_IsTypeOf(PhysX::Pipeline::MeshGroup::TYPEINFO_Uuid())) { return; } const PhysX::Pipeline::MeshGroup* group = azrtti_cast(&target); const AZ::SceneAPI::Containers::RuleContainer& rules = group->GetRuleContainerConst(); if (rules.ContainsRuleOfType()) { return; } modifiers.push_back(AZ::SceneAPI::SceneData::OriginRule::TYPEINFO_Uuid()); } AZ::SceneAPI::Events::ProcessingResult MeshBehavior::UpdatePhysXMeshGroups(AZ::SceneAPI::Containers::Scene& scene) const { bool updated = false; AZ::SceneAPI::Containers::SceneManifest& manifest = scene.GetManifest(); auto valueStorage = manifest.GetValueStorage(); auto view = AZ::SceneAPI::Containers::MakeDerivedFilterView(valueStorage); for (MeshGroup& group : view) { if (group.GetName().empty()) { group.SetName(AZ::SceneAPI::DataTypes::Utilities::CreateUniqueName(scene.GetName(), scene.GetManifest())); } AZ::SceneAPI::Utilities::SceneGraphSelector::UpdateNodeSelection(scene.GetGraph(), group.GetSceneNodeSelectionList()); updated = true; } return updated ? AZ::SceneAPI::Events::ProcessingResult::Success : AZ::SceneAPI::Events::ProcessingResult::Ignored; } } // namespace SceneAPI } // namespace AZ