Select to view content in your preferred language

I want to retrieve and display 3d attribute data using Feature ID as a key

1418
1
12-17-2022 08:57 PM
hiroyuki_s
New Contributor

I would like to retrieve and display 3d attribute data using the Feature ID obtained from the ArcGISHitTestSample scene as a key.

In the Sample3DAttributesComponent class of the 3DAttributesSample scene, the material is changed when "AttributeType:BuildingName" matches a unique name.

I thought that if this matched the Feature ID obtained in the aforementioned hit test, the corresponding building would be considered to have been identified and the 3D attribute data (year of construction, building name, etc.) could be retrieved and displayed.
However, this does not work.

Is this possible?
Or is this a misguided attempt?

Code is here:Sample3DAttributesComponent.cs
(I first tried to debug output of the FID.
I can output it, but it seems to be different from the value output in the HitTestSample scene.)

    private void Setup3DAttributes(ArcGIS3DObjectSceneLayer buildingLayer)
    {
        if (buildingLayer == null)
        {
            return;
        }

        if (layerAttribute == AttributeType.ConstructionYear)
        {
            Setup3DAttributesFloatAndIntegerType(buildingLayer);
        }
        else if (layerAttribute == AttributeType.BuildingName)
        {
            Setup3DAttributesOtherType(buildingLayer);
        }

        // Add a process to handle FIDs
        else if (layerAttribute == AttributeType.FID)
        {
            var layerAttributes = ArcGISImmutableArray<String>.CreateBuilder();
            layerAttributes.Add("FID");

            var renderAttributeDescriptions = ArcGISImmutableArray<Esri.GameEngine.Attributes.ArcGISVisualizationAttributeDescription>.CreateBuilder();
            renderAttributeDescriptions.Add(new Esri.GameEngine.Attributes.ArcGISVisualizationAttributeDescription("IsBuildingOfInterest", Esri.GameEngine.Attributes.ArcGISVisualizationAttributeType.Float32));

            attributeProcessor = new Esri.GameEngine.Attributes.ArcGISAttributeProcessor();

            attributeProcessor.ProcessEvent += (ArcGISImmutableArray<Esri.GameEngine.Attributes.ArcGISAttribute> layerNodeAttributes, ArcGISImmutableArray<Esri.GameEngine.Attributes.ArcGISVisualizationAttribute> renderNodeAttributes) =>
            {
                var fidAttribute = layerNodeAttributes.At(0);
                var isBuildingOfInterestAttribute = renderNodeAttributes.At(0);
                var isBuildingOfInterestBuffer = isBuildingOfInterestAttribute.Data;
                var isBuildingOfInterestData = isBuildingOfInterestBuffer.Reinterpret<float>(sizeof(byte));

                // FID Debug Output
                ForEachInt64(fidAttribute, (long element, Int32 index) =>
                {
                    Debug.Log("FID::" + element);
                });
            };

            buildingLayer.SetAttributesToVisualize(layerAttributes.MoveToArray(), renderAttributeDescriptions.MoveToArray(), attributeProcessor);
        }
    }

    // Add function
    void ForEachInt64(Esri.GameEngine.Attributes.ArcGISAttribute attribute, Action<Int64, Int32> predicate)
    {
        unsafe
        {
            var buffer = attribute.Data;
            var unsafePtr = NativeArrayUnsafeUtility.GetUnsafePtr(buffer);
            var metadata = (int*)unsafePtr;
            var count = metadata[0];

            IntPtr intPtr = (IntPtr)unsafePtr + sizeof(int);

            for (var i = 0; i < count; ++i)
            {
                Int64 element = *((Int64*)intPtr); // Rises NullReferenceException: Object reference not set to an instance of an object

                predicate(element, i);

                intPtr += sizeof(Int64);
            }
        }
    }


runtime console:

hiroyuki_s_0-1671339146788.png





Tags (2)
0 Kudos
1 Reply
dun82
by
New Contributor II

Same question here, also the float value extraction, appreciated if some one can help 🙏

Editted on 7 Feb 23:

I found the data stored in 8 byte, this works for float... may be int as well

var buffer = attribute.Data;
var unsafePtr = NativeArrayUnsafeUtility.GetUnsafePtr(buffer);
var metadata = (double*)unsafePtr;
var count = attribute.Data.Length / 8;

for (var i = 0; i < count; ++i)
{
    predicate((float)metadata[i], i);
}

 

0 Kudos