// Copyright 2020-2024 CesiumGS, Inc. and Contributors #include "CesiumFeatureIdTexture.h" #include "CesiumGltf/FeatureIdTexture.h" #include "CesiumGltf/Model.h" #include "CesiumGltfPrimitiveComponent.h" #include "CesiumMetadataPickingBlueprintLibrary.h" #include FCesiumFeatureIdTexture::FCesiumFeatureIdTexture( const CesiumGltf::Model& Model, const CesiumGltf::MeshPrimitive& Primitive, const CesiumGltf::FeatureIdTexture& FeatureIdTexture, const FString& PropertyTableName) : _status(ECesiumFeatureIdTextureStatus::ErrorInvalidTexture), _featureIdTextureView(), _texCoordAccessor(), _textureCoordinateSetIndex(FeatureIdTexture.texCoord), _propertyTableName(PropertyTableName) { CesiumGltf::TextureViewOptions options; options.applyKhrTextureTransformExtension = true; if (FeatureIdTexture.extras.find("makeImageCopy") != FeatureIdTexture.extras.end()) { options.makeImageCopy = FeatureIdTexture.extras.at("makeImageCopy").getBoolOrDefault(false); } this->_featureIdTextureView = CesiumGltf::FeatureIdTextureView(Model, FeatureIdTexture, options); switch (_featureIdTextureView.status()) { case CesiumGltf::FeatureIdTextureViewStatus::Valid: this->_status = ECesiumFeatureIdTextureStatus::Valid; break; case CesiumGltf::FeatureIdTextureViewStatus::ErrorInvalidChannels: this->_status = ECesiumFeatureIdTextureStatus::ErrorInvalidTextureAccess; return; default: // Error with the texture or image. The status is already set by the // initializer list. return; } // The EXT_feature_metadata version of FCesiumFeatureIdTexture was not // constructed with an "owner" primitive. It was possible to access the // texture data with technically arbitrary coordinates. // // To maintain this functionality in EXT_mesh_features, the texture view will // still be valid if the intended texcoords don't exist. However, feature IDs // won't be retrievable by vertex index. this->_texCoordAccessor = CesiumGltf::getTexCoordAccessorView( Model, Primitive, this->_textureCoordinateSetIndex); } const FString& UCesiumFeatureIdTextureBlueprintLibrary::GetFeatureTableName( UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture) { return FeatureIDTexture._propertyTableName; } ECesiumFeatureIdTextureStatus UCesiumFeatureIdTextureBlueprintLibrary::GetFeatureIDTextureStatus( UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture) { return FeatureIDTexture._status; } int64 UCesiumFeatureIdTextureBlueprintLibrary::GetGltfTextureCoordinateSetIndex( UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture) { return FeatureIDTexture._featureIdTextureView.getTexCoordSetIndex(); } int64 UCesiumFeatureIdTextureBlueprintLibrary::GetUnrealUVChannel( const UPrimitiveComponent* PrimitiveComponent, UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture) { const auto* pCesiumPrimitive = Cast(PrimitiveComponent); if (!pCesiumPrimitive || FeatureIDTexture._status != ECesiumFeatureIdTextureStatus::Valid) { return -1; } const CesiumPrimitiveData& primData = pCesiumPrimitive->getPrimitiveData(); auto textureCoordinateIndexIt = primData.GltfToUnrealTexCoordMap.find( UCesiumFeatureIdTextureBlueprintLibrary::GetGltfTextureCoordinateSetIndex( FeatureIDTexture)); if (textureCoordinateIndexIt == primData.GltfToUnrealTexCoordMap.end()) { return -1; } return textureCoordinateIndexIt->second; } PRAGMA_DISABLE_DEPRECATION_WARNINGS int64 UCesiumFeatureIdTextureBlueprintLibrary:: GetFeatureIDForTextureCoordinates( UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture, float U, float V) { return FeatureIDTexture._featureIdTextureView.getFeatureID(U, V); } PRAGMA_ENABLE_DEPRECATION_WARNINGS int64 UCesiumFeatureIdTextureBlueprintLibrary::GetFeatureIDForUV( UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture, const FVector2D& UV) { return FeatureIDTexture._featureIdTextureView.getFeatureID(UV[0], UV[1]); } int64 UCesiumFeatureIdTextureBlueprintLibrary::GetFeatureIDForVertex( UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture, int64 VertexIndex) { const std::optional texCoords = std::visit( CesiumGltf::TexCoordFromAccessor{VertexIndex}, FeatureIDTexture._texCoordAccessor); if (!texCoords) { return -1; } return FeatureIDTexture._featureIdTextureView.getFeatureID( (*texCoords)[0], (*texCoords)[1]); } int64 UCesiumFeatureIdTextureBlueprintLibrary::GetFeatureIDFromHit( UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture, const FHitResult& Hit) { FVector2D UV; if (UCesiumMetadataPickingBlueprintLibrary::FindUVFromHit( Hit, FeatureIDTexture._featureIdTextureView.getTexCoordSetIndex(), UV)) { return FeatureIDTexture._featureIdTextureView.getFeatureID(UV[0], UV[1]); } return -1; }