GodotVR / godot_openxr_vendors

Godot 4 wrapper for OpenXR vendors loaders and extensions
MIT License
99 stars 22 forks source link

openxr_fb_spatial_anchor_tracked custom_data bug #135

Closed SixArne closed 5 months ago

SixArne commented 5 months ago
var created_spatial_entity: OpenXRFbSpatialEntity = null

# Called manually on newly created scenes
#    var anchor_visualizer: Node3D = anchor_visualization.instantiate()
#    get_node("/root").add_child(anchor_visualizer)
func create_anchor(node: Node3D):
    spatial_anchor_manager.create_anchor(node.transform)

# openxr_fb_spatial_anchor_tracked but named differently
func _on_spatial_anchor_tracked(anchor_node: XRAnchor3D, spatial_entity: OpenXRFbSpatialEntity) -> void:
    if not spatial_entity.custom_data.has("is_saved"):
        spatial_entity.custom_data.get_or_add("is_saved", false)

    created_spatial_entity = spatial_entity
    print("Anchor tracked ", spatial_entity.uuid)

# Called on button press
func save_last_created_anchor(location: OpenXRFbSpatialEntity.StorageLocation):
    if created_spatial_entity.custom_data.get("is_saved") == false:
        created_spatial_entity.openxr_fb_spatial_entity_saved.connect(self._on_saved_anchor.bind(created_spatial_entity))
        created_spatial_entity.save_to_storage(location)
    else:
        print("Already saved anchor")

When I create 1 anchor and press the save button it works as expected:

Local anchor: 33528d6b-3ee4-ca2b-90af-206778fa3796 is success: true
Already saved anchor

But when I create more anchors and press save after every anchor spawn I get this

Already saved anchor
Already saved anchor
Already saved anchor

First placed anchor that got tracked has no custom_data, which is as expected. So we add the data and set it as saved image

Now when I spawn a new anchor (On a newly instantiated node) It somehow has the custom_data already

var anchor_visualizer: Node3D = anchor_visualization.instantiate()
get_node("/root").add_child(anchor_visualizer)

image

Does anyone know what's going on here? I must admit I am new to Godot and GDScript. I first though that maybe my created_spatial_entity was somehow the same, but the ObjectID's are completely different.

SixArne commented 5 months ago

Full code for reproduction

extends XROrigin3D

@onready var spatial_anchor_manager: OpenXRFbSpatialAnchorManager = $OpenXRFbSpatialAnchorManager
@onready var left_controller: XRController3D = $XRLeftController
@onready var left_pointer_raycast: RayCast3D = $XRLeftController/FunctionPointer/RayCast

@export var anchor_visualization: PackedScene;

var created_spatial_entity: OpenXRFbSpatialEntity = null

func create_anchor(node: Node3D):
    spatial_anchor_manager.create_anchor(node.transform)

func _on_spatial_anchor_tracked(anchor_node: XRAnchor3D, spatial_entity: OpenXRFbSpatialEntity) -> void:
    if not spatial_entity.custom_data.has("is_saved"):
        spatial_entity.custom_data.get_or_add("is_saved", false)

    created_spatial_entity = spatial_entity
    print("Anchor tracked ", spatial_entity.uuid)

func save_anchor(spatial_entity: OpenXRFbSpatialEntity, location: OpenXRFbSpatialEntity.StorageLocation):
    spatial_entity.openxr_fb_spatial_entity_saved.connect(self._on_saved_anchor.bind(spatial_entity))
    spatial_entity.save_to_storage(location)

func save_last_created_anchor(location: OpenXRFbSpatialEntity.StorageLocation):
    if created_spatial_entity.custom_data.get("is_saved") == false:
        created_spatial_entity.openxr_fb_spatial_entity_saved.connect(self._on_saved_anchor.bind(created_spatial_entity))
        created_spatial_entity.save_to_storage(location)
    else:
        print("Already saved anchor")

func _on_saved_anchor(success: bool, location: OpenXRFbSpatialEntity.StorageLocation, spatial_entity: OpenXRFbSpatialEntity):
    if success:

        if location == OpenXRFbSpatialEntity.StorageLocation.STORAGE_CLOUD:
            spatial_entity.openxr_fb_spatial_entity_set_component_enabled_completed.connect(self._on_enable_share.bind(spatial_entity))
            spatial_entity.set_component_enabled(OpenXRFbSpatialEntity.COMPONENT_TYPE_SHARABLE, true)

        else:
            spatial_entity.custom_data["is_saved"] = true
            print("Local anchor: ", spatial_entity.uuid, " is success: ", success)

