Browse Source

crowd agents update

Cedric Guillemet 6 years ago
parent
commit
da9d257b96

+ 1 - 0
Playground/debug.html

@@ -38,6 +38,7 @@
 
     <!-- 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-local.html

@@ -18,6 +18,7 @@
     <script src="js/libs/fileSaver.js"></script>
     <!-- Dependencies -->
     <script src="../dist/preview%20release/ammo.js"></script>
+    <script src="../dist/preview%20release/recast.js"></script>
     <script src="../dist/preview%20release/cannon.js"></script>
     <script src="../dist/preview%20release/Oimo.js"></script>
     <script src="../dist/preview%20release/gltf_validator.js"></script>

+ 1 - 0
localDev/index.html

@@ -9,6 +9,7 @@
     <script src="../dist/preview%20release/cannon.js"></script>
     <script src="../dist/preview%20release/Oimo.js"></script>
     <script src="../dist/preview%20release/ammo.js"></script>
+    <script src="../dist/preview%20release/recast.js"></script>
     <script src="../dist/preview%20release/gltf_validator.js"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
     <script src="src/webgl-debug.js"></script>

+ 16 - 2
src/Navigation/INavigationEngine.ts

@@ -1,5 +1,5 @@
-//import { Nullable } from "../types";
-//import { Vector3, Quaternion } from "../Maths/math";
+import { TransformNode } from "../Meshes/transformNode";
+import { Vector3 } from "../Maths/math";
 import { AbstractMesh } from "../Meshes/abstractMesh";
 import { Mesh } from "../Meshes/mesh";
 import { Scene } from "../scene";
@@ -10,9 +10,12 @@ export interface INavigationEnginePlugin {
     name: string;
     createMavMesh(mesh: AbstractMesh): void;
     createDebugNavMesh(scene: Scene): Mesh;
+    getClosestPoint(position: Vector3): Vector3;
     dispose(): void;
     isSupported(): boolean;
     check(): void;
+
+    createCrowd(maxAgents: number, maxAgentRadius: number, scene: Scene) : ICrowd;
 }
 
 /**
@@ -30,5 +33,16 @@ export interface INavigationEngine {
      */
     createMavMesh(mesh: AbstractMesh): void;
     createDebugNavMesh(scene: Scene): Mesh;
+    getClosestPoint(position: Vector3): Vector3;
     check(): void;
+
+    createCrowd(maxAgents: number, maxAgentRadius: number, scene: Scene) : ICrowd;
 }
+
+export interface ICrowd {
+    addAgent(pos: Vector3, transform:TransformNode): number;
+    getAgentPosition(index: number): Vector3
+	removeAgent(index:number): void;
+    update(deltaTime: number): void;
+    agentGoto(index: number, destination: Vector3): void;
+}

+ 14 - 4
src/Navigation/NavigationEngine.ts

@@ -1,6 +1,5 @@
-//import { Nullable } from "../types";
-//import { Vector3 } from "../Maths/math";
-import { INavigationEngine, INavigationEnginePlugin } from "./INavigationEngine";
+import { Vector3 } from "../Maths/math";
+import { INavigationEngine, INavigationEnginePlugin, ICrowd } from "./INavigationEngine";
 import { _DevTools } from '../Misc/devTools';
 import { AbstractMesh } from "../Meshes/abstractMesh";
 import { Mesh } from "../Meshes/mesh";
@@ -28,8 +27,8 @@ export class NavigationEngine implements INavigationEngine {
             throw new Error("Navigation Engine " + this._navigationPlugin.name + " cannot be found. "
                 + "Please make sure it is included.");
         }
-
     }
+
     createMavMesh(mesh: AbstractMesh): void {
         this._navigationPlugin.createMavMesh(mesh);
     }
@@ -38,6 +37,17 @@ export class NavigationEngine implements INavigationEngine {
         return this._navigationPlugin.createDebugNavMesh(scene);
     }
 
+    getClosestPoint(position: Vector3): Vector3
+    {
+        return this._navigationPlugin.getClosestPoint(position);
+    }
+
+    createCrowd(maxAgents: number, maxAgentRadius: number, scene: Scene) : ICrowd
+    {
+        var crowd = this._navigationPlugin.createCrowd(maxAgents, maxAgentRadius, scene);
+        return crowd;
+    }
+
     /**
      * Release all resources
      */

+ 82 - 18
src/Navigation/Plugins/recastJSPlugin.ts

@@ -1,12 +1,11 @@
-//import { Quaternion, Vector3, Matrix } from "../../Maths/math";
-import { INavigationEnginePlugin } from "../../Navigation/INavigationEngine";
+import { INavigationEnginePlugin, ICrowd } from "../../Navigation/INavigationEngine";
 import { Logger } from "../../Misc/logger";
-//import { VertexBuffer } from "../../Meshes/buffer";
 import { VertexData } from "../../Meshes/mesh.vertexData";
-//import { Nullable } from "../../types";
 import { AbstractMesh } from "../../Meshes/abstractMesh";
 import { Mesh } from "../../Meshes/mesh";
 import { Scene } from "../../scene";
+import { Vector3 } from '../../Maths/math';
+import { TransformNode } from "../../Meshes/transformNode";
 
 declare var Recast: any;
 
@@ -19,7 +18,7 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
      */
     public bjsRECAST: any = {};
     public name: string = "RecastJSPlugin";
-    private navMesh: any;
+    public navMesh: any;
     /**
      * Initializes the recastJS plugin
      */
@@ -38,46 +37,52 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
         this.navMesh = new this.bjsRECAST.NavMesh();
         var meshIndices = mesh.getIndices();
         var positions = mesh.getVerticesData('position');	
