1use cxx::{type_id, ExternType, UniquePtr};
2use static_assertions::const_assert_eq;
3use std::fmt::{self, Debug, Formatter};
4use std::mem;
5use std::ops::{Deref, DerefMut};
6use std::pin::Pin;
7use std::slice;
8
9use crate::base::XError;
10
11pub const RC_SPAN_HEIGHT_BITS: u32 = 13;
12pub const RC_SPAN_MAX_HEIGHT: u32 = (1 << RC_SPAN_HEIGHT_BITS) - 1;
13pub const RC_SPANS_PER_POOL: usize = 2048;
14
15pub const RC_BORDER_REG: u16 = 0x8000;
16pub const RC_MULTIPLE_REGS: u16 = 0;
17pub const RC_BORDER_VERTEX: i32 = 0x10000;
18pub const RC_AREA_BORDER: i32 = 0x20000;
19pub const RC_CONTOUR_REG_MASK: i32 = 0xffff;
20pub const RC_MESH_NULL_IDX: u16 = 0xffff;
21pub const RC_NULL_AREA: u8 = 0;
22pub const RC_WALKABLE_AREA: u8 = 63;
23pub const RC_NOT_CONNECTED: i32 = 0x3f;
24
25#[allow(dead_code)]
26#[cxx::bridge]
27pub(crate) mod ffi {
28 #[repr(u32)]
30 enum rcLogCategory {
31 RC_LOG_PROGRESS = 1,
32 RC_LOG_WARNING,
33 RC_LOG_ERROR,
34 }
35
36 #[repr(u32)]
38 enum rcTimerLabel {
39 RC_TIMER_TOTAL,
40 RC_TIMER_TEMP,
41 RC_TIMER_RASTERIZE_TRIANGLES,
42 RC_TIMER_BUILD_COMPACTHEIGHTFIELD,
43 RC_TIMER_BUILD_CONTOURS,
44 RC_TIMER_BUILD_CONTOURS_TRACE,
45 RC_TIMER_BUILD_CONTOURS_SIMPLIFY,
46 RC_TIMER_FILTER_BORDER,
47 RC_TIMER_FILTER_WALKABLE,
48 RC_TIMER_MEDIAN_AREA,
49 RC_TIMER_FILTER_LOW_OBSTACLES,
50 RC_TIMER_BUILD_POLYMESH,
51 RC_TIMER_MERGE_POLYMESH,
52 RC_TIMER_ERODE_AREA,
53 RC_TIMER_MARK_BOX_AREA,
54 RC_TIMER_MARK_CYLINDER_AREA,
55 RC_TIMER_MARK_CONVEXPOLY_AREA,
56 RC_TIMER_BUILD_DISTANCEFIELD,
57 RC_TIMER_BUILD_DISTANCEFIELD_DIST,
58 RC_TIMER_BUILD_DISTANCEFIELD_BLUR,
59 RC_TIMER_BUILD_REGIONS,
60 RC_TIMER_BUILD_REGIONS_WATERSHED,
61 RC_TIMER_BUILD_REGIONS_EXPAND,
62 RC_TIMER_BUILD_REGIONS_FLOOD,
63 RC_TIMER_BUILD_REGIONS_FILTER,
64 RC_TIMER_BUILD_LAYERS,
65 RC_TIMER_BUILD_POLYMESHDETAIL,
66 RC_TIMER_MERGE_POLYMESHDETAIL,
67 RC_MAX_TIMERS,
68 }
69
70 #[repr(i32)]
71 enum rcBuildContoursFlags {
72 RC_CONTOUR_TESS_WALL_EDGES = 0x01,
73 RC_CONTOUR_TESS_AREA_EDGES = 0x02,
74 }
75
76 unsafe extern "C++" {
77 include!("recastnavigation-rs/src/recast/recast-ffi.h");
78
79 type rcLogCategory;
84 type rcTimerLabel;
85 type rcBuildContoursFlags;
86
87 type rcContext;
92 fn rcNewContext(state: bool) -> UniquePtr<rcContext>;
93 fn enableLog(self: Pin<&mut rcContext>, state: bool);
94 fn resetLog(self: Pin<&mut rcContext>);
95 fn enableTimer(self: Pin<&mut rcContext>, state: bool);
97 fn resetTimers(self: Pin<&mut rcContext>);
98 fn startTimer(self: Pin<&mut rcContext>, label: rcTimerLabel);
99 fn stopTimer(self: Pin<&mut rcContext>, label: rcTimerLabel);
100 fn getAccumulatedTime(self: &rcContext, label: rcTimerLabel) -> i32;
101
102 type rcConfig = crate::recast::recast::RcConfig;
103
104 type rcSpan = crate::recast::recast::RcSpan;
105 type rcSpanPool = crate::recast::recast::RcSpanPool;
106
107 type rcHeightfield = crate::recast::recast::CxxRcHeightfield;
108 unsafe fn rcAllocHeightfield() -> *mut rcHeightfield;
109 unsafe fn rcFreeHeightField(heightfield: *mut rcHeightfield);
110
111 type rcCompactCell = crate::recast::recast::RcCompactCell;
112 type rcCompactSpan = crate::recast::recast::RcCompactSpan;
113
114 type rcCompactHeightfield = crate::recast::recast::CxxRcCompactHeightfield;
115 unsafe fn rcAllocCompactHeightfield() -> *mut rcCompactHeightfield;
116 unsafe fn rcFreeCompactHeightfield(compactHeightfield: *mut rcCompactHeightfield);
117
118 type rcHeightfieldLayer = crate::recast::recast::RcHeightfieldLayer;
119
120 type rcHeightfieldLayerSet = crate::recast::recast::CxxRcHeightfieldLayerSet;
121 unsafe fn rcAllocHeightfieldLayerSet() -> *mut rcHeightfieldLayerSet;
122 unsafe fn rcFreeHeightfieldLayerSet(layerSet: *mut rcHeightfieldLayerSet);
123
124 type rcContour = crate::recast::recast::RcContour;
125 type rcContourSet = crate::recast::recast::CxxRcContourSet;
126 unsafe fn rcAllocContourSet() -> *mut rcContourSet;
127 unsafe fn rcFreeContourSet(contourSet: *mut rcContourSet);
128
129 type rcPolyMesh = crate::recast::recast::CxxRcPolyMesh;
130 unsafe fn rcAllocPolyMesh() -> *mut rcPolyMesh;
131 unsafe fn rcFreePolyMesh(polyMesh: *mut rcPolyMesh);
132
133 type rcPolyMeshDetail = crate::recast::recast::CxxRcPolyMeshDetail;
134 unsafe fn rcAllocPolyMeshDetail() -> *mut rcPolyMeshDetail;
135 unsafe fn rcFreePolyMeshDetail(detailMesh: *mut rcPolyMeshDetail);
136
137 unsafe fn rcCalcBounds(verts: *const f32, numVerts: i32, minBounds: *mut f32, maxBounds: *mut f32);
142 unsafe fn rcCalcGridSize(
143 minBounds: *const f32,
144 maxBounds: *const f32,
145 cellSize: f32,
146 sizeX: *mut i32,
147 sizeZ: *mut i32,
148 );
149 unsafe fn rcCreateHeightfield(
150 context: *mut rcContext,
151 heightfield: Pin<&mut rcHeightfield>,
152 sizeX: i32,
153 sizeZ: i32,
154 minBounds: *const f32,
155 maxBounds: *const f32,
156 cellSize: f32,
157 cellHeight: f32,
158 ) -> bool;
159 unsafe fn rcMarkWalkableTriangles(
160 context: *mut rcContext,
161 walkableSlopeAngle: f32,
162 verts: *const f32,
163 numVerts: i32,
164 tris: *const i32,
165 numTris: i32,
166 triAreaIDs: *mut u8,
167 );
168 unsafe fn rcClearUnwalkableTriangles(
169 context: *mut rcContext,
170 walkableSlopeAngle: f32,
171 verts: *const f32,
172 numVerts: i32,
173 tris: *const i32,
174 numTris: i32,
175 triAreaIDs: *mut u8,
176 );
177 unsafe fn rcAddSpan(
178 context: *mut rcContext,
179 heightfield: Pin<&mut rcHeightfield>,
180 x: i32,
181 z: i32,
182 spanMin: u16,
183 spanMax: u16,
184 areaID: u8,
185 flagMergeThreshold: i32,
186 ) -> bool;
187 unsafe fn rcRasterizeTriangle(
188 context: *mut rcContext,
189 v0: *const f32,
190 v1: *const f32,
191 v2: *const f32,
192 areaID: u8,
193 heightfield: Pin<&mut rcHeightfield>,
194 flagMergeThreshold: i32,
195 ) -> bool;
196 #[rust_name = "rcRasterizeTriangles1"]
197 unsafe fn rcRasterizeTriangles(
198 context: *mut rcContext,
199 verts: *const f32,
200 numVerts: i32,
201 tris: *const i32,
202 triAreaIDs: *const u8,
203 numTris: i32,
204 heightfield: Pin<&mut rcHeightfield>,
205 flagMergeThreshold: i32,
206 ) -> bool;
207 #[rust_name = "rcRasterizeTriangles2"]
208 unsafe fn rcRasterizeTriangles(
209 context: *mut rcContext,
210 verts: *const f32,
211 numVerts: i32,
212 tris: *const u16,
213 triAreaIDs: *const u8,
214 numTris: i32,
215 heightfield: Pin<&mut rcHeightfield>,
216 flagMergeThreshold: i32,
217 ) -> bool;
218 #[rust_name = "rcRasterizeTriangles3"]
219 unsafe fn rcRasterizeTriangles(
220 context: *mut rcContext,
221 verts: *const f32,
222 triAreaIDs: *const u8,
223 numTris: i32,
224 heightfield: Pin<&mut rcHeightfield>,
225 flagMergeThreshold: i32,
226 ) -> bool;
227 unsafe fn rcFilterLowHangingWalkableObstacles(
228 context: *mut rcContext,
229 walkableClimb: i32,
230 heightfield: Pin<&mut rcHeightfield>,
231 );
232 unsafe fn rcFilterLedgeSpans(
233 context: *mut rcContext,
234 walkableHeight: i32,
235 walkableClimb: i32,
236 heightfield: Pin<&mut rcHeightfield>,
237 );
238 unsafe fn rcFilterWalkableLowHeightSpans(
239 context: *mut rcContext,
240 walkableHeight: i32,
241 heightfield: Pin<&mut rcHeightfield>,
242 );
243 unsafe fn rcGetHeightFieldSpanCount(context: *mut rcContext, heightfield: &rcHeightfield) -> i32;
244 unsafe fn rcBuildCompactHeightfield(
245 context: *mut rcContext,
246 walkableHeight: i32,
247 walkableClimb: i32,
248 heightfield: &rcHeightfield,
249 compactHeightfield: Pin<&mut rcCompactHeightfield>,
250 ) -> bool;
251 unsafe fn rcErodeWalkableArea(
252 context: *mut rcContext,
253 erosionRadius: i32,
254 compactHeightfield: Pin<&mut rcCompactHeightfield>,
255 ) -> bool;
256 unsafe fn rcMedianFilterWalkableArea(
257 context: *mut rcContext,
258 compactHeightfield: Pin<&mut rcCompactHeightfield>,
259 ) -> bool;
260 unsafe fn rcMarkBoxArea(
261 context: *mut rcContext,
262 boxMinBounds: *const f32,
263 boxMaxBounds: *const f32,
264 areaId: u8,
265 compactHeightfield: Pin<&mut rcCompactHeightfield>,
266 );
267 unsafe fn rcMarkConvexPolyArea(
268 context: *mut rcContext,
269 verts: *const f32,
270 numVerts: i32,
271 minY: f32,
272 maxY: f32,
273 areaId: u8,
274 compactHeightfield: Pin<&mut rcCompactHeightfield>,
275 );
276 unsafe fn rcOffsetPoly(
277 verts: *const f32,
278 numVerts: i32,
279 offset: f32,
280 outVerts: *mut f32,
281 maxOutVerts: i32,
282 ) -> i32;
283 unsafe fn rcMarkCylinderArea(
284 context: *mut rcContext,
285 position: *const f32,
286 radius: f32,
287 height: f32,
288 areaId: u8,
289 compactHeightfield: Pin<&mut rcCompactHeightfield>,
290 );
291 unsafe fn rcBuildDistanceField(ctx: *mut rcContext, chf: Pin<&mut rcCompactHeightfield>) -> bool;
292 unsafe fn rcBuildRegions(
293 ctx: *mut rcContext,
294 chf: Pin<&mut rcCompactHeightfield>,
295 borderSize: i32,
296 minRegionArea: i32,
297 mergeRegionArea: i32,
298 ) -> bool;
299 unsafe fn rcBuildLayerRegions(
300 ctx: *mut rcContext,
301 chf: Pin<&mut rcCompactHeightfield>,
302 borderSize: i32,
303 minRegionArea: i32,
304 ) -> bool;
305 unsafe fn rcBuildRegionsMonotone(
306 ctx: *mut rcContext,
307 chf: Pin<&mut rcCompactHeightfield>,
308 borderSize: i32,
309 minRegionArea: i32,
310 mergeRegionArea: i32,
311 ) -> bool;
312 unsafe fn rcBuildHeightfieldLayers(
313 ctx: *mut rcContext,
314 chf: &rcCompactHeightfield,
315 borderSize: i32,
316 walkableHeight: i32,
317 lset: Pin<&mut rcHeightfieldLayerSet>,
318 ) -> bool;
319 unsafe fn rcBuildContours(
320 ctx: *mut rcContext,
321 chf: &rcCompactHeightfield,
322 maxError: f32,
323 maxEdgeLen: i32,
324 cset: Pin<&mut rcContourSet>,
325 buildFlags: i32,
326 ) -> bool;
327 unsafe fn rcBuildPolyMesh(
328 ctx: *mut rcContext,
329 cset: &rcContourSet,
330 nvp: i32,
331 mesh: Pin<&mut rcPolyMesh>,
332 ) -> bool;
333 unsafe fn rcMergePolyMeshes(
334 ctx: *mut rcContext,
335 meshes: *const *const rcPolyMesh,
336 nmeshes: i32,
337 mesh: Pin<&mut rcPolyMesh>,
338 ) -> bool;
339 unsafe fn rcBuildPolyMeshDetail(
340 ctx: *mut rcContext,
341 mesh: &rcPolyMesh,
342 chf: &rcCompactHeightfield,
343 sampleDist: f32,
344 sampleMaxError: f32,
345 dmesh: Pin<&mut rcPolyMeshDetail>,
346 ) -> bool;
347 unsafe fn rcCopyPolyMesh(ctx: *mut rcContext, src: &rcPolyMesh, dst: Pin<&mut rcPolyMesh>) -> bool;
348 unsafe fn rcMergePolyMeshDetails(
349 ctx: *mut rcContext,
350 meshes: *const *const rcPolyMeshDetail,
351 nmeshes: i32,
352 mesh: Pin<&mut rcPolyMeshDetail>,
353 ) -> bool;
354 }
355}
356
357pub type RcLogCategory = ffi::rcLogCategory;
358pub type RcTimerLabel = ffi::rcTimerLabel;
359pub type RcBuildContoursFlags = ffi::rcBuildContoursFlags;
360
361pub struct RcContext(UniquePtr<ffi::rcContext>);
366
367impl Debug for RcContext {
368 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
369 return f
370 .debug_tuple("RcContext")
371 .field(&unsafe { mem::transmute_copy::<_, *const ffi::rcContext>(&self.0) })
372 .finish();
373 }
374}
375
376impl RcContext {
377 pub fn new(state: bool) -> RcContext {
378 return RcContext(ffi::rcNewContext(state));
379 }
380
381 #[inline]
382 pub fn enable_log(&mut self, state: bool) {
383 self.0.pin_mut().enableLog(state);
384 }
385
386 #[inline]
387 pub fn reset_log(&mut self) {
388 self.0.pin_mut().resetLog();
389 }
390
391 #[inline]
392 pub fn enable_timer(&mut self, state: bool) {
393 self.0.pin_mut().enableTimer(state);
394 }
395
396 #[inline]
397 pub fn reset_timers(&mut self) {
398 self.0.pin_mut().resetTimers();
399 }
400
401 #[inline]
402 pub fn start_timer(&mut self, label: RcTimerLabel) {
403 self.0.pin_mut().startTimer(label);
404 }
405
406 #[inline]
407 pub fn stop_timer(&mut self, label: RcTimerLabel) {
408 self.0.pin_mut().stopTimer(label);
409 }
410
411 #[inline]
412 pub fn get_accumulated_time(&self, label: RcTimerLabel) -> i32 {
413 return self.0.getAccumulatedTime(label);
414 }
415}
416
417#[repr(C)]
422#[derive(Debug, Default, Clone)]
423pub struct RcConfig {
424 pub width: i32,
426
427 pub height: i32,
429
430 pub tile_size: i32,
432
433 pub border_size: i32,
435
436 pub cs: f32,
438
439 pub ch: f32,
441
442 pub bmin: [f32; 3],
444
445 pub bmax: [f32; 3],
447
448 pub walkable_slope_angle: f32,
450
451 pub walkable_height: i32,
454
455 pub walkable_climb: i32,
457
458 pub walkable_radius: i32,
461
462 pub max_edge_len: i32,
464
465 pub max_simplification_error: f32,
468
469 pub min_region_area: i32,
471
472 pub merge_region_area: i32,
475
476 pub max_verts_per_poly: i32,
479
480 pub detail_sample_dist: f32,
483
484 pub detail_sample_max_error: f32,
487}
488
489const_assert_eq!(mem::size_of::<RcConfig>(), 92);
490
491unsafe impl ExternType for RcConfig {
492 type Id = type_id!("rcConfig");
493 type Kind = cxx::kind::Trivial;
494}
495
496#[repr(C)]
501#[derive(Clone)]
502pub struct RcSpan {
503 pub bits: u32,
504 next: *const RcSpan,
505}
506
507#[cfg(target_pointer_width = "64")]
508const_assert_eq!(mem::size_of::<RcSpan>(), 16);
509
510#[cfg(target_pointer_width = "32")]
511const_assert_eq!(mem::size_of::<RcSpan>(), 8);
512
513unsafe impl ExternType for RcSpan {
514 type Id = type_id!("rcSpan");
515 type Kind = cxx::kind::Trivial;
516}
517
518const RC_SPAN_SMIN_MASK: u32 = RC_SPAN_MAX_HEIGHT;
519const RC_SPAN_SMAX_OFF: u32 = RC_SPAN_HEIGHT_BITS;
520const RC_SPAN_SMAX_MASK: u32 = RC_SPAN_MAX_HEIGHT << RC_SPAN_SMAX_OFF;
521const RC_SPAN_AREA_OFF: u32 = RC_SPAN_HEIGHT_BITS * 2;
522const RC_SPAN_AREA_MASK: u32 = !(RC_SPAN_SMIN_MASK | RC_SPAN_SMAX_MASK);
523
524impl RcSpan {
525 #[inline]
526 pub fn smin(&self) -> u32 {
527 return self.bits & RC_SPAN_SMIN_MASK;
528 }
529
530 #[inline]
531 pub fn set_smin(&mut self, smin: u32) {
532 self.bits = (self.bits & !RC_SPAN_SMIN_MASK) | (smin & RC_SPAN_SMIN_MASK);
533 }
534
535 #[inline]
536 pub fn smax(&self) -> u32 {
537 return (self.bits & RC_SPAN_SMAX_MASK) >> RC_SPAN_SMAX_OFF;
538 }
539
540 #[inline]
541 pub fn set_smax(&mut self, smax: u32) {
542 self.bits = (self.bits & !RC_SPAN_SMAX_MASK) | ((smax << RC_SPAN_SMAX_OFF) | RC_SPAN_SMAX_MASK);
543 }
544
545 #[inline]
546 pub fn area(&self) -> u32 {
547 return self.bits >> RC_SPAN_AREA_OFF;
548 }
549
550 #[inline]
551 pub fn set_area(&mut self, area: u32) {
552 self.bits = (self.bits & !RC_SPAN_AREA_MASK) | (area << RC_SPAN_AREA_OFF);
553 }
554
555 #[inline]
556 pub fn next(&self) -> Option<&RcSpan> {
557 if self.next.is_null() {
558 return None;
559 } else {
560 return Some(unsafe { &*self.next });
561 }
562 }
563}
564
565impl Debug for RcSpan {
566 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
567 return f
568 .debug_struct("RcSpan")
569 .field("smin", &self.smin())
570 .field("smax", &self.smax())
571 .field("area", &self.area())
572 .field("next", &self.next())
573 .finish();
574 }
575}
576
577#[repr(C)]
582#[derive(Debug, Clone)]
583pub struct RcSpanPool {
584 next: *const RcSpanPool,
585 pub items: [RcSpan; RC_SPANS_PER_POOL],
586}
587
588#[cfg(target_pointer_width = "64")]
589const_assert_eq!(mem::size_of::<RcSpanPool>(), 32776);
590
591#[cfg(target_pointer_width = "32")]
592const_assert_eq!(mem::size_of::<RcSpanPool>(), 16388);
593
594unsafe impl ExternType for RcSpanPool {
595 type Id = type_id!("rcSpanPool");
596 type Kind = cxx::kind::Trivial;
597}
598
599#[repr(C)]
604#[derive(Debug)]
605pub struct CxxRcHeightfield {
606 width: i32,
607 height: i32,
608 pub bmin: [f32; 3],
609 pub bmax: [f32; 3],
610 pub cs: f32,
611 pub ch: f32,
612 spans: *mut *mut RcSpan,
613 pools: *mut RcSpanPool,
614 freelist: *mut RcSpan,
615}
616
617#[cfg(target_pointer_width = "64")]
618const_assert_eq!(mem::size_of::<CxxRcHeightfield>(), 64);
619
620#[cfg(target_pointer_width = "32")]
621const_assert_eq!(mem::size_of::<CxxRcHeightfield>(), 52);
622
623unsafe impl ExternType for CxxRcHeightfield {
624 type Id = type_id!("rcHeightfield");
625 type Kind = cxx::kind::Trivial;
626}
627
628pub struct RcHeightfield(*mut CxxRcHeightfield);
629
630impl Deref for RcHeightfield {
631 type Target = CxxRcHeightfield;
632
633 fn deref(&self) -> &Self::Target {
634 return self.inner();
635 }
636}
637
638impl DerefMut for RcHeightfield {
639 fn deref_mut(&mut self) -> &mut Self::Target {
640 return self.inner_mut().get_mut();
641 }
642}
643
644impl Drop for RcHeightfield {
645 fn drop(&mut self) {
646 unsafe { ffi::rcFreeHeightField(self.0) };
647 }
648}
649
650impl RcHeightfield {
651 #[inline]
652 pub fn new() -> RcHeightfield {
653 return RcHeightfield(unsafe { ffi::rcAllocHeightfield() });
654 }
655
656 #[inline]
657 fn inner(&self) -> &ffi::rcHeightfield {
658 return unsafe { &*self.0 };
659 }
660
661 #[inline]
662 fn inner_mut(&mut self) -> Pin<&mut ffi::rcHeightfield> {
663 return unsafe { Pin::new_unchecked(&mut *self.0) };
664 }
665
666 #[inline]
667 pub fn as_ptr(&self) -> *const ffi::rcHeightfield {
668 return self.0;
669 }
670
671 #[inline]
672 pub fn as_mut_ptr(&mut self) -> *mut ffi::rcHeightfield {
673 return self.0;
674 }
675
676 #[inline]
677 pub fn width(&self) -> i32 {
678 return self.width;
679 }
680
681 #[inline]
682 pub fn height(&self) -> i32 {
683 return self.height;
684 }
685
686 #[inline]
687 pub fn get_span(&self, idx: usize) -> Option<&RcSpan> {
688 if idx >= (self.width() * self.height()) as usize {
689 return None;
690 }
691 let span = unsafe { *self.spans.add(idx) };
692 if span.is_null() {
693 return None;
694 }
695 return Some(unsafe { &*span });
696 }
697
698 #[inline]
699 pub fn get_span_mut(&mut self, idx: usize) -> Option<&mut RcSpan> {
700 if idx >= (self.width() * self.height()) as usize {
701 return None;
702 }
703 let span = unsafe { *self.spans.add(idx) };
704 if span.is_null() {
705 return None;
706 }
707 return Some(unsafe { &mut *span });
708 }
709}
710
711impl Debug for RcHeightfield {
712 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
713 return self.inner().fmt(f);
714 }
715}
716
717#[repr(C)]
722#[derive(Clone)]
723pub struct RcCompactCell {
724 bits: u32,
725}
726
727const_assert_eq!(mem::size_of::<RcCompactCell>(), 4);
728
729unsafe impl ExternType for RcCompactCell {
730 type Id = type_id!("rcCompactCell");
731 type Kind = cxx::kind::Trivial;
732}
733
734const RC_COMPACT_CELL_INDEX_MASK: u32 = 0xFFFFFF;
735const RC_COMPACT_CELL_COUNT_OFF: u32 = 24;
736const RC_COMPACT_CELL_COUNT_MASK: u32 = 0xFF;
737
738impl RcCompactCell {
739 #[inline]
740 pub fn index(&self) -> u32 {
741 return self.bits & RC_COMPACT_CELL_INDEX_MASK;
742 }
743
744 #[inline]
745 pub fn set_index(&mut self, index: u32) {
746 self.bits = (self.bits & !RC_COMPACT_CELL_INDEX_MASK) | (index & RC_COMPACT_CELL_INDEX_MASK);
747 }
748
749 #[inline]
750 pub fn count(&self) -> u32 {
751 return self.bits >> RC_COMPACT_CELL_COUNT_OFF;
752 }
753
754 #[inline]
755 pub fn set_count(&mut self, count: u32) {
756 self.bits = (self.bits & !RC_COMPACT_CELL_COUNT_MASK) | (count << RC_COMPACT_CELL_COUNT_OFF);
757 }
758}
759
760impl Debug for RcCompactCell {
761 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
762 return f
763 .debug_struct("RcCompactCell")
764 .field("index", &self.index())
765 .field("count", &self.count())
766 .finish();
767 }
768}
769
770#[repr(C)]
775#[derive(Clone)]
776pub struct RcCompactSpan {
777 pub y: u16,
778 pub reg: u16,
779 bits: u32,
780}
781
782const_assert_eq!(mem::size_of::<RcCompactSpan>(), 8);
783
784unsafe impl ExternType for RcCompactSpan {
785 type Id = type_id!("rcCompactSpan");
786 type Kind = cxx::kind::Trivial;
787}
788
789const RC_COMPACT_SPAN_CON_MASK: u32 = 0xFFFFFF;
790const RC_COMPACT_SPAN_H_OFF: u32 = 24;
791const RC_COMPACT_SPAN_H_MASK: u32 = 0xFF;
792
793impl RcCompactSpan {
794 #[inline]
795 pub fn con(&self) -> u32 {
796 return self.bits & RC_COMPACT_SPAN_CON_MASK;
797 }
798
799 #[inline]
800 pub fn set_con(&mut self, con: u32) {
801 self.bits = (self.bits & !RC_COMPACT_SPAN_CON_MASK) | (con & RC_COMPACT_SPAN_CON_MASK);
802 }
803
804 #[inline]
805 pub fn h(&self) -> u32 {
806 return self.bits >> RC_COMPACT_SPAN_H_OFF;
807 }
808
809 #[inline]
810 pub fn set_h(&mut self, h: u32) {
811 self.bits = (self.bits & !RC_COMPACT_SPAN_H_MASK) | (h << RC_COMPACT_SPAN_H_OFF);
812 }
813}
814
815impl Debug for RcCompactSpan {
816 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
817 return f
818 .debug_struct("RcCompactSpan")
819 .field("y", &self.y)
820 .field("reg", &self.reg)
821 .field("con", &self.con())
822 .field("h", &self.h())
823 .finish();
824 }
825}
826
827#[repr(C)]
832#[derive(Debug)]
833pub struct CxxRcCompactHeightfield {
834 width: i32,
835 height: i32,
836 span_count: i32,
837 pub walkable_height: i32,
838 pub walkable_climb: i32,
839 pub border_size: i32,
840 pub max_distance: u16,
841 pub max_regions: u16,
842 pub bmin: [f32; 3],
843 pub bmax: [f32; 3],
844 pub cs: f32,
845 pub ch: f32,
846 cells: *mut RcCompactCell,
847 spans: *mut RcCompactSpan,
848 dist: *mut u16,
849 areas: *mut u8,
850}
851
852#[cfg(target_pointer_width = "64")]
853const_assert_eq!(mem::size_of::<CxxRcCompactHeightfield>(), 96);
854
855#[cfg(target_pointer_width = "32")]
856const_assert_eq!(mem::size_of::<CxxRcCompactHeightfield>(), 76);
857
858unsafe impl ExternType for CxxRcCompactHeightfield {
859 type Id = type_id!("rcCompactHeightfield");
860 type Kind = cxx::kind::Trivial;
861}
862
863pub struct RcCompactHeightfield(*mut ffi::rcCompactHeightfield);
864
865impl Deref for RcCompactHeightfield {
866 type Target = CxxRcCompactHeightfield;
867
868 fn deref(&self) -> &Self::Target {
869 return self.inner();
870 }
871}
872
873impl DerefMut for RcCompactHeightfield {
874 fn deref_mut(&mut self) -> &mut Self::Target {
875 return self.inner_mut().get_mut();
876 }
877}
878
879impl Drop for RcCompactHeightfield {
880 fn drop(&mut self) {
881 unsafe { ffi::rcFreeCompactHeightfield(self.0) };
882 }
883}
884
885impl RcCompactHeightfield {
886 #[inline]
887 pub fn new() -> RcCompactHeightfield {
888 return RcCompactHeightfield(unsafe { ffi::rcAllocCompactHeightfield() });
889 }
890
891 #[inline]
892 fn inner(&self) -> &ffi::rcCompactHeightfield {
893 return unsafe { &*self.0 };
894 }
895
896 #[inline]
897 fn inner_mut(&mut self) -> Pin<&mut ffi::rcCompactHeightfield> {
898 return unsafe { Pin::new_unchecked(&mut *self.0) };
899 }
900
901 #[inline]
902 pub fn as_ptr(&self) -> *const ffi::rcCompactHeightfield {
903 return self.0;
904 }
905
906 #[inline]
907 pub fn as_mut_ptr(&mut self) -> *mut ffi::rcCompactHeightfield {
908 return self.0;
909 }
910
911 #[inline]
912 pub fn width(&self) -> i32 {
913 return self.width;
914 }
915
916 #[inline]
917 pub fn height(&self) -> i32 {
918 return self.height;
919 }
920
921 #[inline]
922 pub fn span_count(&self) -> usize {
923 return self.span_count as usize;
924 }
925
926 #[inline]
927 pub fn cells(&self) -> &[RcCompactCell] {
928 return unsafe { slice::from_raw_parts(self.cells, (self.width() * self.height()) as usize) };
929 }
930
931 #[inline]
932 pub fn cells_mut(&mut self) -> &mut [RcCompactCell] {
933 return unsafe { slice::from_raw_parts_mut(self.cells, (self.width() * self.height()) as usize) };
934 }
935
936 #[inline]
937 pub fn spans(&self) -> &[RcCompactSpan] {
938 return unsafe { slice::from_raw_parts(self.spans, self.span_count()) };
939 }
940
941 #[inline]
942 pub fn spans_mut(&mut self) -> &mut [RcCompactSpan] {
943 return unsafe { slice::from_raw_parts_mut(self.spans, self.span_count()) };
944 }
945
946 #[inline]
947 pub fn dist(&self) -> &[u16] {
948 let dist_ptr = self.dist;
949 let mut dist_len = self.span_count();
950 if dist_ptr.is_null() {
951 dist_len = 0;
952 }
953 return unsafe { slice::from_raw_parts(dist_ptr, dist_len) };
954 }
955
956 #[inline]
957 pub fn dist_mut(&mut self) -> &mut [u16] {
958 let dist_ptr = self.dist;
959 let mut dist_len = self.span_count();
960 if dist_ptr.is_null() {
961 dist_len = 0;
962 }
963 return unsafe { slice::from_raw_parts_mut(dist_ptr, dist_len) };
964 }
965
966 #[inline]
967 pub fn areas(&self) -> &[u8] {
968 return unsafe { slice::from_raw_parts(self.areas, self.span_count()) };
969 }
970
971 #[inline]
972 pub fn areas_mut(&mut self) -> &mut [u8] {
973 return unsafe { slice::from_raw_parts_mut(self.areas, self.span_count()) };
974 }
975}
976
977impl Debug for RcCompactHeightfield {
978 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
979 return self.inner().fmt(f);
980 }
981}
982
983#[repr(C)]
988#[derive(Debug)]
989pub struct RcHeightfieldLayer {
990 pub bmin: [f32; 3], pub bmax: [f32; 3], pub cs: f32, pub ch: f32, width: i32, height: i32, pub minx: i32, pub maxx: i32, pub miny: i32, pub maxy: i32, pub hmin: i32, pub hmax: i32, heights: *mut u8, areas: *mut u8, cons: *mut u8, }
1006
1007#[cfg(target_pointer_width = "64")]
1008const_assert_eq!(mem::size_of::<RcHeightfieldLayer>(), 88);
1009
1010#[cfg(target_pointer_width = "32")]
1011const_assert_eq!(mem::size_of::<RcHeightfieldLayer>(), 76);
1012
1013unsafe impl ExternType for RcHeightfieldLayer {
1014 type Id = type_id!("rcHeightfieldLayer");
1015 type Kind = cxx::kind::Trivial;
1016}
1017
1018impl RcHeightfieldLayer {
1019 #[inline]
1020 pub fn width(&self) -> i32 {
1021 return self.width;
1022 }
1023
1024 #[inline]
1025 pub fn height(&self) -> i32 {
1026 return self.height;
1027 }
1028
1029 #[inline]
1030 pub fn heights(&self) -> &[u8] {
1031 return unsafe { slice::from_raw_parts(self.heights, (self.width * self.height) as usize) };
1032 }
1033
1034 #[inline]
1035 pub fn heights_mut(&mut self) -> &mut [u8] {
1036 return unsafe { slice::from_raw_parts_mut(self.heights, (self.width * self.height) as usize) };
1037 }
1038
1039 #[inline]
1040 pub fn areas(&self) -> &[u8] {
1041 return unsafe { slice::from_raw_parts(self.areas, self.height as usize) };
1042 }
1043
1044 #[inline]
1045 pub fn areas_mut(&mut self) -> &mut [u8] {
1046 return unsafe { slice::from_raw_parts_mut(self.areas, self.height as usize) };
1047 }
1048
1049 #[inline]
1050 pub fn cons(&self) -> &[u8] {
1051 return unsafe { slice::from_raw_parts(self.cons, self.height as usize) };
1052 }
1053
1054 #[inline]
1055 pub fn cons_mut(&mut self) -> &mut [u8] {
1056 return unsafe { slice::from_raw_parts_mut(self.cons, self.height as usize) };
1057 }
1058}
1059
1060#[repr(C)]
1065#[derive(Debug)]
1066pub struct CxxRcHeightfieldLayerSet {
1067 layers: *mut ffi::rcHeightfieldLayer,
1068 nlayers: i32,
1069}
1070
1071#[cfg(target_pointer_width = "64")]
1072const_assert_eq!(mem::size_of::<CxxRcHeightfieldLayerSet>(), 16);
1073
1074#[cfg(target_pointer_width = "32")]
1075const_assert_eq!(mem::size_of::<CxxRcHeightfieldLayerSet>(), 8);
1076
1077unsafe impl ExternType for CxxRcHeightfieldLayerSet {
1078 type Id = type_id!("rcHeightfieldLayerSet");
1079 type Kind = cxx::kind::Trivial;
1080}
1081
1082pub struct RcHeightfieldLayerSet(*mut ffi::rcHeightfieldLayerSet);
1083
1084impl Deref for RcHeightfieldLayerSet {
1085 type Target = CxxRcHeightfieldLayerSet;
1086
1087 fn deref(&self) -> &Self::Target {
1088 return self.inner();
1089 }
1090}
1091
1092impl DerefMut for RcHeightfieldLayerSet {
1093 fn deref_mut(&mut self) -> &mut Self::Target {
1094 return self.inner_mut().get_mut();
1095 }
1096}
1097
1098impl Drop for RcHeightfieldLayerSet {
1099 fn drop(&mut self) {
1100 unsafe { ffi::rcFreeHeightfieldLayerSet(self.0) };
1101 }
1102}
1103
1104impl RcHeightfieldLayerSet {
1105 #[inline]
1106 pub fn new() -> RcHeightfieldLayerSet {
1107 return RcHeightfieldLayerSet(unsafe { ffi::rcAllocHeightfieldLayerSet() });
1108 }
1109
1110 #[inline]
1111 fn inner(&self) -> &ffi::rcHeightfieldLayerSet {
1112 return unsafe { &*self.0 };
1113 }
1114
1115 #[inline]
1116 fn inner_mut(&mut self) -> Pin<&mut ffi::rcHeightfieldLayerSet> {
1117 return unsafe { Pin::new_unchecked(&mut *self.0) };
1118 }
1119
1120 #[inline]
1121 pub fn as_ptr(&self) -> *const ffi::rcHeightfieldLayerSet {
1122 return self.0;
1123 }
1124
1125 #[inline]
1126 pub fn as_mut_ptr(&mut self) -> *mut ffi::rcHeightfieldLayerSet {
1127 return self.0;
1128 }
1129
1130 #[inline]
1131 pub fn layers(&self) -> &[RcHeightfieldLayer] {
1132 return unsafe { slice::from_raw_parts(self.layers, self.nlayers()) };
1133 }
1134
1135 #[inline]
1136 pub fn layers_mut(&mut self) -> &mut [RcHeightfieldLayer] {
1137 return unsafe { slice::from_raw_parts_mut(self.layers, self.nlayers()) };
1138 }
1139
1140 #[inline]
1141 pub fn nlayers(&self) -> usize {
1142 return self.inner().nlayers as usize;
1143 }
1144}
1145
1146impl Debug for RcHeightfieldLayerSet {
1147 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1148 return self.inner().fmt(f);
1149 }
1150}
1151
1152#[repr(C)]
1157#[derive(Debug)]
1158pub struct RcContour {
1159 verts: *mut [i32; 4],
1160 nverts: i32,
1161 rverts: *mut [i32; 4],
1162 nrverts: i32,
1163 pub reg: u16,
1164 pub area: u8,
1165}
1166
1167#[cfg(target_pointer_width = "64")]
1168const_assert_eq!(mem::size_of::<RcContour>(), 32);
1169
1170#[cfg(target_pointer_width = "32")]
1171const_assert_eq!(mem::size_of::<RcContour>(), 20);
1172
1173unsafe impl ExternType for RcContour {
1174 type Id = type_id!("rcContour");
1175 type Kind = cxx::kind::Trivial;
1176}
1177
1178impl RcContour {
1179 #[inline]
1180 pub fn nverts(&self) -> usize {
1181 return self.nverts as usize;
1182 }
1183
1184 #[inline]
1185 pub fn verts(&self) -> &[[i32; 4]] {
1186 return unsafe { slice::from_raw_parts(self.verts, self.nverts()) };
1187 }
1188
1189 #[inline]
1190 pub fn verts_mut(&mut self) -> &mut [[i32; 4]] {
1191 return unsafe { slice::from_raw_parts_mut(self.verts, self.nverts()) };
1192 }
1193
1194 #[inline]
1195 pub fn nrverts(&self) -> usize {
1196 return self.nrverts as usize;
1197 }
1198
1199 #[inline]
1200 pub fn rverts(&self) -> &[[i32; 4]] {
1201 return unsafe { slice::from_raw_parts(self.rverts, self.nrverts()) };
1202 }
1203
1204 #[inline]
1205 pub fn rverts_mut(&mut self) -> &mut [[i32; 4]] {
1206 return unsafe { slice::from_raw_parts_mut(self.rverts, self.nrverts()) };
1207 }
1208}
1209
1210#[repr(C)]
1215#[derive(Debug)]
1216pub struct CxxRcContourSet {
1217 conts: *mut RcContour,
1218 nconts: i32,
1219 pub bmin: [f32; 3],
1220 pub bmax: [f32; 3],
1221 pub cs: f32,
1222 pub ch: f32,
1223 pub width: i32,
1224 pub height: i32,
1225 pub border_size: i32,
1226 pub max_error: f32,
1227}
1228
1229#[cfg(target_pointer_width = "64")]
1230const_assert_eq!(mem::size_of::<CxxRcContourSet>(), 64);
1231
1232#[cfg(target_pointer_width = "32")]
1233const_assert_eq!(mem::size_of::<CxxRcContourSet>(), 56);
1234
1235unsafe impl ExternType for CxxRcContourSet {
1236 type Id = type_id!("rcContourSet");
1237 type Kind = cxx::kind::Trivial;
1238}
1239
1240pub struct RcContourSet(*mut ffi::rcContourSet);
1241
1242impl Deref for RcContourSet {
1243 type Target = CxxRcContourSet;
1244
1245 fn deref(&self) -> &Self::Target {
1246 return self.inner();
1247 }
1248}
1249
1250impl DerefMut for RcContourSet {
1251 fn deref_mut(&mut self) -> &mut Self::Target {
1252 return self.inner_mut().get_mut();
1253 }
1254}
1255
1256impl Drop for RcContourSet {
1257 fn drop(&mut self) {
1258 unsafe { ffi::rcFreeContourSet(self.0) };
1259 }
1260}
1261
1262impl RcContourSet {
1263 #[inline]
1264 pub fn new() -> RcContourSet {
1265 return RcContourSet(unsafe { ffi::rcAllocContourSet() });
1266 }
1267
1268 #[inline]
1269 fn inner(&self) -> &ffi::rcContourSet {
1270 return unsafe { &*self.0 };
1271 }
1272
1273 #[inline]
1274 fn inner_mut(&mut self) -> Pin<&mut ffi::rcContourSet> {
1275 return unsafe { Pin::new_unchecked(&mut *self.0) };
1276 }
1277
1278 #[inline]
1279 pub fn as_ptr(&self) -> *const ffi::rcContourSet {
1280 return self.0;
1281 }
1282
1283 #[inline]
1284 pub fn as_mut_ptr(&mut self) -> *mut ffi::rcContourSet {
1285 return self.0;
1286 }
1287
1288 #[inline]
1289 pub fn conts(&self) -> &[RcContour] {
1290 return unsafe { slice::from_raw_parts(self.inner().conts, self.nconts()) };
1291 }
1292
1293 #[inline]
1294 pub fn conts_mut(&mut self) -> &mut [RcContour] {
1295 return unsafe { slice::from_raw_parts_mut(self.inner_mut().conts, self.nconts()) };
1296 }
1297
1298 #[inline]
1299 pub fn nconts(&self) -> usize {
1300 return self.inner().nconts as usize;
1301 }
1302}
1303
1304impl Debug for RcContourSet {
1305 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1306 return self.inner().fmt(f);
1307 }
1308}
1309
1310#[repr(C)]
1315#[derive(Debug)]
1316pub struct CxxRcPolyMesh {
1317 verts: *mut [u16; 3],
1318 polys: *mut u16,
1319 regs: *mut u16,
1320 flags: *mut u16,
1321 areas: *mut u8,
1322 nverts: i32,
1323 npolys: i32,
1324 maxpolys: i32,
1325 nvp: i32,
1326 pub bmin: [f32; 3],
1327 pub bmax: [f32; 3],
1328 pub cs: f32,
1329 pub ch: f32,
1330 pub border_size: i32,
1331 pub max_edge_error: f32,
1332}
1333
1334#[cfg(target_pointer_width = "64")]
1335const_assert_eq!(mem::size_of::<CxxRcPolyMesh>(), 96);
1336
1337#[cfg(target_pointer_width = "32")]
1338const_assert_eq!(mem::size_of::<CxxRcPolyMesh>(), 76);
1339
1340unsafe impl ExternType for CxxRcPolyMesh {
1341 type Id = type_id!("rcPolyMesh");
1342 type Kind = cxx::kind::Trivial;
1343}
1344
1345pub struct RcPolyMesh(*mut ffi::rcPolyMesh);
1346
1347impl Deref for RcPolyMesh {
1348 type Target = CxxRcPolyMesh;
1349
1350 fn deref(&self) -> &Self::Target {
1351 return self.inner();
1352 }
1353}
1354
1355impl DerefMut for RcPolyMesh {
1356 fn deref_mut(&mut self) -> &mut Self::Target {
1357 return self.inner_mut().get_mut();
1358 }
1359}
1360
1361impl Drop for RcPolyMesh {
1362 fn drop(&mut self) {
1363 unsafe { ffi::rcFreePolyMesh(self.0) };
1364 }
1365}
1366
1367impl RcPolyMesh {
1368 #[inline]
1369 pub fn new() -> RcPolyMesh {
1370 return RcPolyMesh(unsafe { ffi::rcAllocPolyMesh() });
1371 }
1372
1373 #[inline]
1374 fn inner(&self) -> &ffi::rcPolyMesh {
1375 return unsafe { &*self.0 };
1376 }
1377
1378 #[inline]
1379 fn inner_mut(&mut self) -> Pin<&mut ffi::rcPolyMesh> {
1380 return unsafe { Pin::new_unchecked(&mut *self.0) };
1381 }
1382
1383 #[inline]
1384 pub fn as_ptr(&self) -> *const ffi::rcPolyMesh {
1385 return self.0;
1386 }
1387
1388 #[inline]
1389 pub fn as_mut_ptr(&mut self) -> *mut ffi::rcPolyMesh {
1390 return self.0;
1391 }
1392
1393 #[inline]
1394 pub fn verts(&self) -> &[[u16; 3]] {
1395 return unsafe { slice::from_raw_parts(self.verts, self.nverts()) };
1396 }
1397
1398 #[inline]
1399 pub fn verts_mut(&mut self) -> &mut [[u16; 3]] {
1400 return unsafe { slice::from_raw_parts_mut(self.verts, self.nverts()) };
1401 }
1402
1403 #[inline]
1404 pub fn polys(&self) -> &[u16] {
1405 return unsafe { slice::from_raw_parts(self.polys, self.npolys() * 2 * self.nvp()) };
1406 }
1407
1408 #[inline]
1409 pub fn polys_mut(&mut self) -> &mut [u16] {
1410 return unsafe { slice::from_raw_parts_mut(self.polys, self.npolys() * 2 * self.nvp()) };
1411 }
1412
1413 #[inline]
1414 pub fn regs(&self) -> &[u16] {
1415 return unsafe { slice::from_raw_parts(self.regs, self.npolys()) };
1416 }
1417
1418 #[inline]
1419 pub fn regs_mut(&mut self) -> &mut [u16] {
1420 return unsafe { slice::from_raw_parts_mut(self.regs, self.npolys()) };
1421 }
1422
1423 #[inline]
1424 pub fn flags(&self) -> &[u16] {
1425 return unsafe { slice::from_raw_parts(self.flags, self.npolys()) };
1426 }
1427
1428 #[inline]
1429 pub fn flags_mut(&mut self) -> &mut [u16] {
1430 return unsafe { slice::from_raw_parts_mut(self.flags, self.npolys()) };
1431 }
1432
1433 #[inline]
1434 pub fn areas(&self) -> &[u8] {
1435 return unsafe { slice::from_raw_parts(self.areas, self.npolys()) };
1436 }
1437
1438 #[inline]
1439 pub fn areas_mut(&mut self) -> &mut [u8] {
1440 return unsafe { slice::from_raw_parts_mut(self.areas, self.npolys()) };
1441 }
1442
1443 #[inline]
1444 pub fn nverts(&self) -> usize {
1445 return self.nverts as usize;
1446 }
1447
1448 #[inline]
1449 pub fn npolys(&self) -> usize {
1450 return self.npolys as usize;
1451 }
1452
1453 #[inline]
1454 pub fn maxpolys(&self) -> usize {
1455 return self.maxpolys as usize;
1456 }
1457
1458 #[inline]
1459 pub fn nvp(&self) -> usize {
1460 return self.nvp as usize;
1461 }
1462}
1463
1464impl Debug for RcPolyMesh {
1465 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1466 return self.inner().fmt(f);
1467 }
1468}
1469
1470#[repr(C)]
1475#[derive(Debug)]
1476pub struct CxxRcPolyMeshDetail {
1477 meshes: *mut [u32; 4],
1478 verts: *mut [f32; 3],
1479 tris: *mut [u8; 4],
1480 nmeshes: i32,
1481 nverts: i32,
1482 ntris: i32,
1483}
1484
1485#[cfg(target_pointer_width = "64")]
1486const_assert_eq!(mem::size_of::<CxxRcPolyMeshDetail>(), 40);
1487
1488#[cfg(target_pointer_width = "32")]
1489const_assert_eq!(mem::size_of::<CxxRcPolyMeshDetail>(), 24);
1490
1491unsafe impl ExternType for CxxRcPolyMeshDetail {
1492 type Id = type_id!("rcPolyMeshDetail");
1493 type Kind = cxx::kind::Trivial;
1494}
1495
1496pub struct RcPolyMeshDetail(*mut ffi::rcPolyMeshDetail);
1497
1498impl Deref for RcPolyMeshDetail {
1499 type Target = CxxRcPolyMeshDetail;
1500
1501 fn deref(&self) -> &Self::Target {
1502 return self.inner();
1503 }
1504}
1505
1506impl DerefMut for RcPolyMeshDetail {
1507 fn deref_mut(&mut self) -> &mut Self::Target {
1508 return self.inner_mut().get_mut();
1509 }
1510}
1511
1512impl Drop for RcPolyMeshDetail {
1513 fn drop(&mut self) {
1514 unsafe { ffi::rcFreePolyMeshDetail(self.0) };
1515 }
1516}
1517
1518impl RcPolyMeshDetail {
1519 #[inline]
1520 pub fn new() -> RcPolyMeshDetail {
1521 return RcPolyMeshDetail(unsafe { ffi::rcAllocPolyMeshDetail() });
1522 }
1523
1524 #[inline]
1525 fn inner(&self) -> &ffi::rcPolyMeshDetail {
1526 return unsafe { &*self.0 };
1527 }
1528
1529 #[inline]
1530 fn inner_mut(&mut self) -> Pin<&mut ffi::rcPolyMeshDetail> {
1531 return unsafe { Pin::new_unchecked(&mut *self.0) };
1532 }
1533
1534 #[inline]
1535 pub fn as_ptr(&self) -> *const ffi::rcPolyMeshDetail {
1536 return self.0;
1537 }
1538
1539 #[inline]
1540 pub fn as_mut_ptr(&mut self) -> *mut ffi::rcPolyMeshDetail {
1541 return self.0;
1542 }
1543
1544 #[inline]
1545 pub fn meshes(&self) -> &[[u32; 4]] {
1546 return unsafe { slice::from_raw_parts(self.meshes, self.nmeshes()) };
1547 }
1548
1549 #[inline]
1550 pub fn meshes_mut(&mut self) -> &mut [[u32; 4]] {
1551 return unsafe { slice::from_raw_parts_mut(self.meshes, self.nmeshes()) };
1552 }
1553
1554 #[inline]
1555 pub fn verts(&self) -> &[[f32; 3]] {
1556 return unsafe { slice::from_raw_parts(self.verts, self.nverts()) };
1557 }
1558
1559 #[inline]
1560 pub fn verts_mut(&mut self) -> &mut [[f32; 3]] {
1561 return unsafe { slice::from_raw_parts_mut(self.verts, self.nverts()) };
1562 }
1563
1564 #[inline]
1565 pub fn tris(&self) -> &[[u8; 4]] {
1566 return unsafe { slice::from_raw_parts(self.tris, self.ntris()) };
1567 }
1568
1569 #[inline]
1570 pub fn tris_mut(&mut self) -> &mut [[u8; 4]] {
1571 return unsafe { slice::from_raw_parts_mut(self.tris, self.ntris()) };
1572 }
1573
1574 #[inline]
1575 pub fn nmeshes(&self) -> usize {
1576 return self.nmeshes as usize;
1577 }
1578
1579 #[inline]
1580 pub fn nverts(&self) -> usize {
1581 return self.nverts as usize;
1582 }
1583
1584 #[inline]
1585 pub fn ntris(&self) -> usize {
1586 return self.ntris as usize;
1587 }
1588}
1589
1590impl Debug for RcPolyMeshDetail {
1591 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1592 return self.inner().fmt(f);
1593 }
1594}
1595
1596pub fn rc_calc_bounds(verts: &[[f32; 3]]) -> ([f32; 3], [f32; 3]) {
1601 let mut min_bounds = [0.0; 3];
1602 let mut max_bounds = [0.0; 3];
1603 unsafe {
1604 ffi::rcCalcBounds(
1605 verts.as_ptr() as *const _,
1606 verts.len() as i32,
1607 min_bounds.as_mut_ptr(),
1608 max_bounds.as_mut_ptr(),
1609 );
1610 }
1611 return (min_bounds, max_bounds);
1612}
1613
1614pub fn rc_calc_grid_size(min_bounds: &[f32; 3], max_bounds: &[f32; 3], cell_size: f32) -> (i32, i32) {
1615 let mut size_x = 0;
1616 let mut size_z = 0;
1617 unsafe {
1618 ffi::rcCalcGridSize(
1619 min_bounds.as_ptr(),
1620 max_bounds.as_ptr(),
1621 cell_size,
1622 &mut size_x,
1623 &mut size_z,
1624 );
1625 }
1626 return (size_x, size_z);
1627}
1628
1629pub fn rc_create_heightfield(
1630 context: &mut RcContext,
1631 heightfield: &mut RcHeightfield,
1632 size_x: i32,
1633 size_z: i32,
1634 min_bounds: &[f32; 3],
1635 max_bounds: &[f32; 3],
1636 cell_size: f32,
1637 cell_height: f32,
1638) -> Result<(), XError> {
1639 let res = unsafe {
1640 ffi::rcCreateHeightfield(
1641 context.0.pin_mut().get_unchecked_mut() as *mut _,
1642 heightfield.inner_mut(),
1643 size_x,
1644 size_z,
1645 min_bounds.as_ptr(),
1646 max_bounds.as_ptr(),
1647 cell_size,
1648 cell_height,
1649 )
1650 };
1651 return if res { Ok(()) } else { Err(XError::Failed) };
1652}
1653
1654pub fn rc_mark_walkable_triangles(
1655 context: &mut RcContext,
1656 walkable_slope_angle: f32,
1657 verts: &[[f32; 3]],
1658 tris: &[[i32; 3]],
1659 tri_area_ids: &mut [u8],
1660) -> Result<(), XError> {
1661 if tri_area_ids.len() < tris.len() {
1662 return Err(XError::InvalidParam);
1663 }
1664 unsafe {
1665 ffi::rcMarkWalkableTriangles(
1666 context.0.pin_mut().get_unchecked_mut() as *mut _,
1667 walkable_slope_angle,
1668 verts.as_ptr() as *const f32,
1669 verts.len() as i32,
1670 tris.as_ptr() as *const i32,
1671 tris.len() as i32,
1672 tri_area_ids.as_mut_ptr(),
1673 );
1674 }
1675 return Ok(());
1676}
1677
1678pub fn rc_clear_unwalkable_triangles(
1679 context: &mut RcContext,
1680 walkable_slope_angle: f32,
1681 verts: &[[f32; 3]],
1682 tris: &[[i32; 3]],
1683 tri_area_ids: &mut [u8],
1684) -> Result<(), XError> {
1685 if tri_area_ids.len() < tris.len() {
1686 return Err(XError::InvalidParam);
1687 }
1688 unsafe {
1689 ffi::rcClearUnwalkableTriangles(
1690 context.0.pin_mut().get_unchecked_mut() as *mut _,
1691 walkable_slope_angle,
1692 verts.as_ptr() as *const f32,
1693 verts.len() as i32,
1694 tris.as_ptr() as *const i32,
1695 tris.len() as i32,
1696 tri_area_ids.as_mut_ptr(),
1697 );
1698 }
1699 return Ok(());
1700}
1701
1702pub fn rc_add_span(
1703 context: &mut RcContext,
1704 heightfield: &mut RcHeightfield,
1705 x: i32,
1706 z: i32,
1707 span_min: u16,
1708 span_max: u16,
1709 area_id: u8,
1710 flag_merge_threshold: i32,
1711) -> Result<(), XError> {
1712 let res = unsafe {
1713 ffi::rcAddSpan(
1714 context.0.pin_mut().get_unchecked_mut() as *mut _,
1715 heightfield.inner_mut(),
1716 x,
1717 z,
1718 span_min,
1719 span_max,
1720 area_id,
1721 flag_merge_threshold,
1722 )
1723 };
1724 return if res { Ok(()) } else { Err(XError::Failed) };
1725}
1726
1727pub fn rc_rasterize_triangle(
1728 context: &mut RcContext,
1729 v0: &[f32; 3],
1730 v1: &[f32; 3],
1731 v2: &[f32; 3],
1732 area_id: u8,
1733 heightfield: &mut RcHeightfield,
1734 flag_merge_threshold: i32,
1735) -> Result<(), XError> {
1736 let res = unsafe {
1737 ffi::rcRasterizeTriangle(
1738 context.0.pin_mut().get_unchecked_mut() as *mut _,
1739 v0.as_ptr(),
1740 v1.as_ptr(),
1741 v2.as_ptr(),
1742 area_id,
1743 heightfield.inner_mut(),
1744 flag_merge_threshold,
1745 )
1746 };
1747 return if res { Ok(()) } else { Err(XError::Failed) };
1748}
1749
1750pub fn rc_rasterize_triangles_1(
1751 context: &mut RcContext,
1752 verts: &[[f32; 3]],
1753 tris: &[[i32; 3]],
1754 tri_area_ids: &[u8],
1755 heightfield: &mut RcHeightfield,
1756 flag_merge_threshold: i32,
1757) -> Result<bool, XError> {
1758 if tri_area_ids.len() < tris.len() {
1759 return Err(XError::InvalidParam);
1760 }
1761 let res = unsafe {
1762 ffi::rcRasterizeTriangles1(
1763 context.0.pin_mut().get_unchecked_mut() as *mut _,
1764 verts.as_ptr() as *const f32,
1765 verts.len() as i32,
1766 tris.as_ptr() as *const i32,
1767 tri_area_ids.as_ptr(),
1768 tris.len() as i32,
1769 heightfield.inner_mut(),
1770 flag_merge_threshold,
1771 )
1772 };
1773 return Ok(res);
1774}
1775
1776pub fn rc_rasterize_triangles_2(
1777 context: &mut RcContext,
1778 verts: &[[f32; 3]],
1779 tris: &[[u16; 3]],
1780 tri_area_ids: &[u8],
1781 heightfield: &mut RcHeightfield,
1782 flag_merge_threshold: i32,
1783) -> Result<bool, XError> {
1784 if tri_area_ids.len() < tris.len() {
1785 return Err(XError::InvalidParam);
1786 }
1787 let res = unsafe {
1788 ffi::rcRasterizeTriangles2(
1789 context.0.pin_mut().get_unchecked_mut() as *mut _,
1790 verts.as_ptr() as *const f32,
1791 verts.len() as i32,
1792 tris.as_ptr() as *const u16,
1793 tri_area_ids.as_ptr(),
1794 tris.len() as i32,
1795 heightfield.inner_mut(),
1796 flag_merge_threshold,
1797 )
1798 };
1799 return Ok(res);
1800}
1801
1802pub fn rc_rasterize_triangles_3(
1803 context: &mut RcContext,
1804 verts: &[[f32; 3]],
1805 tri_area_ids: &[u8],
1806 heightfield: &mut RcHeightfield,
1807 flag_merge_threshold: i32,
1808) -> Result<bool, XError> {
1809 if tri_area_ids.len() < verts.len() {
1810 return Err(XError::InvalidParam);
1811 }
1812 let res = unsafe {
1813 ffi::rcRasterizeTriangles3(
1814 context.0.pin_mut().get_unchecked_mut() as *mut _,
1815 verts.as_ptr() as *const f32,
1816 tri_area_ids.as_ptr(),
1817 tri_area_ids.len() as i32,
1818 heightfield.inner_mut(),
1819 flag_merge_threshold,
1820 )
1821 };
1822 return Ok(res);
1823}
1824
1825pub fn rc_filter_low_hanging_walkable_obstacles(
1826 context: &mut RcContext,
1827 walkable_climb: i32,
1828 heightfield: &mut RcHeightfield,
1829) {
1830 unsafe {
1831 ffi::rcFilterLowHangingWalkableObstacles(
1832 context.0.pin_mut().get_unchecked_mut() as *mut _,
1833 walkable_climb,
1834 heightfield.inner_mut(),
1835 );
1836 }
1837}
1838
1839pub fn rc_filter_ledge_spans(
1840 context: &mut RcContext,
1841 walkable_height: i32,
1842 walkable_climb: i32,
1843 heightfield: &mut RcHeightfield,
1844) {
1845 unsafe {
1846 ffi::rcFilterLedgeSpans(
1847 context.0.pin_mut().get_unchecked_mut() as *mut _,
1848 walkable_height,
1849 walkable_climb,
1850 heightfield.inner_mut(),
1851 );
1852 }
1853}
1854
1855pub fn rc_filter_walkable_low_height_spans(
1856 context: &mut RcContext,
1857 walkable_height: i32,
1858 heightfield: &mut RcHeightfield,
1859) {
1860 unsafe {
1861 ffi::rcFilterWalkableLowHeightSpans(
1862 context.0.pin_mut().get_unchecked_mut() as *mut _,
1863 walkable_height,
1864 heightfield.inner_mut(),
1865 );
1866 }
1867}
1868
1869pub fn rc_get_height_field_span_count(context: &mut RcContext, heightfield: &RcHeightfield) -> i32 {
1870 unsafe {
1871 return ffi::rcGetHeightFieldSpanCount(context.0.pin_mut().get_unchecked_mut() as *mut _, heightfield.inner());
1872 }
1873}
1874
1875pub fn rc_build_compact_heightfield(
1876 context: &mut RcContext,
1877 walkable_height: i32,
1878 walkable_climb: i32,
1879 heightfield: &RcHeightfield,
1880 compact_heightfield: &mut RcCompactHeightfield,
1881) -> Result<(), XError> {
1882 let res = unsafe {
1883 ffi::rcBuildCompactHeightfield(
1884 context.0.pin_mut().get_unchecked_mut() as *mut _,
1885 walkable_height,
1886 walkable_climb,
1887 heightfield.inner(),
1888 compact_heightfield.inner_mut(),
1889 )
1890 };
1891 return if res { Ok(()) } else { Err(XError::Failed) };
1892}
1893
1894pub fn rc_erode_walkable_area(
1895 context: &mut RcContext,
1896 erosion_radius: i32,
1897 compact_heightfield: &mut RcCompactHeightfield,
1898) -> Result<(), XError> {
1899 let res = unsafe {
1900 ffi::rcErodeWalkableArea(
1901 context.0.pin_mut().get_unchecked_mut() as *mut _,
1902 erosion_radius,
1903 compact_heightfield.inner_mut(),
1904 )
1905 };
1906 return if res { Ok(()) } else { Err(XError::Failed) };
1907}
1908
1909pub fn rc_median_filter_walkable_area(
1910 context: &mut RcContext,
1911 compact_heightfield: &mut RcCompactHeightfield,
1912) -> Result<(), XError> {
1913 let res = unsafe {
1914 ffi::rcMedianFilterWalkableArea(
1915 context.0.pin_mut().get_unchecked_mut() as *mut _,
1916 compact_heightfield.inner_mut(),
1917 )
1918 };
1919 return if res { Ok(()) } else { Err(XError::Failed) };
1920}
1921
1922pub fn rc_mark_box_area(
1923 context: &mut RcContext,
1924 box_min_bounds: &[f32; 3],
1925 box_max_bounds: &[f32; 3],
1926 area_id: u8,
1927 compact_heightfield: &mut RcCompactHeightfield,
1928) {
1929 unsafe {
1930 ffi::rcMarkBoxArea(
1931 context.0.pin_mut().get_unchecked_mut() as *mut _,
1932 box_min_bounds.as_ptr(),
1933 box_max_bounds.as_ptr(),
1934 area_id,
1935 compact_heightfield.inner_mut(),
1936 );
1937 }
1938}
1939
1940pub fn rc_offset_poly(
1941 verts: &[[f32; 3]],
1942 num_verts: i32,
1943 offset: f32,
1944 out_verts: &mut [[f32; 3]],
1945 max_out_verts: i32,
1946) -> i32 {
1947 unsafe {
1948 return ffi::rcOffsetPoly(
1949 verts.as_ptr() as *const f32,
1950 num_verts,
1951 offset,
1952 out_verts.as_mut_ptr() as *mut f32,
1953 max_out_verts,
1954 );
1955 }
1956}
1957
1958pub fn rc_mark_convex_poly_area(
1959 context: &mut RcContext,
1960 verts: &[[f32; 3]],
1961 min_y: f32,
1962 max_y: f32,
1963 area_id: u8,
1964 compact_heightfield: &mut RcCompactHeightfield,
1965) {
1966 unsafe {
1967 ffi::rcMarkConvexPolyArea(
1968 context.0.pin_mut().get_unchecked_mut() as *mut _,
1969 verts.as_ptr() as *const f32,
1970 verts.len() as i32,
1971 min_y,
1972 max_y,
1973 area_id,
1974 compact_heightfield.inner_mut(),
1975 );
1976 }
1977}
1978
1979pub fn rc_mark_cylinder_area(
1980 context: &mut RcContext,
1981 position: &[f32; 3],
1982 radius: f32,
1983 height: f32,
1984 area_id: u8,
1985 compact_heightfield: &mut RcCompactHeightfield,
1986) {
1987 unsafe {
1988 ffi::rcMarkCylinderArea(
1989 context.0.pin_mut().get_unchecked_mut() as *mut _,
1990 position.as_ptr(),
1991 radius,
1992 height,
1993 area_id,
1994 compact_heightfield.inner_mut(),
1995 );
1996 }
1997}
1998
1999pub fn rc_build_distance_field(context: &mut RcContext, chf: &mut RcCompactHeightfield) -> Result<(), XError> {
2000 let res = unsafe { ffi::rcBuildDistanceField(context.0.pin_mut().get_unchecked_mut() as *mut _, chf.inner_mut()) };
2001 return if res { Ok(()) } else { Err(XError::Failed) };
2002}
2003
2004pub fn rc_build_regions(
2005 context: &mut RcContext,
2006 chf: &mut RcCompactHeightfield,
2007 border_size: i32,
2008 min_region_area: i32,
2009 merge_region_area: i32,
2010) -> Result<(), XError> {
2011 let res = unsafe {
2012 ffi::rcBuildRegions(
2013 context.0.pin_mut().get_unchecked_mut() as *mut _,
2014 chf.inner_mut(),
2015 border_size,
2016 min_region_area,
2017 merge_region_area,
2018 )
2019 };
2020 return if res { Ok(()) } else { Err(XError::Failed) };
2021}
2022
2023pub fn rc_build_layer_regions(
2024 context: &mut RcContext,
2025 chf: &mut RcCompactHeightfield,
2026 border_size: i32,
2027 min_region_area: i32,
2028) -> Result<(), XError> {
2029 let res = unsafe {
2030 ffi::rcBuildLayerRegions(
2031 context.0.pin_mut().get_unchecked_mut() as *mut _,
2032 chf.inner_mut(),
2033 border_size,
2034 min_region_area,
2035 )
2036 };
2037 return if res { Ok(()) } else { Err(XError::Failed) };
2038}
2039
2040pub fn rc_build_regions_monotone(
2041 context: &mut RcContext,
2042 chf: &mut RcCompactHeightfield,
2043 border_size: i32,
2044 min_region_area: i32,
2045 merge_region_area: i32,
2046) -> Result<(), XError> {
2047 let res = unsafe {
2048 ffi::rcBuildRegionsMonotone(
2049 context.0.pin_mut().get_unchecked_mut() as *mut _,
2050 chf.inner_mut(),
2051 border_size,
2052 min_region_area,
2053 merge_region_area,
2054 )
2055 };
2056 return if res { Ok(()) } else { Err(XError::Failed) };
2057}
2058
2059pub fn rc_build_heightfield_layers(
2060 context: &mut RcContext,
2061 chf: &RcCompactHeightfield,
2062 border_size: i32,
2063 walkable_height: i32,
2064 lset: &mut RcHeightfieldLayerSet,
2065) -> Result<(), XError> {
2066 let res = unsafe {
2067 ffi::rcBuildHeightfieldLayers(
2068 context.0.pin_mut().get_unchecked_mut() as *mut _,
2069 chf.inner(),
2070 border_size,
2071 walkable_height,
2072 lset.inner_mut(),
2073 )
2074 };
2075 return if res { Ok(()) } else { Err(XError::Failed) };
2076}
2077
2078pub fn rc_build_contours(
2079 context: &mut RcContext,
2080 chf: &RcCompactHeightfield,
2081 max_error: f32,
2082 max_edge_len: i32,
2083 cset: &mut RcContourSet,
2084 build_flags: RcBuildContoursFlags,
2085) -> Result<(), XError> {
2086 let res = unsafe {
2087 ffi::rcBuildContours(
2088 context.0.pin_mut().get_unchecked_mut() as *mut _,
2089 chf.inner(),
2090 max_error,
2091 max_edge_len,
2092 cset.inner_mut(),
2093 build_flags.repr,
2094 )
2095 };
2096 return if res { Ok(()) } else { Err(XError::Failed) };
2097}
2098
2099pub fn rc_build_poly_mesh(
2100 context: &mut RcContext,
2101 cset: &RcContourSet,
2102 nvp: i32,
2103 mesh: &mut RcPolyMesh,
2104) -> Result<(), XError> {
2105 let res = unsafe {
2106 ffi::rcBuildPolyMesh(
2107 context.0.pin_mut().get_unchecked_mut() as *mut _,
2108 cset.inner(),
2109 nvp,
2110 mesh.inner_mut(),
2111 )
2112 };
2113 return if res { Ok(()) } else { Err(XError::Failed) };
2114}
2115
2116pub fn rc_merge_poly_meshes(context: &mut RcContext, meshes: &[&RcPolyMesh], mesh: &mut RcPolyMesh) -> bool {
2117 let tmp_meshes: Vec<_> = meshes.iter().map(|m| m.as_ptr()).collect();
2118 unsafe {
2119 return ffi::rcMergePolyMeshes(
2120 context.0.pin_mut().get_unchecked_mut() as *mut _,
2121 tmp_meshes.as_ptr(),
2122 meshes.len() as i32,
2123 mesh.inner_mut(),
2124 );
2125 }
2126}
2127
2128pub fn rc_build_poly_mesh_detail(
2129 context: &mut RcContext,
2130 mesh: &RcPolyMesh,
2131 chf: &RcCompactHeightfield,
2132 sample_dist: f32,
2133 sample_max_error: f32,
2134 dmesh: &mut RcPolyMeshDetail,
2135) -> Result<(), XError> {
2136 let res = unsafe {
2137 ffi::rcBuildPolyMeshDetail(
2138 context.0.pin_mut().get_unchecked_mut() as *mut _,
2139 mesh.inner(),
2140 chf.inner(),
2141 sample_dist,
2142 sample_max_error,
2143 dmesh.inner_mut(),
2144 )
2145 };
2146 return if res { Ok(()) } else { Err(XError::Failed) };
2147}
2148
2149pub fn rc_copy_poly_mesh(context: &mut RcContext, src: &RcPolyMesh, dst: &mut RcPolyMesh) -> Result<(), XError> {
2150 let res = unsafe {
2151 ffi::rcCopyPolyMesh(
2152 context.0.pin_mut().get_unchecked_mut() as *mut _,
2153 src.inner(),
2154 dst.inner_mut(),
2155 )
2156 };
2157 return if res { Ok(()) } else { Err(XError::Failed) };
2158}
2159
2160pub fn rc_merge_poly_mesh_details(
2161 context: &mut RcContext,
2162 meshes: &[&RcPolyMeshDetail],
2163 mesh: &mut RcPolyMeshDetail,
2164) -> bool {
2165 let tmp_meshes: Vec<_> = meshes.iter().map(|m| m.as_ptr()).collect();
2166 unsafe {
2167 return ffi::rcMergePolyMeshDetails(
2168 context.0.pin_mut().get_unchecked_mut() as *mut _,
2169 tmp_meshes.as_ptr(),
2170 meshes.len() as i32,
2171 mesh.inner_mut(),
2172 );
2173 }
2174}