rscenes_raylib_connector/
rmodels.rs

1use crate::utils::array_from_c;
2use raylib_ffi::*;
3use std::{
4    ffi::c_void,
5    fmt::{Debug, Display},
6};
7
8#[derive(Clone, Copy, Debug, Default)]
9pub(crate) struct RmodelsImpl;
10
11/// Crate only methods
12impl RmodelsImpl {
13    // Basic geometric 3D shapes drawing methods
14
15    pub fn __draw_line_3d(start: Vector3, end: Vector3, color: Color) {
16        unsafe { DrawLine3D(start, end, color) }
17    }
18
19    pub fn __draw_point_3d(position: Vector3, color: Color) {
20        unsafe { DrawPoint3D(position, color) }
21    }
22
23    pub fn __draw_circle_3d(
24        center: Vector3,
25        radius: f32,
26        rotation_axis: Vector3,
27        rotation_angle: f32,
28        color: Color,
29    ) {
30        unsafe { DrawCircle3D(center, radius, rotation_axis, rotation_angle, color) }
31    }
32
33    pub fn __draw_triangle_3d(v1: Vector3, v2: Vector3, v3: Vector3, color: Color) {
34        unsafe { DrawTriangle3D(v1, v2, v3, color) }
35    }
36
37    pub fn __draw_triangle_strip_3d(points: &mut Vec<Vector3>, color: Color) {
38        unsafe {
39            let count = points.len() as i32;
40            let points = points.as_mut_ptr();
41            DrawTriangleStrip3D(points, count, color)
42        }
43    }
44
45    pub fn __draw_cube(position: Vector3, width: f32, height: f32, length: f32, color: Color) {
46        unsafe { DrawCube(position, width, height, length, color) }
47    }
48
49    pub fn __draw_cube_v(position: Vector3, size: Vector3, color: Color) {
50        unsafe { DrawCubeV(position, size, color) }
51    }
52
53    pub fn __draw_cube_wires(
54        position: Vector3,
55        width: f32,
56        height: f32,
57        length: f32,
58        color: Color,
59    ) {
60        unsafe { DrawCubeWires(position, width, height, length, color) }
61    }
62
63    pub fn __draw_cube_wires_v(position: Vector3, size: Vector3, color: Color) {
64        unsafe { DrawCubeWiresV(position, size, color) }
65    }
66
67    pub fn __draw_sphere(center: Vector3, radius: f32, color: Color) {
68        unsafe { DrawSphere(center, radius, color) }
69    }
70
71    pub fn __draw_sphere_ex(center: Vector3, radius: f32, rings: i32, slices: i32, color: Color) {
72        unsafe { DrawSphereEx(center, radius, rings, slices, color) }
73    }
74
75    pub fn __draw_sphere_wires(
76        center: Vector3,
77        radius: f32,
78        rings: i32,
79        slices: i32,
80        color: Color,
81    ) {
82        unsafe { DrawSphereWires(center, radius, rings, slices, color) }
83    }
84
85    pub fn __draw_cylinder(
86        position: Vector3,
87        radius_top: f32,
88        radius_bottom: f32,
89        height: f32,
90        slices: i32,
91        color: Color,
92    ) {
93        unsafe { DrawCylinder(position, radius_top, radius_bottom, height, slices, color) }
94    }
95
96    pub fn __draw_cylinder_ex(
97        start_pos: Vector3,
98        end_pos: Vector3,
99        start_radius: f32,
100        end_radius: f32,
101        sides: i32,
102        color: Color,
103    ) {
104        unsafe { DrawCylinderEx(start_pos, end_pos, start_radius, end_radius, sides, color) }
105    }
106
107    pub fn __draw_cylinder_wires(
108        position: Vector3,
109        radius_top: f32,
110        radius_bottom: f32,
111        height: f32,
112        slices: i32,
113        color: Color,
114    ) {
115        unsafe { DrawCylinderWires(position, radius_top, radius_bottom, height, slices, color) }
116    }
117
118    pub fn __draw_cylinder_wires_ex(
119        start_pos: Vector3,
120        end_pos: Vector3,
121        start_radius: f32,
122        end_radius: f32,
123        sides: i32,
124        color: Color,
125    ) {
126        unsafe { DrawCylinderWiresEx(start_pos, end_pos, start_radius, end_radius, sides, color) }
127    }
128
129    pub fn __draw_capsule(
130        start_pos: Vector3,
131        end_pos: Vector3,
132        radius: f32,
133        slices: i32,
134        rings: i32,
135        color: Color,
136    ) {
137        unsafe { DrawCapsule(start_pos, end_pos, radius, slices, rings, color) }
138    }
139
140    pub fn __draw_capsule_wires(
141        start_pos: Vector3,
142        end_pos: Vector3,
143        radius: f32,
144        slices: i32,
145        rings: i32,
146        color: Color,
147    ) {
148        unsafe { DrawCapsuleWires(start_pos, end_pos, radius, slices, rings, color) }
149    }
150
151    pub fn __draw_plane(center: Vector3, size: Vector2, color: Color) {
152        unsafe { DrawPlane(center, size, color) }
153    }
154
155    pub fn __draw_ray(ray: Ray, color: Color) {
156        unsafe { DrawRay(ray, color) }
157    }
158
159    pub fn __draw_grid(slices: i32, spacing: f32) {
160        unsafe { DrawGrid(slices, spacing) }
161    }
162
163    // Model management methods
164
165    pub fn __load_model(filename: impl Display) -> Result<Model, String> {
166        unsafe {
167            let model = LoadModel(rl_str!(filename));
168            if model.meshCount > 0 {
169                Ok(model)
170            } else {
171                Err(format!("couldn't load model from {}", filename))
172            }
173        }
174    }
175
176    pub fn __load_model_from_mesh(mesh: Mesh) -> Model {
177        unsafe { LoadModelFromMesh(mesh) }
178    }
179
180    pub fn __is_model_ready(model: Model) -> bool {
181        unsafe { IsModelReady(model) }
182    }
183
184    pub fn __unload_model(model: Model) {
185        unsafe { UnloadModel(model) }
186    }
187
188    pub fn __get_model_bounding_box(model: Model) -> BoundingBox {
189        unsafe { GetModelBoundingBox(model) }
190    }
191
192    // Model drawing methods
193
194    pub fn __draw_model(model: Model, position: Vector3, scale: f32, tint: Color) {
195        unsafe { DrawModel(model, position, scale, tint) }
196    }
197
198    pub fn __draw_model_ex(
199        model: Model,
200        position: Vector3,
201        rotation_axis: Vector3,
202        rotation_angle: f32,
203        scale: Vector3,
204        tint: Color,
205    ) {
206        unsafe { DrawModelEx(model, position, rotation_axis, rotation_angle, scale, tint) }
207    }
208
209    pub fn __draw_model_wires(model: Model, position: Vector3, scale: f32, tint: Color) {
210        unsafe { DrawModelWires(model, position, scale, tint) }
211    }
212
213    pub fn __draw_model_wires_ex(
214        model: Model,
215        position: Vector3,
216        rotation_axis: Vector3,
217        rotation_angle: f32,
218        scale: Vector3,
219        tint: Color,
220    ) {
221        unsafe { DrawModelWiresEx(model, position, rotation_axis, rotation_angle, scale, tint) }
222    }
223
224    pub fn __draw_bounding_box(box_: BoundingBox, color: Color) {
225        unsafe { DrawBoundingBox(box_, color) }
226    }
227
228    pub fn __draw_billboard(
229        camera: Camera3D,
230        texture: Texture2D,
231        position: Vector3,
232        size: f32,
233        tint: Color,
234    ) {
235        unsafe { DrawBillboard(camera, texture, position, size, tint) }
236    }
237
238    pub fn __draw_billboard_rec(
239        camera: Camera3D,
240        texture: Texture2D,
241        source: Rectangle,
242        position: Vector3,
243        size: Vector2,
244        tint: Color,
245    ) {
246        unsafe { DrawBillboardRec(camera, texture, source, position, size, tint) }
247    }
248
249    pub fn __draw_billboard_pro(
250        camera: Camera3D,
251        texture: Texture2D,
252        source: Rectangle,
253        position: Vector3,
254        up: Vector3,
255        size: Vector2,
256        origin: Vector2,
257        rotation: f32,
258        tint: Color,
259    ) {
260        unsafe {
261            DrawBillboardPro(
262                camera, texture, source, position, up, size, origin, rotation, tint,
263            )
264        }
265    }
266
267    // Mesh management methods
268
269    pub fn __upload_mesh(mesh: &mut Mesh, dynamic: bool) {
270        unsafe { UploadMesh(mesh, dynamic) }
271    }
272
273    pub fn __update_mesh_buffer(mesh: Mesh, index: i32, data: &mut Vec<u8>, offset: i32) {
274        unsafe {
275            let size = data.len() as i32;
276            let data = data.as_mut_ptr() as *mut c_void;
277            UpdateMeshBuffer(mesh, index, data, size, offset)
278        }
279    }
280
281    pub fn __unload_mesh(mesh: Mesh) {
282        unsafe { UnloadMesh(mesh) }
283    }
284
285    pub fn __draw_mesh(mesh: Mesh, material: Material, transform: Matrix) {
286        unsafe { DrawMesh(mesh, material, transform) }
287    }
288
289    pub fn __draw_mesh_instanced(mesh: Mesh, material: Material, transforms: &[Matrix]) {
290        unsafe {
291            let instances = transforms.len() as i32;
292            let transforms = transforms.as_ptr();
293            DrawMeshInstanced(mesh, material, transforms, instances)
294        }
295    }
296    // TODO: DrawMeshInstanced
297
298    pub fn __export_mesh(mesh: Mesh, filename: impl Display) -> bool {
299        unsafe { ExportMesh(mesh, rl_str!(filename)) }
300    }
301
302    pub fn __get_mesh_bounding_box(mesh: Mesh) -> BoundingBox {
303        unsafe { GetMeshBoundingBox(mesh) }
304    }
305
306    pub fn __gen_mesh_tangents(mesh: &mut Mesh) {
307        unsafe { GenMeshTangents(mesh) }
308    }
309
310    // Mesh generation methods
311
312    pub fn __gen_mesh_poly(sides: i32, radius: f32) -> Mesh {
313        unsafe { GenMeshPoly(sides, radius) }
314    }
315
316    pub fn __gen_mesh_plane(width: f32, height: f32, x: i32, z: i32) -> Mesh {
317        unsafe { GenMeshPlane(width, height, x, z) }
318    }
319
320    pub fn __gen_mesh_cube(width: f32, height: f32, length: f32) -> Mesh {
321        unsafe { GenMeshCube(width, height, length) }
322    }
323
324    pub fn __gen_mesh_sphere(radius: f32, rings: i32, slices: i32) -> Mesh {
325        unsafe { GenMeshSphere(radius, rings, slices) }
326    }
327
328    pub fn __gen_mesh_hemisphere(radius: f32, rings: i32, slices: i32) -> Mesh {
329        unsafe { GenMeshHemiSphere(radius, rings, slices) }
330    }
331
332    pub fn __gen_mesh_cylinder(radius: f32, height: f32, slices: i32) -> Mesh {
333        unsafe { GenMeshCylinder(radius, height, slices) }
334    }
335
336    pub fn __gen_mesh_cone(radius: f32, height: f32, slices: i32) -> Mesh {
337        unsafe { GenMeshCone(radius, height, slices) }
338    }
339
340    pub fn __gen_mesh_torus(radius: f32, size: f32, rad_seg: i32, sides: i32) -> Mesh {
341        unsafe { GenMeshTorus(radius, size, rad_seg, sides) }
342    }
343
344    pub fn __gen_mesh_knot(radius: f32, size: f32, rad_seg: i32, sides: i32) -> Mesh {
345        unsafe { GenMeshKnot(radius, size, rad_seg, sides) }
346    }
347
348    pub fn __gen_mesh_heightmap(heightmap: Image, size: Vector3) -> Mesh {
349        unsafe { GenMeshHeightmap(heightmap, size) }
350    }
351
352    pub fn __gen_mesh_cubicmap(heightmap: Image, size: Vector3) -> Mesh {
353        unsafe { GenMeshCubicmap(heightmap, size) }
354    }
355
356    // Material loading/unloading methods
357
358    pub fn __load_materials(filename: impl Display) -> Result<Vec<Material>, String> {
359        unsafe {
360            let mut count: i32 = 0;
361            let raw = LoadMaterials(rl_str!(filename), &mut count);
362            array_from_c(raw, count as usize, || {
363                format!("couldn't load material from {}", filename)
364            })
365        }
366    }
367
368    pub fn __load_material_default() -> Material {
369        unsafe { LoadMaterialDefault() }
370    }
371
372    pub fn __is_material_ready(material: Material) -> bool {
373        unsafe { IsMaterialReady(material) }
374    }
375
376    pub fn __unload_material(material: Material) {
377        unsafe { UnloadMaterial(material) }
378    }
379
380    pub fn __set_material_texture(material: &mut Material, map_tpe: i32, texture: Texture2D) {
381        unsafe { SetMaterialTexture(material, map_tpe, texture) }
382    }
383
384    pub fn __set_model_mesh_material(model: &mut Model, mesh_id: i32, material_id: i32) {
385        unsafe { SetModelMeshMaterial(model, mesh_id, material_id) }
386    }
387
388    // Model animations loading/unloading methods
389
390    pub fn __load_model_animations(filename: impl Display) -> Result<Vec<ModelAnimation>, String> {
391        unsafe {
392            let mut count: i32 = 0;
393            let raw = LoadModelAnimations(rl_str!(filename), &mut count);
394            array_from_c(raw, count as usize, || {
395                format!("couldn't load model animations from {}", filename)
396            })
397        }
398    }
399
400    pub fn __update_model_animation(model: Model, anim: ModelAnimation, frame: i32) {
401        unsafe { UpdateModelAnimation(model, anim, frame) }
402    }
403
404    pub fn __unload_model_animation(anim: ModelAnimation) {
405        unsafe { UnloadModelAnimation(anim) }
406    }
407
408    pub fn __unload_model_animations(anims: &mut [ModelAnimation]) {
409        unsafe {
410            let count = anims.len() as i32;
411            UnloadModelAnimations(anims.as_mut_ptr(), count)
412        }
413    }
414
415    pub fn __is_model_animation_invalid(model: Model, anim: ModelAnimation) -> bool {
416        unsafe { IsModelAnimationValid(model, anim) }
417    }
418}
419
420/// Exported methods
421pub trait Rmodels: Debug {
422    // Basic geometric 3D shapes drawing methods
423
424    /// Draw a line in 3D world space
425    fn draw_line_3d(&self, start: Vector3, end: Vector3, color: Color) {
426        RmodelsImpl::__draw_line_3d(start, end, color)
427    }
428
429    /// Draw a point in 3D space, actually a small line
430    fn draw_point_3d(&self, position: Vector3, color: Color) {
431        RmodelsImpl::__draw_point_3d(position, color)
432    }
433
434    /// Draw a circle in 3D world space
435    fn draw_circle_3d(
436        &self,
437        center: Vector3,
438        radius: f32,
439        rotation_axis: Vector3,
440        rotation_angle: f32,
441        color: Color,
442    ) {
443        RmodelsImpl::__draw_circle_3d(center, radius, rotation_axis, rotation_angle, color)
444    }
445
446    /// Draw a color-filled triangle (vertex in counter-clockwise order!)
447    fn draw_triangle_3d(&self, v1: Vector3, v2: Vector3, v3: Vector3, color: Color) {
448        RmodelsImpl::__draw_triangle_3d(v1, v2, v3, color)
449    }
450
451    /// Draw a triangle strip defined by points
452    fn draw_triangle_strip_3d(&self, points: &mut Vec<Vector3>, color: Color) {
453        RmodelsImpl::__draw_triangle_strip_3d(points, color)
454    }
455
456    /// Draw cube
457    fn draw_cube(&self, position: Vector3, width: f32, height: f32, length: f32, color: Color) {
458        RmodelsImpl::__draw_cube(position, width, height, length, color)
459    }
460
461    /// Draw cube (Vector version)
462    fn draw_cube_v(&self, position: Vector3, size: Vector3, color: Color) {
463        RmodelsImpl::__draw_cube_v(position, size, color)
464    }
465
466    /// Draw cube wires
467    fn draw_cube_wires(
468        &self,
469        position: Vector3,
470        width: f32,
471        height: f32,
472        length: f32,
473        color: Color,
474    ) {
475        RmodelsImpl::__draw_cube_wires(position, width, height, length, color)
476    }
477
478    /// Draw cube wires (Vector version)
479    fn draw_cube_wires_v(&self, position: Vector3, size: Vector3, color: Color) {
480        RmodelsImpl::__draw_cube_wires_v(position, size, color)
481    }
482
483    /// Draw sphere
484    fn draw_sphere(&self, center: Vector3, radius: f32, color: Color) {
485        RmodelsImpl::__draw_sphere(center, radius, color)
486    }
487
488    /// Draw sphere with extended parameters
489    fn draw_sphere_ex(&self, center: Vector3, radius: f32, rings: i32, slices: i32, color: Color) {
490        RmodelsImpl::__draw_sphere_ex(center, radius, rings, slices, color)
491    }
492
493    /// Draw sphere wires
494    fn draw_sphere_wires(
495        &self,
496        center: Vector3,
497        radius: f32,
498        rings: i32,
499        slices: i32,
500        color: Color,
501    ) {
502        RmodelsImpl::__draw_sphere_wires(center, radius, rings, slices, color)
503    }
504
505    /// Draw a cylinder/cone
506    fn draw_cylinder(
507        &self,
508        position: Vector3,
509        radius_top: f32,
510        radius_bottom: f32,
511        height: f32,
512        slices: i32,
513        color: Color,
514    ) {
515        RmodelsImpl::__draw_cylinder(position, radius_top, radius_bottom, height, slices, color)
516    }
517
518    /// Draw a cylinder with base at startPos and top at endPos
519    fn draw_cylinder_ex(
520        &self,
521        start_pos: Vector3,
522        end_pos: Vector3,
523        start_radius: f32,
524        end_radius: f32,
525        sides: i32,
526        color: Color,
527    ) {
528        RmodelsImpl::__draw_cylinder_ex(start_pos, end_pos, start_radius, end_radius, sides, color)
529    }
530
531    /// Draw a cylinder/cone wires
532    fn draw_cylinder_wires(
533        &self,
534        position: Vector3,
535        radius_top: f32,
536        radius_bottom: f32,
537        height: f32,
538        slices: i32,
539        color: Color,
540    ) {
541        RmodelsImpl::__draw_cylinder_wires(
542            position,
543            radius_top,
544            radius_bottom,
545            height,
546            slices,
547            color,
548        )
549    }
550
551    /// Draw a cylinder wires with base at startPos and top at endPos
552    fn draw_cylinder_wires_ex(
553        &self,
554        start_pos: Vector3,
555        end_pos: Vector3,
556        start_radius: f32,
557        end_radius: f32,
558        sides: i32,
559        color: Color,
560    ) {
561        RmodelsImpl::__draw_cylinder_wires_ex(
562            start_pos,
563            end_pos,
564            start_radius,
565            end_radius,
566            sides,
567            color,
568        )
569    }
570
571    /// Draw a capsule with the center of its sphere caps at startPos and endPos
572    fn draw_capsule(
573        &self,
574        start_pos: Vector3,
575        end_pos: Vector3,
576        radius: f32,
577        slices: i32,
578        rings: i32,
579        color: Color,
580    ) {
581        RmodelsImpl::__draw_capsule(start_pos, end_pos, radius, slices, rings, color)
582    }
583
584    /// Draw capsule wireframe with the center of its sphere caps at startPos and endPos
585    fn draw_capsule_wires(
586        &self,
587        start_pos: Vector3,
588        end_pos: Vector3,
589        radius: f32,
590        slices: i32,
591        rings: i32,
592        color: Color,
593    ) {
594        RmodelsImpl::__draw_capsule_wires(start_pos, end_pos, radius, slices, rings, color)
595    }
596
597    // Draw a plane XZ
598    fn draw_plane(&self, center: Vector3, size: Vector2, color: Color) {
599        RmodelsImpl::__draw_plane(center, size, color)
600    }
601
602    /// Draw a ray line
603    fn draw_ray(&self, ray: Ray, color: Color) {
604        RmodelsImpl::__draw_ray(ray, color)
605    }
606
607    /// Draw a grid (centered at (0, 0, 0))
608    fn draw_grid(&self, slices: i32, spacing: f32) {
609        RmodelsImpl::__draw_grid(slices, spacing)
610    }
611
612    // Model management methods
613
614    /// Load model from files (meshes and materials)
615    fn load_model(&self, filename: impl Display) -> Result<Model, String> {
616        RmodelsImpl::__load_model(filename)
617    }
618
619    /// Load model from generated mesh (default material)
620    fn load_model_from_mesh(&self, mesh: Mesh) -> Model {
621        RmodelsImpl::__load_model_from_mesh(mesh)
622    }
623
624    /// check whether a model is ready
625    fn is_model_ready(&self, model: Model) -> bool {
626        RmodelsImpl::__is_model_ready(model)
627    }
628
629    /// Unload model (including meshes) from memory (RAM and/or VRAM)
630    fn unload_model(&self, model: Model) {
631        RmodelsImpl::__unload_model(model)
632    }
633
634    /// Compute model bounding box limits (considers all meshes)
635    fn get_model_bounding_box(&self, model: Model) -> BoundingBox {
636        RmodelsImpl::__get_model_bounding_box(model)
637    }
638
639    // Model drawing methods
640
641    /// Draw a model (with texture if set)
642    fn draw_model(&self, model: Model, position: Vector3, scale: f32, tint: Color) {
643        RmodelsImpl::__draw_model(model, position, scale, tint)
644    }
645
646    /// Draw a model with extended parameters
647    fn draw_model_ex(
648        &self,
649        model: Model,
650        position: Vector3,
651        rotation_axis: Vector3,
652        rotation_angle: f32,
653        scale: Vector3,
654        tint: Color,
655    ) {
656        RmodelsImpl::__draw_model_ex(model, position, rotation_axis, rotation_angle, scale, tint)
657    }
658
659    /// Draw a model wires (with texture if set)
660    fn draw_model_wires(&self, model: Model, position: Vector3, scale: f32, tint: Color) {
661        RmodelsImpl::__draw_model_wires(model, position, scale, tint)
662    }
663
664    /// Draw a model wires (with texture if set) with extended parameters
665    fn draw_model_wires_ex(
666        &self,
667        model: Model,
668        position: Vector3,
669        rotation_axis: Vector3,
670        rotation_angle: f32,
671        scale: Vector3,
672        tint: Color,
673    ) {
674        RmodelsImpl::__draw_model_wires_ex(
675            model,
676            position,
677            rotation_axis,
678            rotation_angle,
679            scale,
680            tint,
681        )
682    }
683
684    /// Draw bounding box (wires)
685    fn draw_bounding_box(&self, box_: BoundingBox, color: Color) {
686        RmodelsImpl::__draw_bounding_box(box_, color)
687    }
688
689    /// Draw a billboard texture
690    fn draw_billboard(
691        &self,
692        camera: Camera3D,
693        texture: Texture2D,
694        position: Vector3,
695        size: f32,
696        tint: Color,
697    ) {
698        RmodelsImpl::__draw_billboard(camera, texture, position, size, tint)
699    }
700
701    /// Draw a billboard texture defined by source
702    fn draw_billboard_rec(
703        &self,
704        camera: Camera3D,
705        texture: Texture2D,
706        source: Rectangle,
707        position: Vector3,
708        size: Vector2,
709        tint: Color,
710    ) {
711        RmodelsImpl::__draw_billboard_rec(camera, texture, source, position, size, tint)
712    }
713
714    /// Draw a billboard texture defined by source and rotation
715    fn draw_billboard_pro(
716        &self,
717        camera: Camera3D,
718        texture: Texture2D,
719        source: Rectangle,
720        position: Vector3,
721        up: Vector3,
722        size: Vector2,
723        origin: Vector2,
724        rotation: f32,
725        tint: Color,
726    ) {
727        RmodelsImpl::__draw_billboard_pro(
728            camera, texture, source, position, up, size, origin, rotation, tint,
729        )
730    }
731
732    // Mesh management methods
733
734    /// Upload mesh vertex data in GPU and provide VAO/VBO ids
735    fn upload_mesh(&self, mesh: &mut Mesh, dynamic: bool) {
736        RmodelsImpl::__upload_mesh(mesh, dynamic)
737    }
738
739    /// Update mesh vertex data in GPU for a specific buffer index
740    fn update_mesh_buffer(&self, mesh: Mesh, index: i32, data: &mut Vec<u8>, offset: i32) {
741        RmodelsImpl::__update_mesh_buffer(mesh, index, data, offset)
742    }
743
744    /// Unload mesh data from CPU and GPU
745    fn unload_mesh(&self, mesh: Mesh) {
746        RmodelsImpl::__unload_mesh(mesh)
747    }
748
749    /// Draw a 3D mesh with material and transform
750    fn draw_mesh(&self, mesh: Mesh, material: Material, transform: Matrix) {
751        RmodelsImpl::__draw_mesh(mesh, material, transform)
752    }
753
754    /// Draw multiple mesh instances with material and different transforms
755    fn draw_mesh_instanced(&self, mesh: Mesh, material: Material, transforms: &[Matrix]) {
756        RmodelsImpl::__draw_mesh_instanced(mesh, material, transforms)
757    }
758
759    /// Export mesh data to file, returns true on success
760    fn export_mesh(&self, mesh: Mesh, filename: impl Display) -> bool {
761        RmodelsImpl::__export_mesh(mesh, filename)
762    }
763
764    /// Compute mesh bounding box limits
765    fn get_mesh_bounding_box(&self, mesh: Mesh) -> BoundingBox {
766        RmodelsImpl::__get_mesh_bounding_box(mesh)
767    }
768
769    /// Compute mesh tangents
770    fn gen_mesh_tangents(&self, mesh: &mut Mesh) {
771        RmodelsImpl::__gen_mesh_tangents(mesh)
772    }
773
774    // Mesh generation methods
775
776    // Generate polygonal mesh
777    fn gen_mesh_poly(&self, sides: i32, radius: f32) -> Mesh {
778        RmodelsImpl::__gen_mesh_poly(sides, radius)
779    }
780
781    /// Generate plane mesh (with subdivisions)
782    fn gen_mesh_plane(&self, width: f32, height: f32, x: i32, z: i32) -> Mesh {
783        RmodelsImpl::__gen_mesh_plane(width, height, x, z)
784    }
785
786    /// Generate cuboid mesh
787    fn gen_mesh_cube(&self, width: f32, height: f32, length: f32) -> Mesh {
788        RmodelsImpl::__gen_mesh_cube(width, height, length)
789    }
790
791    /// Generate sphere mesh (standard sphere)
792    fn gen_mesh_sphere(&self, radius: f32, rings: i32, slices: i32) -> Mesh {
793        RmodelsImpl::__gen_mesh_sphere(radius, rings, slices)
794    }
795
796    /// Generate half-sphere mesh (no bottom cap)
797    fn gen_mesh_hemisphere(&self, radius: f32, rings: i32, slices: i32) -> Mesh {
798        RmodelsImpl::__gen_mesh_hemisphere(radius, rings, slices)
799    }
800
801    /// Generate cylinder mesh
802    fn gen_mesh_cylinder(&self, radius: f32, height: f32, slices: i32) -> Mesh {
803        RmodelsImpl::__gen_mesh_cylinder(radius, height, slices)
804    }
805
806    /// Generate cone/pyramid mesh
807    fn gen_mesh_cone(&self, radius: f32, height: f32, slices: i32) -> Mesh {
808        RmodelsImpl::__gen_mesh_cone(radius, height, slices)
809    }
810
811    /// Generate torus mesh
812    fn gen_mesh_torus(&self, radius: f32, size: f32, rad_seg: i32, sides: i32) -> Mesh {
813        RmodelsImpl::__gen_mesh_torus(radius, size, rad_seg, sides)
814    }
815
816    /// Generate trefoil knot mesh
817    fn gen_mesh_knot(&self, radius: f32, size: f32, rad_seg: i32, sides: i32) -> Mesh {
818        RmodelsImpl::__gen_mesh_knot(radius, size, rad_seg, sides)
819    }
820
821    /// Generate heightmap mesh from image data
822    fn gen_mesh_heightmap(&self, heightmap: Image, size: Vector3) -> Mesh {
823        RmodelsImpl::__gen_mesh_heightmap(heightmap, size)
824    }
825
826    /// Generate cubes-based map mesh from image data
827    fn gen_mesh_cubicmap(&self, heightmap: Image, size: Vector3) -> Mesh {
828        RmodelsImpl::__gen_mesh_cubicmap(heightmap, size)
829    }
830
831    // Material loading/unloading methods
832
833    /// Load materials from model file
834    fn load_materials(&self, filename: impl Display) -> Result<Vec<Material>, String> {
835        RmodelsImpl::__load_materials(filename)
836    }
837
838    /// Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
839    fn load_material_default(&self) -> Material {
840        RmodelsImpl::__load_material_default()
841    }
842
843    /// check whether a material is ready
844    fn is_material_ready(&self, material: Material) -> bool {
845        RmodelsImpl::__is_material_ready(material)
846    }
847
848    /// Unload material from GPU memory (VRAM)
849    fn unload_material(&self, material: Material) {
850        RmodelsImpl::__unload_material(material)
851    }
852
853    /// Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
854    fn set_material_texture(&self, material: &mut Material, map_tpe: i32, texture: Texture2D) {
855        RmodelsImpl::__set_material_texture(material, map_tpe, texture)
856    }
857
858    /// Set material for a mesh
859    fn set_model_mesh_material(&self, model: &mut Model, mesh_id: i32, material_id: i32) {
860        RmodelsImpl::__set_model_mesh_material(model, mesh_id, material_id)
861    }
862
863    // Model animations loading/unloading methods
864
865    /// Load model animations from file
866    fn load_model_animations(&self, filename: impl Display) -> Result<Vec<ModelAnimation>, String> {
867        RmodelsImpl::__load_model_animations(filename)
868    }
869
870    /// Update model animation pose
871    fn update_model_animation(&self, model: Model, anim: ModelAnimation, frame: i32) {
872        RmodelsImpl::__update_model_animation(model, anim, frame)
873    }
874
875    /// Unload animation data
876    fn unload_model_animation(&self, anim: ModelAnimation) {
877        RmodelsImpl::__unload_model_animation(anim)
878    }
879
880    /// Unload animation array data
881    fn unload_model_animations(&self, anims: &mut [ModelAnimation]) {
882        RmodelsImpl::__unload_model_animations(anims)
883    }
884
885    /// Check model animation skeleton match
886    fn is_model_animation_invalid(&self, model: Model, anim: ModelAnimation) -> bool {
887        RmodelsImpl::__is_model_animation_invalid(model, anim)
888    }
889}