modelio-rs 0.3.1

Safe Rust bindings for Apple's ModelIO framework — assets, meshes, materials, lights, cameras, voxels, textures, and animation on macOS
Documentation
import Foundation
import ModelIO
import simd

private func mdl_camera_info(_ camera: MDLCamera) -> [String: Any] {
    [
        "projection": camera.projection.rawValue,
        "projection_matrix": mdl_matrix_to_array(camera.projectionMatrix),
        "near_visibility_distance": camera.nearVisibilityDistance,
        "far_visibility_distance": camera.farVisibilityDistance,
        "world_to_meters_conversion_scale": camera.worldToMetersConversionScale,
        "barrel_distortion": camera.barrelDistortion,
        "fisheye_distortion": camera.fisheyeDistortion,
        "optical_vignetting": camera.opticalVignetting,
        "chromatic_aberration": camera.chromaticAberration,
        "focal_length": camera.focalLength,
        "focus_distance": camera.focusDistance,
        "field_of_view": camera.fieldOfView,
        "f_stop": camera.fStop,
        "aperture_blade_count": camera.apertureBladeCount,
        "maximum_circle_of_confusion": camera.maximumCircleOfConfusion,
        "shutter_open_interval": camera.shutterOpenInterval,
        "sensor_vertical_aperture": camera.sensorVerticalAperture,
        "sensor_aspect": camera.sensorAspect,
        "sensor_enlargement": [camera.sensorEnlargement.x, camera.sensorEnlargement.y],
        "sensor_shift": [camera.sensorShift.x, camera.sensorShift.y],
        "flash": [camera.flash.x, camera.flash.y, camera.flash.z],
        "exposure_compression": [camera.exposureCompression.x, camera.exposureCompression.y],
        "exposure": [camera.exposure.x, camera.exposure.y, camera.exposure.z],
    ]
}

@_cdecl("mdl_camera_new")
public func mdl_camera_new(
    _ outCamera: UnsafeMutablePointer<UnsafeMutableRawPointer?>?,
    _ outError: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>?
) -> Int32 {
    mdl_run(outError) {
        guard let outCamera else {
            throw ModelIOBridgeError.invalidArgument("missing output camera pointer")
        }
        outCamera.pointee = mdl_retain(MDLCamera())
    }
}

@_cdecl("mdl_camera_info_json")
public func mdl_camera_info_json(_ handle: UnsafeMutableRawPointer?) -> UnsafeMutablePointer<CChar>? {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return nil }
    return mdl_string(mdl_json_string(from: mdl_camera_info(camera)) ?? "{}")
}

@_cdecl("mdl_camera_set_projection")
public func mdl_camera_set_projection(_ handle: UnsafeMutableRawPointer?, _ rawValue: UInt32) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera,
          let projection = try? mdl_camera_projection(rawValue)
    else {
        return
    }
    camera.projection = projection
}

@_cdecl("mdl_camera_set_near_visibility_distance")
public func mdl_camera_set_near_visibility_distance(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return }
    camera.nearVisibilityDistance = value
}

@_cdecl("mdl_camera_set_far_visibility_distance")
public func mdl_camera_set_far_visibility_distance(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return }
    camera.farVisibilityDistance = value
}

@_cdecl("mdl_camera_set_world_to_meters_conversion_scale")
public func mdl_camera_set_world_to_meters_conversion_scale(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return }
    camera.worldToMetersConversionScale = value
}

@_cdecl("mdl_camera_set_focal_length")
public func mdl_camera_set_focal_length(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return }
    camera.focalLength = value
}

@_cdecl("mdl_camera_set_focus_distance")
public func mdl_camera_set_focus_distance(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return }
    camera.focusDistance = value
}

@_cdecl("mdl_camera_set_field_of_view")
public func mdl_camera_set_field_of_view(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return }
    camera.fieldOfView = value
}

@_cdecl("mdl_camera_look_at")
public func mdl_camera_look_at(_ handle: UnsafeMutableRawPointer?, _ x: Float, _ y: Float, _ z: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return }
    camera.look(at: SIMD3<Float>(x, y, z))
}

@_cdecl("mdl_camera_look_at_from")
public func mdl_camera_look_at_from(
    _ handle: UnsafeMutableRawPointer?,
    _ focusX: Float,
    _ focusY: Float,
    _ focusZ: Float,
    _ cameraX: Float,
    _ cameraY: Float,
    _ cameraZ: Float
) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return }
    camera.look(at: SIMD3<Float>(focusX, focusY, focusZ), from: SIMD3<Float>(cameraX, cameraY, cameraZ))
}

