@woosh/meep-engine 2.163.2 → 2.163.3
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/equirectangular/equirectangular_direction_to_uv.d.ts +12 -0
- package/src/core/geom/3d/equirectangular/equirectangular_direction_to_uv.d.ts.map +1 -0
- package/src/core/geom/3d/equirectangular/equirectangular_direction_to_uv.js +18 -0
- package/src/core/geom/3d/equirectangular/equirectangular_uv_to_direction.d.ts +14 -0
- package/src/core/geom/3d/equirectangular/equirectangular_uv_to_direction.d.ts.map +1 -0
- package/src/core/geom/3d/equirectangular/equirectangular_uv_to_direction.js +24 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_island_erode.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_island_erode.js +368 -290
- package/src/core/geom/vec3/v3_uniform_sample_cone.d.ts +11 -0
- package/src/core/geom/vec3/v3_uniform_sample_cone.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_uniform_sample_cone.js +21 -0
- package/src/core/math/physics/brdf/cone_cosine_from_roughness.d.ts +13 -0
- package/src/core/math/physics/brdf/cone_cosine_from_roughness.d.ts.map +1 -0
- package/src/core/math/physics/brdf/cone_cosine_from_roughness.js +28 -0
- package/src/core/math/physics/brdf/reflection_sample_weight.d.ts +18 -0
- package/src/core/math/physics/brdf/reflection_sample_weight.d.ts.map +1 -0
- package/src/core/math/physics/brdf/reflection_sample_weight.js +48 -0
- package/src/engine/graphics/GraphicsEngine.d.ts.map +1 -1
- package/src/engine/graphics/GraphicsEngine.js +52 -0
- package/src/engine/graphics/sh3/sky/hosek/make_environment_sky_hosek.d.ts +26 -0
- package/src/engine/graphics/sh3/sky/hosek/make_environment_sky_hosek.d.ts.map +1 -0
- package/src/engine/graphics/sh3/sky/hosek/make_environment_sky_hosek.js +49 -0
- package/src/engine/graphics/sh3/sky/hosek/render_hosek_sky_to_equirectangular.d.ts +26 -0
- package/src/engine/graphics/sh3/sky/hosek/render_hosek_sky_to_equirectangular.d.ts.map +1 -0
- package/src/engine/graphics/sh3/sky/hosek/render_hosek_sky_to_equirectangular.js +70 -0
- package/src/engine/graphics/sh3/sky/hosek/setup_environment_sky_from_ecd.d.ts +24 -0
- package/src/engine/graphics/sh3/sky/hosek/setup_environment_sky_from_ecd.d.ts.map +1 -0
- package/src/engine/graphics/sh3/sky/hosek/setup_environment_sky_from_ecd.js +51 -0
- package/src/engine/graphics/texture/EnvironmentTextureProjection.d.ts +9 -0
- package/src/engine/graphics/texture/EnvironmentTextureProjection.d.ts.map +1 -0
- package/src/engine/graphics/texture/EnvironmentTextureProjection.js +15 -0
- package/src/engine/graphics/texture/reflection/convolve_equirectangular_reflection.d.ts +44 -0
- package/src/engine/graphics/texture/reflection/convolve_equirectangular_reflection.d.ts.map +1 -0
- package/src/engine/graphics/texture/reflection/convolve_equirectangular_reflection.js +189 -0
- package/src/engine/graphics/texture/reflection/equirectangular_reflection_roughness.d.ts +25 -0
- package/src/engine/graphics/texture/reflection/equirectangular_reflection_roughness.d.ts.map +1 -0
- package/src/engine/graphics/texture/reflection/equirectangular_reflection_roughness.js +51 -0
- package/src/engine/graphics/texture/sampler/sampler2d_sample_equirectangular_direction.d.ts +15 -0
- package/src/engine/graphics/texture/sampler/sampler2d_sample_equirectangular_direction.d.ts.map +1 -0
- package/src/engine/graphics/texture/sampler/sampler2d_sample_equirectangular_direction.js +63 -0
- package/src/engine/navigation/mesh/build/bt_mesh_carve_height_clearance.d.ts +27 -0
- package/src/engine/navigation/mesh/build/bt_mesh_carve_height_clearance.d.ts.map +1 -0
- package/src/engine/navigation/mesh/build/bt_mesh_carve_height_clearance.js +323 -0
- package/src/engine/navigation/mesh/build/navmesh_build_topology.d.ts.map +1 -1
- package/src/engine/navigation/mesh/build/navmesh_build_topology.js +223 -226
- package/src/engine/.fuse_hidden0000001500000001 +0 -581
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { NULL_NODE } from "../../../../core/bvh2/bvh3/BVH.js";
|
|
2
|
+
import {
|
|
3
|
+
bvh_query_leaves_ray_segment
|
|
4
|
+
} from "../../../../core/bvh2/bvh3/query/bvh_query_leaves_ray_segment.js";
|
|
5
|
+
import {
|
|
6
|
+
bvh_query_user_data_overlaps_aabb
|
|
7
|
+
} from "../../../../core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.js";
|
|
8
|
+
import { NULL_POINTER } from "../../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
|
|
9
|
+
import {
|
|
10
|
+
bt_mesh_cleanup_faceless_references
|
|
11
|
+
} from "../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_cleanup_faceless_references.js";
|
|
12
|
+
import { bt_edge_split } from "../../../../core/geom/3d/topology/struct/binary/io/edge/bt_edge_split.js";
|
|
13
|
+
import { bt_face_kill } from "../../../../core/geom/3d/topology/struct/binary/io/face/bt_face_kill.js";
|
|
14
|
+
import {
|
|
15
|
+
computeTriangleRayIntersectionBarycentric
|
|
16
|
+
} from "../../../../core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Lift a ray origin off the surface so the upward clearance ray does not immediately re-hit the floor.
|
|
20
|
+
* @type {number}
|
|
21
|
+
*/
|
|
22
|
+
const SURFACE_EPSILON = 1e-4;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Horizontal inset applied to a face footprint before testing for overhead geometry. Prevents a
|
|
26
|
+
* neighbour that merely *touches* a face along a shared edge (e.g. an adjacent platform at a slightly
|
|
27
|
+
* different height) from being mistaken for an overhang. A real overhang overlaps the interior with
|
|
28
|
+
* positive area and still registers.
|
|
29
|
+
* @type {number}
|
|
30
|
+
*/
|
|
31
|
+
const FOOTPRINT_INSET = 1e-2;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Safety cap on the number of faces the refinement is allowed to grow to, so a pathological input
|
|
35
|
+
* cannot loop forever.
|
|
36
|
+
* @type {number}
|
|
37
|
+
*/
|
|
38
|
+
const MAX_FACES = 200000;
|
|
39
|
+
|
|
40
|
+
// reused scratch
|
|
41
|
+
const ray_leaf_buffer = [];
|
|
42
|
+
const intersection_result = new Float32Array(6);
|
|
43
|
+
const tri_a = new Float32Array(3);
|
|
44
|
+
const tri_b = new Float32Array(3);
|
|
45
|
+
const tri_c = new Float32Array(3);
|
|
46
|
+
|
|
47
|
+
const va = new Float32Array(3);
|
|
48
|
+
const vb = new Float32Array(3);
|
|
49
|
+
const vc = new Float32Array(3);
|
|
50
|
+
|
|
51
|
+
const overhead_hits = [];
|
|
52
|
+
const query_aabb = new Float32Array(6);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* True if there is no source geometry within `agent_height` directly above the point along `up`.
|
|
56
|
+
* (Mirrors the clearance ray-cast used by the old soup-based pass.)
|
|
57
|
+
*/
|
|
58
|
+
function point_has_clearance(source_bvh, source, px, py, pz, up_x, up_y, up_z, agent_height) {
|
|
59
|
+
const origin_x = px + up_x * SURFACE_EPSILON;
|
|
60
|
+
const origin_y = py + up_y * SURFACE_EPSILON;
|
|
61
|
+
const origin_z = pz + up_z * SURFACE_EPSILON;
|
|
62
|
+
|
|
63
|
+
const leaf_count = bvh_query_leaves_ray_segment(
|
|
64
|
+
source_bvh, source_bvh.root,
|
|
65
|
+
ray_leaf_buffer, 0,
|
|
66
|
+
origin_x, origin_y, origin_z,
|
|
67
|
+
up_x, up_y, up_z,
|
|
68
|
+
0, agent_height
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
for (let i = 0; i < leaf_count; i++) {
|
|
72
|
+
const node = ray_leaf_buffer[i];
|
|
73
|
+
const face_id = source_bvh.node_get_user_data(node);
|
|
74
|
+
|
|
75
|
+
const loop_a = source.face_read_loop(face_id);
|
|
76
|
+
if (loop_a === NULL_POINTER) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const loop_b = source.loop_read_next(loop_a);
|
|
80
|
+
const loop_c = source.loop_read_next(loop_b);
|
|
81
|
+
|
|
82
|
+
source.vertex_read_coordinate(tri_a, 0, source.loop_read_vertex(loop_a));
|
|
83
|
+
source.vertex_read_coordinate(tri_b, 0, source.loop_read_vertex(loop_b));
|
|
84
|
+
source.vertex_read_coordinate(tri_c, 0, source.loop_read_vertex(loop_c));
|
|
85
|
+
|
|
86
|
+
const hit = computeTriangleRayIntersectionBarycentric(
|
|
87
|
+
intersection_result,
|
|
88
|
+
origin_x, origin_y, origin_z,
|
|
89
|
+
up_x, up_y, up_z,
|
|
90
|
+
tri_a[0], tri_a[1], tri_a[2],
|
|
91
|
+
tri_b[0], tri_b[1], tri_b[2],
|
|
92
|
+
tri_c[0], tri_c[1], tri_c[2]
|
|
93
|
+
);
|
|
94
|
+
if (!hit) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const t = intersection_result[0];
|
|
99
|
+
if (t > 0 && t <= agent_height) {
|
|
100
|
+
// overhead obstruction within the agent's height
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Read the three vertices of a triangular face into va/vb/vc and return its loops.
|
|
110
|
+
*/
|
|
111
|
+
function read_face_triangle(mesh, face_id) {
|
|
112
|
+
const la = mesh.face_read_loop(face_id);
|
|
113
|
+
const lb = mesh.loop_read_next(la);
|
|
114
|
+
const lc = mesh.loop_read_next(lb);
|
|
115
|
+
|
|
116
|
+
mesh.vertex_read_coordinate(va, 0, mesh.loop_read_vertex(la));
|
|
117
|
+
mesh.vertex_read_coordinate(vb, 0, mesh.loop_read_vertex(lb));
|
|
118
|
+
mesh.vertex_read_coordinate(vc, 0, mesh.loop_read_vertex(lc));
|
|
119
|
+
|
|
120
|
+
return { la, lb, lc };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Does the upward column (height `agent_height` along `up`) over this face's footprint contain any
|
|
125
|
+
* source geometry that sits *above* the face? Uses a loose axis-aligned box (conservative), inset
|
|
126
|
+
* horizontally so edge-touching neighbours do not count. May report true for a face whose triangle
|
|
127
|
+
* does not actually pass under the overhang, which only costs a little extra refinement, never a
|
|
128
|
+
* wrong cull.
|
|
129
|
+
*/
|
|
130
|
+
function column_has_overhead(source_bvh, source, face_max_along_up, up_x, up_y, up_z, agent_height) {
|
|
131
|
+
let min_x = Math.min(va[0], vb[0], vc[0]);
|
|
132
|
+
let min_y = Math.min(va[1], vb[1], vc[1]);
|
|
133
|
+
let min_z = Math.min(va[2], vb[2], vc[2]);
|
|
134
|
+
let max_x = Math.max(va[0], vb[0], vc[0]);
|
|
135
|
+
let max_y = Math.max(va[1], vb[1], vc[1]);
|
|
136
|
+
let max_z = Math.max(va[2], vb[2], vc[2]);
|
|
137
|
+
|
|
138
|
+
// inset the footprint on the axes perpendicular to up (so touching-only neighbours are excluded)
|
|
139
|
+
const ex = FOOTPRINT_INSET * (1 - Math.abs(up_x));
|
|
140
|
+
const ey = FOOTPRINT_INSET * (1 - Math.abs(up_y));
|
|
141
|
+
const ez = FOOTPRINT_INSET * (1 - Math.abs(up_z));
|
|
142
|
+
min_x += ex; max_x -= ex;
|
|
143
|
+
min_y += ey; max_y -= ey;
|
|
144
|
+
min_z += ez; max_z -= ez;
|
|
145
|
+
if (min_x > max_x) { const m = (min_x + max_x) * 0.5; min_x = m; max_x = m; }
|
|
146
|
+
if (min_y > max_y) { const m = (min_y + max_y) * 0.5; min_y = m; max_y = m; }
|
|
147
|
+
if (min_z > max_z) { const m = (min_z + max_z) * 0.5; min_z = m; max_z = m; }
|
|
148
|
+
|
|
149
|
+
// sweep the box by agent_height along the up direction
|
|
150
|
+
const dx = up_x * agent_height, dy = up_y * agent_height, dz = up_z * agent_height;
|
|
151
|
+
if (dx > 0) max_x += dx; else min_x += dx;
|
|
152
|
+
if (dy > 0) max_y += dy; else min_y += dy;
|
|
153
|
+
if (dz > 0) max_z += dz; else min_z += dz;
|
|
154
|
+
|
|
155
|
+
query_aabb[0] = min_x; query_aabb[1] = min_y; query_aabb[2] = min_z;
|
|
156
|
+
query_aabb[3] = max_x; query_aabb[4] = max_y; query_aabb[5] = max_z;
|
|
157
|
+
|
|
158
|
+
const count = bvh_query_user_data_overlaps_aabb(overhead_hits, 0, source_bvh, query_aabb);
|
|
159
|
+
|
|
160
|
+
for (let i = 0; i < count; i++) {
|
|
161
|
+
const fid = overhead_hits[i];
|
|
162
|
+
|
|
163
|
+
const la = source.face_read_loop(fid);
|
|
164
|
+
if (la === NULL_POINTER) continue;
|
|
165
|
+
const lb = source.loop_read_next(la);
|
|
166
|
+
const lc = source.loop_read_next(lb);
|
|
167
|
+
|
|
168
|
+
source.vertex_read_coordinate(tri_a, 0, source.loop_read_vertex(la));
|
|
169
|
+
source.vertex_read_coordinate(tri_b, 0, source.loop_read_vertex(lb));
|
|
170
|
+
source.vertex_read_coordinate(tri_c, 0, source.loop_read_vertex(lc));
|
|
171
|
+
|
|
172
|
+
// lowest extent of the candidate along up
|
|
173
|
+
const cand_min_along_up = Math.min(
|
|
174
|
+
tri_a[0] * up_x + tri_a[1] * up_y + tri_a[2] * up_z,
|
|
175
|
+
tri_b[0] * up_x + tri_b[1] * up_y + tri_b[2] * up_z,
|
|
176
|
+
tri_c[0] * up_x + tri_c[1] * up_y + tri_c[2] * up_z
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// strictly above the face (the face's own/coplanar floor reads <= face_max_along_up)
|
|
180
|
+
if (cand_min_along_up > face_max_along_up + 1e-3) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Carve holes into a (welded, connected) walkable topology wherever an agent of the given height
|
|
190
|
+
* would not fit under overhead geometry.
|
|
191
|
+
*
|
|
192
|
+
* Operates on the topology rather than a triangle soup so that all subdivision is conformal:
|
|
193
|
+
* {@link bt_edge_split} re-triangulates every face around a split edge, so neighbouring faces can
|
|
194
|
+
* never disagree on a shared edge (no cracks / T-junctions). Refinement is adaptive - only faces whose
|
|
195
|
+
* column actually contains an overhang are subdivided, and only down to `resolution` - so clear areas
|
|
196
|
+
* stay coarse and the subdivision hugs the obstacle contour instead of tessellating whole triangles.
|
|
197
|
+
*
|
|
198
|
+
* @param {object} params
|
|
199
|
+
* @param {BinaryTopology} params.mesh walkable topology to carve (modified in place)
|
|
200
|
+
* @param {BinaryTopology} params.source original source mesh (walkable + overhead geometry)
|
|
201
|
+
* @param {BVH} params.source_bvh BVH over `source` (leaves carry source face IDs)
|
|
202
|
+
* @param {number} params.agent_height
|
|
203
|
+
* @param {number} params.agent_radius
|
|
204
|
+
* @param {Vector3} params.up world up direction
|
|
205
|
+
*/
|
|
206
|
+
export function bt_mesh_carve_height_clearance({
|
|
207
|
+
mesh,
|
|
208
|
+
source,
|
|
209
|
+
source_bvh,
|
|
210
|
+
agent_height,
|
|
211
|
+
agent_radius,
|
|
212
|
+
up,
|
|
213
|
+
}) {
|
|
214
|
+
|
|
215
|
+
if (agent_height <= 0 || source_bvh.root === NULL_NODE) {
|
|
216
|
+
// nothing overhead can obstruct anything
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// normalize up
|
|
221
|
+
let up_x = up.x, up_y = up.y, up_z = up.z;
|
|
222
|
+
const up_len = Math.sqrt(up_x * up_x + up_y * up_y + up_z * up_z);
|
|
223
|
+
if (up_len === 0) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
up_x /= up_len; up_y /= up_len; up_z /= up_len;
|
|
227
|
+
|
|
228
|
+
// Contour resolution: how finely the obstacle outline is resolved. Tied to the agent footprint;
|
|
229
|
+
// floored so a tiny radius cannot trigger runaway refinement.
|
|
230
|
+
const resolution = Math.max(agent_radius > 0 ? agent_radius : agent_height / 4, 0.25);
|
|
231
|
+
const res_sq = resolution * resolution;
|
|
232
|
+
|
|
233
|
+
// ---- Phase 1: adaptive, conformal refinement around overhangs ----
|
|
234
|
+
// Repeated fixed-point passes: split the longest edge of any face that (a) is still larger than
|
|
235
|
+
// the contour resolution and (b) has overhead geometry in its column. Splitting is conformal, so
|
|
236
|
+
// the mesh stays crack-free throughout.
|
|
237
|
+
let changed = true;
|
|
238
|
+
let guard = 0;
|
|
239
|
+
|
|
240
|
+
while (changed && guard < 64) {
|
|
241
|
+
changed = false;
|
|
242
|
+
guard++;
|
|
243
|
+
|
|
244
|
+
const face_count = mesh.faces.size;
|
|
245
|
+
|
|
246
|
+
for (let f = 0; f < face_count; f++) {
|
|
247
|
+
if (!mesh.faces.is_allocated(f)) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
read_face_triangle(mesh, f);
|
|
252
|
+
|
|
253
|
+
// longest edge (by squared length); read_face_triangle puts va/vb/vc in loop order
|
|
254
|
+
// la=(a,b), lb=(b,c), lc=(c,a)
|
|
255
|
+
const ab = (va[0] - vb[0]) ** 2 + (va[1] - vb[1]) ** 2 + (va[2] - vb[2]) ** 2;
|
|
256
|
+
const bc = (vb[0] - vc[0]) ** 2 + (vb[1] - vc[1]) ** 2 + (vb[2] - vc[2]) ** 2;
|
|
257
|
+
const ca = (vc[0] - va[0]) ** 2 + (vc[1] - va[1]) ** 2 + (vc[2] - va[2]) ** 2;
|
|
258
|
+
|
|
259
|
+
const longest_sq = Math.max(ab, bc, ca);
|
|
260
|
+
|
|
261
|
+
if (longest_sq <= res_sq) {
|
|
262
|
+
// small enough to resolve the contour
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const face_max_along_up = Math.max(
|
|
267
|
+
va[0] * up_x + va[1] * up_y + va[2] * up_z,
|
|
268
|
+
vb[0] * up_x + vb[1] * up_y + vb[2] * up_z,
|
|
269
|
+
vc[0] * up_x + vc[1] * up_y + vc[2] * up_z
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
if (!column_has_overhead(source_bvh, source, face_max_along_up, up_x, up_y, up_z, agent_height)) {
|
|
273
|
+
// fully clear column - keep this face coarse
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const { la, lb, lc } = read_face_triangle(mesh, f);
|
|
278
|
+
let split_loop;
|
|
279
|
+
if (longest_sq === ab) {
|
|
280
|
+
split_loop = la;
|
|
281
|
+
} else if (longest_sq === bc) {
|
|
282
|
+
split_loop = lb;
|
|
283
|
+
} else {
|
|
284
|
+
split_loop = lc;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
bt_edge_split(mesh, mesh.loop_read_edge(split_loop), 0.5);
|
|
288
|
+
changed = true;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (mesh.faces.size > MAX_FACES) {
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ---- Phase 2: cull blocked faces (whole-face, conformal) ----
|
|
297
|
+
const faces_to_kill = [];
|
|
298
|
+
const face_count = mesh.faces.size;
|
|
299
|
+
|
|
300
|
+
for (let f = 0; f < face_count; f++) {
|
|
301
|
+
if (!mesh.faces.is_allocated(f)) {
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
read_face_triangle(mesh, f);
|
|
306
|
+
|
|
307
|
+
const cx = (va[0] + vb[0] + vc[0]) / 3;
|
|
308
|
+
const cy = (va[1] + vb[1] + vc[1]) / 3;
|
|
309
|
+
const cz = (va[2] + vb[2] + vc[2]) / 3;
|
|
310
|
+
|
|
311
|
+
if (!point_has_clearance(source_bvh, source, cx, cy, cz, up_x, up_y, up_z, agent_height)) {
|
|
312
|
+
faces_to_kill.push(f);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
for (let i = 0; i < faces_to_kill.length; i++) {
|
|
317
|
+
bt_face_kill(mesh, faces_to_kill[i]);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (faces_to_kill.length > 0) {
|
|
321
|
+
bt_mesh_cleanup_faceless_references(mesh);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navmesh_build_topology.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/navigation/mesh/build/navmesh_build_topology.js"],"names":[],"mappings":"AA2CA;;;;;;;;;;GAUG;AACH,wKATW,cAAc,
|
|
1
|
+
{"version":3,"file":"navmesh_build_topology.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/navigation/mesh/build/navmesh_build_topology.js"],"names":[],"mappings":"AA2CA;;;;;;;;;;GAUG;AACH,wKATW,cAAc,QAiLxB;+BA5N8B,mEAAmE"}
|