// Re-export passthrough functions from internal FFI layer
///|
pub using @ffi {
type Model,
type Mesh,
type Material,
type ModelAnimations,
unload_model,
draw_grid,
is_model_valid,
// Mesh generation (passthrough)
gen_mesh_poly,
gen_mesh_plane,
gen_mesh_cube,
gen_mesh_sphere,
gen_mesh_hemisphere,
gen_mesh_cylinder,
gen_mesh_cone,
gen_mesh_torus,
gen_mesh_knot,
// Mesh utilities (passthrough)
unload_mesh,
upload_mesh,
gen_mesh_tangents,
load_model_from_mesh,
// Material (passthrough)
load_material_default,
is_material_valid,
unload_material,
set_material_texture,
set_material_shader,
set_model_mesh_material,
// Model animations (passthrough)
model_animations_count,
update_model_animation,
update_model_animation_bones,
is_model_animation_valid,
unload_model_animations,
}
// ============================================================================
// 3D shape drawing (wrappers)
// ============================================================================
///|
pub fn draw_line_3d(
start_pos : Vector3,
end_pos : Vector3,
color : Color,
) -> Unit {
@ffi.draw_line_3d(start_pos.to_bytes(), end_pos.to_bytes(), color.to_bytes())
}
///|
pub fn draw_point_3d(position : Vector3, color : Color) -> Unit {
@ffi.draw_point_3d(position.to_bytes(), color.to_bytes())
}
///|
pub fn draw_circle_3d(
center : Vector3,
radius : Float,
rot_axis : Vector3,
rot_angle : Float,
color : Color,
) -> Unit {
@ffi.draw_circle_3d(
center.to_bytes(),
radius,
rot_axis.to_bytes(),
rot_angle,
color.to_bytes(),
)
}
///|
pub fn draw_cube(
position : Vector3,
width : Float,
height : Float,
length : Float,
color : Color,
) -> Unit {
@ffi.draw_cube(position.to_bytes(), width, height, length, color.to_bytes())
}
///|
pub fn draw_cube_v(position : Vector3, size : Vector3, color : Color) -> Unit {
@ffi.draw_cube_v(position.to_bytes(), size.to_bytes(), color.to_bytes())
}
///|
pub fn draw_cube_wires(
position : Vector3,
width : Float,
height : Float,
length : Float,
color : Color,
) -> Unit {
@ffi.draw_cube_wires(
position.to_bytes(),
width,
height,
length,
color.to_bytes(),
)
}
///|
pub fn draw_cube_wires_v(
position : Vector3,
size : Vector3,
color : Color,
) -> Unit {
@ffi.draw_cube_wires_v(position.to_bytes(), size.to_bytes(), color.to_bytes())
}
///|
pub fn draw_sphere(center : Vector3, radius : Float, color : Color) -> Unit {
@ffi.draw_sphere(center.to_bytes(), radius, color.to_bytes())
}
///|
pub fn draw_sphere_ex(
center : Vector3,
radius : Float,
rings : Int,
slices : Int,
color : Color,
) -> Unit {
@ffi.draw_sphere_ex(
center.to_bytes(),
radius,
rings,
slices,
color.to_bytes(),
)
}
///|
pub fn draw_sphere_wires(
center : Vector3,
radius : Float,
rings : Int,
slices : Int,
color : Color,
) -> Unit {
@ffi.draw_sphere_wires(
center.to_bytes(),
radius,
rings,
slices,
color.to_bytes(),
)
}
///|
pub fn draw_cylinder(
position : Vector3,
radius_top : Float,
radius_bottom : Float,
height : Float,
slices : Int,
color : Color,
) -> Unit {
@ffi.draw_cylinder(
position.to_bytes(),
radius_top,
radius_bottom,
height,
slices,
color.to_bytes(),
)
}
///|
pub fn draw_cylinder_wires(
position : Vector3,
radius_top : Float,
radius_bottom : Float,
height : Float,
slices : Int,
color : Color,
) -> Unit {
@ffi.draw_cylinder_wires(
position.to_bytes(),
radius_top,
radius_bottom,
height,
slices,
color.to_bytes(),
)
}
///|
pub fn draw_triangle_3d(
v1 : Vector3,
v2 : Vector3,
v3 : Vector3,
color : Color,
) -> Unit {
@ffi.draw_triangle_3d(
v1.to_bytes(),
v2.to_bytes(),
v3.to_bytes(),
color.to_bytes(),
)
}
///|
pub fn draw_cylinder_ex(
start_pos : Vector3,
end_pos : Vector3,
start_radius : Float,
end_radius : Float,
sides : Int,
color : Color,
) -> Unit {
@ffi.draw_cylinder_ex(
start_pos.to_bytes(),
end_pos.to_bytes(),
start_radius,
end_radius,
sides,
color.to_bytes(),
)
}
///|
pub fn draw_cylinder_wires_ex(
start_pos : Vector3,
end_pos : Vector3,
start_radius : Float,
end_radius : Float,
sides : Int,
color : Color,
) -> Unit {
@ffi.draw_cylinder_wires_ex(
start_pos.to_bytes(),
end_pos.to_bytes(),
start_radius,
end_radius,
sides,
color.to_bytes(),
)
}
///|
pub fn draw_capsule(
start_pos : Vector3,
end_pos : Vector3,
radius : Float,
slices : Int,
rings : Int,
color : Color,
) -> Unit {
@ffi.draw_capsule(
start_pos.to_bytes(),
end_pos.to_bytes(),
radius,
slices,
rings,
color.to_bytes(),
)
}
///|
pub fn draw_capsule_wires(
start_pos : Vector3,
end_pos : Vector3,
radius : Float,
slices : Int,
rings : Int,
color : Color,
) -> Unit {
@ffi.draw_capsule_wires(
start_pos.to_bytes(),
end_pos.to_bytes(),
radius,
slices,
rings,
color.to_bytes(),
)
}
///|
pub fn draw_plane(center : Vector3, size : Vector2, color : Color) -> Unit {
@ffi.draw_plane(center.to_bytes(), size.to_bytes(), color.to_bytes())
}
///|
pub fn draw_ray(ray : Ray, color : Color) -> Unit {
@ffi.draw_ray(ray.to_bytes(), color.to_bytes())
}
///|
pub fn draw_bounding_box(box_ : BoundingBox, color : Color) -> Unit {
@ffi.draw_bounding_box(box_.to_bytes(), color.to_bytes())
}
// ============================================================================
// Model loading (wrappers)
// ============================================================================
///|
pub fn load_model(file_name : String) -> Model {
@ffi.load_model(@utf8.encode(file_name))
}
///|
pub fn draw_model(
model : Model,
position : Vector3,
scale : Float,
tint : Color,
) -> Unit {
@ffi.draw_model(model, position.to_bytes(), scale, tint.to_bytes())
}
///|
pub fn draw_model_ex(
model : Model,
position : Vector3,
rotation_axis : Vector3,
rotation_angle : Float,
scale : Vector3,
tint : Color,
) -> Unit {
@ffi.draw_model_ex(
model,
position.to_bytes(),
rotation_axis.to_bytes(),
rotation_angle,
scale.to_bytes(),
tint.to_bytes(),
)
}
///|
pub fn draw_model_wires(
model : Model,
position : Vector3,
scale : Float,
tint : Color,
) -> Unit {
@ffi.draw_model_wires(model, position.to_bytes(), scale, tint.to_bytes())
}
///|
pub fn draw_model_wires_ex(
model : Model,
position : Vector3,
rotation_axis : Vector3,
rotation_angle : Float,
scale : Vector3,
tint : Color,
) -> Unit {
@ffi.draw_model_wires_ex(
model,
position.to_bytes(),
rotation_axis.to_bytes(),
rotation_angle,
scale.to_bytes(),
tint.to_bytes(),
)
}
///|
pub fn draw_model_points(
model : Model,
position : Vector3,
scale : Float,
tint : Color,
) -> Unit {
@ffi.draw_model_points(model, position.to_bytes(), scale, tint.to_bytes())
}
///|
pub fn draw_model_points_ex(
model : Model,
position : Vector3,
rotation_axis : Vector3,
rotation_angle : Float,
scale : Vector3,
tint : Color,
) -> Unit {
@ffi.draw_model_points_ex(
model,
position.to_bytes(),
rotation_axis.to_bytes(),
rotation_angle,
scale.to_bytes(),
tint.to_bytes(),
)
}
// ============================================================================
// Model material shader (wrappers)
// ============================================================================
///|
pub fn set_model_material_shader(
model : Model,
material_index : Int,
shader : Shader,
) -> Unit {
@ffi.set_model_material_shader(model, material_index, shader)
}
// ============================================================================
// Model management (wrappers)
// ============================================================================
///|
pub fn get_model_bounding_box(model : Model) -> BoundingBox {
BoundingBox::from_bytes(@ffi.get_model_bounding_box(model))
}
// ============================================================================
// Model material texture (wrappers)
// ============================================================================
///|
pub fn set_model_material_texture(
model : Model,
material_index : Int,
map_type : Int,
texture : Texture,
) -> Unit {
@ffi.set_model_material_texture(model, material_index, map_type, texture)
}
// ============================================================================
// Billboard drawing (wrappers)
// ============================================================================
///|
pub fn draw_billboard(
camera : Camera3D,
texture : Texture,
position : Vector3,
scale : Float,
tint : Color,
) -> Unit {
@ffi.draw_billboard(
camera.to_bytes(),
texture,
position.to_bytes(),
scale,
tint.to_bytes(),
)
}
///|
pub fn draw_billboard_rec(
camera : Camera3D,
texture : Texture,
source : Rectangle,
position : Vector3,
size : Vector2,
tint : Color,
) -> Unit {
@ffi.draw_billboard_rec(
camera.to_bytes(),
texture,
source.to_bytes(),
position.to_bytes(),
size.to_bytes(),
tint.to_bytes(),
)
}
///|
pub fn draw_billboard_pro(
camera : Camera3D,
texture : Texture,
source : Rectangle,
position : Vector3,
up : Vector3,
size : Vector2,
origin : Vector2,
rotation : Float,
tint : Color,
) -> Unit {
@ffi.draw_billboard_pro(
camera.to_bytes(),
texture,
source.to_bytes(),
position.to_bytes(),
up.to_bytes(),
size.to_bytes(),
origin.to_bytes(),
rotation,
tint.to_bytes(),
)
}
// ============================================================================
// 3D collision detection (wrappers)
// ============================================================================
///|
pub fn check_collision_spheres(
center1 : Vector3,
radius1 : Float,
center2 : Vector3,
radius2 : Float,
) -> Bool {
@ffi.check_collision_spheres(
center1.to_bytes(),
radius1,
center2.to_bytes(),
radius2,
)
}
///|
pub fn check_collision_boxes(box1 : BoundingBox, box2 : BoundingBox) -> Bool {
@ffi.check_collision_boxes(box1.to_bytes(), box2.to_bytes())
}
///|
pub fn check_collision_box_sphere(
box_ : BoundingBox,
center : Vector3,
radius : Float,
) -> Bool {
@ffi.check_collision_box_sphere(box_.to_bytes(), center.to_bytes(), radius)
}
///|
pub fn get_ray_collision_sphere(
ray : Ray,
center : Vector3,
radius : Float,
) -> RayCollision {
RayCollision::from_bytes(
@ffi.get_ray_collision_sphere(ray.to_bytes(), center.to_bytes(), radius),
)
}
///|
pub fn get_ray_collision_box(ray : Ray, box_ : BoundingBox) -> RayCollision {
RayCollision::from_bytes(
@ffi.get_ray_collision_box(ray.to_bytes(), box_.to_bytes()),
)
}
///|
pub fn get_ray_collision_triangle(
ray : Ray,
p1 : Vector3,
p2 : Vector3,
p3 : Vector3,
) -> RayCollision {
RayCollision::from_bytes(
@ffi.get_ray_collision_triangle(
ray.to_bytes(),
p1.to_bytes(),
p2.to_bytes(),
p3.to_bytes(),
),
)
}
// ============================================================================
// Mesh generation (wrappers)
// ============================================================================
///|
pub fn gen_mesh_heightmap(heightmap : Image, size : Vector3) -> Mesh {
@ffi.gen_mesh_heightmap(heightmap, size.to_bytes())
}
///|
pub fn gen_mesh_cubicmap(cubicmap : Image, cube_size : Vector3) -> Mesh {
@ffi.gen_mesh_cubicmap(cubicmap, cube_size.to_bytes())
}
// ============================================================================
// Mesh utilities (wrappers)
// ============================================================================
///|
pub fn get_mesh_bounding_box(mesh : Mesh) -> BoundingBox {
BoundingBox::from_bytes(@ffi.get_mesh_bounding_box(mesh))
}
///|
pub fn export_mesh(mesh : Mesh, file_name : String) -> Bool {
@ffi.export_mesh(mesh, @utf8.encode(file_name))
}
///|
pub fn get_ray_collision_mesh(
ray : Ray,
mesh : Mesh,
transform : Matrix,
) -> RayCollision {
RayCollision::from_bytes(
@ffi.get_ray_collision_mesh(ray.to_bytes(), mesh, transform.to_bytes()),
)
}
// ============================================================================
// Mesh drawing (wrappers)
// ============================================================================
///|
pub fn draw_mesh(mesh : Mesh, material : Material, transform : Matrix) -> Unit {
@ffi.draw_mesh(mesh, material, transform.to_bytes())
}
///|
pub fn draw_mesh_instanced(
mesh : Mesh,
material : Material,
transforms : Array[Matrix],
instances : Int,
) -> Unit {
let arr = FixedArray::make(instances * 64, b'\x00')
for i in 0.. Unit {
@ffi.set_material_map_color(material, map_type, color.to_bytes())
}
///|
pub fn set_material_map_value(
material : Material,
map_type : Int,
value : Float,
) -> Unit {
@ffi.set_material_map_value(material, map_type, value)
}
// ============================================================================
// Model animations (wrappers)
// ============================================================================
///|
pub fn load_model_animations(file_name : String) -> ModelAnimations {
@ffi.load_model_animations(@utf8.encode(file_name))
}
// ============================================================================
// Ray collision: quad (wrapper)
// ============================================================================
///|
pub fn get_ray_collision_quad(
ray : Ray,
p1 : Vector3,
p2 : Vector3,
p3 : Vector3,
p4 : Vector3,
) -> RayCollision {
RayCollision::from_bytes(
@ffi.get_ray_collision_quad(
ray.to_bytes(),
p1.to_bytes(),
p2.to_bytes(),
p3.to_bytes(),
p4.to_bytes(),
),
)
}
// ============================================================================
// Mesh: Export as code (wrappers)
// ============================================================================
///|
pub fn export_mesh_as_code(mesh : Mesh, file_name : String) -> Bool {
@ffi.export_mesh_as_code(mesh, @utf8.encode(file_name))
}
// ============================================================================
// Mesh: UpdateMeshBuffer (re-export)
// ============================================================================
///|
pub using @ffi {update_mesh_buffer}
// ============================================================================
// LoadMaterials (wrappers)
// ============================================================================
///|
pub using @ffi {
type MaterialsArray,
unload_materials_array,
materials_array_count,
materials_array_get,
}
///|
pub fn load_materials(file_name : String) -> MaterialsArray {
@ffi.load_materials(@utf8.encode(file_name))
}
// ============================================================================
// Model: transform / mesh access
// ============================================================================
///|
pub fn set_model_transform(model : Model, transform : Matrix) -> Unit {
@ffi.set_model_transform(model, transform.to_bytes())
}
///|
pub fn get_model_mesh_count(model : Model) -> Int {
@ffi.get_model_mesh_count(model)
}
///|
pub fn get_model_mesh(model : Model, index : Int) -> Mesh {
@ffi.get_model_mesh(model, index)
}
///|
pub fn get_model_transform(model : Model) -> Matrix {
Matrix::from_bytes(@ffi.get_model_transform(model))
}
///|
pub fn get_model_material_count(model : Model) -> Int {
@ffi.get_model_material_count(model)
}
///|
pub fn get_model_material(model : Model, index : Int) -> Material {
@ffi.get_model_material(model, index)
}
///|
pub fn get_model_bone_count(model : Model) -> Int {
@ffi.get_model_bone_count(model)
}
///|
pub fn get_model_bone_parent(model : Model, bone_index : Int) -> Int {
@ffi.get_model_bone_parent(model, bone_index)
}
///|
pub fn get_model_bind_pose_translation(
model : Model,
bone_index : Int,
) -> Vector3 {
Vector3::from_bytes(@ffi.get_model_bind_pose_translation(model, bone_index))
}
///|
pub fn get_model_animation_frame_count(
anims : ModelAnimations,
anim_index : Int,
) -> Int {
@ffi.get_model_animation_frame_count(anims, anim_index)
}
///|
pub fn get_model_animation_bone_count(
anims : ModelAnimations,
anim_index : Int,
) -> Int {
@ffi.get_model_animation_bone_count(anims, anim_index)
}
///|
pub fn get_model_animation_bone_parent(
anims : ModelAnimations,
anim_index : Int,
bone_index : Int,
) -> Int {
@ffi.get_model_animation_bone_parent(anims, anim_index, bone_index)
}
///|
pub fn get_model_animation_frame_pose_translation(
anims : ModelAnimations,
anim_index : Int,
frame : Int,
bone_index : Int,
) -> Vector3 {
Vector3::from_bytes(
@ffi.get_model_animation_frame_pose_translation(
anims, anim_index, frame, bone_index,
),
)
}
///|
pub fn get_model_animation_frame_pose_rotation(
anims : ModelAnimations,
anim_index : Int,
frame : Int,
bone_index : Int,
) -> Vector4 {
Vector4::from_bytes(
@ffi.get_model_animation_frame_pose_rotation(
anims, anim_index, frame, bone_index,
),
)
}
///|
pub fn get_model_bone_name(model : Model, bone_index : Int) -> String {
@utf8.decode_lossy(@ffi.get_model_bone_name(model, bone_index))
}
///|
pub fn get_model_bind_pose_rotation(model : Model, bone_index : Int) -> Vector4 {
Vector4::from_bytes(@ffi.get_model_bind_pose_rotation(model, bone_index))
}
// ============================================================================
// Mesh: Generate point cloud from vertex+color data
// ============================================================================
///|
pub fn gen_mesh_from_points(
vertices : Bytes,
colors : Bytes,
num_points : Int,
) -> Mesh {
@ffi.gen_mesh_from_points(vertices, colors, num_points)
}
// ============================================================================
// Mesh: setup texcoords2 (allocate, fill, upload VBO, set vertex attribute)
// ============================================================================
///|
pub fn mesh_setup_texcoords2(
mesh : Mesh,
data : Bytes,
float_count : Int,
) -> Unit {
@ffi.mesh_setup_texcoords2(mesh, data, float_count)
}