# Get all geometry under raycast?

**URL:** https://forum.castle-engine.io/t/get-all-geometry-under-raycast/957
**Category:** Physics and Collisions
**Created:** [October 30, 2023, 1:12am UTC](https://forum.castle-engine.io/t/get-all-geometry-under-raycast/957 "2023-10-30T01:12:37Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![bugan11](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/b/c5a1d2/32.png) [@bugan11](https://forum.castle-engine.io/u/bugan11)
#### Post date: [October 30, 2023, 1:12am UTC](https://forum.castle-engine.io/t/get-all-geometry-under-raycast/957/1 "2023-10-30T01:12:37Z")

</div>

Hello, is there any way, I could get whole list of items, when I do RayCast on the viewport items? I need to pick geometry on click and currently MouseRayHit or RayCast, WorldRayCast, etc., returns just the first item it hits with it. Is there any way in engine to pick all the items, also underneath the first item picked by RayCast? Thank you.

---

<div class="post-metadata">

### Author: ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)
#### Post date: [October 31, 2023, 10:55am UTC](https://forum.castle-engine.io/t/get-all-geometry-under-raycast/957/2 "2023-10-31T10:55:49Z")

</div>

All the ray-casting methods are indeed designed to only return _first_ hit object. There are specific optimizations inside for this use-case, since it is the most common need.

To query everything, you can repeat the query, shifting `RayOrigin` (position at which the ray starts) each time. This is similar to what I described in this post: [Convenient way to determine exact point under mouse - #4 by michalis](https://forum.castle-engine.io/t/convenient-way-to-determine-exact-point-under-mouse/791/4) , albeit that was for a bit different task (to avoid detecting hits on transparent pixels).

So:

- Use `MyViewport.CameraRayCollision(RayOrigin, RayDirection)` . It returns `TRayCollision`, just like `MouseRayHit` (so it can be processed in the same way as above to detect the particular point). It takes as input ray position and direction.

- Use it in a loop.

---

<div class="post-metadata">

### Author: ![bugan11](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/b/c5a1d2/32.png) [@bugan11](https://forum.castle-engine.io/u/bugan11)
#### Post date: [November 5, 2023, 4:01pm UTC](https://forum.castle-engine.io/t/get-all-geometry-under-raycast/957/3 "2023-11-05T16:01:50Z")

</div>

Hello, thank you, it worked nicely, with just one thing - Pickable property needs to be set to false while raycasting, to prevent picking object multiple times depending on shape. But I found one issue, with TCastleAbstractPrimitives, whenever I create for example a TCastleBox in editor and load it into runtime app, this does not work. Box is registered correctly by raycast, but no Name given event if I had named it, and also another raycast for object behind or under it does not work either. For loaded TCastleScene models or created geometry via X3D it works perfect. Is there anything specific why it would not work on primitives like box, plane etc.? Thanks.

---

<div class="post-metadata">

### Author: ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)
#### Post date: [November 6, 2023, 2:36pm UTC](https://forum.castle-engine.io/t/get-all-geometry-under-raycast/957/4 "2023-11-06T14:36:59Z")

</div>

> [@bugan11](#):
>
> Hello, thank you, it worked nicely, with just one thing - Pickable property needs to be set to false while raycasting, to prevent picking object multiple times depending on shape.

Indeed. If you don’t want multiple hits on the same object, you can toggle `Pickable` or `Exsists` on the object.

> [@bugan11](#):
>
> But I found one issue, with TCastleAbstractPrimitives, whenever I create for example a TCastleBox in editor and load it into runtime app, this does not work. Box is registered correctly by raycast, but no Name given event if I had named it, and also another raycast for object behind or under it does not work either. For loaded TCastleScene models or created geometry via X3D it works perfect. Is there anything specific why it would not work on primitives like box, plane etc.? Thanks.

Ray collisions with primitives (TCastleAbstractPrimitive) should be detected OK.

But note that `MyViewport.MouseRayHit` will then be more complicated: the first item on `MyViewport.MouseRayHit` will be the internal `TCastleScene` instance (each TCastleAbstractPrimitives actually creates an internal `TCastleScene` that it manages). The 2nd item will be a reference to the actual TCastleAbstractPrimitive instance.

It that is the case, it is easiest to just use `MyViewport.TransformUnderMouse`. Or look at `MyViewport.MouseRayHit <> nil`, if not nil then look at `MyViewport.MouseRayHit.Transform`. Both these methods will return the first transform **that is not internal**. (they detect it by looking at `csTransient in Transform.ComponentStyle`).

It is possible we’ll change `MouseRayHit` at some point to avoid showing these internal instances at all. I know they can be confusing. These are also discussed in [Tiled maps | Manual | Castle Game Engine](https://castle-engine.io/tiled_maps#tile_under_mouse) .

Let me know if this fixes your problem with TCastleAbstractPrimitive. If the problem will remain, please submit a testcase to reproduce the problem.

---

<div class="post-metadata">

### Author: ![bugan11](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/b/c5a1d2/32.png) [@bugan11](https://forum.castle-engine.io/u/bugan11)
#### Post date: [November 7, 2023, 3:57pm UTC](https://forum.castle-engine.io/t/get-all-geometry-under-raycast/957/5 "2023-11-07T15:57:02Z")

</div>

Hello, so it looks like I did not thoroughly tested, because I have found a strange issue. It does not work completely I figured now, but I do not understand why. Basically I have saved user interface file which I edit in the editor where I do have viewport as root, some background and then in the Items, I do have Camera, DirLight and all models as TCastleScene. One of them I do have generated as custom geometry through X3DNodes and is saved as X3D and loaded into scene (there I need to differentiate per shape with help of triangle, so I need extended collision result). The thing is, that when I move around and get mouse cursor over object like e.g. building there, and box behind it, it only registers the building and then proceeds to return nil as WorldRay result even if I previously make the building Pickable property false. But when there is that custom geometry behind building (but should be irelevant as it is loaded as X3D model), it does register both objects correctly. Where could possibly be a problem hidden here? Here is the code for method which I call to get all geometry in Viewport’s OnMotion procedure.

```auto
function CGEForm.AllItemsHitByRay(pos: TVector2; depth: integer): TList<TPair<TShape, TCastleTransform>>;
var
  RayHit: TRayCollision;
  RayOrigin, RayDirection: TVector3;
  Item: TPair<TShape, TCastleTransform>;
  Shape: TShape;
  rayColNode: TRayCollisionNode;
  rayColPos: Integer;
begin
  Result := nil;
  depth := Max(depth, 1);
  fCGEViewport.PositionToRay(pos, true, RayOrigin, RayDirection);
  RayHit := fCGEViewport.Items.WorldRay(RayOrigin, RayDirection);
  if RayHit <> nil then
  begin
    rayColPos := GetCorrectRayCollisionNodePos(rayHit);
    Result := TList<TPair<TShape, TCastleTransform>>.Create();
    while (RayHit <> nil) AND (rayColPos > -1) AND (depth > 0) do
    begin
      shape := nil;
      rayColNode := RayHit.Items[rayColPos];
      if (rayColNode.Item is TCastleScene) AND (rayColNode.Triangle <> nil) AND (rayColNode.Triangle.Shape <> nil) then
      begin
        if TCastleScene(rayColNode.Item).VerticesCount <> rayColNode.Triangle.Shape.VerticesCount then
          shape := rayColNode.Triangle.Shape;
      end;

      Result.Add(TPair<TShape, TCastleTransform>.Create(shape, rayColNode.Item));
      rayColNode.Item.Pickable := false;
      RayOrigin := rayColNode.Point + RayDirection.AdjustToLength(SingleEqualityEpsilon);
      FreeAndNil(RayHit);
      RayHit := fCGEViewport.Items.WorldRay(RayOrigin, RayDirection);
      rayColPos := GetCorrectRayCollisionNodePos(RayHit);
      Dec(depth);
    end;

    if RayHit <> nil then
      FreeAndNil(RayHit);

    for Item in Result do
    begin
      Item.Value.Pickable := true;
    end;
  end;
end;

```

Thanks for any further advice.

---

<div class="post-metadata">

### Author: ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)
#### Post date: [November 8, 2023, 9:08pm UTC](https://forum.castle-engine.io/t/get-all-geometry-under-raycast/957/6 "2023-11-08T21:08:47Z")

</div>

Hmm, I don’t know the solution from a first glance. Your code looks OK (in particular you restore the `...Pickable := true` reliably, which was my first suspicion). I will need to have a complete testcase (code that compiles + data) to experiment and advise more on this. Can you post it (on this forum, or as GitHub issue [Issues · castle-engine/castle-engine · GitHub](https://github.com/castle-engine/castle-engine/issues) ) ?

---

<div class="post-metadata">

### Author: ![bugan11](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/b/c5a1d2/32.png) [@bugan11](https://forum.castle-engine.io/u/bugan11)
#### Post date: [November 9, 2023, 1:06pm UTC](https://forum.castle-engine.io/t/get-all-geometry-under-raycast/957/7 "2023-11-09T13:06:16Z")

</div>

Hello, sorry for the inconvenience, I just found out that I changed a logic for printing out the names of objects under pick slightly and also quite poorly debugged probably, because now I have noticed the cause and the solution seems to work flawless as it is there. Also there is probably no need to computing vector from hitPoint when disabling pickable, thus saving a line and small operation cost maybe. Thanks for help.
