1#![allow(dead_code)]
3
4use std::collections::HashMap;
5
6use bevy::prelude::*;
7use wde_animation::AnimationClip;
8
9use crate::material::GltfMaterial;
10
11#[derive(Debug, Clone)]
13pub struct GltfModel {
14 pub path: String,
15 pub filename: String,
16 pub buffers: Vec<GltfBuffer>,
17 pub meshes: Vec<GltfMesh>,
18 pub materials: Vec<GltfMaterial>,
19 pub properties: HashMap<String, (Vec3, Vec3)>,
22 pub bones: Vec<GltfBone>,
24 pub animations: Vec<AnimationClip>,
26 pub lights: Vec<GltfLight>
28}
29
30#[derive(Debug, Clone)]
32pub struct GltfLight {
33 pub name: String,
34 pub kind: GltfLightKind,
35 pub transform: Transform,
37 pub color: Vec3,
39 pub intensity: f32,
40 pub range: f32
42}
43
44#[derive(Debug, Clone, Copy, PartialEq)]
45pub enum GltfLightKind {
46 Point,
47 Spot {
49 inner_cone: f32,
50 outer_cone: f32
51 }
52}
53
54#[derive(Debug, Clone)]
56pub struct GltfBone {
57 pub name: String,
58 pub parent: Option<usize>,
60 pub rest: Transform
62}
63
64#[derive(Clone)]
66pub struct GltfBuffer {
67 pub data: Vec<u8>,
68 pub slices: Vec<BufferSliceData>
69}
70impl std::fmt::Debug for GltfBuffer {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 f.debug_struct("GltfBuffer")
73 .field("data_length", &self.data.len())
74 .field("slices", &self.slices)
75 .finish()
76 }
77}
78
79#[derive(Debug, Clone)]
81pub struct BufferSliceData {
82 pub byte_offset: usize
84}
85
86#[derive(Debug, Clone)]
88pub struct GltfMesh {
89 pub primitives: Vec<MeshPrimitive>
90}
91
92#[derive(Debug, Clone)]
94pub struct MeshPrimitive {
95 pub name: String,
97 pub vertex_indexed: Option<AccessorData>,
99 pub vertex_attributes: Vec<(String, AccessorData)>,
101 pub material_id: Option<u32>,
103 pub translation: [f32; 3],
105 pub rotation: [f32; 4],
107 pub scale: [f32; 3],
109 pub condition: Option<ModelCondition>,
111 pub bone: Option<usize>
113}
114
115#[derive(Debug, Clone, PartialEq, Eq)]
117pub struct ModelCondition {
118 pub anchor: String,
120 pub connected: bool
122}
123impl ModelCondition {
124 pub fn from_node_name(name: &str) -> Option<Self> {
126 let rest = name.strip_prefix("%V%")?;
127 let rest = match rest.rfind(['+', '-']) {
129 Some(i) => &rest[..=i],
130 None => return None
131 };
132 let (anchor, sign) = rest.split_at(rest.len() - 1);
133 Some(Self {
134 anchor: anchor.to_string(),
135 connected: sign == "+"
136 })
137 }
138}
139
140#[derive(Debug, Clone)]
142pub struct AccessorData {
143 pub buffer_view_index: i64,
145 pub byte_offset: usize,
147 pub component_type: GltfAccessorComponentType,
149 pub count: usize,
151 pub accessor_type: String,
153 pub min: Option<Vec<f32>>,
155 pub max: Option<Vec<f32>>
157}
158
159#[derive(Debug, Clone, Copy)]
161pub enum GltfAccessorComponentType {
162 Byte = 5120,
163 UnsignedByte = 5121,
164 Short = 5122,
165 UnsignedShort = 5123,
166 UnsignedInt = 5125,
167 Float = 5126
168}
169impl GltfAccessorComponentType {
170 pub fn from_i64(value: i64) -> Option<Self> {
172 match value {
173 5120 => Some(GltfAccessorComponentType::Byte),
174 5121 => Some(GltfAccessorComponentType::UnsignedByte),
175 5122 => Some(GltfAccessorComponentType::Short),
176 5123 => Some(GltfAccessorComponentType::UnsignedShort),
177 5125 => Some(GltfAccessorComponentType::UnsignedInt),
178 5126 => Some(GltfAccessorComponentType::Float),
179 _ => unreachable!("Unsupported component type: {}", value)
180 }
181 }
182}