浏览代码

Merge pull request #9372 from CedricGuillemet/navigationDeltaTime

set/get delta step and step count for navigation tick update
David Catuhe 4 年之前
父节点
当前提交
1b1f7b490e
共有 3 个文件被更改,包括 90 次插入4 次删除
  1. 1 0
      dist/preview release/what's new.md
  2. 29 0
      src/Navigation/INavigationEngine.ts
  3. 60 4
      src/Navigation/Plugins/recastJSPlugin.ts

+ 1 - 0
dist/preview release/what's new.md

@@ -183,6 +183,7 @@
 
 - export/load prebuilt binary navigation mesh ([cedricguillemet](https://github.com/cedricguillemet))
 - get next path step point for an agent ([cedricguillemet](https://github.com/cedricguillemet))
+- set/get delta step and step count for navigation tick update ([cedricguillemet](https://github.com/cedricguillemet))
 
 ### Materials
 

+ 29 - 0
src/Navigation/INavigationEngine.ts

@@ -128,6 +128,35 @@ export interface INavigationEnginePlugin {
     getDefaultQueryExtentToRef(result: Vector3): void;
 
     /**
+     * Set the time step of the navigation tick update.
+     * Default is 1/60.
+     * A value of 0 will disable fixed time update
+     * @param newTimeStep the new timestep to apply to this world.
+     */
+    setTimeStep(newTimeStep: number): void;
+
+    /**
+     * Get the time step of the navigation tick update.
+     * @returns the current time step
+     */
+    getTimeStep(): number;
+
+    /**
+     * If delta time in navigation tick update is greater than the time step
+     * a number of sub iterations are done. If more iterations are need to reach deltatime
+     * they will be discarded.
+     * A value of 0 will set to no maximum and update will use as many substeps as needed
+     * @param newStepCount the maximum number of iterations
+     */
+    setMaximumSubStepCount(newStepCount: number): void;
+
+    /**
+     * Get the maximum number of iterations per navigation tick update
+     * @returns the maximum number of iterations
+     */
+    getMaximumSubStepCount(): number;
+
+    /**
      * Release all resources
      */
     dispose(): void;

+ 60 - 4
src/Navigation/Plugins/recastJSPlugin.ts

@@ -3,7 +3,7 @@ import { Logger } from "../../Misc/logger";
 import { VertexData } from "../../Meshes/mesh.vertexData";
 import { Mesh } from "../../Meshes/mesh";
 import { Scene } from "../../scene";
-import { Vector3 } from '../../Maths/math';
+import { Epsilon, Vector3 } from '../../Maths/math';
 import { TransformNode } from "../../Meshes/transformNode";
 import { Observer } from "../../Misc/observable";
 import { Nullable } from "../../types";
@@ -30,6 +30,9 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
      */
     public navMesh: any;
 
+    private _maximumSubStepCount: number = 10;
+    private _timeStep: number = 1 / 60;
+
     /**
      * Initializes the recastJS plugin
      * @param recastInjection can be used to inject your own recast reference
@@ -45,6 +48,45 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
             Logger.Error("RecastJS is not available. Please make sure you included the js file.");
             return;
         }
+        this.setTimeStep();
+    }
+
+    /**
+     * Set the time step of the navigation tick update.
+     * Default is 1/60.
+     * A value of 0 will disable fixed time update
+     * @param newTimeStep the new timestep to apply to this world.
+     */
+    setTimeStep(newTimeStep: number = 1 / 60): void {
+        this._timeStep = newTimeStep;
+    }
+
+    /**
+     * Get the time step of the navigation tick update.
+     * @returns the current time step
+     */
+    getTimeStep(): number {
+        return this._timeStep;
+    }
+
+    /**
+     * If delta time in navigation tick update is greater than the time step
+     * a number of sub iterations are done. If more iterations are need to reach deltatime
+     * they will be discarded.
+     * A value of 0 will set to no maximum and update will use as many substeps as needed
+     * @param newStepCount the maximum number of iterations
+     */
+    setMaximumSubStepCount(newStepCount: number = 10): void {
+        this._maximumSubStepCount = newStepCount;
+    }
+
+    /**
+     * Get the maximum number of iterations per navigation tick update
+     * @returns the maximum number of iterations
+     */
+    getMaximumSubStepCount(): number
+    {
+        return this._maximumSubStepCount;
     }
 
     /**
@@ -577,11 +619,25 @@ export class RecastJSCrowd implements ICrowd {
      */
     update(deltaTime: number): void {
         // update crowd
-        this.recastCrowd.update(deltaTime);
+        var timeStep = this.bjsRECASTPlugin.getTimeStep();
+        var maxStepCount = this.bjsRECASTPlugin.getMaximumSubStepCount();
+        if (timeStep <= Epsilon) {
+            this.recastCrowd.update(deltaTime);
+        } else {
+            var iterationCount = deltaTime / timeStep;
+            if (maxStepCount && iterationCount > maxStepCount) {
+                iterationCount = maxStepCount;
+            }
+            if (iterationCount < 1) {
+                iterationCount = 1;
+            }
+            for (let i = 0; i < iterationCount; i++) {
+                this.recastCrowd.update(timeStep);
+            }
+        }
 
         // update transforms
-        for (let index = 0; index < this.agents.length; index++)
-        {
+        for (let index = 0; index < this.agents.length; index++) {
             this.transforms[index].position = this.getAgentPosition(this.agents[index]);
         }
     }