@viamrobotics/motion-tools 1.15.1 → 1.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -93,7 +93,6 @@
93
93
  isOpen
94
94
  exitable={false}
95
95
  title="Lasso"
96
- strategy="absolute"
97
96
  defaultSize={{ width: 445, height: 100 }}
98
97
  defaultPosition={{ x: rect.width / 2 - 200, y: rect.height - 10 - 100 }}
99
98
  >
@@ -51,8 +51,9 @@
51
51
 
52
52
  keys.onKeys('-', () => {
53
53
  if (selectedCustomGeometry) {
54
- selectedCustomGeometry.destroy()
55
- entities.delete(selectedCustomGeometry)
54
+ const entity = selectedCustomGeometry
55
+ entity.destroy()
56
+ entities.delete(entity)
56
57
  selectedEntity.set()
57
58
  }
58
59
  })
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte'
3
3
 
4
+ import { useThrelte } from '@threlte/core'
4
5
  import { Icon } from '@viamrobotics/prime-core'
5
6
  import * as floatingPanel from '@zag-js/floating-panel'
6
7
  import { normalizeProps, useMachine } from '@zag-js/svelte'
@@ -12,7 +13,6 @@
12
13
  exitable?: boolean
13
14
  resizable?: boolean
14
15
  persistRect?: boolean
15
- strategy?: 'absolute' | 'fixed'
16
16
  isOpen?: boolean
17
17
  children: Snippet
18
18
  }
@@ -20,10 +20,7 @@
20
20
  let {
21
21
  title = '',
22
22
  defaultSize = { width: 700, height: 500 },
23
- defaultPosition = {
24
- x: globalThis.innerWidth / 2 - defaultSize.width / 2,
25
- y: globalThis.innerHeight / 2 - defaultSize.height / 2,
26
- },
23
+ defaultPosition,
27
24
  exitable = true,
28
25
  resizable = false,
29
26
  persistRect = true,
@@ -32,13 +29,19 @@
32
29
  ...props
33
30
  }: Props = $props()
34
31
 
32
+ const { dom } = useThrelte()
33
+
35
34
  const id = $props.id()
