use crate::*;
use bve::parse::mesh;
use bve::{ColorU8RGB, ColorU8RGBA};
use bve_derive::c_interface;
use std::ffi::CStr;
use std::ptr::null;
use crate::parse::Span;
pub use mesh::BlendMode;
pub use mesh::FileType;
pub use mesh::Glow;
pub use mesh::GlowAttenuationMode;
pub use mesh::Vertex;
#[repr(C)]
pub struct Parsed_Static_Object {
pub meshes: CVector<Mesh>,
pub textures: *mut Texture_Set,
pub warnings: CVector<Mesh_Warning>,
pub errors: CVector<Mesh_Error>,
}
impl From<mesh::ParsedStaticObject> for Parsed_Static_Object {
#[inline]
fn from(other: mesh::ParsedStaticObject) -> Self {
Self {
meshes: other.meshes.into(),
textures: Box::into_raw(Box::new(other.textures.into())),
warnings: other.warnings.into(),
errors: other.errors.into(),
}
}
}
impl Into<mesh::ParsedStaticObject> for Parsed_Static_Object {
#[inline]
fn into(self) -> mesh::ParsedStaticObject {
mesh::ParsedStaticObject {
meshes: self.meshes.into(),
textures: unsafe { *Box::from_raw(self.textures) }.into(),
warnings: self.warnings.into(),
errors: self.errors.into(),
}
}
}
#[c_interface]
pub unsafe extern "C" fn bve_delete_parsed_static_object(object: Parsed_Static_Object) {
let _reassembled: mesh::ParsedStaticObject = object.into();
}
pub struct Texture_Set {
pub inner: mesh::TextureSet,
}
impl From<mesh::TextureSet> for Texture_Set {
#[inline]
fn from(other: mesh::TextureSet) -> Self {
Self { inner: other }
}
}
impl Into<mesh::TextureSet> for Texture_Set {
#[inline]
fn into(self) -> mesh::TextureSet {
self.inner
}
}
#[must_use]
#[c_interface]
pub unsafe extern "C" fn BVE_Texture_Set_len(ptr: *const Texture_Set) -> libc::size_t {
(*ptr).inner.len()
}
#[c_interface]
pub unsafe extern "C" fn BVE_Texture_Set_add(ptr: *mut Texture_Set, value: *const c_char) -> libc::size_t {
(*ptr).inner.add(&CStr::from_ptr(value).to_string_lossy())
}
#[must_use]
#[c_interface]
pub unsafe extern "C" fn BVE_Texture_Set_lookup(ptr: *const Texture_Set, idx: libc::size_t) -> *const c_char {
let result = (*ptr).inner.lookup(idx);
match result {
Some(s) => string_to_owned_ptr(s),
None => null(),
}
}
#[repr(C)]
pub struct Mesh_Texture {
pub texture_id: COption<usize>,
pub decal_transparent_color: COption<ColorU8RGB>,
pub emission_color: ColorU8RGB,
}
impl From<mesh::Texture> for Mesh_Texture {
fn from(other: mesh::Texture) -> Self {
Self {
texture_id: other.texture_id.into(),
decal_transparent_color: other.decal_transparent_color.into(),
emission_color: other.emission_color,
}
}
}
impl Into<mesh::Texture> for Mesh_Texture {
fn into(self) -> mesh::Texture {
mesh::Texture {
texture_id: self.texture_id.into(),
decal_transparent_color: self.decal_transparent_color.into(),
emission_color: self.emission_color,
}
}
}
#[repr(C)]
pub struct Mesh {
pub vertices: CVector<Vertex>,
pub indices: CVector<libc::size_t>,
pub texture: Mesh_Texture,
pub color: ColorU8RGBA,
pub blend_mode: BlendMode,
pub glow: Glow,
}
impl From<mesh::Mesh> for Mesh {
fn from(other: mesh::Mesh) -> Self {
Self {
vertices: other.vertices.into(),
indices: other.indices.into(),
texture: other.texture.into(),
color: other.color,
blend_mode: other.blend_mode,
glow: other.glow,
}
}
}
impl Into<mesh::Mesh> for Mesh {
fn into(self) -> mesh::Mesh {
mesh::Mesh {
vertices: self.vertices.into(),
indices: self.indices.into(),
texture: self.texture.into(),
color: self.color,
blend_mode: self.blend_mode,
glow: self.glow,
}
}
}
#[repr(C)]
pub struct Mesh_Error {
pub location: Span,
pub kind: Mesh_Error_Kind,
}
impl From<mesh::MeshError> for Mesh_Error {
fn from(other: mesh::MeshError) -> Self {
Self {
location: other.location.into(),
kind: other.kind.into(),
}
}
}
impl Into<mesh::MeshError> for Mesh_Error {
fn into(self) -> mesh::MeshError {
mesh::MeshError {
location: self.location.into(),
kind: self.kind.into(),
}
}
}
#[repr(C, u8)]
pub enum Mesh_Error_Kind {
UTF8 { column: COption<u64> },
OutOfBounds { idx: usize },
UnknownInstruction { name: *const c_char },
GenericCSV { msg: *const c_char },
UnknownCSV,
}
impl From<mesh::MeshErrorKind> for Mesh_Error_Kind {
fn from(other: mesh::MeshErrorKind) -> Self {
match other {
mesh::MeshErrorKind::UTF8 { column } => Self::UTF8 { column: column.into() },
mesh::MeshErrorKind::OutOfBounds { idx } => Self::OutOfBounds { idx },
mesh::MeshErrorKind::UnknownInstruction { name } => Self::UnknownInstruction {
name: string_to_owned_ptr(&name),
},
mesh::MeshErrorKind::GenericCSV { msg } => Self::GenericCSV {
msg: string_to_owned_ptr(&msg),
},
mesh::MeshErrorKind::UnknownCSV => Self::UnknownCSV,
}
}
}
impl Into<mesh::MeshErrorKind> for Mesh_Error_Kind {
fn into(self) -> mesh::MeshErrorKind {
match self {
Self::UTF8 { column } => mesh::MeshErrorKind::UTF8 { column: column.into() },
Self::OutOfBounds { idx } => mesh::MeshErrorKind::OutOfBounds { idx },
Self::UnknownInstruction { name } => mesh::MeshErrorKind::UnknownInstruction {
name: unsafe { owned_ptr_to_string(name as *mut c_char) },
},
Self::GenericCSV { msg } => mesh::MeshErrorKind::GenericCSV {
msg: unsafe { owned_ptr_to_string(msg as *mut c_char) },
},
Self::UnknownCSV => mesh::MeshErrorKind::UnknownCSV,
}
}
}
#[repr(C)]
pub struct Mesh_Warning {
pub location: Span,
pub kind: Mesh_Warning_Kind,
}
impl From<mesh::MeshWarning> for Mesh_Warning {
fn from(other: mesh::MeshWarning) -> Self {
Self {
location: other.location.into(),
kind: other.kind.into(),
}
}
}
impl Into<mesh::MeshWarning> for Mesh_Warning {
fn into(self) -> mesh::MeshWarning {
mesh::MeshWarning {
location: self.location.into(),
kind: self.kind.into(),
}
}
}
#[repr(C, u8)]
pub enum Mesh_Warning_Kind {
UselessInstruction { name: *const c_char },
}
impl From<mesh::MeshWarningKind> for Mesh_Warning_Kind {
fn from(other: mesh::MeshWarningKind) -> Self {
match other {
mesh::MeshWarningKind::UselessInstruction { name } => Self::UselessInstruction {
name: string_to_owned_ptr(&name),
},
}
}
}
impl Into<mesh::MeshWarningKind> for Mesh_Warning_Kind {
fn into(self) -> mesh::MeshWarningKind {
match self {
Self::UselessInstruction { name } => mesh::MeshWarningKind::UselessInstruction {
name: unsafe { owned_ptr_to_string(name as *mut c_char) },
},
}
}
}
#[must_use]
#[c_interface]
pub unsafe extern "C" fn bve_parse_mesh_from_string(
string: *const c_char,
file_type: FileType,
) -> Parsed_Static_Object {
let result = mesh::mesh_from_str(&unowned_ptr_to_str(&string), file_type);
result.into()
}