Skip to content

useSceneDrillPick

A reactive wrapper for Cesium.Scene.drillPick: it picks every object at the same screen coordinates and returns a computed property with the array of results. Use it when the scene contains overlapping graphics or you need a "pick a point, then choose from the list" interaction; unlike useScenePick, there is no result cache here.

Usage

vue
<script setup lang="ts">
import * as Cesium from 'cesium';
import { useEntity, useSceneDrillPick, useScreenSpaceEventHandler } from 'vesium';
import { computed, shallowRef } from 'vue';

const cursorPosition = shallowRef<Cesium.Cartesian2>();

// track mouse move
useScreenSpaceEventHandler(Cesium.ScreenSpaceEventType.MOUSE_MOVE, (movement: { endPosition: Cesium.Cartesian2 }) => {
  cursorPosition.value = movement.endPosition.clone();
});

// use scene drill pick to pick multiple objects at cursor
const drillPick = useSceneDrillPick(cursorPosition, {
  width: 5,
  height: 5,
  limit: 10,
});

// show all picked objects
const pickInfo = computed(() => {
  if (!drillPick.value || drillPick.value.length === 0) {
    return 'No object picked';
  }
  const names = drillPick.value.map((item: any, index: number) => {
    if (item.id instanceof Cesium.Entity) {
      return `${index + 1}. Entity: ${item.id.name || 'unnamed'}`;
    }
    if (item.primitive) {
      return `${index + 1}. Primitive: ${item.primitive.id?.name || 'unnamed'}`;
    }
    return `${index + 1}. Unknown`;
  });
  return names.join('\n');
});

// add overlapping entities for drill pick demo
const _entity1 = useEntity(new Cesium.Entity({
  name: 'Layer 1 - Red',
  position: Cesium.Cartesian3.fromDegrees(120, 30, 100),
  box: {
    dimensions: new Cesium.Cartesian3(3000, 3000, 1000),
    material: new Cesium.ColorMaterialProperty(Cesium.Color.RED.withAlpha(0.6)),
  },
}));

const _entity2 = useEntity(new Cesium.Entity({
  name: 'Layer 2 - Green',
  position: Cesium.Cartesian3.fromDegrees(120, 30, 200),
  box: {
    dimensions: new Cesium.Cartesian3(2000, 2000, 1000),
    material: new Cesium.ColorMaterialProperty(Cesium.Color.GREEN.withAlpha(0.6)),
  },
}));

const _entity3 = useEntity(new Cesium.Entity({
  name: 'Layer 3 - Blue',
  position: Cesium.Cartesian3.fromDegrees(120, 30, 300),
  box: {
    dimensions: new Cesium.Cartesian3(1000, 1000, 1000),
    material: new Cesium.ColorMaterialProperty(Cesium.Color.BLUE.withAlpha(0.6)),
  },
}));
</script>

<template>
  <div style="position: fixed; top: 10px; left: 10px; padding: 8px; font-size: 12px; color: white; white-space: pre-wrap; background: rgb(0 0 0 / 70%); border-radius: 4px;">
    {{ pickInfo }}
  </div>
</template>
ts
import * as Cesium from 'cesium';
import { useSceneDrillPick, useScreenSpaceEventHandler } from 'vesium';
import { shallowRef } from 'vue';

const cursorPosition = shallowRef<Cesium.Cartesian2>();
useScreenSpaceEventHandler(Cesium.ScreenSpaceEventType.MOUSE_MOVE, (m) => {
  cursorPosition.value = m.endPosition.clone();
});
const picks = useSceneDrillPick(cursorPosition, { limit: 10 }); // at most 10, lower cost
picks.value?.forEach((item, index) => {
  console.log(`${index + 1}.`, item.id.name);
});

Options

  • isActive - Whether picking is active, defaults to true; when false the result is reset to undefined. Supports a ref/getter.
  • throttled - The throttled sampling interval (ms) for coordinate changes, defaults to 8.
  • limit - Stop collecting after this many results, forwarded to scene.drillPick; omitted returns every hit object, a smaller value reduces cost.
  • width / height - The width and height of the pick rectangle, defaults to 3.

Return Value

  • Returns ComputedRef<any[] | undefined>: an array of pick results with fields such as id and primitive (matching each item of scene.drillPick); undefined when nothing is picked or conditions are not met.

Notes

  • drillPick is more expensive than pick and has no result cache, so combine it with the throttled sampling and a limit cap.
  • When the viewer is missing, the position is empty, or isActive is false, the result is reset to undefined.

Type Definitions

typescript
import type { Cartesian2 } from 'cesium';
import type { ComputedRef, MaybeRefOrGetter } from 'vue';
export interface UseSceneDrillPickOptions {
    /**
     * Whether to activate the pick function.
     * @default true
     */
    isActive?: MaybeRefOrGetter<boolean | undefined>;
    /**
     * Throttled sampling (ms)
     * @default 8
     */
    throttled?: number;
    /**
     * If supplied, stop drilling after collecting this many picks.
     */
    limit?: MaybeRefOrGetter<number | undefined>;
    /**
     * The width of the pick rectangle.
     * @default 3
     */
    width?: MaybeRefOrGetter<number | undefined>;
    /**
     * The height of the pick rectangle.
     * @default 3
     */
    height?: MaybeRefOrGetter<number | undefined>;
}
/**
 * Uses the `scene.drillPick` function to perform screen point picking,
 * return a computed property containing the pick result, or undefined if no object is picked.
 *
 * @param windowPosition The screen coordinates of the pick point.
 */
export declare function useSceneDrillPick(windowPosition: MaybeRefOrGetter<Cartesian2 | undefined>, options?: UseSceneDrillPickOptions): ComputedRef<any[] | undefined>;