func _on_enable_share(success: bool, component: OpenXRFbSpatialEntity.StorageLocation, enabled: bool, spatial_entity: OpenXRFbSpatialEntity):
    if success:
        var spatial_entity_user = OpenXRFbSpatialEntityUser.create_user(000)
        spatial_entity.openxr_fb_spatial_entity_shared.connect(self._on_shared.bind(spatial_entity))
        print("Anchor shared")
    else:
        print("Failed to share")

func _on_shared(success: bool, spatial_entity: OpenXRFbSpatialEntity) -> void:
    print("Share ", spatial_entity.uuid, " is success: ", success)

func _on_xr_left_controller_button_pressed(name: String) -> void:
    if name == "trigger_click":
        if left_pointer_raycast.is_colliding():
            var position: Vector3 = left_pointer_raycast.get_collision_point()
            var anchor_visualizer: Node3D = anchor_visualization.instantiate()
            get_node("/root").add_child(anchor_visualizer)

            anchor_visualizer.global_position = position
            create_anchor(anchor_visualizer)

    if name == "by_button":
        save_last_created_anchor(OpenXRFbSpatialEntity.StorageLocation.STORAGE_LOCAL)
dsnopek commented 5 months ago

Thanks for the report!

I think there may be some confusion around the different places the anchor data is being saved, which may become somewhat more clear with recent changes.

The OpenXRFbSpatialEntity.save_to_storage() method saves the anchor with the OpenXR runtime. This doesn't include the custom_data - in the version of the PR that you were using, that is automatically saved to a JSON file by the OpenXRFbSpatialAnchorManager node. So, to save changes to the custom_data, you'd want to call OpenXRFbSpatialAnchorManager.save_anchors_to_local_file().

However, per this discussion, we decided that saving custom data to a file doesn't belong in OpenXRFbSpatialAnchorManager, and is instead up to the developer to do. I just rebased PR https://github.com/GodotVR/godot_openxr_vendors/pull/128 to include the latest changes from PR https://github.com/GodotVR/godot_openxr_vendors/pull/121, which moves the saving of the custom_data into the demo project. Take a look at the save_spatial_anchors_to_file() function in main.gd.

Sorry for the confusion - I'm really looking forward to writing some documentation for all these classes, in order to clear all these things up :-)

SixArne commented 5 months ago

Aaah, alrighty makes sense. Thank you for the clarification :-)

On Thu, May 2, 2024, 18:19 David Snopek @.***> wrote:

Thanks for the report!

I think there may be some confusion around the different places the anchor data is being saved, which may become somewhat more clear with recent changes.

The OpenXRFbSpatialEntity.save_to_storage() method saves the anchor with the OpenXR runtime. This doesn't include the custom_data - in the version of the PR that you were using, that is automatically saved to a JSON file by the OpenXRFbSpatialAnchorManager node. So, to save changes to the custom_data, you'd want to call OpenXRFbSpatialAnchorManager.save_anchors_to_local_file().

However, per this discussion https://github.com/GodotVR/godot_openxr_vendors/pull/121#pullrequestreview-2027539061, we decided that saving custom data to a file doesn't belong in OpenXRFbSpatialAnchorManager, and is instead up to the developer to do. I just rebased PR #128 https://github.com/GodotVR/godot_openxr_vendors/pull/128 to include the latest changes from PR #121 https://github.com/GodotVR/godot_openxr_vendors/pull/121, which moves the saving of the custom_data into the demo project. Take a look at the save_spatial_anchors_to_file() function in main.gd.

Sorry for the confusion - I'm really looking forward to writing some documentation for all these classes, in order to clear all these things up :-)

— Reply to this email directly, view it on GitHub https://github.com/GodotVR/godot_openxr_vendors/issues/135#issuecomment-2090948483, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQBU633NCFIXY3ZA2XVHHQTZAJRQVAVCNFSM6AAAAABHCEHQCGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJQHE2DQNBYGM . You are receiving this because you authored the thread.Message ID: @.***>