// Copyright 2020-2024 CesiumGS, Inc. and Contributors #include "CesiumPrimitiveFeatures.h" #include "CesiumGltf/ExtensionExtInstanceFeatures.h" #include "CesiumGltf/ExtensionExtMeshFeatures.h" #include "CesiumGltf/ExtensionExtMeshGpuInstancing.h" #include "CesiumGltf/Model.h" #include "CesiumGltfPrimitiveComponent.h" static FCesiumPrimitiveFeatures EmptyPrimitiveFeatures; FCesiumPrimitiveFeatures::FCesiumPrimitiveFeatures( const CesiumGltf::Model& Model, const CesiumGltf::MeshPrimitive& Primitive, const CesiumGltf::ExtensionExtMeshFeatures& Features) : _vertexCount(0), _primitiveMode(Primitive.mode) { this->_indexAccessor = CesiumGltf::getIndexAccessorView(Model, Primitive); auto positionIt = Primitive.attributes.find("POSITION"); if (positionIt != Primitive.attributes.end()) { const CesiumGltf::Accessor& positionAccessor = Model.getSafe(Model.accessors, positionIt->second); _vertexCount = positionAccessor.count; } for (const CesiumGltf::FeatureId& FeatureId : Features.featureIds) { this->_featureIdSets.Add(FCesiumFeatureIdSet(Model, Primitive, FeatureId)); } } FCesiumPrimitiveFeatures::FCesiumPrimitiveFeatures( const CesiumGltf::Model& Model, const CesiumGltf::Node& Node, const CesiumGltf::ExtensionExtInstanceFeatures& InstanceFeatures) : _vertexCount(0), _primitiveMode(-1) { if (Node.mesh < 0 || Node.mesh >= Model.meshes.size()) { return; } for (const auto& featureId : InstanceFeatures.featureIds) { this->_featureIdSets.Emplace(Model, Node, featureId); } } const FCesiumPrimitiveFeatures& UCesiumPrimitiveFeaturesBlueprintLibrary::GetPrimitiveFeatures( const UPrimitiveComponent* component) { const UCesiumGltfPrimitiveComponent* pGltfComponent = Cast(component); if (!IsValid(pGltfComponent)) { return EmptyPrimitiveFeatures; } return pGltfComponent->getPrimitiveData().Features; } const TArray& UCesiumPrimitiveFeaturesBlueprintLibrary::GetFeatureIDSets( UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures) { return PrimitiveFeatures._featureIdSets; } const TArray UCesiumPrimitiveFeaturesBlueprintLibrary::GetFeatureIDSetsOfType( UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures, ECesiumFeatureIdSetType Type) { TArray featureIdSets; for (int32 i = 0; i < PrimitiveFeatures._featureIdSets.Num(); i++) { const FCesiumFeatureIdSet& featureIdSet = PrimitiveFeatures._featureIdSets[i]; if (UCesiumFeatureIdSetBlueprintLibrary::GetFeatureIDSetType( featureIdSet) == Type) { featureIdSets.Add(featureIdSet); } } return featureIdSets; } int64 UCesiumPrimitiveFeaturesBlueprintLibrary::GetVertexCount( UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures) { return PrimitiveFeatures._vertexCount; } int64 UCesiumPrimitiveFeaturesBlueprintLibrary::GetFirstVertexFromFace( UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures, int64 FaceIndex) { if (FaceIndex < 0) { return -1; } auto VertexIndices = std::visit( CesiumGltf::IndicesForFaceFromAccessor{ FaceIndex, PrimitiveFeatures._vertexCount, PrimitiveFeatures._primitiveMode}, PrimitiveFeatures._indexAccessor); return VertexIndices[0]; } int64 UCesiumPrimitiveFeaturesBlueprintLibrary::GetFeatureIDFromFace( UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures, int64 FaceIndex, int64 FeatureIDSetIndex) { if (FeatureIDSetIndex < 0 || FeatureIDSetIndex >= PrimitiveFeatures._featureIdSets.Num()) { return -1; } return UCesiumFeatureIdSetBlueprintLibrary::GetFeatureIDForVertex( PrimitiveFeatures._featureIdSets[FeatureIDSetIndex], UCesiumPrimitiveFeaturesBlueprintLibrary::GetFirstVertexFromFace( PrimitiveFeatures, FaceIndex)); } int64 UCesiumPrimitiveFeaturesBlueprintLibrary::GetFeatureIDFromInstance( const FCesiumPrimitiveFeatures& InstanceFeatures, int64 InstanceIndex, int64 FeatureIDSetIndex) { if (FeatureIDSetIndex < 0 || FeatureIDSetIndex >= InstanceFeatures._featureIdSets.Num()) { return -1; } const auto& featureIDSet = InstanceFeatures._featureIdSets[FeatureIDSetIndex]; return UCesiumFeatureIdSetBlueprintLibrary::GetFeatureIDForInstance( featureIDSet, InstanceIndex); } int64 UCesiumPrimitiveFeaturesBlueprintLibrary::GetFeatureIDFromHit( UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures, const FHitResult& Hit, int64 FeatureIDSetIndex) { if (FeatureIDSetIndex < 0 || FeatureIDSetIndex >= PrimitiveFeatures._featureIdSets.Num()) { return -1; } return UCesiumFeatureIdSetBlueprintLibrary::GetFeatureIDFromHit( PrimitiveFeatures._featureIdSets[FeatureIDSetIndex], Hit); }