Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
1.0.0:pathfinding [2023/03/21 15:29] – [Click to Start Pathfinding] admin1.0.0:pathfinding [2023/03/21 15:33] – [Click to Start Pathfinding] admin
Line 155: Line 155:
 Image1.Bitmap.Assign(FVerifyBmp); Image1.Bitmap.Assign(FVerifyBmp);
 </file> </file>
 +
 +
 +===== Click to Start Pathfinding  =====
 +
 +Many developers may struggle with the question how to combine the setup above with user interaction.
 +
 +Speaking for a classic Point & Click Adventure, a recommend way is to add a simple plane (TPlane, TGorillaPlane) for click detection.
 +
 +All other 3D elements should be set to HitTest = false, to not disturb mouse interaction with the helper plane.
 +
 +We then register a MouseUp event on the viewport, where we put all of our mouse handling.
 +
 +<file pascal>
 +var 
 +  FDestPoint : TPoint3D;
 +  
 +procedure TForm1.GorillaViewport1MouseUp(Sender: TObject; Button: TMouseButton;
 +  Shift: TShiftState; X, Y: Single);
 +var LRayPos,
 +    LRayDir : TPoint3D;
 +    LHitPos,
 +    LNormal,
 +    LScreenPos : TPoint3D;
 +begin
 +  // 1) Get 3D position of click, by converting screen coordinates into 3D coordinates
 +  LScreenPos := GorillaViewport1.ScreenToWorld(PointF(X, Y));
 +
 +  // 2) Cast a ray from camera to the clicking position, to retrieve the real
 +  //    3D destination coordinate
 +  LRayPos := GorillaCamera1.AbsolutePosition;
 +  LRayDir := (LScreenPos - LRayPos).Normalize();
 +  if GorillaPlane1.RayCastIntersect(LRayPos, LRayDir, LHitPos, LNormal) then
 +  begin
 +    // If raycasting was successfully - we can start store the point hit by the ray
 +    FDestPoint := LHitPos;
 +    FDestPoint.Y := 0;
 +    
 +    // Aftwards we start pathfinding
 +    UpdatePathfinding();
 +  end;
 +end;
 +
 +procedure TForm1.UpdatePathfinding();
 +var LAgentPos : TPoint3D;
 +begin
 +  // Get the agent position (pathfinding moving object)
 +  LAgentPos := GorillaModel1.AbsolutePosition;
 +  
 +  // Compute the path from 3D position - this will generate our new walking path
 +  FPathFinder.FindPath(LAgentPos, FDestPoint);
 +
 +  // Stop the current animation
 +  FPathAnim.Stop();
 +  FPathAnim.Enabled := false;
 +
 +  // Apply computed path data to our existing TGorillaPath3D instance, instead for recreating each time
 +  FPathFinder.ApplyToPath3D(FPath);
 +
 +  // Reset the used path data in our path animation
 +  FPathAnim.Duration := FPath.Path.GetLength;
 +  FPathAnim.Path := FPath.Path;
 +
 +  // For correct rotation of our character, we need the polygon to detect the
 +  // next node to adjust to
 +  FPath.Path.FlattenToPolygon(FPolygon);
 +
 +  // Restart movement on path
 +  FPathAnim.Enabled := true;
 +  FPathAnim.Start();
 +end;
 +</file>
 +
  
 ===== Auto-Rotate an animated character ===== ===== Auto-Rotate an animated character =====
Line 228: Line 300:
 </file> </file>
  
-===== Click to Start Pathfinding  ===== 
- 
-Many developers may struggle with the question how to combine the setup above with user interaction. 
- 
-Speaking for a classic Point & Click Adventure, a recommend way is to add a simple plane (TPlane, TGorillaPlane) for click detection. 
- 
-All other 3D elements should be set to HitTest = false, to not disturb mouse interaction with the helper plane. 
- 
-We then register a MouseUp event on the viewport, where we put all of our mouse handling. 
- 
-<file pascal> 
-var  
-  FDestPoint : TPoint3D; 
-   
-procedure TForm1.GorillaViewport1MouseUp(Sender: TObject; Button: TMouseButton; 
-  Shift: TShiftState; X, Y: Single); 
-var LRayPos, 
-    LRayDir : TPoint3D; 
-    LHitPos, 
-    LNormal, 
-    LScreenPos : TPoint3D; 
-begin 
-  // 1) Get 3D position of click, by converting screen coordinates into 3D coordinates 
-  LScreenPos := GorillaViewport1.ScreenToWorld(PointF(X, Y)); 
- 
-  // 2) Cast a ray from camera to the clicking position, to retrieve the real 
-  //    3D destination coordinate 
-  LRayPos := GorillaCamera1.AbsolutePosition; 
-  LRayDir := (LScreenPos - LRayPos).Normalize(); 
-  if GorillaPlane1.RayCastIntersect(LRayPos, LRayDir, LHitPos, LNormal) then 
-  begin 
-    // If raycasting was successfull - we can start updating the path 
-    FDestPoint := LHitPos; 
-    FDestPoint.Y := 0; 
-     
-    // Start pathfinding 
-    UpdatePathfinding(); 
-  end; 
-end; 
- 
-procedure TForm1.UpdatePathfinding(); 
-var LAgentPos : TPoint3D; 
-begin 
-  // New computation of path 
-  LAgentPos := GorillaModel1.AbsolutePosition; 
-  FPathFinder.FindPath(LAgentPos, FDestPoint); 
- 
-  // Stop the current animation 
-  FPathAnim.Stop(); 
-  FPathAnim.Enabled := false; 
- 
-  // Apply computed path data to our existing TGorillaPath3D instance, instead for recreating each time 
-  FPathFinder.ApplyToPath3D(FPath); 
- 
-  // Reset the used path data in our path animation 
-  FPathAnim.Duration := FPath.Path.GetLength; 
-  FPathAnim.Path := FPath.Path; 
- 
-  // For correct rotation of our character, we need the polygon to detect the 
-  // next node to adjust to 
-  FPath.Path.FlattenToPolygon(FPolygon); 
- 
-  // Restart movement on path 
-  FPathAnim.Enabled := true; 
-  FPathAnim.Start(); 
-end; 
-</file> 
  
 Next: [[renderpass|Render Pass]] Next: [[renderpass|Render Pass]]