Преглед на файлове

Create navmesh from an array of mesh and compute a compound on the fly. faster and more reliable from meshes merge

Cedric Guillemet преди 6 години
родител
ревизия
3e0aba890a
променени са 3 файла, в които са добавени 81 реда и са изтрити 15 реда
  1. 8 8
      dist/preview release/recast.js
  2. 9 2
      src/Navigation/INavigationEngine.ts
  3. 64 5
      src/Navigation/Plugins/recastJSPlugin.ts

Файловите разлики са ограничени, защото са твърде много
+ 8 - 8
dist/preview release/recast.js


+ 9 - 2
src/Navigation/INavigationEngine.ts

@@ -1,6 +1,5 @@
 import { TransformNode } from "../Meshes/transformNode";
 import { Vector3 } from "../Maths/math";
-import { AbstractMesh } from "../Meshes/abstractMesh";
 import { Mesh } from "../Meshes/mesh";
 import { Scene } from "../scene";
 
@@ -18,7 +17,7 @@ export interface INavigationEnginePlugin {
      * @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: INavMeshParameters): void;
+    createMavMesh(meshes: Array<Mesh>, parameters: INavMeshParameters): void;
 
     /**
      * Create a navigation mesh debug mesh
@@ -43,6 +42,14 @@ export interface INavigationEnginePlugin {
     getRandomPointAround(position: Vector3, maxRadius: number): Vector3;
 
     /**
+     * Compute a navigation path from start to end. Returns an empty array if no path can be computed
+     * @param start world position
+     * @param end world position
+     * @returns array containing world position composing the path
+     */
+    computePath(start: Vector3, end: Vector3): Vector3[];
+
+    /**
      * If this plugin is supported
      * @returns true if plugin is supported
      */

+ 64 - 5
src/Navigation/Plugins/recastJSPlugin.ts

@@ -1,13 +1,13 @@
 import { INavigationEnginePlugin, ICrowd, IAgentParameters, INavMeshParameters } from "../../Navigation/INavigationEngine";
 import { Logger } from "../../Misc/logger";
 import { VertexData } from "../../Meshes/mesh.vertexData";
-import { AbstractMesh } from "../../Meshes/abstractMesh";
 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";
+import { VertexBuffer } from "../../Meshes/buffer";
 
 declare var Recast: any;
 
@@ -52,7 +52,7 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
      * @param mesh of all the geometry used to compute the navigatio mesh
      * @param parameters bunch of parameters used to filter geometry
      */
-    createMavMesh(mesh: AbstractMesh, parameters: INavMeshParameters): void {
+    createMavMesh(meshes: Array<Mesh>, parameters: INavMeshParameters): void {
         const rc = new this.bjsRECAST.rcConfig();
         rc.cs = parameters.cs;
         rc.ch = parameters.ch;
@@ -69,9 +69,46 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
         rc.detailSampleMaxError = parameters.detailSampleMaxError;
 
         this.navMesh = new this.bjsRECAST.NavMesh();
-        const meshIndices = mesh.getIndices();
-        const positions = mesh.getVerticesData('position');
-        this.navMesh.build(positions, mesh.getTotalVertices(), meshIndices, mesh.getTotalIndices(), rc);
+
+        var index: number;
+        var tri: number;
+        var pt: number;
+
+        var indices = [];
+        var positions = [];
+        var offset = 0;
+        for (index = 0; index < meshes.length; index++) {
+            if (meshes[index]) {
+                var mesh = meshes[index];
+
+                const meshIndices = mesh.getIndices();
+                if (!meshIndices) {
+                    continue;
+                }
+                const meshPositions = mesh.getVerticesData(VertexBuffer.PositionKind, false, false);
+                if (!meshPositions) {
+                    continue;
+                }
+
+                const wm = mesh.computeWorldMatrix(false);
+
+                for (tri = 0; tri < meshIndices.length; tri++) {
+                    indices.push(meshIndices[tri] + offset);
+                }
+
+                var transformed = Vector3.Zero();
+                var position = Vector3.Zero();
+                for (pt = 0; pt < meshPositions.length; pt += 3) {
+                    Vector3.FromArrayToRef(meshPositions, pt, position);
+                    Vector3.TransformCoordinatesToRef(position, wm, transformed);
+                    positions.push(transformed.x, transformed.y, transformed.z);
+                }
+                
+                offset += meshPositions.length / 3;
+            }
+        }
+
+        this.navMesh.build(positions, offset, indices, indices.length, rc);
     }
 
     /**
@@ -136,6 +173,28 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
     }
 
     /**
+     * Compute a navigation path from start to end. Returns an empty array if no path can be computed
+     * @param start world position
+     * @param end world position
+     * @returns array containing world position composing the path
+     */
+    computePath(start: Vector3, end: Vector3): Vector3[]
+    {
+        var pt: number;
+        let startPos = new this.bjsRECAST.Vec3(start.x, start.y, start.z);
+        let endPos = new this.bjsRECAST.Vec3(end.x, end.y, end.z);
+        let navPath = this.navMesh.computePath(startPos, endPos);
+        let pointCount = navPath.getPointCount();
+        var positions = [];
+        for (pt = 0; pt < pointCount; pt++)
+        {
+            let p = navPath.getPoint(pt);
+            positions.push(new Vector3(p.x, p.y, p.z));
+        }
+        return positions;
+    }
+
+    /**
      * Create a new Crowd so you can add agents
      * @param maxAgents the maximum agent count in the crowd
      * @param maxAgentRadius the maximum radius an agent can have