I am trying to find the best way to determine the exact point coordinates under mouse cursor in 3D world. My current solution was the following.
I created a new function TCastleViewport.HitUnderMouse based on TCastleViewport.TransformUnderMouse to return not just the transform but the whole PRayCollisionNode (defined the new pointer type to be able to return nil) containing also hit point coordinates:
function TCastleViewport.HitUnderMouse: PRayCollisionNode;
var
I: Integer;
begin
if MouseRayHit <> nil then
for I := 0 to MouseRayHit.Count - 1 do
begin
if not (csTransient in MouseRayHit[I].Item.ComponentStyle) then
begin
New(Result);
Result^ := MouseRayHit[I];
Exit;
end;
end;
// Return nil if all items on MouseRayHit list are csTransient, or MouseRayHit = nil
Result := nil;
end;
To test it I modified the detect_scene_hit demo Update method and it seems to work OK:
procedure TViewMain.Update(const SecondsPassed: Single; var HandleInput: Boolean);
var
SceneName: String;
Hit: PRayCollisionNode;
begin
inherited;
{ This virtual method is executed every frame (many times per second). }
LabelFps.Caption := 'FPS: ' + Container.Fps.ToString;
Hit := MainViewport.HitUnderMouse;
if Hit <> nil then
begin
SceneName := Hit^.Item.Name + ', ' + Hit^.Point.ToString;
Dispose(Hit);
end
else
SceneName := 'none';
LabelSceneUnderMouse.Caption := 'Scene Under Mouse/Touch Position: ' + SceneName;
end;
My question is that is there a better way to do this or maybe could this new function (or similar functionality) be added to CastleViewport unit for all projects to be able to use it?