36
35
  const floatingPanelService = useMachine(floatingPanel.machine, () => ({
37
36
  id,
38
37
  defaultSize,
39
- defaultPosition,
38
+ defaultPosition: defaultPosition ?? {
39
+ x: dom.clientWidth / 2 - defaultSize.width / 2 + dom.clientLeft,
40
+ y: dom.clientHeight / 2 - defaultSize.width / 2 + dom.clientTop,
41
+ },
40
42
  resizable,
41
43
  allowOverflow: false,
44
+ strategy: 'absolute' as const,
42
45
  persistRect,
43
46
  open: isOpen,
44
47
  ...props,
@@ -12,7 +12,6 @@ interface Props {
12
12
  exitable?: boolean;
13
13
  resizable?: boolean;
14
14
  persistRect?: boolean;
15
- strategy?: 'absolute' | 'fixed';
16
15
  isOpen?: boolean;
17
16
  children: Snippet;
18
17
  }
@@ -6,7 +6,7 @@ const key = Symbol('anchors-context');
6
6
  export const provideAnchors = () => {
7
7
  const matrix4 = new Matrix4();
8
8
  const { renderer } = useThrelte();
9
- const { xrFrame, isPresenting } = useXR();
9
+ const { isPresenting } = useXR();
10
10
  const map = new WeakMap();
11
11
  let space = renderer.xr.getReferenceSpace();
12
12
  const createAnchor = (position, orientation) => {
@@ -14,14 +14,14 @@ export const provideAnchors = () => {
14
14
  if (space === null)
15
15
  return;
16
16
  const pose = new XRRigidTransform(position, orientation);
17
- return xrFrame.current.createAnchor?.(pose, space);
17
+ return renderer.xr.getFrame().createAnchor?.(pose, space);
18
18
  };
19
19
  const { start, stop } = useTask(() => {
20
20
  space ??= renderer.xr.getReferenceSpace();
21
21
  if (!space) {
22
22
  return;
23
23
  }
24
- const frame = xrFrame.current;
24
+ const frame = renderer.xr.getFrame();
25
25
  if (!frame.trackedAnchors) {
26
26
  return;
27
27
  }
@@ -1,4 +1,4 @@
1
1
  import { type QueryParameter, type QueryResult } from 'koota';
2
- export declare function useQuery<T extends QueryParameter[]>(...parameters: T): {
2
+ export declare const useQuery: <T extends QueryParameter[]>(...parameters: T) => {
3
3
  current: QueryResult<T>;
4
4
  };
@@ -1,49 +1,56 @@
1
- import { createQuery, $internal as internal } from 'koota';
2
- import { untrack } from 'svelte';
1
+ import { createQuery, $internal as internalKey } from 'koota';
2
+ import { createSubscriber } from 'svelte/reactivity';
3
3
  import { useWorld } from './useWorld';
4
- export function useQuery(...parameters) {
4
+ export const useQuery = (...parameters) => {
5
5
  const world = useWorld();
6
- const createdQuery = createQuery(...parameters);
7
- // Using internals to get the query data.
8
- const query = world[internal].queriesHashMap.get(createdQuery.hash);
9
- const initialQueryVersion = query?.version;
10
- let version = $state.raw(0);
11
- let entities = $state.raw(world.query(createdQuery));
12
- $effect(() => {
13
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
14
- version;
15
- // Compare the initial version to the current version to
16
- // see it the query has changed.
17
- const query = world[internal].queriesHashMap.get(createdQuery.hash);
18
- if (query?.version !== initialQueryVersion) {
19
- entities = world.query(createdQuery);
20
- }
21
- return untrack(() => {
22
- const unsubAdd = world.onQueryAdd(createdQuery, () => {
23
- entities = world.query(createdQuery);
24
- });
25
- const unsubRemove = world.onQueryRemove(createdQuery, () => {
26
- entities = world.query(createdQuery);
27
- });
28
- return () => {
29
- unsubAdd();
30
- unsubRemove();
31
- };
32
- });
33
- });
34
- const handler = () => {
35
- version += 1;
36
- };
37
- // Force reattaching event listeners when the world is reset.
38
- $effect(() => {
39
- world[internal].resetSubscriptions.add(handler);
6
+ const queryRef = createQuery(...parameters);
7
+ let cache = null;
8
+ const subscribe = createSubscriber((update) => {
9
+ let unsubAdd = () => { };
10
+ let unsubRemove = () => { };
11
+ const subscribe = () => {
12
+ unsubAdd = world.onQueryAdd(queryRef, update);
13
+ unsubRemove = world.onQueryRemove(queryRef, update);
14
+ // Check if query changed before subscriptions were attached
15
+ const query = world[internalKey].queriesHashMap.get(queryRef.hash);
16
+ if (query && cache && query.version !== cache.version) {
17
+ update();
18
+ }
19
+ };
20
+ const handleReset = () => {
21
+ cache = null;
22
+ unsubAdd();
23
+ unsubRemove();
24
+ subscribe();
25
+ update();
26
+ };
27
+ subscribe();
28
+ world[internalKey].resetSubscriptions.add(handleReset);
40
29
  return () => {
41
- world[internal].resetSubscriptions.delete(handler);
30
+ world[internalKey].resetSubscriptions.delete(handleReset);
31
+ unsubAdd();
32
+ unsubRemove();
42
33
  };
43
34
  });
35
+ const getResult = () => {
36
+ const query = world[internalKey].queriesHashMap.get(queryRef.hash);
37
+ if (query && cache?.hash === queryRef.hash && cache.version === query.version) {
38
+ return cache.result;
39
+ }
40
+ // eslint-disable-next-line unicorn/no-array-sort
41
+ const result = world.query(queryRef).sort();
42
+ const registeredQuery = world[internalKey].queriesHashMap.get(queryRef.hash);
43
+ cache = {
44
+ hash: queryRef.hash,
45
+ version: registeredQuery.version,
46
+ result,
47
+ };
48
+ return result;
49
+ };
44
50
  return {
45
51
  get current() {
46
- return entities;
52
+ subscribe();
53
+ return getResult();
47
54
  },
48
55
  };
49
- }
56
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viamrobotics/motion-tools",
3
- "version": "1.15.1",
3
+ "version": "1.15.3",
4
4
  "description": "Motion visualization with Viam",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -25,10 +25,10 @@
25
25
  "@testing-library/jest-dom": "6.8.0",
26
26
  "@testing-library/svelte": "5.2.8",
27
27
  "@testing-library/user-event": "^14.6.1",
28
- "@threlte/core": "8.3.0",
29
- "@threlte/extras": "9.7.0",
30
- "@threlte/rapier": "3.2.0",
31
- "@threlte/xr": "1.0.8",
28
+ "@threlte/core": "8.5.0",
29
+ "@threlte/extras": "9.9.0",
30
+ "@threlte/rapier": "3.4.0",
31
+ "@threlte/xr": "1.4.0",
32
32
  "@types/bun": "1.2.21",
33
33
  "@types/earcut": "^3.0.0",
34
34
  "@types/lodash-es": "4.17.12",