mirror of
https://github.com/redstrate/Kawari.git
synced 2025-07-13 00:57:45 +00:00
Generate more Recast data, start using Detour functions
This commit is contained in:
parent
e929f40e94
commit
5bea7f9b34
2 changed files with 126 additions and 18 deletions
|
@ -98,7 +98,7 @@ bevy = { version = "0.16", features = ["std",
|
||||||
"x11"], default-features = false, optional = true }
|
"x11"], default-features = false, optional = true }
|
||||||
|
|
||||||
# for navimesh generation
|
# for navimesh generation
|
||||||
recastnavigation-sys = { git = "https://github.com/redstrate/recastnavigation-rs-sys", features = ["recast"], optional = true }
|
recastnavigation-sys = { git = "https://github.com/redstrate/recastnavigation-rs-sys", features = ["recast", "detour"], optional = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||||
# Used for the web servers
|
# Used for the web servers
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::ptr::{null, null_mut};
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
asset::RenderAssetUsages,
|
asset::RenderAssetUsages,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
@ -13,9 +15,11 @@ use physis::{
|
||||||
resource::{Resource, SqPackResource},
|
resource::{Resource, SqPackResource},
|
||||||
};
|
};
|
||||||
use recastnavigation_sys::{
|
use recastnavigation_sys::{
|
||||||
CreateContext, rcAllocCompactHeightfield, rcAllocContourSet, rcAllocHeightfield,
|
CreateContext, dtCreateNavMeshData, dtNavMeshCreateParams, rcAllocCompactHeightfield,
|
||||||
rcAllocPolyMesh, rcAllocPolyMeshDetail, rcBuildCompactHeightfield, rcBuildContours,
|
rcAllocContourSet, rcAllocHeightfield, rcAllocPolyMesh, rcAllocPolyMeshDetail,
|
||||||
rcBuildPolyMesh, rcBuildPolyMeshDetail, rcContext, rcCreateHeightfield, rcHeightfield,
|
rcBuildCompactHeightfield, rcBuildContours, rcBuildContoursFlags_RC_CONTOUR_TESS_WALL_EDGES,
|
||||||
|
rcBuildDistanceField, rcBuildPolyMesh, rcBuildPolyMeshDetail, rcBuildRegions, rcCalcGridSize,
|
||||||
|
rcContext, rcCreateHeightfield, rcErodeWalkableArea, rcHeightfield, rcMarkWalkableTriangles,
|
||||||
rcRasterizeTriangles,
|
rcRasterizeTriangles,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,18 +96,31 @@ fn walk_node(
|
||||||
|
|
||||||
// Step 2: insert geoemtry into heightfield
|
// Step 2: insert geoemtry into heightfield
|
||||||
let tile_indices: Vec<i32> = indices.iter().map(|x| *x as i32).collect();
|
let tile_indices: Vec<i32> = indices.iter().map(|x| *x as i32).collect();
|
||||||
let tri_area_ids: Vec<u8> = vec![0; tile_indices.len() / 3];
|
let mut tri_area_ids: Vec<u8> = vec![0; tile_indices.len() / 3];
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let ntris = tile_indices.len() as i32 / 3;
|
||||||
|
|
||||||
|
// mark areas as walkable
|
||||||
|
rcMarkWalkableTriangles(
|
||||||
|
context,
|
||||||
|
45.0,
|
||||||
|
std::mem::transmute::<*const [f32; 3], *const f32>(positions.as_ptr()),
|
||||||
|
positions.len() as i32,
|
||||||
|
tile_indices.as_ptr(),
|
||||||
|
ntris,
|
||||||
|
tri_area_ids.as_mut_ptr(),
|
||||||
|
);
|
||||||
|
|
||||||
assert!(rcRasterizeTriangles(
|
assert!(rcRasterizeTriangles(
|
||||||
context,
|
context,
|
||||||
std::mem::transmute::<*const [f32; 3], *const f32>(positions.as_ptr()),
|
std::mem::transmute::<*const [f32; 3], *const f32>(positions.as_ptr()),
|
||||||
positions.len() as i32,
|
positions.len() as i32,
|
||||||
tile_indices.as_ptr(),
|
tile_indices.as_ptr(),
|
||||||
tri_area_ids.as_ptr(),
|
tri_area_ids.as_ptr(),
|
||||||
tile_indices.len() as i32 / 3,
|
ntris,
|
||||||
height_field,
|
height_field,
|
||||||
1
|
2
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,16 +167,24 @@ fn setup(
|
||||||
|
|
||||||
let context;
|
let context;
|
||||||
let height_field;
|
let height_field;
|
||||||
|
let cell_size = 0.25;
|
||||||
|
let cell_height = 0.25;
|
||||||
unsafe {
|
unsafe {
|
||||||
context = CreateContext(true);
|
context = CreateContext(true);
|
||||||
|
|
||||||
// Step 1: Create a heightfield
|
// Step 1: Create a heightfield
|
||||||
let size_x = 100;
|
let mut size_x: i32 = 0;
|
||||||
let size_z = 100;
|
let mut size_z: i32 = 0;
|
||||||
let min_bounds = [-100.0, -100.0, -100.0];
|
let min_bounds = [-100.0, -100.0, -100.0];
|
||||||
let max_bounds = [100.0, 100.0, 100.0];
|
let max_bounds = [100.0, 100.0, 100.0];
|
||||||
let cell_size = 10.0;
|
|
||||||
let cell_height = 10.0;
|
rcCalcGridSize(
|
||||||
|
min_bounds.as_ptr(),
|
||||||
|
max_bounds.as_ptr(),
|
||||||
|
cell_size,
|
||||||
|
&mut size_x,
|
||||||
|
&mut size_z,
|
||||||
|
);
|
||||||
|
|
||||||
height_field = rcAllocHeightfield();
|
height_field = rcAllocHeightfield();
|
||||||
assert!(rcCreateHeightfield(
|
assert!(rcCreateHeightfield(
|
||||||
|
@ -224,8 +249,9 @@ fn setup(
|
||||||
unsafe {
|
unsafe {
|
||||||
// Step 3: Build a compact heightfield out of the normal heightfield
|
// Step 3: Build a compact heightfield out of the normal heightfield
|
||||||
let compact_heightfield = rcAllocCompactHeightfield();
|
let compact_heightfield = rcAllocCompactHeightfield();
|
||||||
let walkable_height = 1;
|
let walkable_height = 2;
|
||||||
let walkable_climb = 1;
|
let walkable_climb = 1;
|
||||||
|
let walkable_radius = 0.5;
|
||||||
assert!(rcBuildCompactHeightfield(
|
assert!(rcBuildCompactHeightfield(
|
||||||
context,
|
context,
|
||||||
walkable_height,
|
walkable_height,
|
||||||
|
@ -233,12 +259,32 @@ fn setup(
|
||||||
height_field,
|
height_field,
|
||||||
compact_heightfield
|
compact_heightfield
|
||||||
));
|
));
|
||||||
|
assert!((*compact_heightfield).spanCount > 0);
|
||||||
|
|
||||||
|
assert!(rcErodeWalkableArea(
|
||||||
|
context,
|
||||||
|
walkable_radius as i32,
|
||||||
|
compact_heightfield
|
||||||
|
));
|
||||||
|
|
||||||
|
assert!(rcBuildDistanceField(context, compact_heightfield));
|
||||||
|
|
||||||
|
let border_size = 2;
|
||||||
|
let min_region_area = 1;
|
||||||
|
let merge_region_area = 0;
|
||||||
|
assert!(rcBuildRegions(
|
||||||
|
context,
|
||||||
|
compact_heightfield,
|
||||||
|
border_size,
|
||||||
|
min_region_area,
|
||||||
|
merge_region_area
|
||||||
|
));
|
||||||
|
|
||||||
// Step 4: Build the contour set from the compact heightfield
|
// Step 4: Build the contour set from the compact heightfield
|
||||||
let contour_set = rcAllocContourSet();
|
let contour_set = rcAllocContourSet();
|
||||||
let max_error = 1.0;
|
let max_error = 1.5;
|
||||||
let max_edge_len = 0;
|
let max_edge_len = (12.0 / cell_size) as i32;
|
||||||
let build_flags = 0;
|
let build_flags = rcBuildContoursFlags_RC_CONTOUR_TESS_WALL_EDGES as i32;
|
||||||
assert!(rcBuildContours(
|
assert!(rcBuildContours(
|
||||||
context,
|
context,
|
||||||
compact_heightfield,
|
compact_heightfield,
|
||||||
|
@ -247,16 +293,25 @@ fn setup(
|
||||||
contour_set,
|
contour_set,
|
||||||
build_flags
|
build_flags
|
||||||
));
|
));
|
||||||
|
assert!((*contour_set).nconts > 0);
|
||||||
|
|
||||||
// Step 5: Build the polymesh out of the contour set
|
// Step 5: Build the polymesh out of the contour set
|
||||||
let poly_mesh = rcAllocPolyMesh();
|
let poly_mesh = rcAllocPolyMesh();
|
||||||
let nvp = 3;
|
let nvp = 6;
|
||||||
assert!(rcBuildPolyMesh(context, contour_set, nvp, poly_mesh));
|
assert!(rcBuildPolyMesh(context, contour_set, nvp, poly_mesh));
|
||||||
|
assert!((*poly_mesh).verts != null_mut());
|
||||||
|
assert!((*poly_mesh).nverts > 0);
|
||||||
|
|
||||||
|
let flags =
|
||||||
|
std::slice::from_raw_parts_mut((*poly_mesh).flags, (*poly_mesh).npolys as usize);
|
||||||
|
for flag in flags {
|
||||||
|
*flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Step 6: Build the polymesh detail
|
// Step 6: Build the polymesh detail
|
||||||
let poly_mesh_detail = rcAllocPolyMeshDetail();
|
let poly_mesh_detail = rcAllocPolyMeshDetail();
|
||||||
let sample_dist = 0.0;
|
let sample_dist = 1.0;
|
||||||
let sample_max_error = 0.0;
|
let sample_max_error = 0.1;
|
||||||
assert!(rcBuildPolyMeshDetail(
|
assert!(rcBuildPolyMeshDetail(
|
||||||
context,
|
context,
|
||||||
poly_mesh,
|
poly_mesh,
|
||||||
|
@ -265,6 +320,59 @@ fn setup(
|
||||||
sample_max_error,
|
sample_max_error,
|
||||||
poly_mesh_detail
|
poly_mesh_detail
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let mut create_params = dtNavMeshCreateParams {
|
||||||
|
// Polygon Mesh Attributes
|
||||||
|
verts: (*poly_mesh).verts,
|
||||||
|
vertCount: (*poly_mesh).nverts,
|
||||||
|
polys: (*poly_mesh).polys,
|
||||||
|
polyFlags: (*poly_mesh).flags,
|
||||||
|
polyAreas: (*poly_mesh).areas,
|
||||||
|
polyCount: (*poly_mesh).npolys,
|
||||||
|
nvp: (*poly_mesh).nvp,
|
||||||
|
|
||||||
|
// Height Detail Attributes
|
||||||
|
detailMeshes: (*poly_mesh_detail).meshes,
|
||||||
|
detailVerts: (*poly_mesh_detail).verts,
|
||||||
|
detailVertsCount: (*poly_mesh_detail).nverts,
|
||||||
|
detailTris: (*poly_mesh_detail).tris,
|
||||||
|
detailTriCount: (*poly_mesh_detail).ntris,
|
||||||
|
|
||||||
|
// Off-Mesh Connections Attributes
|
||||||
|
offMeshConVerts: null(),
|
||||||
|
offMeshConRad: null(),
|
||||||
|
offMeshConFlags: null(),
|
||||||
|
offMeshConAreas: null(),
|
||||||
|
offMeshConDir: null(),
|
||||||
|
offMeshConUserID: null(),
|
||||||
|
offMeshConCount: 0,
|
||||||
|
|
||||||
|
// Tile Attributes
|
||||||
|
userId: 0,
|
||||||
|
tileX: 0,
|
||||||
|
tileY: 0,
|
||||||
|
tileLayer: 0,
|
||||||
|
bmin: (*poly_mesh).bmin,
|
||||||
|
bmax: (*poly_mesh).bmax,
|
||||||
|
|
||||||
|
// General Configuration Attributes
|
||||||
|
walkableHeight: walkable_height as f32,
|
||||||
|
walkableRadius: walkable_radius,
|
||||||
|
walkableClimb: walkable_climb as f32,
|
||||||
|
cs: cell_size,
|
||||||
|
ch: cell_height,
|
||||||
|
buildBvTree: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut out_data: *mut u8 = null_mut();
|
||||||
|
let mut out_data_size = 0;
|
||||||
|
assert!(dtCreateNavMeshData(
|
||||||
|
&mut create_params,
|
||||||
|
&mut out_data,
|
||||||
|
&mut out_data_size
|
||||||
|
));
|
||||||
|
assert!(out_data != null_mut());
|
||||||
|
assert!(out_data_size > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// camera
|
// camera
|
||||||
|
|
Loading…
Add table
Reference in a new issue