瀏覽代碼

PR feedback

Cedric Guillemet 6 年之前
父節點
當前提交
7aacbd621a
共有 7 個文件被更改,包括 63 次插入87 次删除
  1. 1 0
      Playground/frame.html
  2. 1 0
      Playground/full.html
  3. 1 0
      Playground/index.html
  4. 0 38
      dist/recast.js
  5. 10 5
      src/Navigation/INavigationEngine.ts
  6. 50 15
      src/Navigation/Plugins/recastJSPlugin.ts
  7. 0 29
      src/scene.ts

+ 1 - 0
Playground/frame.html

@@ -16,6 +16,7 @@
     <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
     <!-- Babylon.js -->
     <script src="https://preview.babylonjs.com/ammo.js"></script>
+    <script src="https://preview.babylonjs.com/recast.js"></script>
     <script src="https://preview.babylonjs.com/cannon.js"></script>
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/earcut.min.js"></script>

+ 1 - 0
Playground/full.html

@@ -14,6 +14,7 @@
     <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
     <!-- Babylon.js -->
     <script src="https://preview.babylonjs.com/ammo.js"></script>
+    <script src="https://preview.babylonjs.com/recast.js"></script>
     <script src="https://preview.babylonjs.com/cannon.js"></script>
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/gltf_validator.js"></script>

+ 1 - 0
Playground/index.html

@@ -19,6 +19,7 @@
     <script src="js/libs/fileSaver.js"></script>
     <!-- Dependencies -->
     <script src="https://preview.babylonjs.com/ammo.js"></script>
+    <script src="https://preview.babylonjs.com/recast.js"></script>
     <script src="https://preview.babylonjs.com/cannon.js"></script>
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/gltf_validator.js"></script>

File diff suppressed because it is too large
+ 0 - 38
dist/recast.js


+ 10 - 5
src/Navigation/INavigationEngine.ts

