Browse Source

obstacles and corners

Cedric Guillemet 4 years ago
parent
commit
cc7aa6ccef

+ 7 - 0
dist/preview release/recast.d.ts

@@ -39,6 +39,8 @@ export class DebugNavMesh {
 }
 export class dtNavMesh {
 }
+export class dtObstacleRef {
+}
 export class NavmeshData {
     new ();
     dataPointer: any;
@@ -77,6 +79,10 @@ export class NavMesh {
     computePath(start: Vec3, end: Vec3): NavPath;
     setDefaultQueryExtent(extent: Vec3): void;
     getDefaultQueryExtent(): Vec3;
+    addCylinderObstacle(position: Vec3, radius: number, height: number): dtObstacleRef;
+    addBoxObstacle(position: Vec3, extent: Vec3, angle: number): dtObstacleRef;
+    removeObstacle(obstacle: dtObstacleRef): void;
+    update(): void;
 }
 export class Crowd {
     new (maxAgents: number, maxAgentRadius: number, nav: dtNavMesh);
@@ -95,5 +101,6 @@ export class Crowd {
     setAgentParameters(idx: number, params: dtCrowdAgentParams): void;
     setDefaultQueryExtent(extent: Vec3): void;
     getDefaultQueryExtent(): Vec3;
+    getCorners(idx: number): NavPath;
 }
 }

File diff suppressed because it is too large
+ 9 - 8
dist/preview release/recast.js


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

@@ -35,6 +35,7 @@
 
 - Added support for thin instances in navigation mesh creation ([CedricGuillemet](https://github.com/CedricGuillemet))
 - Added recast.d.ts definition file for recast.js ([CedricGuillemet](https://github.com/CedricGuillemet))
+- Added obstacle support ([CedricGuillemet](https://github.com/CedricGuillemet))
 
 ### Materials
 

+ 49 - 0
src/Navigation/INavigationEngine.ts

@@ -157,12 +157,42 @@ export interface INavigationEnginePlugin {
     getMaximumSubStepCount(): number;
 
     /**
+     * Creates a cylinder obstacle and add it to the navigation
+     * @param position world position
+     * @param radius cylinder radius
+     * @param height cylinder height
+     * @returns the obstacle freshly created
+     */
+    addCylinderObstacle(position: Vector3, radius: number, height: number): IObstacle;
+
+    /**
+     * Creates an oriented box obstacle and add it to the navigation
+     * @param position world position
+     * @param extent box size
+     * @param angle angle in radians of the box orientation on Y axis
+     * @returns the obstacle freshly created
+     */
+    addBoxObstacle(position: Vector3, extent: Vector3, angle: number): IObstacle;
+
+    /**
+     * Removes an obstacle created by addCylinderObstacle or addBoxObstacle
+     * @param obstacle obstacle to remove from the navigation
+     */
+    removeObstacle(obstacle: IObstacle): void;
+
+    /**
      * Release all resources
      */
     dispose(): void;
 }
 
 /**
+ * Obstacle interface
+ */
+export interface IObstacle {
+}
+
+/**
  * Crowd Interface. A Crowd is a collection of moving agents constrained by a navigation mesh
  */
 export interface ICrowd {
@@ -292,6 +322,13 @@ export interface ICrowd {
     getDefaultQueryExtentToRef(result: Vector3): void;
 
     /**
+     * Get the next corner points composing the path (max 4 points)
+     * @param index agent index returned by addAgent
+     * @returns array containing world position composing the path
+     */
+    getCorners(index: number): Vector3[];
+
+    /**
      * Release all resources
      */
     dispose() : void;
@@ -412,4 +449,16 @@ export interface INavMeshParameters {
      * data. (For height detail only.) [Limit: >=0] [Units: wu]
      */
     detailSampleMaxError: number;
+
+    /**
+     * If using obstacles, the navmesh must be subdivided internaly by tiles.
+     * This member defines the tile cube side length in world units.
+     * If no obstacles are needed, leave it undefined or 0.
+     */
+    tileSize: number;
+
+    /*
+    * The size of the non-navigable border around the heightfield.
+    */
+    borderSize: number;
 }

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

@@ -1,4 +1,4 @@
-import { INavigationEnginePlugin, ICrowd, IAgentParameters, INavMeshParameters } from "../../Navigation/INavigationEngine";
+import { INavigationEnginePlugin, ICrowd, IAgentParameters, INavMeshParameters, IObstacle } from "../../Navigation/INavigationEngine";
 import { Logger } from "../../Misc/logger";
 import { VertexData } from "../../Meshes/mesh.vertexData";
 import { Mesh } from "../../Meshes/mesh";
@@ -98,8 +98,8 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
         const rc = new this.bjsRECAST.rcConfig();
         rc.cs = parameters.cs;
         rc.ch = parameters.ch;
-        rc.borderSize = 0;
-        rc.tileSize = 0;
+        rc.borderSize = parameters.borderSize ? parameters.borderSize : 0;
+        rc.tileSize = parameters.tileSize ? parameters.tileSize : 0;
         rc.walkableSlopeAngle = parameters.walkableSlopeAngle;
         rc.walkableHeight = parameters.walkableHeight;
         rc.walkableClimb = parameters.walkableClimb;
@@ -167,7 +167,6 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
                 }
             }
         }
-
         this.navMesh.build(positions, offset, indices, indices.length, rc);
     }
 
@@ -393,6 +392,39 @@ export class RecastJSPlugin implements INavigationEnginePlugin {
     }
 
     /**
+     * Creates a cylinder obstacle and add it to the navigation
+     * @param position world position
+     * @param radius cylinder radius
+     * @param height cylinder height
+     * @returns the obstacle freshly created
+     */
+    addCylinderObstacle(position: Vector3, radius: number, height: number): IObstacle
+    {
+        return this.navMesh.addCylinderObstacle(new this.bjsRECAST.Vec3(position.x, position.y, position.z), radius, height);
+    }
+
+    /**
+     * Creates an oriented box obstacle and add it to the navigation
+     * @param position world position
+     * @param extent box size
+     * @param angle angle in radians of the box orientation on Y axis
+     * @returns the obstacle freshly created
+     */
+    addBoxObstacle(position: Vector3, extent: Vector3, angle: number): IObstacle
+    {
+        return this.navMesh.addBoxObstacle(new this.bjsRECAST.Vec3(position.x, position.y, position.z), new this.bjsRECAST.Vec3(extent.x, extent.y, extent.z), angle);
+    }
+
+    /**
+     * Removes an obstacle created by addCylinderObstacle or addBoxObstacle
+     * @param obstacle obstacle to remove from the navigation
+     */
+    removeObstacle(obstacle: IObstacle): void
+    {
+        this.navMesh.removeObstacle(obstacle);
+    }
+
+    /**
      * If this plugin is supported
      * @returns true if plugin is supported
      */
@@ -634,6 +666,8 @@ export class RecastJSCrowd implements ICrowd {
      * @param deltaTime in seconds
      */
     update(deltaTime: number): void {
+        // update obstacles
+        this.bjsRECASTPlugin.navMesh.update();
         // update crowd
         var timeStep = this.bjsRECASTPlugin.getTimeStep();
         var maxStepCount = this.bjsRECASTPlugin.getMaximumSubStepCount();
@@ -693,6 +727,25 @@ export class RecastJSCrowd implements ICrowd {
     }
 
     /**
+     * Get the next corner points composing the path (max 4 points)
+     * @param index agent index returned by addAgent
+     * @returns array containing world position composing the path
+     */
+    getCorners(index: number): Vector3[]
+    {
+        var pt: number;
+        let navPath = this.recastCrowd.getPath(index);
+        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;
+    }
+
+    /**
      * Release all resources
      */
     dispose() : void