diff --git a/src/viser/_scene_handles.py b/src/viser/_scene_handles.py index 543d5a8e..72fba26b 100644 --- a/src/viser/_scene_handles.py +++ b/src/viser/_scene_handles.py @@ -329,6 +329,10 @@ def remove_click_callback( self._impl.click_cb.clear() else: self._impl.click_cb = [cb for cb in self._impl.click_cb if cb != callback] + if len(self._impl.click_cb) == 0: + self._impl.api._websock_interface.queue_message( + _messages.SetSceneNodeClickableMessage(self._impl.name, False) + ) class CameraFrustumHandle( diff --git a/src/viser/client/src/MessageHandler.tsx b/src/viser/client/src/MessageHandler.tsx index 0bd5f367..8a26ca87 100644 --- a/src/viser/client/src/MessageHandler.tsx +++ b/src/viser/client/src/MessageHandler.tsx @@ -298,7 +298,7 @@ function useMessageHandler() { const attr = viewer.nodeAttributesFromName.current; if (attr[message.name] === undefined) attr[message.name] = {}; attr[message.name]!.wxyz = message.wxyz; - if (attr[message.name]!.poseUpdateState == "updated") + if (attr[message.name]!.poseUpdateState != "waitForMakeObject") attr[message.name]!.poseUpdateState = "needsUpdate"; break; } @@ -306,7 +306,7 @@ function useMessageHandler() { const attr = viewer.nodeAttributesFromName.current; if (attr[message.name] === undefined) attr[message.name] = {}; attr[message.name]!.position = message.position; - if (attr[message.name]!.poseUpdateState == "updated") + if (attr[message.name]!.poseUpdateState != "waitForMakeObject") attr[message.name]!.poseUpdateState = "needsUpdate"; break; } diff --git a/src/viser/client/src/SceneTree.tsx b/src/viser/client/src/SceneTree.tsx index 8f20a0a2..11c6343a 100644 --- a/src/viser/client/src/SceneTree.tsx +++ b/src/viser/client/src/SceneTree.tsx @@ -735,14 +735,10 @@ export function SceneNodeThreeObject(props: { if (attrs.poseUpdateState == "needsUpdate") { attrs.poseUpdateState = "updated"; - const wxyz = attrs.wxyz; - if (wxyz !== undefined) { - obj.quaternion.set(wxyz[1], wxyz[2], wxyz[3], wxyz[0]); - } - const position = attrs.position; - if (position !== undefined) { - obj.position.set(position[0], position[1], position[2]); - } + const wxyz = attrs.wxyz ?? [1, 0, 0, 0]; + obj.quaternion.set(wxyz[1], wxyz[2], wxyz[3], wxyz[0]); + const position = attrs.position ?? [0, 0, 0]; + obj.position.set(position[0], position[1], position[2]); // Update matrices if necessary. This is necessary for PivotControls. if (!obj.matrixAutoUpdate) obj.updateMatrix(); diff --git a/src/viser/client/src/SceneTreeState.tsx b/src/viser/client/src/SceneTreeState.tsx index dc0aac5a..9398d654 100644 --- a/src/viser/client/src/SceneTreeState.tsx +++ b/src/viser/client/src/SceneTreeState.tsx @@ -137,6 +137,13 @@ export function useSceneTreeState( }), updateSceneNode: (name, updates) => set((state) => { + if (state.nodeFromName[name] === undefined) { + console.error( + `Attempted to update non-existent node ${name} with updates:`, + updates, + ); + return; + } state.nodeFromName[name]!.message.props = { ...state.nodeFromName[name]!.message.props, ...updates,