@_cdecl("mdl_camera_frame_bounding_box")
public func mdl_camera_frame_bounding_box(
    _ handle: UnsafeMutableRawPointer?,
    _ minX: Float,
    _ minY: Float,
    _ minZ: Float,
    _ maxX: Float,
    _ maxY: Float,
    _ maxZ: Float,
    _ setNearAndFar: Int32
) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return }
    let boundingBox = MDLAxisAlignedBoundingBox(maxBounds: SIMD3<Float>(maxX, maxY, maxZ), minBounds: SIMD3<Float>(minX, minY, minZ))
    camera.frameBoundingBox(boundingBox, setNearAndFar: setNearAndFar != 0)
}

@_cdecl("mdl_camera_ray_to")
public func mdl_camera_ray_to(
    _ handle: UnsafeMutableRawPointer?,
    _ pixelX: Int32,
    _ pixelY: Int32,
    _ viewportWidth: Int32,
    _ viewportHeight: Int32,
    _ outX: UnsafeMutablePointer<Float>?,
    _ outY: UnsafeMutablePointer<Float>?,
    _ outZ: UnsafeMutablePointer<Float>?
) {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else {
        outX?.pointee = 0
        outY?.pointee = 0
        outZ?.pointee = 0
        return
    }
    let ray = camera.ray(to: vector_int2(pixelX, pixelY), forViewPort: vector_int2(viewportWidth, viewportHeight))
    outX?.pointee = ray.x
    outY?.pointee = ray.y
    outZ?.pointee = ray.z
}

private func mdl_stereoscopic_camera_info(_ camera: MDLStereoscopicCamera) -> [String: Any] {
    [
        "inter_pupillary_distance": camera.interPupillaryDistance,
        "left_vergence": camera.leftVergence,
        "right_vergence": camera.rightVergence,
        "overlap": camera.overlap,
        "left_view_matrix": mdl_matrix_to_array(camera.leftViewMatrix),
        "right_view_matrix": mdl_matrix_to_array(camera.rightViewMatrix),
        "left_projection_matrix": mdl_matrix_to_array(camera.leftProjectionMatrix),
        "right_projection_matrix": mdl_matrix_to_array(camera.rightProjectionMatrix),
    ]
}

@_cdecl("mdl_camera_bokeh_kernel")
public func mdl_camera_bokeh_kernel(
    _ handle: UnsafeMutableRawPointer?,
    _ width: Int32,
    _ height: Int32
) -> UnsafeMutableRawPointer? {
    guard let camera = mdl_borrow_object(handle) as? MDLCamera else { return nil }
    return mdl_retain(camera.bokehKernel(withSize: vector_int2(width, height)))
}

@_cdecl("mdl_stereoscopic_camera_new")
public func mdl_stereoscopic_camera_new(
    _ outCamera: UnsafeMutablePointer<UnsafeMutableRawPointer?>?,
    _ outError: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>?
) -> Int32 {
    mdl_run(outError) {
        guard let outCamera else {
            throw ModelIOBridgeError.invalidArgument("missing output stereoscopic camera pointer")
        }
        outCamera.pointee = mdl_retain(MDLStereoscopicCamera())
    }
}

@_cdecl("mdl_stereoscopic_camera_info_json")
public func mdl_stereoscopic_camera_info_json(_ handle: UnsafeMutableRawPointer?) -> UnsafeMutablePointer<CChar>? {
    guard let camera = mdl_borrow_object(handle) as? MDLStereoscopicCamera else { return nil }
    return mdl_string(mdl_json_string(from: mdl_stereoscopic_camera_info(camera)) ?? "{}")
}

@_cdecl("mdl_stereoscopic_camera_set_inter_pupillary_distance")
public func mdl_stereoscopic_camera_set_inter_pupillary_distance(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLStereoscopicCamera else { return }
    camera.interPupillaryDistance = value
}

@_cdecl("mdl_stereoscopic_camera_set_left_vergence")
public func mdl_stereoscopic_camera_set_left_vergence(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLStereoscopicCamera else { return }
    camera.leftVergence = value
}

@_cdecl("mdl_stereoscopic_camera_set_right_vergence")
public func mdl_stereoscopic_camera_set_right_vergence(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLStereoscopicCamera else { return }
    camera.rightVergence = value
}

@_cdecl("mdl_stereoscopic_camera_set_overlap")
public func mdl_stereoscopic_camera_set_overlap(_ handle: UnsafeMutableRawPointer?, _ value: Float) {
    guard let camera = mdl_borrow_object(handle) as? MDLStereoscopicCamera else { return }
    camera.overlap = value
}