@@ -8,11 +8,14 @@ import { Scene } from "../scene";
  * Navigation plugin interface to add navigation constrained by a navigation mesh
  */
 export interface INavigationEnginePlugin {
+    /**
+     * plugin name
+     */
     name: string;
 
     /**
      * Creates a navigation mesh
-     * @param mesh of all the geometry used to compute the navigatio mesh
+     * @param mesh of all the geometry used to compute the navigation mesh
      * @param parameters bunch of parameters used to filter geometry
      */
     createMavMesh(mesh: AbstractMesh, parameters: NavMeshParameters): void;
@@ -39,7 +42,10 @@ export interface INavigationEnginePlugin {
      */
     getRandomPointAround(position: Vector3, maxRadius: number): Vector3;
 
-    ///
+    /**
+     * If this plugin is supported
+     * @returns true if plugin is supported
+     */
     isSupported(): boolean;
 
     /**
@@ -107,7 +113,6 @@ export interface ICrowd {
      * Asks a particular agent to go to a destination. That destination is constrained by the navigation mesh
      * @param index agent index returned by addAgent
      * @param destination targeted world position
-     * @returns the closest point to position constrained by the navigation mesh
      */
     agentGoto(index: number, destination: Vector3): void;
 
@@ -120,7 +125,7 @@ export interface ICrowd {
 /**
  * Configures an agent
  */
-export class AgentParameters {
+export interface AgentParameters {
     /**
      *  Agent radius. [Limit: >= 0]
      */
@@ -160,7 +165,7 @@ export class AgentParameters {
 /**
  * Configures the navigation mesh creation
  */
-export class NavMeshParameters {
+export interface NavMeshParameters {
     /**
      * The xz-plane cell size to use for fields. [Limit: > 0] [Units: wu]
      */

+ 50 - 15
src/Navigation/Plugins/recastJSPlugin.ts

@@ -6,6 +6,8 @@ import { Mesh } from "../../Meshes/mesh";
 import { Scene } from "../../scene";
 import { Vector3 } from '../../Maths/math';
 import { TransformNode } from "../../Meshes/transformNode";
+import { Observer } from "../../Misc/observable";
+import { Nullable } from "../../types";
 
 declare var Recast: any;
 
@@ -17,11 +19,20 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
      * Reference to the Recast library
      */
     public bjsRECAST: any = {};
+
+    /**
+     * plugin name
+     */
     public name: string = "RecastJSPlugin";
+
+    /**
+     * the first navmesh created. We might extend this to support multiple navmeshes
+     */
     public navMesh: any;
 
     /**
      * Initializes the recastJS plugin
+     * @param recastInjection can be used to inject your own recast reference
      */
     public constructor(recastInjection: any = Recast) {
         if (typeof recastInjection === "function") {
@@ -42,7 +53,7 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
      * @param parameters bunch of parameters used to filter geometry
      */
     createMavMesh(mesh: AbstractMesh, parameters: NavMeshParameters): void {
-        var rc = new this.bjsRECAST.rcConfig();
+        const rc = new this.bjsRECAST.rcConfig();
         rc.cs = parameters.cs;
         rc.ch = parameters.ch;
         rc.walkableSlopeAngle = parameters.walkableSlopeAngle;
@@ -58,8 +69,8 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
         rc.detailSampleMaxError = parameters.detailSampleMaxError;
 
         this.navMesh = new this.bjsRECAST.NavMesh();
-        var meshIndices = mesh.getIndices();
-        var positions = mesh.getVerticesData('position');
+        const meshIndices = mesh.getIndices();
+        const positions = mesh.getVerticesData('position');
         this.navMesh.build(positions, mesh.getTotalVertices(), meshIndices, mesh.getTotalIndices(), rc);
     }
 
@@ -134,7 +145,6 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
     createCrowd(maxAgents: number, maxAgentRadius: number, scene: Scene) : ICrowd
     {
         var crowd = new RecastJSCrowd(this, maxAgents, maxAgentRadius, scene);
-        scene.addCrowd(crowd);
         return crowd;
     }
 
@@ -146,19 +156,43 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
     }
 
     /**
-     *
+     * If this plugin is supported
+     * @returns true if plugin is supported
      */
     public isSupported(): boolean {
         return this.bjsRECAST !== undefined;
     }
 }
 
+/**
+ * Recast detour crowd implementation
+ */
 export class RecastJSCrowd implements ICrowd {
+    /**
+     * Recast/detour plugin
+     */
     public bjsRECASTPlugin: RecastJSPlugin;
+    /**
+     * Link to the detour crowd
+     */
     public recastCrowd: any = {};
-    public transforms: TransformNode[];
-    public agents: number[];
-    private scene: Scene;
+    /**
+     * One transform per agent
+     */
+    public transforms: TransformNode[] = new Array<TransformNode>();
+    /**
+     * All agents created
+     */
+    public agents: number[] = new Array<number>();
+    /**
+     * Link to the scene is kept to unregister the crowd from the scene
+     */
+    private _scene: Scene;
+
+    /**
+     * Observer for crowd updates
+     */
+    private _onBeforeAnimationsObserver: Nullable<Observer<Scene>> = null;
 
     /**
      * Constructor
@@ -171,9 +205,11 @@ export class RecastJSCrowd implements ICrowd {
     public constructor(plugin: RecastJSPlugin, maxAgents: number, maxAgentRadius: number, scene: Scene) {
         this.bjsRECASTPlugin = plugin;
         this.recastCrowd = new this.bjsRECASTPlugin.bjsRECAST.Crowd(maxAgents, maxAgentRadius, this.bjsRECASTPlugin.navMesh.getNavMesh());
-        this.transforms = new Array<TransformNode>();
-        this.agents = new Array<number>();
-        this.scene = scene;
+        this._scene = scene;
+
+        this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {
+            this.update(scene.getEngine().getDeltaTime() * 0.001);
+        });
     }
 
     /**
@@ -229,7 +265,6 @@ export class RecastJSCrowd implements ICrowd {
      * Asks a particular agent to go to a destination. That destination is constrained by the navigation mesh
      * @param index agent index returned by addAgent
      * @param destination targeted world position
-     * @returns the closest point to position constrained by the navigation mesh
      */
     agentGoto(index: number, destination: Vector3): void {
         this.recastCrowd.agentGoto(index, new this.bjsRECASTPlugin.bjsRECAST.Vec3(destination.x, destination.y, destination.z));
@@ -266,8 +301,7 @@ export class RecastJSCrowd implements ICrowd {
         this.recastCrowd.update(deltaTime);
 
         // update transforms
-        var index: number;
-        for (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]);
         }
@@ -279,6 +313,7 @@ export class RecastJSCrowd implements ICrowd {
     dispose() : void
     {
         this.recastCrowd.destroy();
-        this.scene.removeCrowd(this);
+        this._scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);
+        this._onBeforeAnimationsObserver = null;
     }
 }

+ 0 - 29
src/scene.ts

@@ -47,7 +47,6 @@ import { AbstractActionManager } from './Actions/abstractActionManager';
 import { _DevTools } from './Misc/devTools';
 import { WebRequest } from './Misc/webRequest';
 import { InputManager } from './Inputs/scene.inputManager';
-import { ICrowd } from './Navigation/INavigationEngine';
 
 declare type Ray = import("./Culling/ray").Ray;
 declare type TrianglePickingPredicate = import("./Culling/ray").TrianglePickingPredicate;
@@ -165,27 +164,6 @@ export class Scene extends AbstractScene implements IAnimatable {
      */
     public ambientColor = new Color3(0, 0, 0);
 
-    public crowds: ICrowd[];
-
-    /**
-     * Adds an agent crowd to the scene
-     * Once added, every agent will have its position updated based on crowd update
-     */
-    addCrowd(crowd: ICrowd): void {
-        this.crowds.push(crowd);
-    }
-
-    /**
-     * Removes a crowd from the scene
-     * Once removed, there will be no more updats to the crowd agents
-     */
-    removeCrowd(crowd: ICrowd): void {
-        var item = this.crowds.indexOf(crowd);
-        if (item > -1) {
-            this.crowds.splice(item, 1);
-        }
-    }
-
     /**
      * This is use to store the default BRDF lookup for PBR materials in your scene.
      * It should only be one of the following (if not the default embedded one):
@@ -1367,8 +1345,6 @@ export class Scene extends AbstractScene implements IAnimatable {
         if (!options || !options.virtual) {
             this._engine.onNewSceneAddedObservable.notifyObservers(this);
         }
-
-        this.crowds = new Array<ICrowd>();
     }
 
     /**
@@ -3740,11 +3716,6 @@ export class Scene extends AbstractScene implements IAnimatable {
             this.animate();
         }
 
-        // Navigation
-        for (let crowd of this.crowds) {
-            crowd.update(this._engine.getDeltaTime() * 0.001);
-        }
-
         // Before camera update steps
         for (let step of this._beforeCameraUpdateStage) {
             step.action();