pub const VRM: &str = "VRM";
#[cfg(feature = "rustc_hash")]
use rustc_hash::FxHashMap as HashMap;
use serde::{Deserialize, Serialize};
#[cfg(not(feature = "rustc_hash"))]
use std::collections::HashMap;
use crate::serde_utils::{
deserialize_option_index, deserialize_option_map_and_skip_nullable,
deserialize_option_map_index,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRM0Schema {
#[serde(skip_serializing_if = "Option::is_none")]
pub blend_shape_master: Option<VRMBlendShape>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exporter_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub first_person: Option<VRMFirstPerson>,
#[serde(skip_serializing_if = "Option::is_none")]
pub humanoid: Option<VRMHumanoid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub material_properties: Option<Vec<VRMMaterial>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub meta: Option<VRMMeta>,
#[serde(skip_serializing_if = "Option::is_none")]
pub secondary_animation: Option<VRMSecondaryAnimation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec_version: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMBlendShape {
#[serde(skip_serializing_if = "Option::is_none")]
pub blend_shape_groups: Option<Vec<VRMBlendShapeGroup>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMBlendShapeGroup {
#[serde(skip_serializing_if = "Option::is_none")]
pub binds: Option<Vec<VRMBlendShapeBind>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_binary: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub material_values: Option<Vec<VRMBlendShapeMaterialBind>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub preset_name: Option<PresetName>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VRMBlendShapeBind {
#[serde(skip_serializing_if = "Option::is_none")]
pub index: Option<i64>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_option_index::<_, gltf::json::Mesh>"
)]
#[cfg(feature = "gltf_index")]
pub mesh: Option<gltf::json::Index<gltf::json::Mesh>>,
#[cfg(not(feature = "gltf_index"))]
pub mesh: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub weight: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMBlendShapeMaterialBind {
#[serde(skip_serializing_if = "Option::is_none")]
pub material_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub property_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_value: Option<Vec<f64>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMFirstPerson {
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_option_index::<_, gltf::json::Node>"
)]
#[cfg(feature = "gltf_index")]
pub first_person_bone: Option<gltf::json::Index<gltf::json::Node>>,
#[cfg(not(feature = "gltf_index"))]
pub first_person_bone: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub first_person_bone_offset: Option<FirstPersonBoneOffset>,
#[serde(skip_serializing_if = "Option::is_none")]
pub look_at_horizontal_inner: Option<VRMFirstPersonDegreeMap>,
#[serde(skip_serializing_if = "Option::is_none")]
pub look_at_horizontal_outer: Option<VRMFirstPersonDegreeMap>,
#[serde(skip_serializing_if = "Option::is_none")]
pub look_at_type_name: Option<LookAtTypeName>,
#[serde(skip_serializing_if = "Option::is_none")]
pub look_at_vertical_down: Option<VRMFirstPersonDegreeMap>,
#[serde(skip_serializing_if = "Option::is_none")]
pub look_at_vertical_up: Option<VRMFirstPersonDegreeMap>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mesh_annotations: Option<Vec<VRMFirstPersonMeshAnnotation>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OptionalVector3 {
#[serde(skip_serializing_if = "Option::is_none")]
pub x: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub y: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub z: Option<f64>,
}
pub type FirstPersonBoneOffset = OptionalVector3;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMFirstPersonDegreeMap {
#[serde(skip_serializing_if = "Option::is_none")]
pub curve: Option<Vec<f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub x_range: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub y_range: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMFirstPersonMeshAnnotation {
#[serde(skip_serializing_if = "Option::is_none")]
pub first_person_flag: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_option_index::<_, gltf::json::Mesh>"
)]
#[cfg(feature = "gltf_index")]
pub mesh: Option<gltf::json::Index<gltf::json::Mesh>>,
#[cfg(not(feature = "gltf_index"))]
pub mesh: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMHumanoid {
#[serde(skip_serializing_if = "Option::is_none")]
pub arm_stretch: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub feet_spacing: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub has_translation_do_f: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub human_bones: Option<Vec<VRMHumanoidBone>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub leg_stretch: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lower_arm_twist: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lower_leg_twist: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub upper_arm_twist: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub upper_leg_twist: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMHumanoidBone {
#[serde(skip_serializing_if = "Option::is_none")]
pub axis_length: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bone: Option<Bone>,
#[serde(skip_serializing_if = "Option::is_none")]
pub center: Option<Center>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max: Option<Max>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min: Option<Min>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_option_index::<_, gltf::json::Node>"
)]
#[cfg(feature = "gltf_index")]
pub node: Option<gltf::json::Index<gltf::json::Node>>,
#[cfg(not(feature = "gltf_index"))]
pub node: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub use_default_values: Option<bool>,
}
pub type Center = OptionalVector3;
pub type Max = OptionalVector3;
pub type Min = OptionalVector3;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMMaterial {
#[serde(
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_option_map_and_skip_nullable::<_, String, f64>"
)]
pub float_properties: Option<HashMap<String, f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keyword_map: Option<HashMap<String, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub render_queue: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub shader: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tag_map: Option<HashMap<String, String>>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_option_map_index::<_, gltf::json::Texture>"
)]
#[cfg(feature = "gltf_index")]
pub texture_properties: Option<HashMap<String, gltf::json::Index<gltf::json::Texture>>>,
#[cfg(not(feature = "gltf_index"))]
pub texture_properties: Option<HashMap<String, usize>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub vector_properties: Option<HashMap<String, Vec<f64>>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMMeta {
#[serde(skip_serializing_if = "Option::is_none")]
pub allowed_user_name: Option<AllowedUserName>,
#[serde(skip_serializing_if = "Option::is_none")]
pub author: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub commercial_ussage_name: Option<UssageName>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contact_information: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub license_name: Option<LicenseName>,
#[serde(skip_serializing_if = "Option::is_none")]
pub other_license_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub other_permission_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reference: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sexual_ussage_name: Option<UssageName>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_option_index::<_, gltf::json::Texture>"
)]
#[cfg(feature = "gltf_index")]
pub texture: Option<gltf::json::Index<gltf::json::Texture>>,
#[cfg(not(feature = "gltf_index"))]
pub texture: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub violent_ussage_name: Option<UssageName>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMSecondaryAnimation {
#[serde(skip_serializing_if = "Option::is_none")]
pub bone_groups: Option<Vec<VRMSecondaryAnimationSpring>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub collider_groups: Option<Vec<VRMSecondaryAnimationColliderGroup>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VRMSecondaryAnimationSpring {
#[serde(skip_serializing_if = "Option::is_none")]
#[cfg(feature = "gltf_index")]
pub bones: Option<Vec<gltf::json::Index<gltf::json::Node>>>,
#[cfg(not(feature = "gltf_index"))]
pub bones: Option<Vec<i64>>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_option_index::<_, gltf::json::Node>"
)]
#[cfg(feature = "gltf_index")]
pub center: Option<gltf::json::Index<gltf::json::Node>>,
#[cfg(not(feature = "gltf_index"))]
pub center: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub collider_groups: Option<Vec<i64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub drag_force: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gravity_dir: Option<GravityDir>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gravity_power: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hit_radius: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stiffiness: Option<f64>,
}
pub type GravityDir = OptionalVector3;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VRMSecondaryAnimationColliderGroup {
#[serde(skip_serializing_if = "Option::is_none")]
pub colliders: Option<Vec<Collider>>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_option_index::<_, gltf::json::Node>"
)]
pub node: Option<gltf::json::Index<gltf::json::Node>>,
#[cfg(not(feature = "gltf_index"))]
pub node: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Collider {
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<Offset>,
#[serde(skip_serializing_if = "Option::is_none")]
pub radius: Option<f64>,
}
pub type Offset = OptionalVector3;
#[derive(Debug, Clone, Copy, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PresetName {
A,
Angry,
Blink,
BlinkL,
BlinkR,
E,
Fun,
I,
Joy,
Lookdown,
Lookleft,
Lookright,
Lookup,
Neutral,
O,
Sorrow,
U,
Unknown,
}
#[derive(Debug, Clone, Copy, Hash, Serialize, Deserialize)]
pub enum LookAtTypeName {
BlendShape,
Bone,
}
#[derive(Debug, Clone, Copy, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum Bone {
Chest,
Head,
Hips,
Jaw,
LeftEye,
LeftFoot,
LeftHand,
LeftIndexDistal,
LeftIndexIntermediate,
LeftIndexProximal,
LeftLittleDistal,
LeftLittleIntermediate,
LeftLittleProximal,
LeftLowerArm,
LeftLowerLeg,
LeftMiddleDistal,
LeftMiddleIntermediate,
LeftMiddleProximal,
LeftRingDistal,
LeftRingIntermediate,
LeftRingProximal,
LeftShoulder,
LeftThumbDistal,
LeftThumbIntermediate,
LeftThumbProximal,
LeftToes,
LeftUpperArm,
LeftUpperLeg,
Neck,
RightEye,
RightFoot,
RightHand,
RightIndexDistal,
RightIndexIntermediate,
RightIndexProximal,
RightLittleDistal,
RightLittleIntermediate,
RightLittleProximal,
RightLowerArm,
RightLowerLeg,
RightMiddleDistal,
RightMiddleIntermediate,
RightMiddleProximal,
RightRingDistal,
RightRingIntermediate,
RightRingProximal,
RightShoulder,
RightThumbDistal,
RightThumbIntermediate,
RightThumbProximal,
RightToes,
RightUpperArm,
RightUpperLeg,
Spine,
UpperChest,
}
#[derive(Debug, Clone, Copy, Hash, Serialize, Deserialize)]
pub enum AllowedUserName {
Everyone,
ExplicitlyLicensedPerson,
OnlyAuthor,
}
#[derive(Debug, Clone, Copy, Hash, Serialize, Deserialize)]
pub enum UssageName {
Allow,
Disallow,
}
#[derive(Debug, Clone, Copy, Hash, Serialize, Deserialize)]
pub enum LicenseName {
#[serde(rename = "CC0")]
Cc0,
#[serde(rename = "CC_BY")]
CcBy,
#[serde(rename = "CC_BY_NC")]
CcByNc,
#[serde(rename = "CC_BY_NC_ND")]
CcByNcNd,
#[serde(rename = "CC_BY_NC_SA")]
CcByNcSa,
#[serde(rename = "CC_BY_ND")]
CcByNd,
#[serde(rename = "CC_BY_SA")]
CcBySa,
#[serde(rename = "Redistribution_Prohibited")]
RedistributionProhibited,
Other,
}