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
1.0.0:pathfinding [2023/03/21 15:28] – [Click to Start Pathfinding] admin1.0.0:pathfinding [2023/03/21 15:34] (current) – [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 - 
 +  // NOTICE: READ THE SECTION BELOW
 +  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 301:
 </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 Adventures, 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]]