I have a MouseMoveEvent defined. I am checking it when the right mouse button is down (set in the press handler). I want to be able to see my road as I drag it from the startpoint.
But when this MouseMove event is called, the RayItems from MouseRayHit have the same point as the press point. As I move the mouse, the values don’t change. So it doesn’t seem like MouseRayHit is updating with every mouse move, but only when the button is pressed. My release handler is also only getting the same point as the press point.
procedure TViewPlay.MouseMove(const Sender: TCastleUserInterface;
const Event: TInputMotion; var Handled: Boolean);
var rayitems : TRayCollision;
c, i : integer;
Itemhit : TCastleTransform;
Point : TVector3;
begin
Handled := false;
if right_drag and buildingroad then
begin
RayItems := MainViewport.MouseRayHit;
c := RayItems.Count;
for i := c - 1 downto 0 do
begin
ItemHit := RayItems[i].Item;
IF ( ItemHit is TTerrainTile ) then
begin
Point := RayItems[i].Point;
Notifications.Show( format( 'dragging %f, %f', [Point.x, Point.z]));
// AddRoad(TTerrainTile( ItemHit ), Point );
Handled := true;
end;
end
end;
end;
Thoughts? I haven’t updated to the engine that was just posted yet.
I switched to overriding the Motion method and am calling the inherited, but still the point values aren’t updating.
function TViewPlay.Motion(const Event: TInputMotion): boolean;
var rayitems : TRayCollision;
c, i : integer;
Itemhit : TCastleTransform;
Point : TVector3;
begin
result := inherited Motion( Event );
if right_drag and buildingroad then
begin
RayItems := MainViewport.MouseRayHit;
c := RayItems.Count;
for i := c - 1 downto 0 do
begin
ItemHit := RayItems[i].Item;
IF ( ItemHit is TTerrainTile ) and
( not ( csTransient in ItemHit.ComponentStyle )) then
begin
Point := RayItems[i].Point;
Notifications.Show( format( 'dragging %f, %f', [Point.x, Point.z]));
// AddRoad(TTerrainTile( ItemHit ), Point );
Result := true;
end;
end
end;
end;
if MainViewport.TransformUnderMouse <> nil then
LabelInfo.Caption := MainViewport.TransformUnderMouse.Name
else
LabelInfo.Caption := 'Nothing under mouse';
(The TransformUnderMouse value is derived from MouseRayHit.)
When I run, indeed the MainViewport.TransformUnderMouse.Name remains unchanged if I keep pressing left mouse button and moving the mouse.
The value is updated correctly if I don’t press any mouse button or press the right button. I have one idea how it can go wrong (the navigation class may set “Motion” event to “handled” (returns true) and then it would not be passed to other controls). I’ll see how to solve it in a way that seems “clean”.
Note: The ultimate solution will also be new navigation classes (that will not mark “Motion” as handled, they will be attached to TCastleTransform) – we work on them now with Andrzej Kilijański.
But in the meantime, I will also want to fix it for existing navigation classes.
I pushed a commit that fixes it, alongside some other improvements. So
MouseRayHit is now updated always, period. Even if you move the mouse and hold some button. And even if you don’t move the mouse! This fixes also the case when you don’t move mouse (or even camera) but something “walks in front of you”, e.g. a creature walks and takes position under camera cursor.
Also, internally MouseRayHit is calculated on-demand, but with a flag that it is “valid” until next update. So the above change does not cause any more overhead for games that actually don’t access MouseRayHit (or TransformUnderMouse). And for games that access it, using MouseRayHit (or TransformUnderMouse) multiple times e.g. in one Update makes no additional overhead.
Also TransformUnderMouse is now only a shortcut to MouseRayHit.Transform, makes API a bit more flexible.