-
-        Logger.Error(`mesh infos vt=${mesh.getTotalVertices()} indices = ${mesh.getTotalIndices()}`);
-        this.navMesh.Build(positions, mesh.getTotalVertices(), meshIndices, mesh.getTotalIndices(), rc);
+        this.navMesh.build(positions, mesh.getTotalVertices(), meshIndices, mesh.getTotalIndices(), rc);
     }
 
     createDebugNavMesh(scene: Scene): Mesh {
         var tri: number;
         var pt: number;
-        var debugNavMesh = this.navMesh.GetDebugNavMesh();
-        let triangleCount = debugNavMesh.TriangleCount();
-        Logger.Error(`navmesh has ${triangleCount} triangles`);
+        var debugNavMesh = this.navMesh.getDebugNavMesh();
+        let triangleCount = debugNavMesh.getTriangleCount();
 
         var indices = [];
         var positions = [];
         for (tri = 0; tri < triangleCount*3; tri++) 
         {
             indices.push(tri);
-            Logger.Error(`tri in=${tri}`);
         }
         for (tri = 0; tri < triangleCount; tri++) 
         {
             for (pt = 0; pt < 3 ; pt++)
             {
-                let point = debugNavMesh.GetTriangle(tri).GetPoint(pt);
-                positions.push(point.x(), point.y(), point.z());
-                Logger.Error(`tri x=${point.x()} y=${point.y()} x=${point.z()}`);
+                let point = debugNavMesh.getTriangle(tri).getPoint(pt);
+                positions.push(point.x, point.y, point.z);
             }
         }
         
-
         var mesh = new Mesh("NavMeshDebug", scene);
         var vertexData = new VertexData();
 
         vertexData.indices = indices;
         vertexData.positions = positions;
         vertexData.applyToMesh(mesh, false);
+        return mesh;
+    }
 
-        
+    getClosestPoint(position: Vector3) : Vector3
+    {
+        var p = new this.bjsRECAST.Vec3(position.x, position.y, position.z);
+        var ret = this.navMesh.getClosestPoint(p);
+        var pr = new Vector3(ret.x, ret.y, ret.z);
+        return pr;
+    }
 
-        return mesh;
+    createCrowd(maxAgents: number, maxAgentRadius: number, scene: Scene) : ICrowd
+    {
+        var crowd = new RecastJSCrowd(this, maxAgents, maxAgentRadius);
+        scene.addCrowd(crowd);
+        return crowd;
     }
 
     /**
@@ -94,3 +99,62 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
         return this.bjsRECAST !== undefined;
     }
 }
+
+export class RecastJSCrowd implements ICrowd {
+    public bjsRECASTPlugin: RecastJSPlugin;
+    public recastCrowd: any = {};
+    public transforms:TransformNode[];
+    public agents:number[];
+    public constructor(plugin: RecastJSPlugin, maxAgents: number, maxAgentRadius: number) {
+        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>();
+    }
+
+    addAgent(pos: Vector3, transform:TransformNode): number
+    {
+        var agentParams = new this.bjsRECASTPlugin.bjsRECAST.dtCrowdAgentParams();
+        agentParams.radius = 0.1;
+        agentParams.height = 0.1;
+        agentParams.maxAcceleration = 1.0;
+        agentParams.maxSpeed = 1.0;
+        agentParams.collisionQueryRange = 1.0;
+        agentParams.pathOptimizationRange = 1.0;
+        agentParams.separationWeight = 1.0;
+        agentParams.updateFlags = 7;
+        agentParams.obstacleAvoidanceType = 0;
+        agentParams.queryFilterType = 0;
+        agentParams.userData = 0;
+
+        var agentIndex = this.recastCrowd.addAgent(new this.bjsRECASTPlugin.bjsRECAST.Vec3(pos.x, pos.y, pos.z), agentParams);
+        this.transforms.push(transform);
+        this.agents.push(agentIndex);
+        return agentIndex;
+    }
+
+    getAgentPosition(index: number): Vector3 {
+        var agentPos = this.recastCrowd.getAgentPosition(index);
+        return new Vector3(agentPos.x, agentPos.y, agentPos.z);
+    }
+
+    agentGoto(index: number, destination: Vector3): void {
+        this.recastCrowd.agentGoto(index, new this.bjsRECASTPlugin.bjsRECAST.Vec3(destination.x, destination.y, destination.z));
+    }
+
+    removeAgent(index: number): void {
+        this.recastCrowd.removeAgent(index);
+    }
+
+    update(deltaTime: number): void {
+        // update crowd
+        this.recastCrowd.update(deltaTime);
+
+        // update transforms
+        var index:number;
+        for (index = 0; index < this.agents.length; index++) 
+        {
+            this.transforms[index].position = this.getAgentPosition(this.agents[index]);
+        }
+    }
+}

+ 11 - 0
src/scene.ts

@@ -47,6 +47,7 @@ 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;
@@ -164,6 +165,11 @@ export class Scene extends AbstractScene implements IAnimatable {
      */
     public ambientColor = new Color3(0, 0, 0);
 
+    public crowd: Nullable<ICrowd> = null;
+
+    addCrowd(crowd:ICrowd): void {
+        this.crowd = crowd;
+    }
     /**
      * 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):
@@ -3708,6 +3714,11 @@ export class Scene extends AbstractScene implements IAnimatable {
             this.animate();
         }
 
+        // Navigation
+        if (this.crowd) {
+            this.crowd.update(0.016);
+        }
+
         // Before camera update steps
         for (let step of this._beforeCameraUpdateStage) {
             step.action();