recastnavigation_rs/recast/
recast.rs

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    // Recast log categories.
29    #[repr(u32)]
30    enum rcLogCategory {
31        RC_LOG_PROGRESS = 1,
32        RC_LOG_WARNING,
33        RC_LOG_ERROR,
34    }
35
36    // Recast performance timer categories.
37    #[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        //
80        // enums
81        //
82
83        type rcLogCategory;
84        type rcTimerLabel;
85        type rcBuildContoursFlags;
86
87        //
88        // structs
89        //
90
91        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 log(self: Pin<&mut rcContext>, category: rcLogCategory, format: &str);
96        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        //
138        // functions
139        //
140
141        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
361//
362// RcContext
363//
364
365pub 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//
418// RcConfig
419//
420
421#[repr(C)]
422#[derive(Debug, Default, Clone)]
423pub struct RcConfig {
424    // The width of the field along the x-axis. [Limit: >= 0] [Units: vx]
425    pub width: i32,
426
427    // The height of the field along the z-axis. [Limit: >= 0] [Units: vx]
428    pub height: i32,
429
430    // The width/height size of tile's on the xz-plane. [Limit: >= 0] [Units: vx]
431    pub tile_size: i32,
432
433    // The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx]
434    pub border_size: i32,
435
436    // The xz-plane cell size to use for fields. [Limit: > 0] [Units: wu]
437    pub cs: f32,
438
439    // The y-axis cell size to use for fields. [Limit: > 0] [Units: wu]
440    pub ch: f32,
441
442    // The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu]
443    pub bmin: [f32; 3],
444
445    // The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu]
446    pub bmax: [f32; 3],
447
448    // The maximum slope that is considered walkable. [Limits: 0 <= value < 90] [Units: Degrees]
449    pub walkable_slope_angle: f32,
450
451    // Minimum floor to 'ceiling' height that will still allow the floor area to
452    // be considered walkable. [Limit: >= 3] [Units: vx]
453    pub walkable_height: i32,
454
455    // Maximum ledge height that is considered to still be traversable. [Limit: >=0] [Units: vx]
456    pub walkable_climb: i32,
457
458    // The distance to erode/shrink the walkable area of the heightfield away from
459    // obstructions.  [Limit: >=0] [Units: vx]
460    pub walkable_radius: i32,
461
462    // The maximum allowed length for contour edges along the border of the mesh. [Limit: >=0] [Units: vx]
463    pub max_edge_len: i32,
464
465    // The maximum distance a simplified contour's border edges should deviate
466    // the original raw contour. [Limit: >=0] [Units: vx]
467    pub max_simplification_error: f32,
468
469    // The minimum number of cells allowed to form isolated island areas. [Limit: >=0] [Units: vx]
470    pub min_region_area: i32,
471
472    // Any regions with a span count smaller than this value will, if possible,
473    // be merged with larger regions. [Limit: >=0] [Units: vx]
474    pub merge_region_area: i32,
475
476    // The maximum number of vertices allowed for polygons generated during the
477    // contour to polygon conversion process. [Limit: >= 3]
478    pub max_verts_per_poly: i32,
479
480    // Sets the sampling distance to use when generating the detail mesh.
481    // (For height detail only.) [Limits: 0 or >= 0.9] [Units: wu]
482    pub detail_sample_dist: f32,
483
484    // The maximum distance the detail mesh surface should deviate from heightfield
485    // data. (For height detail only.) [Limit: >=0] [Units: wu]
486    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//
497// RcSpan
498//
499
500#[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//
578// RcSpanPool
579//
580
581#[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//
600// RcHeightfield
601//
602
603#[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//
718// RcCompactCell
719//
720
721#[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//
771// RcCompactSpan
772//
773
774#[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//
828// RcCompactHeightfield
829//
830
831#[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//
984// RcHeightfieldLayer
985//
986
987#[repr(C)]
988#[derive(Debug)]
989pub struct RcHeightfieldLayer {
990    pub bmin: [f32; 3], // The minimum bounds in world space. [(x, y, z)]
991    pub bmax: [f32; 3], // The maximum bounds in world space. [(x, y, z)]
992    pub cs: f32,        // The size of each cell. (On the xz-plane.)
993    pub ch: f32,        // The height of each cell. (The minimum increment along the y-axis.)
994    width: i32,         // The width of the heightfield. (Along the x-axis in cell units.)
995    height: i32,        // The height of the heightfield. (Along the z-axis in cell units.)
996    pub minx: i32,      // The minimum x-bounds of usable data.
997    pub maxx: i32,      // The maximum x-bounds of usable data.
998    pub miny: i32,      // The minimum y-bounds of usable data. (Along the z-axis.)
999    pub maxy: i32,      // The maximum y-bounds of usable data. (Along the z-axis.)
1000    pub hmin: i32,      // The minimum height bounds of usable data. (Along the y-axis.)
1001    pub hmax: i32,      // The maximum height bounds of usable data. (Along the y-axis.)
1002    heights: *mut u8,   // The heightfield. [Size: width * height]
1003    areas: *mut u8,     // Area ids. [Size: Same as #heights]
1004    cons: *mut u8,      // Packed neighbor connection information. [Size: Same as #heights]
1005}
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//
1061// RcHeightfieldLayerSet
1062//
1063
1064#[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//
1153// RcContour
1154//
1155
1156#[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//
1211// RcContourSet
1212//
1213
1214#[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//
1311// RcPolyMesh
1312//
1313
1314#[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//
1471// RcPolyMeshDetail
1472//
1473
1474#[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
1596//
1597// functions
1598//
1599
1600pub 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}