@woosh/meep-engine 2.147.0 → 2.149.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_bridge_islands.d.ts +23 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_bridge_islands.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_bridge_islands.js +295 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +4 -4
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +48 -52
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +23 -21
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +41 -406
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +5 -4
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +400 -395
- package/src/engine/navigation/mesh/NavigationMesh.d.ts +6 -2
- package/src/engine/navigation/mesh/NavigationMesh.d.ts.map +1 -1
- package/src/engine/navigation/mesh/NavigationMesh.js +234 -212
- package/src/engine/navigation/mesh/bt_mesh_face_find_path.d.ts +7 -3
- package/src/engine/navigation/mesh/bt_mesh_face_find_path.d.ts.map +1 -1
- package/src/engine/navigation/mesh/bt_mesh_face_find_path.js +67 -73
- package/src/engine/navigation/mesh/build/enforce_agent_height_clearance.d.ts +16 -5
- package/src/engine/navigation/mesh/build/enforce_agent_height_clearance.d.ts.map +1 -1
- package/src/engine/navigation/mesh/build/enforce_agent_height_clearance.js +262 -147
- package/src/engine/navigation/mesh/build/navmesh_build_topology.d.ts.map +1 -1
- package/src/engine/navigation/mesh/build/navmesh_build_topology.js +33 -3
- package/src/engine/navigation/mesh/bvh_query_nearest_face.d.ts +4 -1
- package/src/engine/navigation/mesh/bvh_query_nearest_face.d.ts.map +1 -1
- package/src/engine/navigation/mesh/bvh_query_nearest_face.js +164 -131
- package/src/engine/physics/body/SolverBodyState.d.ts +142 -0
- package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -0
- package/src/engine/physics/body/SolverBodyState.js +251 -0
- package/src/engine/physics/broadphase/generate_pairs.d.ts +2 -1
- package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
- package/src/engine/physics/broadphase/generate_pairs.js +110 -108
- package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
- package/src/engine/physics/constraint/solve_constraints.js +691 -673
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +21 -18
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +223 -91
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts +23 -0
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
- package/src/engine/physics/inertia/world_inverse_inertia.js +116 -77
- package/src/engine/physics/integration/integrate_position.d.ts +11 -1
- package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_position.js +97 -79
- package/src/engine/physics/integration/integrate_velocity.d.ts +12 -3
- package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_velocity.js +201 -160
- package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/box_box_manifold.js +750 -665
- package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/box_triangle_contact.js +4 -34
- package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts +16 -0
- package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/clip_against_axis_uv.js +49 -0
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/narrowphase_step.js +24 -3
- package/src/engine/physics/queries/raycast.d.ts.map +1 -1
- package/src/engine/physics/queries/raycast.js +201 -198
- package/src/engine/physics/solver/solve_contacts.d.ts +2 -2
- package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
- package/src/engine/physics/solver/solve_contacts.js +1341 -1173
|
@@ -10,13 +10,17 @@ export class NavigationMesh {
|
|
|
10
10
|
* @param {BinaryTopology} source
|
|
11
11
|
* @param {number} [agent_radius]
|
|
12
12
|
* @param {number} [agent_height]
|
|
13
|
+
* @param {number} [agent_max_step_height] agent can bridge vertical gaps in topology, such as stepping up a stair
|
|
14
|
+
* @param {number} [agent_max_step_distance] agent can bridge lateral gaps in topology, such as stepping over a hole in the floor
|
|
13
15
|
* @param {number} [agent_max_climb_angle] In radians, how steep of an angle can the agent go up by
|
|
14
16
|
* @param {Vector3} [up] Defines world's "UP" direction, this is what the agent will respect for climbing constraint
|
|
15
17
|
*/
|
|
16
|
-
build({ source, agent_radius, agent_height, agent_max_climb_angle, up, }: BinaryTopology): void;
|
|
18
|
+
build({ source, agent_radius, agent_height, agent_max_step_height, agent_max_step_distance, agent_max_climb_angle, up, }: BinaryTopology): void;
|
|
17
19
|
/**
|
|
18
20
|
* Compute a walkable path between the two points.
|
|
19
|
-
* The result is a sequence of 3d points written into `output`.
|
|
21
|
+
* The result is a sequence of 3d points written into `output`. The first and last points are the
|
|
22
|
+
* start and goal snapped onto the mesh surface (the closest walkable point to each query position),
|
|
23
|
+
* so they may differ from the raw `start_*`/`goal_*` inputs when those lie off the mesh.
|
|
20
24
|
*
|
|
21
25
|
* @param {Float32Array} output packed XYZ triples
|
|
22
26
|
* @param {number} start_x
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationMesh.d.ts","sourceRoot":"","sources":["../../../../../src/engine/navigation/mesh/NavigationMesh.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NavigationMesh.d.ts","sourceRoot":"","sources":["../../../../../src/engine/navigation/mesh/NavigationMesh.js"],"names":[],"mappings":"AAoCA;IAEI,yBAAgC;IAEhC;;;OAGG;IACH,KAFU,GAAG,CAEG;IAEhB;;;;;;;;;OASG;IACH,0HARW,cAAc,QA8BxB;IAGD;;;;;;;;;;;;;;OAcG;IACH,kBATW,YAAY,WACZ,MAAM,WACN,MAAM,WACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,GACJ,MAAM,CAyIlB;CAEJ;+BAxO4C,gEAAgE;oBADzF,gCAAgC"}
|
|
@@ -1,212 +1,234 @@
|
|
|
1
|
-
import { BVH } from "../../../core/bvh2/bvh3/BVH.js";
|
|
2
|
-
import { BinaryTopology, NULL_POINTER } from "../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
|
|
3
|
-
import { bt_faces_shared_loop } from "../../../core/geom/3d/topology/struct/binary/query/bt_faces_shared_loop.js";
|
|
4
|
-
import Vector3 from "../../../core/geom/Vector3.js";
|
|
5
|
-
import { bt_mesh_face_find_path } from "./bt_mesh_face_find_path.js";
|
|
6
|
-
import { navmesh_build_topology } from "./build/navmesh_build_topology.js";
|
|
7
|
-
import { bvh_build_from_bt_mesh } from "./bvh_build_from_bt_mesh.js";
|
|
8
|
-
import { bvh_query_nearest_face } from "./bvh_query_nearest_face.js";
|
|
9
|
-
import { funnel_string_pull } from "./funnel_string_pull.js";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Hard cap on the number of faces we traverse in a single path query.
|
|
13
|
-
* Limits scratch buffer sizes; paths longer than this are truncated by the A* search.
|
|
14
|
-
* @type {number}
|
|
15
|
-
*/
|
|
16
|
-
const MAX_FACE_PATH_LENGTH = 1024;
|
|
17
|
-
|
|
18
|
-
// face path IDs or (later) final path vertex indices
|
|
19
|
-
const scratch_array_u32 = new Uint32Array(MAX_FACE_PATH_LENGTH);
|
|
20
|
-
|
|
21
|
-
// one more portal than face-path length (start portal + one between each consecutive pair of faces + goal portal)
|
|
22
|
-
const MAX_PORTAL_COUNT = MAX_FACE_PATH_LENGTH + 1;
|
|
23
|
-
|
|
24
|
-
// [left0, right0, left1, right1, ...]
|
|
25
|
-
const scratch_portal_vertices = new Uint32Array(MAX_PORTAL_COUNT * 2);
|
|
26
|
-
|
|
27
|
-
// flat XYZ triples, one per portal
|
|
28
|
-
const scratch_portal_normals = new Float32Array(MAX_PORTAL_COUNT * 3);
|
|
29
|
-
|
|
30
|
-
// flat XYZ triples; indices 0 and 1 are start/goal, then 2 vertices per intermediate portal
|
|
31
|
-
const scratch_vertices = new Float32Array((2 + (MAX_PORTAL_COUNT - 2) * 2) * 3);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
*
|
|
49
|
-
* @param {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
*
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
scratch_portal_vertices
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
1
|
+
import { BVH } from "../../../core/bvh2/bvh3/BVH.js";
|
|
2
|
+
import { BinaryTopology, NULL_POINTER } from "../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
|
|
3
|
+
import { bt_faces_shared_loop } from "../../../core/geom/3d/topology/struct/binary/query/bt_faces_shared_loop.js";
|
|
4
|
+
import Vector3 from "../../../core/geom/Vector3.js";
|
|
5
|
+
import { bt_mesh_face_find_path } from "./bt_mesh_face_find_path.js";
|
|
6
|
+
import { navmesh_build_topology } from "./build/navmesh_build_topology.js";
|
|
7
|
+
import { bvh_build_from_bt_mesh } from "./bvh_build_from_bt_mesh.js";
|
|
8
|
+
import { bvh_query_nearest_face } from "./bvh_query_nearest_face.js";
|
|
9
|
+
import { funnel_string_pull } from "./funnel_string_pull.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Hard cap on the number of faces we traverse in a single path query.
|
|
13
|
+
* Limits scratch buffer sizes; paths longer than this are truncated by the A* search.
|
|
14
|
+
* @type {number}
|
|
15
|
+
*/
|
|
16
|
+
const MAX_FACE_PATH_LENGTH = 1024;
|
|
17
|
+
|
|
18
|
+
// face path IDs or (later) final path vertex indices
|
|
19
|
+
const scratch_array_u32 = new Uint32Array(MAX_FACE_PATH_LENGTH);
|
|
20
|
+
|
|
21
|
+
// one more portal than face-path length (start portal + one between each consecutive pair of faces + goal portal)
|
|
22
|
+
const MAX_PORTAL_COUNT = MAX_FACE_PATH_LENGTH + 1;
|
|
23
|
+
|
|
24
|
+
// [left0, right0, left1, right1, ...]
|
|
25
|
+
const scratch_portal_vertices = new Uint32Array(MAX_PORTAL_COUNT * 2);
|
|
26
|
+
|
|
27
|
+
// flat XYZ triples, one per portal
|
|
28
|
+
const scratch_portal_normals = new Float32Array(MAX_PORTAL_COUNT * 3);
|
|
29
|
+
|
|
30
|
+
// flat XYZ triples; indices 0 and 1 are start/goal, then 2 vertices per intermediate portal
|
|
31
|
+
const scratch_vertices = new Float32Array((2 + (MAX_PORTAL_COUNT - 2) * 2) * 3);
|
|
32
|
+
|
|
33
|
+
// snapped (on-mesh) start/goal positions, reused across queries
|
|
34
|
+
const scratch_start_point = new Float32Array(3);
|
|
35
|
+
const scratch_goal_point = new Float32Array(3);
|
|
36
|
+
|
|
37
|
+
export class NavigationMesh {
|
|
38
|
+
|
|
39
|
+
topology = new BinaryTopology();
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Used for raycasts and neighborhood search.
|
|
43
|
+
* @type {BVH}
|
|
44
|
+
*/
|
|
45
|
+
bvh = new BVH();
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Build from given scene geometry
|
|
49
|
+
* @param {BinaryTopology} source
|
|
50
|
+
* @param {number} [agent_radius]
|
|
51
|
+
* @param {number} [agent_height]
|
|
52
|
+
* @param {number} [agent_max_step_height] agent can bridge vertical gaps in topology, such as stepping up a stair
|
|
53
|
+
* @param {number} [agent_max_step_distance] agent can bridge lateral gaps in topology, such as stepping over a hole in the floor
|
|
54
|
+
* @param {number} [agent_max_climb_angle] In radians, how steep of an angle can the agent go up by
|
|
55
|
+
* @param {Vector3} [up] Defines world's "UP" direction, this is what the agent will respect for climbing constraint
|
|
56
|
+
*/
|
|
57
|
+
build({
|
|
58
|
+
source,
|
|
59
|
+
agent_radius = 0,
|
|
60
|
+
agent_height = 0,
|
|
61
|
+
agent_max_step_height = 0,
|
|
62
|
+
agent_max_step_distance = 0,
|
|
63
|
+
agent_max_climb_angle = Math.PI / 4,
|
|
64
|
+
up = Vector3.up,
|
|
65
|
+
}) {
|
|
66
|
+
|
|
67
|
+
navmesh_build_topology({
|
|
68
|
+
destination: this.topology,
|
|
69
|
+
source,
|
|
70
|
+
agent_radius,
|
|
71
|
+
agent_height,
|
|
72
|
+
agent_max_step_height,
|
|
73
|
+
agent_max_step_distance,
|
|
74
|
+
agent_max_climb_angle,
|
|
75
|
+
up,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
bvh_build_from_bt_mesh(this.bvh, this.topology);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Compute a walkable path between the two points.
|
|
84
|
+
* The result is a sequence of 3d points written into `output`. The first and last points are the
|
|
85
|
+
* start and goal snapped onto the mesh surface (the closest walkable point to each query position),
|
|
86
|
+
* so they may differ from the raw `start_*`/`goal_*` inputs when those lie off the mesh.
|
|
87
|
+
*
|
|
88
|
+
* @param {Float32Array} output packed XYZ triples
|
|
89
|
+
* @param {number} start_x
|
|
90
|
+
* @param {number} start_y
|
|
91
|
+
* @param {number} start_z
|
|
92
|
+
* @param {number} goal_x
|
|
93
|
+
* @param {number} goal_y
|
|
94
|
+
* @param {number} goal_z
|
|
95
|
+
* @returns {number} number of 3d points written to `output` (0 if no path was found)
|
|
96
|
+
*/
|
|
97
|
+
find_path(
|
|
98
|
+
output,
|
|
99
|
+
start_x, start_y, start_z,
|
|
100
|
+
goal_x, goal_y, goal_z
|
|
101
|
+
) {
|
|
102
|
+
|
|
103
|
+
const mesh = this.topology;
|
|
104
|
+
const bvh = this.bvh;
|
|
105
|
+
|
|
106
|
+
const start_face_id = bvh_query_nearest_face(bvh, mesh, start_x, start_y, start_z, scratch_start_point);
|
|
107
|
+
|
|
108
|
+
if (start_face_id === NULL_POINTER) {
|
|
109
|
+
// probably topology is empty
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const goal_face_id = bvh_query_nearest_face(bvh, mesh, goal_x, goal_y, goal_z, scratch_goal_point);
|
|
114
|
+
|
|
115
|
+
if (goal_face_id === NULL_POINTER) {
|
|
116
|
+
// should never happen if we got the start face
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// snap the query points onto the mesh surface; the path begins/ends on the walkable surface,
|
|
121
|
+
// not at the (possibly off-mesh) raw query coordinates
|
|
122
|
+
const snapped_start_x = scratch_start_point[0];
|
|
123
|
+
const snapped_start_y = scratch_start_point[1];
|
|
124
|
+
const snapped_start_z = scratch_start_point[2];
|
|
125
|
+
|
|
126
|
+
const snapped_goal_x = scratch_goal_point[0];
|
|
127
|
+
const snapped_goal_y = scratch_goal_point[1];
|
|
128
|
+
const snapped_goal_z = scratch_goal_point[2];
|
|
129
|
+
|
|
130
|
+
if (goal_face_id === start_face_id) {
|
|
131
|
+
// path within the same triangle
|
|
132
|
+
|
|
133
|
+
output[0] = snapped_start_x;
|
|
134
|
+
output[1] = snapped_start_y;
|
|
135
|
+
output[2] = snapped_start_z;
|
|
136
|
+
|
|
137
|
+
output[3] = snapped_goal_x;
|
|
138
|
+
output[4] = snapped_goal_y;
|
|
139
|
+
output[5] = snapped_goal_z;
|
|
140
|
+
|
|
141
|
+
return 2;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const face_path_length = bt_mesh_face_find_path(scratch_array_u32, start_face_id, goal_face_id, mesh, MAX_FACE_PATH_LENGTH);
|
|
145
|
+
|
|
146
|
+
if (face_path_length === 0) {
|
|
147
|
+
// no face path exists (disconnected topology)
|
|
148
|
+
return 0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// build portals
|
|
152
|
+
// ==================
|
|
153
|
+
|
|
154
|
+
// initialize vertex data pool, vertex index 0 = start, vertex index 1 = goal (snapped on-mesh)
|
|
155
|
+
scratch_vertices[0] = snapped_start_x;
|
|
156
|
+
scratch_vertices[1] = snapped_start_y;
|
|
157
|
+
scratch_vertices[2] = snapped_start_z;
|
|
158
|
+
|
|
159
|
+
scratch_vertices[3] = snapped_goal_x;
|
|
160
|
+
scratch_vertices[4] = snapped_goal_y;
|
|
161
|
+
scratch_vertices[5] = snapped_goal_z;
|
|
162
|
+
|
|
163
|
+
let next_vertex_index = 2;
|
|
164
|
+
|
|
165
|
+
// start portal, degenerate portal at the start point, exiting the start face
|
|
166
|
+
scratch_portal_vertices[0] = 0;
|
|
167
|
+
scratch_portal_vertices[1] = 0;
|
|
168
|
+
|
|
169
|
+
mesh.face_read_normal(scratch_portal_normals, 0, start_face_id);
|
|
170
|
+
|
|
171
|
+
let portal_index = 1;
|
|
172
|
+
|
|
173
|
+
// intermediate portals sit on the shared edge between two consecutive faces along the path;
|
|
174
|
+
// the edge is read in the winding order of the face we are exiting, giving a directed (left, right) pair
|
|
175
|
+
for (let i = 1; i < face_path_length; i++) {
|
|
176
|
+
|
|
177
|
+
const face_from = scratch_array_u32[i - 1];
|
|
178
|
+
const face_to = scratch_array_u32[i];
|
|
179
|
+
|
|
180
|
+
const loop = bt_faces_shared_loop(mesh, face_from, face_to);
|
|
181
|
+
|
|
182
|
+
const left_vertex = mesh.loop_read_vertex(loop);
|
|
183
|
+
const right_vertex = mesh.loop_read_vertex(mesh.loop_read_next(loop));
|
|
184
|
+
|
|
185
|
+
const left_index = next_vertex_index++;
|
|
186
|
+
const right_index = next_vertex_index++;
|
|
187
|
+
|
|
188
|
+
mesh.vertex_read_coordinate(scratch_vertices, left_index * 3, left_vertex);
|
|
189
|
+
mesh.vertex_read_coordinate(scratch_vertices, right_index * 3, right_vertex);
|
|
190
|
+
|
|
191
|
+
const portal_address = portal_index * 2;
|
|
192
|
+
scratch_portal_vertices[portal_address] = left_index;
|
|
193
|
+
scratch_portal_vertices[portal_address + 1] = right_index;
|
|
194
|
+
|
|
195
|
+
mesh.face_read_normal(scratch_portal_normals, portal_index * 3, face_from);
|
|
196
|
+
|
|
197
|
+
portal_index++;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// goal portal, degenerate at the goal point, uses the normal of the face containing the goal
|
|
201
|
+
const goal_portal_address = portal_index * 2;
|
|
202
|
+
|
|
203
|
+
scratch_portal_vertices[goal_portal_address] = 1;
|
|
204
|
+
scratch_portal_vertices[goal_portal_address + 1] = 1;
|
|
205
|
+
|
|
206
|
+
mesh.face_read_normal(scratch_portal_normals, portal_index * 3, goal_face_id);
|
|
207
|
+
|
|
208
|
+
portal_index++;
|
|
209
|
+
|
|
210
|
+
// execute string pulling
|
|
211
|
+
const path_vertex_count = funnel_string_pull(
|
|
212
|
+
scratch_array_u32,
|
|
213
|
+
0,
|
|
214
|
+
scratch_portal_vertices,
|
|
215
|
+
scratch_portal_normals,
|
|
216
|
+
portal_index,
|
|
217
|
+
scratch_vertices,
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
// build the final path
|
|
221
|
+
for (let i = 0; i < path_vertex_count; i++) {
|
|
222
|
+
const vertex_index = scratch_array_u32[i];
|
|
223
|
+
|
|
224
|
+
output[i * 3] = scratch_vertices[vertex_index * 3];
|
|
225
|
+
output[i * 3 + 1] = scratch_vertices[vertex_index * 3 + 1];
|
|
226
|
+
output[i * 3 + 2] = scratch_vertices[vertex_index * 3 + 2];
|
|
227
|
+
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return path_vertex_count;
|
|
231
|
+
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Find a path through topology faces.
|
|
2
|
+
* Find a shortest path through topology faces.
|
|
3
3
|
* If a path is found - the result will contain start and goal faces.
|
|
4
4
|
*
|
|
5
5
|
* NOTE: if either start or goal faces are not part of the topology - an empty path will be produced.
|
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
* @param {number} start_face_id
|
|
9
9
|
* @param {number} goal_face_id
|
|
10
10
|
* @param {BinaryTopology} topology
|
|
11
|
-
* @
|
|
11
|
+
* @param {number} [max_path_length=Infinity] cap on the number of faces written to `output`. If the
|
|
12
|
+
* shortest corridor is longer than this it does not fit the buffer and 0 is returned. Pass the
|
|
13
|
+
* capacity of `output` to guarantee no out-of-bounds writes.
|
|
14
|
+
* @returns {number} number of faces that make up the path. This will be 0 if no path is found (or the
|
|
15
|
+
* path does not fit `max_path_length`).
|
|
12
16
|
*/
|
|
13
|
-
export function bt_mesh_face_find_path(output: number[] | Uint32Array, start_face_id: number, goal_face_id: number, topology: BinaryTopology): number;
|
|
17
|
+
export function bt_mesh_face_find_path(output: number[] | Uint32Array, start_face_id: number, goal_face_id: number, topology: BinaryTopology, max_path_length?: number): number;
|
|
14
18
|
//# sourceMappingURL=bt_mesh_face_find_path.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bt_mesh_face_find_path.d.ts","sourceRoot":"","sources":["../../../../../src/engine/navigation/mesh/bt_mesh_face_find_path.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bt_mesh_face_find_path.d.ts","sourceRoot":"","sources":["../../../../../src/engine/navigation/mesh/bt_mesh_face_find_path.js"],"names":[],"mappings":"AA2GA;;;;;;;;;;;;;;;GAeG;AACH,+CAVW,MAAM,EAAE,GAAC,WAAW,iBACpB,MAAM,gBACN,MAAM,8CAEN,MAAM,GAGJ,MAAM,CAsFlB"}
|