Generate skeleton attention and genepool catalogs (#49)
This commit is contained in:
@@ -25,11 +25,17 @@ jobs:
|
||||
run: |
|
||||
cargo test -p libremetaverse --test generated_catalogs
|
||||
cargo test -p libremetaverse-compat-tests --test appearance_visual_semantics
|
||||
- name: Test generated skeleton, attention, and genepool catalogs
|
||||
run: |
|
||||
cargo test -p libremetaverse --test generated_avatar_catalogs
|
||||
cargo test -p libremetaverse --lib linden_skeleton
|
||||
cargo test -p libremetaverse --lib joint_base_support_category
|
||||
cargo test -p libremetaverse --lib joint_get_aliases_list
|
||||
- name: Regenerate twice without reference checkout access
|
||||
run: |
|
||||
cargo run -p libremetaverse-codegen -- generate
|
||||
cargo run -p libremetaverse-codegen -- generate
|
||||
git diff --exit-code -- codegen/generated crates/libremetaverse/src/packet_catalog.rs crates/libremetaverse/src/visual_catalog.rs crates/libremetaverse/src/foliage_catalog.rs
|
||||
git diff --exit-code -- codegen/generated crates/libremetaverse/src/packet_catalog.rs crates/libremetaverse/src/visual_catalog.rs crates/libremetaverse/src/foliage_catalog.rs crates/libremetaverse/src/skeleton_catalog.rs crates/libremetaverse/src/attention_catalog.rs crates/libremetaverse/src/genepool_catalog.rs
|
||||
- name: Lint native generator
|
||||
run: |
|
||||
cargo clippy -p libremetaverse-codegen --all-targets -- -D warnings
|
||||
|
||||
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -368,6 +368,7 @@ dependencies = [
|
||||
"libremetaverse-imaging",
|
||||
"libremetaverse-structured-data",
|
||||
"libremetaverse-types",
|
||||
"roxmltree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -243,3 +243,10 @@ relationships, skeletal/volume morphs, and every foliage rendering property.
|
||||
Schema validation rejects malformed or ambiguous input, while sorted visual-ID
|
||||
and source-indexed foliage lookups preserve the ordering observable in the
|
||||
reference APIs and packet bytes.
|
||||
The remaining avatar-data generators emit the full 133-bone/26-collision-volume
|
||||
skeleton hierarchy, both masculine and feminine versions of the default and
|
||||
updated 11-slot attention tables, and all 24 genepool archetypes with 3,360
|
||||
visual-parameter values. Native skeleton traversal, alias lookup, expanded mesh
|
||||
joint lists, custom XML loading, attention indexing, and archetype lookup now
|
||||
implement the mapped behavior directly in Rust. Each checked-in catalog retains
|
||||
its own input hash and license provenance.
|
||||
|
||||
@@ -4,7 +4,7 @@ Generated by `python3 tools/generate_api_shims.py`; do not edit by hand.
|
||||
|
||||
| Assembly | Types | Members | Status |
|
||||
|---|---:|---:|---|
|
||||
| `LibreMetaverse` | 2,711 | 27,281 | native implementation: 16 types / 10,554 members; remaining surface is callable failure-only shims |
|
||||
| `LibreMetaverse` | 2,711 | 27,281 | native implementation: 26 types / 10,604 members; remaining surface is callable failure-only shims |
|
||||
| `LibreMetaverse.Imaging.Abstractions` | 3 | 20 | native implementation: 3 types / 20 members; no generated shims remain |
|
||||
| `LibreMetaverse.Imaging.Skia` | 1 | 3 | native implementation: 1 type / 3 members; no generated shims remain |
|
||||
| `LibreMetaverse.LslTools` | 164 | 768 | callable failure-only shim |
|
||||
|
||||
@@ -91,6 +91,32 @@ constant-time indexed lookup. Golden fixtures cover all catalog counts,
|
||||
representative complete records, public getters/setters, appearance decoding,
|
||||
and every generated relationship category.
|
||||
|
||||
## Skeleton, attentions, and genepool
|
||||
|
||||
The skeleton generator validates the pinned hierarchy root, declared counts,
|
||||
finite three-component transforms, unique joint names and aliases, collision
|
||||
volumes, support categories, and child element schema. Its checked-in
|
||||
[`skeleton_catalog.rs`](../crates/libremetaverse/src/skeleton_catalog.rs) output
|
||||
constructs all 133 joints and 26 collision volumes in source hierarchy order.
|
||||
The native skeleton records also implement depth-first enumeration, canonical
|
||||
and alias lookup, expanded mesh-joint lists, the built-in loader, and validated
|
||||
custom XML loading without a serializer or managed runtime.
|
||||
|
||||
The attention generator validates both pinned attention inputs independently,
|
||||
requiring masculine and feminine sets with each of the nine named parameters
|
||||
exactly once. The generated
|
||||
[`attention_catalog.rs`](../crates/libremetaverse/src/attention_catalog.rs)
|
||||
keeps the eleven `LookAtType` slots in enum-discriminant order, including the
|
||||
observable zero-initialized `None` and `Clear` entries.
|
||||
|
||||
The genepool generator validates unique archetype names and parameter IDs,
|
||||
finite values, and each ignored-but-schema-relevant texture UUID and slot. The
|
||||
generated [`genepool_catalog.rs`](../crates/libremetaverse/src/genepool_catalog.rs)
|
||||
preserves source archetype and parameter order for all 24 archetypes and 3,360
|
||||
parameter values; exact-name lookup returns the original source index. Separate
|
||||
generated headers retain the input hashes and BSD-3-Clause provenance for the
|
||||
skeleton, both attention files, and genepool asset.
|
||||
|
||||
## Commands
|
||||
|
||||
Regenerate every currently registered Rust output using only checked-in data:
|
||||
|
||||
@@ -17,6 +17,7 @@ bcdec_rs = { version = "0.2.0", optional = true }
|
||||
libremetaverse-imaging = { path = "../libremetaverse-imaging" }
|
||||
libremetaverse-structured-data = { path = "../libremetaverse-structured-data" }
|
||||
libremetaverse-types = { path = "../libremetaverse-types" }
|
||||
roxmltree = "0.21.1"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
147
crates/libremetaverse/src/attention_catalog.rs
Normal file
147
crates/libremetaverse/src/attention_catalog.rs
Normal file
@@ -0,0 +1,147 @@
|
||||
// @generated by libremetaverse-codegen; DO NOT EDIT.
|
||||
// Regenerate: cargo run -p libremetaverse-codegen -- generate
|
||||
// Generator: attentions
|
||||
// Source: codegen/inputs/attentions.xml sha256=bdbc4ca02dd3bde78b86e796f7eb4ada0000e47be9a127e35d2b77f3010a20af license=BSD-3-Clause
|
||||
// Source: codegen/inputs/attentionsN.xml sha256=80055e12a04d05ef5bb16e8c542cd6c218735f8c72f7e48317b8a34282d1ac5b license=BSD-3-Clause
|
||||
|
||||
#![allow(
|
||||
clippy::missing_errors_doc,
|
||||
clippy::must_use_candidate,
|
||||
clippy::should_implement_trait
|
||||
)]
|
||||
use std::sync::OnceLock;
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub struct AttentionData {
|
||||
priority: f32,
|
||||
timeout: f32,
|
||||
}
|
||||
impl AttentionData {
|
||||
pub fn priority(&self) -> f32 {
|
||||
self.priority
|
||||
}
|
||||
pub fn set_priority(&mut self, value: f32) {
|
||||
self.priority = value;
|
||||
}
|
||||
pub fn timeout(&self) -> f32 {
|
||||
self.timeout
|
||||
}
|
||||
pub fn set_timeout(&mut self, value: f32) {
|
||||
self.timeout = value;
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub struct AttentionSet {
|
||||
name: String,
|
||||
entries: Vec<AttentionData>,
|
||||
}
|
||||
impl AttentionSet {
|
||||
pub fn get(&self, type_: crate::LookAtType) -> Result<AttentionData, crate::Error> {
|
||||
self.entries.get(type_ as usize).cloned().ok_or(crate::Error::IndexOutOfRange)
|
||||
}
|
||||
pub fn entries(&self) -> Vec<AttentionData> {
|
||||
self.entries.clone()
|
||||
}
|
||||
pub fn set_entries(&mut self, value: Vec<AttentionData>) {
|
||||
self.entries = value;
|
||||
}
|
||||
pub fn name(&self) -> String {
|
||||
self.name.clone()
|
||||
}
|
||||
pub fn set_name(&mut self, value: String) {
|
||||
self.name = value;
|
||||
}
|
||||
}
|
||||
fn default_sets() -> &'static [AttentionSet] {
|
||||
static SETS: OnceLock<Vec<AttentionSet>> = OnceLock::new();
|
||||
SETS.get_or_init(|| {
|
||||
vec![
|
||||
AttentionSet { name : "Masculine".to_owned(), entries :
|
||||
vec![AttentionData { priority : 0.0_f32, timeout : 0.0_f32 },
|
||||
AttentionData { priority : 1.0_f32, timeout : 3.0_f32 }, AttentionData {
|
||||
priority : 3.0_f32, timeout : 4.0_f32 }, AttentionData { priority :
|
||||
2.0_f32, timeout : 2.0_f32 }, AttentionData { priority : 3.0_f32, timeout
|
||||
: 4.0_f32 }, AttentionData { priority : 4.0_f32, timeout : 1.0_f32 },
|
||||
AttentionData { priority : 0.0_f32, timeout : - 1.0_f32 }, AttentionData
|
||||
{ priority : 6.0_f32, timeout : - 1.0_f32 }, AttentionData { priority :
|
||||
6.0_f32, timeout : - 1.0_f32 }, AttentionData { priority : 7.0_f32,
|
||||
timeout : - 1.0_f32 }, AttentionData { priority : 0.0_f32, timeout :
|
||||
0.0_f32 }] }, AttentionSet { name : "Feminine".to_owned(), entries :
|
||||
vec![AttentionData { priority : 0.0_f32, timeout : 0.0_f32 },
|
||||
AttentionData { priority : 1.0_f32, timeout : 3.0_f32 }, AttentionData {
|
||||
priority : 3.0_f32, timeout : 4.0_f32 }, AttentionData { priority :
|
||||
2.0_f32, timeout : 2.0_f32 }, AttentionData { priority : 3.0_f32, timeout
|
||||
: 4.0_f32 }, AttentionData { priority : 4.0_f32, timeout : 1.0_f32 },
|
||||
AttentionData { priority : 0.0_f32, timeout : - 1.0_f32 }, AttentionData
|
||||
{ priority : 6.0_f32, timeout : - 1.0_f32 }, AttentionData { priority :
|
||||
6.0_f32, timeout : - 1.0_f32 }, AttentionData { priority : 7.0_f32,
|
||||
timeout : - 1.0_f32 }, AttentionData { priority : 0.0_f32, timeout :
|
||||
0.0_f32 }] }
|
||||
]
|
||||
})
|
||||
.as_slice()
|
||||
}
|
||||
fn updated_sets() -> &'static [AttentionSet] {
|
||||
static SETS: OnceLock<Vec<AttentionSet>> = OnceLock::new();
|
||||
SETS.get_or_init(|| {
|
||||
vec![
|
||||
AttentionSet { name : "Masculine".to_owned(), entries :
|
||||
vec![AttentionData { priority : 0.0_f32, timeout : 0.0_f32 },
|
||||
AttentionData { priority : 1.0_f32, timeout : 3.0_f32 }, AttentionData {
|
||||
priority : 3.0_f32, timeout : 4.0_f32 }, AttentionData { priority :
|
||||
2.0_f32, timeout : 2.0_f32 }, AttentionData { priority : 3.0_f32, timeout
|
||||
: 3.0_f32 }, AttentionData { priority : 4.0_f32, timeout : 1.0_f32 },
|
||||
AttentionData { priority : 5.0_f32, timeout : 3.0_f32 }, AttentionData {
|
||||
priority : 3.5_f32, timeout : - 1.0_f32 }, AttentionData { priority :
|
||||
3.5_f32, timeout : 20.0_f32 }, AttentionData { priority : 7.0_f32,
|
||||
timeout : - 1.0_f32 }, AttentionData { priority : 0.0_f32, timeout :
|
||||
0.0_f32 }] }, AttentionSet { name : "Feminine".to_owned(), entries :
|
||||
vec![AttentionData { priority : 0.0_f32, timeout : 0.0_f32 },
|
||||
AttentionData { priority : 1.0_f32, timeout : 3.0_f32 }, AttentionData {
|
||||
priority : 3.0_f32, timeout : 4.0_f32 }, AttentionData { priority :
|
||||
2.0_f32, timeout : 2.0_f32 }, AttentionData { priority : 3.0_f32, timeout
|
||||
: 6.0_f32 }, AttentionData { priority : 4.0_f32, timeout : 1.0_f32 },
|
||||
AttentionData { priority : 5.0_f32, timeout : 6.0_f32 }, AttentionData {
|
||||
priority : 2.5_f32, timeout : - 1.0_f32 }, AttentionData { priority :
|
||||
2.5_f32, timeout : 10.0_f32 }, AttentionData { priority : 7.0_f32,
|
||||
timeout : - 1.0_f32 }, AttentionData { priority : 0.0_f32, timeout :
|
||||
0.0_f32 }] }
|
||||
]
|
||||
})
|
||||
.as_slice()
|
||||
}
|
||||
pub struct LindenAttentions;
|
||||
impl LindenAttentions {
|
||||
pub fn default() -> Vec<AttentionSet> {
|
||||
default_sets().to_vec()
|
||||
}
|
||||
pub fn updated() -> Vec<AttentionSet> {
|
||||
updated_sets().to_vec()
|
||||
}
|
||||
pub fn default_masculine() -> AttentionSet {
|
||||
default_sets()[0].clone()
|
||||
}
|
||||
pub fn default_feminine() -> AttentionSet {
|
||||
default_sets()[1].clone()
|
||||
}
|
||||
pub fn updated_masculine() -> AttentionSet {
|
||||
updated_sets()[0].clone()
|
||||
}
|
||||
pub fn updated_feminine() -> AttentionSet {
|
||||
updated_sets()[1].clone()
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn generated_attention_shape() {
|
||||
assert_eq!(default_sets().len(), 2);
|
||||
assert_eq!(updated_sets().len(), 2);
|
||||
assert!(
|
||||
default_sets().iter().chain(updated_sets()).all(| set | set.entries.len() ==
|
||||
11)
|
||||
);
|
||||
assert_eq!(default_sets() [0].name, "Masculine");
|
||||
assert_eq!(default_sets() [1].name, "Feminine");
|
||||
}
|
||||
}
|
||||
4042
crates/libremetaverse/src/genepool_catalog.rs
Normal file
4042
crates/libremetaverse/src/genepool_catalog.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4789,33 +4789,10 @@ impl AppearanceSetEventArgs {
|
||||
}
|
||||
|
||||
/// C# type: `T:LibreMetaverse.ArchetypeParam`.
|
||||
pub struct ArchetypeParam;
|
||||
impl ArchetypeParam {
|
||||
/// C# member: `P:LibreMetaverse.ArchetypeParam.Id`.
|
||||
pub fn id(&self) -> i32 {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.ArchetypeParam.Id")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.ArchetypeParam.Id`.
|
||||
pub fn set_id(&mut self, value: i32) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.ArchetypeParam.Id")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.ArchetypeParam.Name`.
|
||||
pub fn name(&self) -> String {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.ArchetypeParam.Name")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.ArchetypeParam.Name`.
|
||||
pub fn set_name(&mut self, value: String) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.ArchetypeParam.Name")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.ArchetypeParam.Value`.
|
||||
pub fn value(&self) -> f32 {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.ArchetypeParam.Value")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.ArchetypeParam.Value`.
|
||||
pub fn set_value(&mut self, value: f32) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.ArchetypeParam.Value")
|
||||
}
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.ArchetypeParam.Id`.
|
||||
/// C# member: `P:LibreMetaverse.ArchetypeParam.Name`.
|
||||
/// C# member: `P:LibreMetaverse.ArchetypeParam.Value`.
|
||||
pub use crate::genepool_catalog::ArchetypeParam;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.AssetCache`.
|
||||
pub struct AssetCache {
|
||||
@@ -5420,55 +5397,15 @@ impl AttachedSoundGainChangeEventArgs {
|
||||
}
|
||||
|
||||
/// C# type: `T:LibreMetaverse.AttentionData`.
|
||||
pub struct AttentionData;
|
||||
impl AttentionData {
|
||||
/// C# member: `P:LibreMetaverse.AttentionData.Priority`.
|
||||
pub fn priority(&self) -> f32 {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.AttentionData.Priority")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.AttentionData.Priority`.
|
||||
pub fn set_priority(&mut self, value: f32) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.AttentionData.Priority")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.AttentionData.Timeout`.
|
||||
pub fn timeout(&self) -> f32 {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.AttentionData.Timeout")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.AttentionData.Timeout`.
|
||||
pub fn set_timeout(&mut self, value: f32) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.AttentionData.Timeout")
|
||||
}
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.AttentionData.Priority`.
|
||||
/// C# member: `P:LibreMetaverse.AttentionData.Timeout`.
|
||||
pub use crate::attention_catalog::AttentionData;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.AttentionSet`.
|
||||
pub struct AttentionSet;
|
||||
impl AttentionSet {
|
||||
/// C# member: `M:LibreMetaverse.AttentionSet.Get(LibreMetaverse.LookAtType)`.
|
||||
pub fn get(
|
||||
&self,
|
||||
type_: libremetaverse::LookAtType,
|
||||
) -> Result<libremetaverse::AttentionData, crate::Error> {
|
||||
libremetaverse_types::not_implemented(
|
||||
"M:LibreMetaverse.AttentionSet.Get(LibreMetaverse.LookAtType)",
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.AttentionSet.Entries`.
|
||||
pub fn entries(&self) -> Vec<libremetaverse::AttentionData> {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.AttentionSet.Entries")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.AttentionSet.Entries`.
|
||||
pub fn set_entries(&mut self, value: Vec<libremetaverse::AttentionData>) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.AttentionSet.Entries")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.AttentionSet.Name`.
|
||||
pub fn name(&self) -> String {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.AttentionSet.Name")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.AttentionSet.Name`.
|
||||
pub fn set_name(&mut self, value: String) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.AttentionSet.Name")
|
||||
}
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.AttentionSet.Get(LibreMetaverse.LookAtType)`.
|
||||
/// C# member: `P:LibreMetaverse.AttentionSet.Entries`.
|
||||
/// C# member: `P:LibreMetaverse.AttentionSet.Name`.
|
||||
pub use crate::attention_catalog::AttentionSet;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.Avatar`.
|
||||
pub struct Avatar {
|
||||
@@ -10936,42 +10873,15 @@ impl GLTFMaterialUpdate {
|
||||
}
|
||||
|
||||
/// C# type: `T:LibreMetaverse.Genepool`.
|
||||
pub struct Genepool;
|
||||
impl Genepool {
|
||||
/// C# member: `F:LibreMetaverse.Genepool.Archetypes`.
|
||||
pub fn archetypes() -> Vec<libremetaverse::GenepoolArchetype> {
|
||||
libremetaverse_types::unimplemented_api!("F:LibreMetaverse.Genepool.Archetypes")
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Genepool.FindIndex(System.String)`.
|
||||
pub fn find_index(name: String) -> Result<i32, crate::Error> {
|
||||
libremetaverse_types::not_implemented("M:LibreMetaverse.Genepool.FindIndex(System.String)")
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Genepool.Get(System.Int32)`.
|
||||
pub fn get(index: i32) -> Result<libremetaverse::GenepoolArchetype, crate::Error> {
|
||||
libremetaverse_types::not_implemented("M:LibreMetaverse.Genepool.Get(System.Int32)")
|
||||
}
|
||||
}
|
||||
/// C# member: `F:LibreMetaverse.Genepool.Archetypes`.
|
||||
/// C# member: `M:LibreMetaverse.Genepool.FindIndex(System.String)`.
|
||||
/// C# member: `M:LibreMetaverse.Genepool.Get(System.Int32)`.
|
||||
pub use crate::genepool_catalog::Genepool;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.GenepoolArchetype`.
|
||||
pub struct GenepoolArchetype;
|
||||
impl GenepoolArchetype {
|
||||
/// C# member: `P:LibreMetaverse.GenepoolArchetype.Name`.
|
||||
pub fn name(&self) -> String {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.GenepoolArchetype.Name")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.GenepoolArchetype.Name`.
|
||||
pub fn set_name(&mut self, value: String) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.GenepoolArchetype.Name")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.GenepoolArchetype.Params`.
|
||||
pub fn params(&self) -> Vec<libremetaverse::ArchetypeParam> {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.GenepoolArchetype.Params")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.GenepoolArchetype.Params`.
|
||||
pub fn set_params(&mut self, value: Vec<libremetaverse::ArchetypeParam>) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.GenepoolArchetype.Params")
|
||||
}
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.GenepoolArchetype.Name`.
|
||||
/// C# member: `P:LibreMetaverse.GenepoolArchetype.Params`.
|
||||
pub use crate::genepool_catalog::GenepoolArchetype;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.GenericStreamingMessageEventArgs`.
|
||||
pub struct GenericStreamingMessageEventArgs;
|
||||
@@ -17214,41 +17124,13 @@ impl LegacyEnvironmentEventArgs {
|
||||
}
|
||||
|
||||
/// C# type: `T:LibreMetaverse.LindenAttentions`.
|
||||
pub struct LindenAttentions;
|
||||
impl LindenAttentions {
|
||||
/// C# member: `F:LibreMetaverse.LindenAttentions.Default`.
|
||||
pub fn default() -> Vec<libremetaverse::AttentionSet> {
|
||||
libremetaverse_types::unimplemented_api!("F:LibreMetaverse.LindenAttentions.Default")
|
||||
}
|
||||
/// C# member: `F:LibreMetaverse.LindenAttentions.Updated`.
|
||||
pub fn updated() -> Vec<libremetaverse::AttentionSet> {
|
||||
libremetaverse_types::unimplemented_api!("F:LibreMetaverse.LindenAttentions.Updated")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.LindenAttentions.DefaultFeminine`.
|
||||
pub fn default_feminine() -> libremetaverse::AttentionSet {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.LindenAttentions.DefaultFeminine"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.LindenAttentions.DefaultMasculine`.
|
||||
pub fn default_masculine() -> libremetaverse::AttentionSet {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.LindenAttentions.DefaultMasculine"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.LindenAttentions.UpdatedFeminine`.
|
||||
pub fn updated_feminine() -> libremetaverse::AttentionSet {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.LindenAttentions.UpdatedFeminine"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.LindenAttentions.UpdatedMasculine`.
|
||||
pub fn updated_masculine() -> libremetaverse::AttentionSet {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.LindenAttentions.UpdatedMasculine"
|
||||
)
|
||||
}
|
||||
}
|
||||
/// C# member: `F:LibreMetaverse.LindenAttentions.Default`.
|
||||
/// C# member: `F:LibreMetaverse.LindenAttentions.Updated`.
|
||||
/// C# member: `P:LibreMetaverse.LindenAttentions.DefaultFeminine`.
|
||||
/// C# member: `P:LibreMetaverse.LindenAttentions.DefaultMasculine`.
|
||||
/// C# member: `P:LibreMetaverse.LindenAttentions.UpdatedFeminine`.
|
||||
/// C# member: `P:LibreMetaverse.LindenAttentions.UpdatedMasculine`.
|
||||
pub use crate::attention_catalog::LindenAttentions;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.LiveParticle`.
|
||||
pub struct LiveParticle {
|
||||
@@ -170382,15 +170264,8 @@ pub mod rendering {
|
||||
impl BoneTransform {}
|
||||
|
||||
/// C# type: `T:LibreMetaverse.Rendering.CollisionVolume`.
|
||||
pub struct CollisionVolume;
|
||||
impl CollisionVolume {
|
||||
/// C# member: `M:LibreMetaverse.Rendering.CollisionVolume.#ctor`.
|
||||
pub fn new() -> Result<Self, crate::Error> {
|
||||
libremetaverse_types::not_implemented(
|
||||
"M:LibreMetaverse.Rendering.CollisionVolume.#ctor",
|
||||
)
|
||||
}
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.CollisionVolume.#ctor`.
|
||||
pub use crate::skeleton::CollisionVolume;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.Rendering.DetailLevel`.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
@@ -170667,150 +170542,27 @@ pub mod rendering {
|
||||
}
|
||||
|
||||
/// C# type: `T:LibreMetaverse.Rendering.Joint`.
|
||||
pub struct Joint {
|
||||
/// Rust composition for C# base type `LibreMetaverse.Rendering.JointBase`.
|
||||
pub base: libremetaverse::rendering::JointBase,
|
||||
}
|
||||
impl Joint {
|
||||
/// C# member: `M:LibreMetaverse.Rendering.Joint.#ctor`.
|
||||
pub fn new() -> Result<Self, crate::Error> {
|
||||
libremetaverse_types::not_implemented("M:LibreMetaverse.Rendering.Joint.#ctor")
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.Joint.GetAliasesList`.
|
||||
pub fn get_aliases_list(&self) -> Result<Vec<String>, crate::Error> {
|
||||
libremetaverse_types::not_implemented("M:LibreMetaverse.Rendering.Joint.GetAliasesList")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.aliases`.
|
||||
pub fn aliases(&self) -> String {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.Joint.aliases")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.Joint.aliases`.
|
||||
pub fn set_aliases(&mut self, value: String) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.Joint.aliases")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.bone`.
|
||||
pub fn bone(&self) -> Option<Vec<libremetaverse::rendering::Joint>> {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.Joint.bone")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.Joint.bone`.
|
||||
pub fn set_bone(&mut self, value: Option<Vec<libremetaverse::rendering::Joint>>) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.Joint.bone")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.collision_volume`.
|
||||
pub fn collision_volume(&self) -> Vec<libremetaverse::rendering::CollisionVolume> {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.Joint.collision_volume"
|
||||
)
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.Joint.collision_volume`.
|
||||
pub fn set_collision_volume(
|
||||
&mut self,
|
||||
value: Vec<libremetaverse::rendering::CollisionVolume>,
|
||||
) {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.Joint.collision_volume"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.connected`.
|
||||
pub fn connected(&self) -> bool {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.Joint.connected")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.Joint.connected`.
|
||||
pub fn set_connected(&mut self, value: bool) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.Joint.connected")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.pivot`.
|
||||
pub fn pivot(&self) -> Vec<f32> {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.Joint.pivot")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.Joint.pivot`.
|
||||
pub fn set_pivot(&mut self, value: Vec<f32>) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.Joint.pivot")
|
||||
}
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.Joint.#ctor`.
|
||||
/// C# member: `M:LibreMetaverse.Rendering.Joint.GetAliasesList`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.aliases`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.bone`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.collision_volume`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.connected`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.Joint.pivot`.
|
||||
pub use crate::skeleton::Joint;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.Rendering.JointBase`.
|
||||
pub struct JointBase;
|
||||
impl JointBase {
|
||||
/// C# member: `M:LibreMetaverse.Rendering.JointBase.#ctor`.
|
||||
pub fn new() -> Result<Self, crate::Error> {
|
||||
libremetaverse_types::not_implemented("M:LibreMetaverse.Rendering.JointBase.#ctor")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.SupportCategory`.
|
||||
pub fn support_category(&self) -> libremetaverse::rendering::JointSupportCategory {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.JointBase.SupportCategory"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.end`.
|
||||
pub fn end(&self) -> Vec<f32> {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.end")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.JointBase.end`.
|
||||
pub fn set_end(&mut self, value: Vec<f32>) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.end")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.group`.
|
||||
pub fn group(&self) -> String {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.group")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.JointBase.group`.
|
||||
pub fn set_group(&mut self, value: String) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.group")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.name`.
|
||||
pub fn name(&self) -> String {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.name")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.JointBase.name`.
|
||||
pub fn set_name(&mut self, value: String) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.name")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.pos`.
|
||||
pub fn pos(&self) -> Vec<f32> {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.pos")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.JointBase.pos`.
|
||||
pub fn set_pos(&mut self, value: Vec<f32>) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.pos")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.reposition`.
|
||||
pub fn reposition(&self) -> bool {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.JointBase.reposition"
|
||||
)
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.JointBase.reposition`.
|
||||
pub fn set_reposition(&mut self, value: bool) {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.JointBase.reposition"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.rot`.
|
||||
pub fn rot(&self) -> Vec<f32> {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.rot")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.JointBase.rot`.
|
||||
pub fn set_rot(&mut self, value: Vec<f32>) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.rot")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.scale`.
|
||||
pub fn scale(&self) -> Vec<f32> {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.scale")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.JointBase.scale`.
|
||||
pub fn set_scale(&mut self, value: Vec<f32>) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.scale")
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.support`.
|
||||
pub fn support(&self) -> String {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.support")
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.JointBase.support`.
|
||||
pub fn set_support(&mut self, value: String) {
|
||||
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Rendering.JointBase.support")
|
||||
}
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.JointBase.#ctor`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.SupportCategory`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.end`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.group`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.name`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.pos`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.reposition`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.rot`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.scale`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.JointBase.support`.
|
||||
pub use crate::skeleton::JointBase;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.Rendering.JointSupportCategory`.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
@@ -171284,133 +171036,20 @@ pub mod rendering {
|
||||
}
|
||||
|
||||
/// C# type: `T:LibreMetaverse.Rendering.LindenSkeleton`.
|
||||
pub struct LindenSkeleton;
|
||||
impl LindenSkeleton {
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.#ctor`.
|
||||
pub fn new() -> Result<Self, crate::Error> {
|
||||
libremetaverse_types::not_implemented("M:LibreMetaverse.Rendering.LindenSkeleton.#ctor")
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.BuildExpandedJointList(System.Collections.Generic.IEnumerable{System.String})`.
|
||||
pub fn build_expanded_joint_list(
|
||||
&self,
|
||||
joints_filter: Box<dyn Iterator<Item = String>>,
|
||||
) -> Result<Vec<String>, crate::Error> {
|
||||
libremetaverse_types::not_implemented(
|
||||
"M:LibreMetaverse.Rendering.LindenSkeleton.BuildExpandedJointList(System.Collections.Generic.IEnumerable{System.String})",
|
||||
)
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.BuildJointDictionary`.
|
||||
pub fn build_joint_dictionary(
|
||||
&self,
|
||||
) -> Result<
|
||||
std::collections::HashMap<String, std::sync::Arc<libremetaverse::rendering::Joint>>,
|
||||
crate::Error,
|
||||
> {
|
||||
libremetaverse_types::not_implemented(
|
||||
"M:LibreMetaverse.Rendering.LindenSkeleton.BuildJointDictionary",
|
||||
)
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.GetAllJoints`.
|
||||
pub fn get_all_joints(
|
||||
&self,
|
||||
) -> Result<
|
||||
Box<dyn Iterator<Item = std::sync::Arc<libremetaverse::rendering::Joint>>>,
|
||||
crate::Error,
|
||||
> {
|
||||
libremetaverse_types::not_implemented(
|
||||
"M:LibreMetaverse.Rendering.LindenSkeleton.GetAllJoints",
|
||||
)
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.GetBone(System.String)`.
|
||||
pub fn get_bone(
|
||||
&self,
|
||||
name_or_alias: String,
|
||||
) -> Result<Option<std::sync::Arc<libremetaverse::rendering::Joint>>, crate::Error>
|
||||
{
|
||||
libremetaverse_types::not_implemented(
|
||||
"M:LibreMetaverse.Rendering.LindenSkeleton.GetBone(System.String)",
|
||||
)
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.GetDefault`.
|
||||
pub fn get_default() -> Result<libremetaverse::rendering::LindenSkeleton, crate::Error> {
|
||||
libremetaverse_types::not_implemented(
|
||||
"M:LibreMetaverse.Rendering.LindenSkeleton.GetDefault",
|
||||
)
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.Load`.
|
||||
pub fn load_with_method() -> Result<libremetaverse::rendering::LindenSkeleton, crate::Error>
|
||||
{
|
||||
libremetaverse_types::not_implemented("M:LibreMetaverse.Rendering.LindenSkeleton.Load")
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.Load(System.String)`.
|
||||
pub fn load_with_string(
|
||||
file_name: Option<String>,
|
||||
) -> Result<libremetaverse::rendering::LindenSkeleton, crate::Error> {
|
||||
libremetaverse_types::not_implemented(
|
||||
"M:LibreMetaverse.Rendering.LindenSkeleton.Load(System.String)",
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.bone`.
|
||||
pub fn bone(&self) -> libremetaverse::rendering::Joint {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.bone"
|
||||
)
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.bone`.
|
||||
pub fn set_bone(&mut self, value: libremetaverse::rendering::Joint) {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.bone"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.num_bones`.
|
||||
pub fn num_bones(&self) -> String {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.num_bones"
|
||||
)
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.num_bones`.
|
||||
pub fn set_num_bones(&mut self, value: String) {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.num_bones"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.num_collision_volumes`.
|
||||
pub fn num_collision_volumes(&self) -> String {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.num_collision_volumes"
|
||||
)
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.num_collision_volumes`.
|
||||
pub fn set_num_collision_volumes(&mut self, value: String) {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.num_collision_volumes"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.version`.
|
||||
pub fn version(&self) -> f32 {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.version"
|
||||
)
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.version`.
|
||||
pub fn set_version(&mut self, value: f32) {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.version"
|
||||
)
|
||||
}
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.versionSpecified`.
|
||||
pub fn version_specified(&self) -> bool {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.versionSpecified"
|
||||
)
|
||||
}
|
||||
/// Setter for C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.versionSpecified`.
|
||||
pub fn set_version_specified(&mut self, value: bool) {
|
||||
libremetaverse_types::unimplemented_api!(
|
||||
"P:LibreMetaverse.Rendering.LindenSkeleton.versionSpecified"
|
||||
)
|
||||
}
|
||||
}
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.#ctor`.
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.BuildExpandedJointList(System.Collections.Generic.IEnumerable{System.String})`.
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.BuildJointDictionary`.
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.GetAllJoints`.
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.GetBone(System.String)`.
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.GetDefault`.
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.Load`.
|
||||
/// C# member: `M:LibreMetaverse.Rendering.LindenSkeleton.Load(System.String)`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.bone`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.num_bones`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.num_collision_volumes`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.version`.
|
||||
/// C# member: `P:LibreMetaverse.Rendering.LindenSkeleton.versionSpecified`.
|
||||
pub use crate::skeleton::LindenSkeleton;
|
||||
|
||||
/// C# type: `T:LibreMetaverse.Rendering.Mesh`.
|
||||
pub struct Mesh {
|
||||
|
||||
@@ -2,15 +2,22 @@
|
||||
|
||||
extern crate self as libremetaverse;
|
||||
|
||||
#[rustfmt::skip] // Deterministic machine output is formatted by the pinned generator.
|
||||
mod attention_catalog;
|
||||
mod bit_pack;
|
||||
#[rustfmt::skip] // Deterministic machine output is formatted by the pinned generator.
|
||||
mod foliage_catalog;
|
||||
mod generated;
|
||||
#[rustfmt::skip] // Deterministic machine output is formatted by the pinned generator.
|
||||
mod genepool_catalog;
|
||||
mod j2k;
|
||||
mod message_codec;
|
||||
#[rustfmt::skip]
|
||||
pub mod packet_catalog;
|
||||
mod packet_wire;
|
||||
mod skeleton;
|
||||
#[rustfmt::skip] // Deterministic machine output is formatted by the pinned generator.
|
||||
mod skeleton_catalog;
|
||||
mod targa;
|
||||
#[rustfmt::skip] // Deterministic machine output is formatted by the pinned generator.
|
||||
mod visual_catalog;
|
||||
|
||||
580
crates/libremetaverse/src/skeleton.rs
Normal file
580
crates/libremetaverse/src/skeleton.rs
Normal file
@@ -0,0 +1,580 @@
|
||||
//! Native skeleton records, traversal helpers, and custom XML loading.
|
||||
|
||||
#![allow(clippy::missing_errors_doc)] // Public signatures are fixed by the compatibility catalog.
|
||||
#![allow(clippy::must_use_candidate)] // Getters mirror C# properties.
|
||||
#![allow(clippy::needless_pass_by_value)] // Owned strings are fixed by the compatibility API.
|
||||
#![allow(clippy::unnecessary_wraps)] // Constructors mirror fallible mapped signatures.
|
||||
|
||||
use roxmltree::{Document, Node};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub struct JointBase {
|
||||
name: String,
|
||||
pos: Vec<f32>,
|
||||
rot: Vec<f32>,
|
||||
scale: Vec<f32>,
|
||||
group: String,
|
||||
support: String,
|
||||
end: Vec<f32>,
|
||||
reposition: bool,
|
||||
}
|
||||
|
||||
impl JointBase {
|
||||
pub fn new() -> Result<Self, crate::Error> {
|
||||
Ok(Self::default())
|
||||
}
|
||||
|
||||
pub fn support_category(&self) -> crate::rendering::JointSupportCategory {
|
||||
if self.support.eq_ignore_ascii_case("extended") {
|
||||
crate::rendering::JointSupportCategory::Extended
|
||||
} else {
|
||||
crate::rendering::JointSupportCategory::Base
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end(&self) -> Vec<f32> {
|
||||
self.end.clone()
|
||||
}
|
||||
|
||||
pub fn set_end(&mut self, value: Vec<f32>) {
|
||||
self.end = value;
|
||||
}
|
||||
|
||||
pub fn group(&self) -> String {
|
||||
self.group.clone()
|
||||
}
|
||||
|
||||
pub fn set_group(&mut self, value: String) {
|
||||
self.group = value;
|
||||
}
|
||||
|
||||
pub fn name(&self) -> String {
|
||||
self.name.clone()
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, value: String) {
|
||||
self.name = value;
|
||||
}
|
||||
|
||||
pub fn pos(&self) -> Vec<f32> {
|
||||
self.pos.clone()
|
||||
}
|
||||
|
||||
pub fn set_pos(&mut self, value: Vec<f32>) {
|
||||
self.pos = value;
|
||||
}
|
||||
|
||||
pub fn reposition(&self) -> bool {
|
||||
self.reposition
|
||||
}
|
||||
|
||||
pub fn set_reposition(&mut self, value: bool) {
|
||||
self.reposition = value;
|
||||
}
|
||||
|
||||
pub fn rot(&self) -> Vec<f32> {
|
||||
self.rot.clone()
|
||||
}
|
||||
|
||||
pub fn set_rot(&mut self, value: Vec<f32>) {
|
||||
self.rot = value;
|
||||
}
|
||||
|
||||
pub fn scale(&self) -> Vec<f32> {
|
||||
self.scale.clone()
|
||||
}
|
||||
|
||||
pub fn set_scale(&mut self, value: Vec<f32>) {
|
||||
self.scale = value;
|
||||
}
|
||||
|
||||
pub fn support(&self) -> String {
|
||||
self.support.clone()
|
||||
}
|
||||
|
||||
pub fn set_support(&mut self, value: String) {
|
||||
self.support = value;
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn from_parts(
|
||||
name: String,
|
||||
pos: Vec<f32>,
|
||||
rot: Vec<f32>,
|
||||
scale: Vec<f32>,
|
||||
group: String,
|
||||
support: String,
|
||||
end: Vec<f32>,
|
||||
reposition: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
name,
|
||||
pos,
|
||||
rot,
|
||||
scale,
|
||||
group,
|
||||
support,
|
||||
end,
|
||||
reposition,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub struct CollisionVolume {
|
||||
pub base: JointBase,
|
||||
}
|
||||
|
||||
impl CollisionVolume {
|
||||
pub fn new() -> Result<Self, crate::Error> {
|
||||
Ok(Self::default())
|
||||
}
|
||||
|
||||
pub(crate) fn from_base(base: JointBase) -> Self {
|
||||
Self { base }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Joint {
|
||||
pub base: JointBase,
|
||||
collision_volume: Vec<CollisionVolume>,
|
||||
bone: Option<Vec<Joint>>,
|
||||
pivot: Vec<f32>,
|
||||
aliases: String,
|
||||
connected: bool,
|
||||
}
|
||||
|
||||
impl Default for Joint {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base: JointBase::default(),
|
||||
collision_volume: Vec::new(),
|
||||
bone: Some(Vec::new()),
|
||||
pivot: Vec::new(),
|
||||
aliases: String::new(),
|
||||
connected: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Joint {
|
||||
pub fn new() -> Result<Self, crate::Error> {
|
||||
Ok(Self::default())
|
||||
}
|
||||
|
||||
pub fn get_aliases_list(&self) -> Result<Vec<String>, crate::Error> {
|
||||
Ok(self
|
||||
.aliases
|
||||
.split_ascii_whitespace()
|
||||
.map(str::to_owned)
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub fn aliases(&self) -> String {
|
||||
self.aliases.clone()
|
||||
}
|
||||
|
||||
pub fn set_aliases(&mut self, value: String) {
|
||||
self.aliases = value;
|
||||
}
|
||||
|
||||
pub fn bone(&self) -> Option<Vec<Self>> {
|
||||
self.bone.clone()
|
||||
}
|
||||
|
||||
pub fn set_bone(&mut self, value: Option<Vec<Self>>) {
|
||||
self.bone = value;
|
||||
}
|
||||
|
||||
pub fn collision_volume(&self) -> Vec<CollisionVolume> {
|
||||
self.collision_volume.clone()
|
||||
}
|
||||
|
||||
pub fn set_collision_volume(&mut self, value: Vec<CollisionVolume>) {
|
||||
self.collision_volume = value;
|
||||
}
|
||||
|
||||
pub fn connected(&self) -> bool {
|
||||
self.connected
|
||||
}
|
||||
|
||||
pub fn set_connected(&mut self, value: bool) {
|
||||
self.connected = value;
|
||||
}
|
||||
|
||||
pub fn pivot(&self) -> Vec<f32> {
|
||||
self.pivot.clone()
|
||||
}
|
||||
|
||||
pub fn set_pivot(&mut self, value: Vec<f32>) {
|
||||
self.pivot = value;
|
||||
}
|
||||
|
||||
pub(crate) fn from_parts(
|
||||
base: JointBase,
|
||||
collision_volume: Vec<CollisionVolume>,
|
||||
bone: Vec<Self>,
|
||||
pivot: Vec<f32>,
|
||||
aliases: String,
|
||||
connected: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
base,
|
||||
collision_volume,
|
||||
bone: Some(bone),
|
||||
pivot,
|
||||
aliases,
|
||||
connected,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct LindenSkeleton {
|
||||
bone: Joint,
|
||||
version: f32,
|
||||
version_specified: bool,
|
||||
num_bones: String,
|
||||
num_collision_volumes: String,
|
||||
}
|
||||
|
||||
impl Default for LindenSkeleton {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bone: Joint::default(),
|
||||
version: 0.0,
|
||||
version_specified: false,
|
||||
num_bones: String::new(),
|
||||
num_collision_volumes: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LindenSkeleton {
|
||||
pub fn new() -> Result<Self, crate::Error> {
|
||||
Ok(Self::default())
|
||||
}
|
||||
|
||||
pub fn build_expanded_joint_list(
|
||||
&self,
|
||||
joints_filter: Box<dyn Iterator<Item = String>>,
|
||||
) -> Result<Vec<String>, crate::Error> {
|
||||
let filter = joints_filter.collect::<Vec<_>>();
|
||||
let mut expanded = Vec::new();
|
||||
if let Some(children) = &self.bone.bone {
|
||||
for child in children {
|
||||
expand_joint(child, &self.bone.base.name, &mut expanded, &filter);
|
||||
}
|
||||
}
|
||||
Ok(expanded)
|
||||
}
|
||||
|
||||
pub fn build_joint_dictionary(&self) -> Result<HashMap<String, Arc<Joint>>, crate::Error> {
|
||||
let mut dictionary = HashMap::new();
|
||||
for joint in collect_joints(&self.bone) {
|
||||
if !joint.base.name.is_empty() {
|
||||
dictionary.insert(joint.base.name.clone(), Arc::clone(&joint));
|
||||
}
|
||||
for alias in joint.aliases.split_ascii_whitespace() {
|
||||
if !alias.is_empty() {
|
||||
dictionary.insert(alias.to_owned(), Arc::clone(&joint));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(dictionary)
|
||||
}
|
||||
|
||||
pub fn get_all_joints(&self) -> Result<Box<dyn Iterator<Item = Arc<Joint>>>, crate::Error> {
|
||||
Ok(Box::new(collect_joints(&self.bone).into_iter()))
|
||||
}
|
||||
|
||||
pub fn get_bone(&self, name_or_alias: String) -> Result<Option<Arc<Joint>>, crate::Error> {
|
||||
if name_or_alias.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
Ok(self.build_joint_dictionary()?.remove(&name_or_alias))
|
||||
}
|
||||
|
||||
pub fn get_default() -> Result<Self, crate::Error> {
|
||||
Ok(crate::skeleton_catalog::default_skeleton())
|
||||
}
|
||||
|
||||
pub fn load_with_method() -> Result<Self, crate::Error> {
|
||||
Self::get_default()
|
||||
}
|
||||
|
||||
pub fn load_with_string(file_name: Option<String>) -> Result<Self, crate::Error> {
|
||||
let Some(file_name) = file_name else {
|
||||
return Self::get_default();
|
||||
};
|
||||
let text = std::fs::read_to_string(file_name).map_err(|_| crate::Error::Argument)?;
|
||||
parse_skeleton_xml(&text)
|
||||
}
|
||||
|
||||
pub fn bone(&self) -> Joint {
|
||||
self.bone.clone()
|
||||
}
|
||||
|
||||
pub fn set_bone(&mut self, value: Joint) {
|
||||
self.bone = value;
|
||||
}
|
||||
|
||||
pub fn num_bones(&self) -> String {
|
||||
self.num_bones.clone()
|
||||
}
|
||||
|
||||
pub fn set_num_bones(&mut self, value: String) {
|
||||
self.num_bones = value;
|
||||
}
|
||||
|
||||
pub fn num_collision_volumes(&self) -> String {
|
||||
self.num_collision_volumes.clone()
|
||||
}
|
||||
|
||||
pub fn set_num_collision_volumes(&mut self, value: String) {
|
||||
self.num_collision_volumes = value;
|
||||
}
|
||||
|
||||
pub fn version(&self) -> f32 {
|
||||
self.version
|
||||
}
|
||||
|
||||
pub fn set_version(&mut self, value: f32) {
|
||||
self.version = value;
|
||||
}
|
||||
|
||||
pub fn version_specified(&self) -> bool {
|
||||
self.version_specified
|
||||
}
|
||||
|
||||
pub fn set_version_specified(&mut self, value: bool) {
|
||||
self.version_specified = value;
|
||||
}
|
||||
|
||||
pub(crate) fn from_parts(
|
||||
bone: Joint,
|
||||
version: f32,
|
||||
version_specified: bool,
|
||||
num_bones: String,
|
||||
num_collision_volumes: String,
|
||||
) -> Self {
|
||||
Self {
|
||||
bone,
|
||||
version,
|
||||
version_specified,
|
||||
num_bones,
|
||||
num_collision_volumes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_joints(root: &Joint) -> Vec<Arc<Joint>> {
|
||||
fn visit(joint: &Joint, output: &mut Vec<Arc<Joint>>) {
|
||||
output.push(Arc::new(joint.clone()));
|
||||
if let Some(children) = &joint.bone {
|
||||
for child in children {
|
||||
visit(child, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut output = Vec::new();
|
||||
visit(root, &mut output);
|
||||
output
|
||||
}
|
||||
|
||||
fn expand_joint(
|
||||
current: &Joint,
|
||||
effective_parent: &str,
|
||||
expanded: &mut Vec<String>,
|
||||
filter: &[String],
|
||||
) {
|
||||
let mut next_effective_parent = effective_parent;
|
||||
if filter.iter().any(|name| name == ¤t.base.name) {
|
||||
let parent_matches_last = expanded.last().is_some_and(|last| last == effective_parent);
|
||||
if !parent_matches_last && filter.iter().any(|name| name == effective_parent) {
|
||||
expanded.push(effective_parent.to_owned());
|
||||
}
|
||||
expanded.push(current.base.name.clone());
|
||||
next_effective_parent = ¤t.base.name;
|
||||
}
|
||||
if let Some(children) = ¤t.bone {
|
||||
for child in children {
|
||||
expand_joint(child, next_effective_parent, expanded, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_error(position: usize) -> crate::Error {
|
||||
crate::Error::Parse {
|
||||
position,
|
||||
context: "avatar skeleton XML",
|
||||
}
|
||||
}
|
||||
|
||||
fn node_position(node: Node<'_, '_>) -> usize {
|
||||
node.range().start
|
||||
}
|
||||
|
||||
fn required_attribute<'a>(node: Node<'a, '_>, name: &str) -> Result<&'a str, crate::Error> {
|
||||
node.attribute(name)
|
||||
.filter(|value| !value.is_empty())
|
||||
.ok_or_else(|| parse_error(node_position(node)))
|
||||
}
|
||||
|
||||
fn vector_attribute(node: Node<'_, '_>, name: &str) -> Result<Vec<f32>, crate::Error> {
|
||||
let Some(value) = node.attribute(name) else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
let values = value
|
||||
.split_ascii_whitespace()
|
||||
.map(str::parse::<f32>)
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|_| parse_error(node_position(node)))?;
|
||||
if values.len() != 3 || values.iter().any(|value| !value.is_finite()) {
|
||||
return Err(parse_error(node_position(node)));
|
||||
}
|
||||
Ok(values)
|
||||
}
|
||||
|
||||
fn boolean_attribute(node: Node<'_, '_>, name: &str) -> Result<bool, crate::Error> {
|
||||
match node.attribute(name) {
|
||||
None => Ok(false),
|
||||
Some(value) if value.eq_ignore_ascii_case("true") => Ok(true),
|
||||
Some(value) if value.eq_ignore_ascii_case("false") => Ok(false),
|
||||
Some(_) => Err(parse_error(node_position(node))),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_base(node: Node<'_, '_>) -> Result<JointBase, crate::Error> {
|
||||
let support = node.attribute("support").unwrap_or_default();
|
||||
if !support.is_empty()
|
||||
&& !support.eq_ignore_ascii_case("base")
|
||||
&& !support.eq_ignore_ascii_case("extended")
|
||||
{
|
||||
return Err(parse_error(node_position(node)));
|
||||
}
|
||||
Ok(JointBase::from_parts(
|
||||
required_attribute(node, "name")?.to_owned(),
|
||||
vector_attribute(node, "pos")?,
|
||||
vector_attribute(node, "rot")?,
|
||||
vector_attribute(node, "scale")?,
|
||||
node.attribute("group").unwrap_or_default().to_owned(),
|
||||
support.to_owned(),
|
||||
vector_attribute(node, "end")?,
|
||||
boolean_attribute(node, "reposition")?,
|
||||
))
|
||||
}
|
||||
|
||||
fn parse_joint(node: Node<'_, '_>, names: &mut HashSet<String>) -> Result<Joint, crate::Error> {
|
||||
if !node.has_tag_name("bone") {
|
||||
return Err(parse_error(node_position(node)));
|
||||
}
|
||||
let base = parse_base(node)?;
|
||||
if !names.insert(base.name.clone()) {
|
||||
return Err(parse_error(node_position(node)));
|
||||
}
|
||||
let aliases = node.attribute("aliases").unwrap_or_default().to_owned();
|
||||
for alias in aliases.split_ascii_whitespace() {
|
||||
if !names.insert(alias.to_owned()) {
|
||||
return Err(parse_error(node_position(node)));
|
||||
}
|
||||
}
|
||||
let mut collision_volumes = Vec::new();
|
||||
let mut bones = Vec::new();
|
||||
for child in node.children().filter(Node::is_element) {
|
||||
if child.has_tag_name("collision_volume") {
|
||||
if child.children().any(|node| node.is_element()) {
|
||||
return Err(parse_error(node_position(child)));
|
||||
}
|
||||
collision_volumes.push(CollisionVolume::from_base(parse_base(child)?));
|
||||
} else if child.has_tag_name("bone") {
|
||||
bones.push(parse_joint(child, names)?);
|
||||
} else {
|
||||
return Err(parse_error(node_position(child)));
|
||||
}
|
||||
}
|
||||
Ok(Joint::from_parts(
|
||||
base,
|
||||
collision_volumes,
|
||||
bones,
|
||||
vector_attribute(node, "pivot")?,
|
||||
aliases,
|
||||
boolean_attribute(node, "connected")?,
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_skeleton_xml(text: &str) -> Result<LindenSkeleton, crate::Error> {
|
||||
let document = Document::parse(text).map_err(|_| parse_error(0))?;
|
||||
let root = document.root_element();
|
||||
if !root.has_tag_name("linden_skeleton") {
|
||||
return Err(parse_error(node_position(root)));
|
||||
}
|
||||
let version_text = required_attribute(root, "version")?;
|
||||
let version = version_text
|
||||
.parse::<f32>()
|
||||
.map_err(|_| parse_error(node_position(root)))?;
|
||||
if !version.is_finite() {
|
||||
return Err(parse_error(node_position(root)));
|
||||
}
|
||||
let num_bones = required_attribute(root, "num_bones")?.to_owned();
|
||||
let expected_bones = num_bones
|
||||
.parse::<usize>()
|
||||
.map_err(|_| parse_error(node_position(root)))?;
|
||||
let num_collision_volumes = required_attribute(root, "num_collision_volumes")?.to_owned();
|
||||
let expected_collision_volumes = num_collision_volumes
|
||||
.parse::<usize>()
|
||||
.map_err(|_| parse_error(node_position(root)))?;
|
||||
let root_bones = root.children().filter(Node::is_element).collect::<Vec<_>>();
|
||||
if root_bones.len() != 1 || !root_bones[0].has_tag_name("bone") {
|
||||
return Err(parse_error(node_position(root)));
|
||||
}
|
||||
let mut names = HashSet::new();
|
||||
let bone = parse_joint(root_bones[0], &mut names)?;
|
||||
let (actual_bones, actual_collision_volumes) = skeleton_counts(&bone);
|
||||
if actual_bones != expected_bones || actual_collision_volumes != expected_collision_volumes {
|
||||
return Err(parse_error(node_position(root)));
|
||||
}
|
||||
Ok(LindenSkeleton::from_parts(
|
||||
bone,
|
||||
version,
|
||||
true,
|
||||
num_bones,
|
||||
num_collision_volumes,
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn skeleton_counts(root: &Joint) -> (usize, usize) {
|
||||
let mut bones = 1;
|
||||
let mut collision_volumes = root.collision_volume.len();
|
||||
if let Some(children) = &root.bone {
|
||||
for child in children {
|
||||
let (child_bones, child_collision_volumes) = skeleton_counts(child);
|
||||
bones += child_bones;
|
||||
collision_volumes += child_collision_volumes;
|
||||
}
|
||||
}
|
||||
(bones, collision_volumes)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn runtime_parser_rejects_count_mismatches_and_unknown_children() {
|
||||
let wrong_count = "<linden_skeleton version=\"1\" num_bones=\"2\" num_collision_volumes=\"0\"><bone name=\"root\"/></linden_skeleton>";
|
||||
assert!(matches!(
|
||||
parse_skeleton_xml(wrong_count),
|
||||
Err(crate::Error::Parse { .. })
|
||||
));
|
||||
let unknown = "<linden_skeleton version=\"1\" num_bones=\"1\" num_collision_volumes=\"0\"><bone name=\"root\"><unknown/></bone></linden_skeleton>";
|
||||
assert!(matches!(
|
||||
parse_skeleton_xml(unknown),
|
||||
Err(crate::Error::Parse { .. })
|
||||
));
|
||||
}
|
||||
}
|
||||
996
crates/libremetaverse/src/skeleton_catalog.rs
Normal file
996
crates/libremetaverse/src/skeleton_catalog.rs
Normal file
@@ -0,0 +1,996 @@
|
||||
// @generated by libremetaverse-codegen; DO NOT EDIT.
|
||||
// Regenerate: cargo run -p libremetaverse-codegen -- generate
|
||||
// Generator: skeleton
|
||||
// Source: codegen/inputs/avatar_skeleton.xml sha256=addb3cc4cd582ed4343d778e06daf90c6b77b61b4ecb4a20d4bf202c2b93908a license=BSD-3-Clause
|
||||
|
||||
#![allow(clippy::float_cmp, clippy::too_many_lines, clippy::unreadable_literal)]
|
||||
pub(crate) fn default_skeleton() -> crate::skeleton::LindenSkeleton {
|
||||
crate::skeleton::LindenSkeleton::from_parts(
|
||||
crate::skeleton::Joint::from_parts(
|
||||
crate::skeleton::JointBase::from_parts(
|
||||
"mPelvis".to_owned(),
|
||||
vec![0.0_f32, 0.0_f32, 1.067_f32],
|
||||
vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32],
|
||||
"Torso".to_owned(),
|
||||
"base".to_owned(),
|
||||
vec![0.0_f32, 0.0_f32, 0.084_f32],
|
||||
true,
|
||||
),
|
||||
vec![
|
||||
crate ::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("PELVIS".to_owned(), vec![- 0.01_f32,
|
||||
0.0_f32,- 0.02_f32], vec![0.0_f32, 8.0_f32, 0.0_f32], vec![0.12_f32,
|
||||
0.16_f32, 0.17_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.03_f32, 0.0_f32, 0.095_f32], true)), crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("BUTT".to_owned(), vec![- 0.06_f32,
|
||||
0.0_f32,- 0.1_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![0.1_f32,
|
||||
0.1_f32, 0.1_f32], "Collision".to_owned(), "base".to_owned(), vec![-
|
||||
0.1_f32, 0.0_f32, 0.0_f32], true))
|
||||
],
|
||||
vec![
|
||||
crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mSpine1".to_owned(), vec![0.0_f32,
|
||||
0.0_f32, 0.084_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Spine".to_owned(), "extended".to_owned(),
|
||||
vec![0.0_f32, 0.0_f32,- 0.084_f32], false), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mSpine2".to_owned(), vec![0.0_f32,
|
||||
0.0_f32,- 0.084_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Spine".to_owned(), "extended".to_owned(),
|
||||
vec![0.0_f32, 0.0_f32, 0.084_f32], false), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mTorso".to_owned(), vec![0.0_f32,
|
||||
0.0_f32, 0.084_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Torso".to_owned(), "base".to_owned(), vec![-
|
||||
0.015_f32, 0.0_f32, 0.205_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("BELLY".to_owned(), vec![0.028_f32,
|
||||
0.0_f32, 0.04_f32], vec![0.0_f32, 8.0_f32, 0.0_f32], vec![0.09_f32,
|
||||
0.13_f32, 0.15_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.028_f32, 0.0_f32, 0.094_f32], true)), crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("LEFT_HANDLE".to_owned(), vec![0.0_f32,
|
||||
0.1_f32, 0.058_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![0.05_f32,
|
||||
0.05_f32, 0.05_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32, 0.1_f32, 0.0_f32], true)), crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("RIGHT_HANDLE".to_owned(),
|
||||
vec![0.0_f32,- 0.1_f32, 0.058_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![0.05_f32, 0.05_f32, 0.05_f32], "Collision".to_owned(), "base"
|
||||
.to_owned(), vec![0.0_f32,- 0.1_f32, 0.0_f32], true)), crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("LOWER_BACK".to_owned(), vec![0.0_f32,
|
||||
0.0_f32, 0.023_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![0.09_f32,
|
||||
0.13_f32, 0.15_f32], "Collision".to_owned(), "base".to_owned(), vec![-
|
||||
0.1_f32, 0.0_f32, 0.0_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mSpine3".to_owned(), vec![- 0.015_f32,
|
||||
0.0_f32, 0.205_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Spine".to_owned(), "extended".to_owned(),
|
||||
vec![0.015_f32, 0.0_f32,- 0.205_f32], false), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mSpine4".to_owned(), vec![0.015_f32,
|
||||
0.0_f32,- 0.205_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Spine".to_owned(), "extended".to_owned(), vec![-
|
||||
0.015_f32, 0.0_f32, 0.205_f32], false), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mChest".to_owned(), vec![- 0.015_f32,
|
||||
0.0_f32, 0.205_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Torso".to_owned(), "base".to_owned(), vec![-
|
||||
0.01_f32, 0.0_f32, 0.25_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("CHEST".to_owned(), vec![0.028_f32,
|
||||
0.0_f32, 0.07_f32], vec![0.0_f32,- 10.0_f32, 0.0_f32], vec![0.11_f32,
|
||||
0.15_f32, 0.2_f32], "Collision".to_owned(), "base".to_owned(), vec![-
|
||||
0.096_f32, 0.0_f32, 0.152_f32], true)), crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("LEFT_PEC".to_owned(), vec![0.119_f32,
|
||||
0.082_f32, 0.042_f32], vec![0.0_f32, 4.29_f32, 0.0_f32], vec![0.05_f32,
|
||||
0.05_f32, 0.05_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.08_f32, 0.0_f32,- 0.006_f32], true)), crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("RIGHT_PEC".to_owned(),
|
||||
vec![0.119_f32,- 0.082_f32, 0.042_f32], vec![0.0_f32, 4.29_f32, 0.0_f32],
|
||||
vec![0.05_f32, 0.05_f32, 0.05_f32], "Collision".to_owned(), "base"
|
||||
.to_owned(), vec![0.08_f32, 0.0_f32,- 0.006_f32], true)), crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("UPPER_BACK".to_owned(), vec![0.0_f32,
|
||||
0.0_f32, 0.017_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![0.09_f32,
|
||||
0.13_f32, 0.15_f32], "Collision".to_owned(), "base".to_owned(), vec![-
|
||||
0.1_f32, 0.0_f32, 0.0_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mNeck".to_owned(), vec![- 0.01_f32,
|
||||
0.0_f32, 0.251_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Torso".to_owned(), "base".to_owned(), vec![0.0_f32,
|
||||
0.0_f32, 0.077_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("NECK".to_owned(), vec![0.0_f32,
|
||||
0.0_f32, 0.02_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![0.05_f32,
|
||||
0.06_f32, 0.08_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32, 0.0_f32, 0.08_f32], false))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHead".to_owned(), vec![0.0_f32,-
|
||||
0.0_f32, 0.076_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Torso".to_owned(), "base".to_owned(), vec![0.0_f32,
|
||||
0.0_f32, 0.079_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("HEAD".to_owned(), vec![0.02_f32,
|
||||
0.0_f32, 0.07_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![0.11_f32,
|
||||
0.09_f32, 0.12_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32, 0.0_f32, 0.1_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mSkull".to_owned(), vec![0.0_f32,
|
||||
0.0_f32, 0.079_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Extra".to_owned(), "base".to_owned(), vec![0.0_f32,
|
||||
0.0_f32, 0.033_f32], true), vec![], vec![], vec![0.0_f32, 0.0_f32,
|
||||
0.079_f32], "figureHair avatar_mSkull".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mEyeRight".to_owned(),
|
||||
vec![0.098_f32,- 0.036_f32, 0.079_f32], vec![0.0_f32, 0.0_f32,- 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Extra".to_owned(), "base".to_owned(),
|
||||
vec![0.025_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.098466_f32,- 0.036_f32, 0.079_f32], "avatar_mEyeRight".to_owned(),
|
||||
false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mEyeLeft".to_owned(), vec![0.098_f32,
|
||||
0.036_f32, 0.079_f32], vec![0.0_f32,- 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Extra".to_owned(), "base".to_owned(), vec![0.025_f32,
|
||||
0.0_f32, 0.0_f32], true), vec![], vec![], vec![0.098461_f32, 0.036_f32,
|
||||
0.079_f32], "avatar_mEyeLeft".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceRoot".to_owned(), vec![0.025_f32,
|
||||
0.0_f32, 0.045_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Face".to_owned(), "extended".to_owned(),
|
||||
vec![0.02_f32, 0.0_f32, 0.0_f32], false), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyeAltRight".to_owned(),
|
||||
vec![0.073_f32,- 0.036_f32, 0.034_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.025_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.073466_f32,- 0.036_f32, 0.03393_f32], "avatar_mFaceEyeAltRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyeAltLeft".to_owned(),
|
||||
vec![0.073_f32, 0.036_f32, 0.034_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.025_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.073461_f32, 0.036_f32, 0.03393_f32], "avatar_mFaceEyeAltLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceForeheadLeft".to_owned(),
|
||||
vec![0.061_f32, 0.035_f32, 0.083_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.024_f32, 0.004_f32, 0.018_f32], true), vec![],
|
||||
vec![], vec![0.061_f32, 0.035_f32, 0.083_f32], "avatar_mFaceForeheadLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceForeheadRight".to_owned(),
|
||||
vec![0.061_f32,- 0.035_f32, 0.083_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.024_f32,- 0.004_f32, 0.018_f32], true), vec![],
|
||||
vec![], vec![0.061_f32,- 0.035_f32, 0.083_f32],
|
||||
"avatar_mFaceForeheadRight".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyebrowOuterLeft".to_owned(),
|
||||
vec![0.064_f32, 0.051_f32, 0.048_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.023_f32, 0.013_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.064_f32, 0.051_f32, 0.048_f32], "avatar_mFaceEyebrowOuterLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyebrowCenterLeft".to_owned(),
|
||||
vec![0.07_f32, 0.043_f32, 0.056_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.027_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.07_f32, 0.043_f32, 0.056_f32], "avatar_mFaceEyebrowCenterLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyebrowInnerLeft".to_owned(),
|
||||
vec![0.075_f32, 0.022_f32, 0.051_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.026_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.075_f32, 0.022_f32, 0.051_f32], "avatar_mFaceEyebrowInnerLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyebrowOuterRight".to_owned(),
|
||||
vec![0.064_f32,- 0.051_f32, 0.048_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.023_f32,- 0.013_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.064_f32,- 0.051_f32, 0.048_f32], "avatar_mFaceEyebrowOuterRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyebrowCenterRight".to_owned(),
|
||||
vec![0.07_f32,- 0.043_f32, 0.056_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.027_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.07_f32,- 0.043_f32, 0.056_f32], "avatar_mFaceEyebrowCenterRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyebrowInnerRight".to_owned(),
|
||||
vec![0.075_f32,- 0.022_f32, 0.051_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.026_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.075_f32,- 0.022_f32, 0.051_f32], "avatar_mFaceEyebrowInnerRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyeLidUpperLeft".to_owned(),
|
||||
vec![0.073_f32, 0.036_f32, 0.034_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.027_f32, 0.0_f32, 0.005_f32], true), vec![], vec![],
|
||||
vec![0.073_f32, 0.036_f32, 0.034_f32], "avatar_mFaceEyeLidUpperLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyeLidLowerLeft".to_owned(),
|
||||
vec![0.073_f32, 0.036_f32, 0.034_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.024_f32, 0.0_f32,- 0.007_f32], true), vec![], vec![],
|
||||
vec![0.073_f32, 0.036_f32, 0.034_f32], "avatar_mFaceEyeLidLowerLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyeLidUpperRight".to_owned(),
|
||||
vec![0.073_f32,- 0.036_f32, 0.034_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.027_f32, 0.0_f32, 0.005_f32], true), vec![], vec![],
|
||||
vec![0.073_f32,- 0.036_f32, 0.034_f32], "avatar_mFaceEyeLidUpperRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyeLidLowerRight".to_owned(),
|
||||
vec![0.073_f32,- 0.036_f32, 0.034_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Eyes".to_owned(), "extended"
|
||||
.to_owned(), vec![0.024_f32, 0.0_f32,- 0.007_f32], true), vec![], vec![],
|
||||
vec![0.073_f32,- 0.036_f32, 0.034_f32], "avatar_mFaceEyeLidLowerRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEar1Left".to_owned(),
|
||||
vec![0.0_f32, 0.08_f32, 0.002_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Ears".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.019_f32, 0.018_f32, 0.025_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEar2Left".to_owned(), vec![-
|
||||
0.019_f32, 0.018_f32, 0.025_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Ears".to_owned(), "extended"
|
||||
.to_owned(), vec![0.0_f32, 0.0_f32, 0.033_f32], true), vec![], vec![],
|
||||
vec![- 0.019_f32, 0.018_f32, 0.025_f32], "avatar_mFaceEar2Left"
|
||||
.to_owned(), true)], vec![0.0_f32, 0.08_f32, 0.002_f32],
|
||||
"avatar_mFaceEar1Left".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEar1Right".to_owned(),
|
||||
vec![0.0_f32,- 0.08_f32, 0.002_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Ears".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.019_f32,- 0.018_f32, 0.025_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEar2Right".to_owned(), vec![-
|
||||
0.019_f32,- 0.018_f32, 0.025_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Ears".to_owned(), "extended"
|
||||
.to_owned(), vec![0.0_f32, 0.0_f32, 0.033_f32], true), vec![], vec![],
|
||||
vec![- 0.019_f32,- 0.018_f32, 0.025_f32], "avatar_mFaceEar2Right"
|
||||
.to_owned(), true)], vec![0.0_f32,- 0.08_f32, 0.002_f32],
|
||||
"avatar_mFaceEar1Right".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceNoseLeft".to_owned(),
|
||||
vec![0.086_f32, 0.015_f32,- 0.004_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.015_f32, 0.004_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.086_f32, 0.015_f32,- 0.004_f32], "avatar_mFaceNoseLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceNoseCenter".to_owned(),
|
||||
vec![0.102_f32, 0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.025_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.102_f32, 0.0_f32, 0.0_f32], "avatar_mFaceNoseCenter".to_owned(),
|
||||
false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceNoseRight".to_owned(),
|
||||
vec![0.086_f32,- 0.015_f32,- 0.004_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.015_f32,- 0.004_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.086_f32,- 0.015_f32,- 0.004_f32], "avatar_mFaceNoseRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceCheekLowerLeft".to_owned(),
|
||||
vec![0.05_f32, 0.034_f32,- 0.031_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.013_f32, 0.03_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.05_f32, 0.034_f32,- 0.031_f32], "avatar_mFaceCheekLowerLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceCheekUpperLeft".to_owned(),
|
||||
vec![0.07_f32, 0.034_f32,- 0.005_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.022_f32, 0.015_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.07_f32, 0.034_f32,- 0.005_f32], "avatar_mFaceCheekUpperLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceCheekLowerRight".to_owned(),
|
||||
vec![0.05_f32,- 0.034_f32,- 0.031_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.013_f32,- 0.03_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.05_f32,- 0.034_f32,- 0.031_f32], "avatar_mFaceCheekLowerRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceCheekUpperRight".to_owned(),
|
||||
vec![0.07_f32,- 0.034_f32,- 0.005_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.022_f32,- 0.015_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.07_f32,- 0.034_f32,- 0.005_f32], "avatar_mFaceCheekUpperRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceJaw".to_owned(), vec![-
|
||||
0.001_f32, 0.0_f32,- 0.015_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Mouth".to_owned(), "extended"
|
||||
.to_owned(), vec![0.059_f32, 0.0_f32,- 0.039_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceChin".to_owned(), vec![0.074_f32,
|
||||
0.0_f32,- 0.054_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Mouth".to_owned(), "extended".to_owned(),
|
||||
vec![0.021_f32, 0.0_f32,- 0.018_f32], true), vec![], vec![],
|
||||
vec![0.074_f32, 0.0_f32,- 0.054_f32], "avatar_mFaceChin".to_owned(),
|
||||
false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceTeethLower".to_owned(),
|
||||
vec![0.021_f32, 0.0_f32,- 0.039_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Mouth".to_owned(), "extended"
|
||||
.to_owned(), vec![0.035_f32, 0.0_f32, 0.0_f32], true), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceLipLowerLeft".to_owned(),
|
||||
vec![0.045_f32, 0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Lips".to_owned(), "extended"
|
||||
.to_owned(), vec![0.034_f32, 0.017_f32, 0.005_f32], true), vec![],
|
||||
vec![], vec![0.045_f32, 0.0_f32, 0.0_f32], "avatar_mFaceLipLowerLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceLipLowerRight".to_owned(),
|
||||
vec![0.045_f32, 0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Lips".to_owned(), "extended"
|
||||
.to_owned(), vec![0.034_f32,- 0.017_f32, 0.005_f32], true), vec![],
|
||||
vec![], vec![0.045_f32, 0.0_f32, 0.0_f32], "avatar_mFaceLipLowerRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceLipLowerCenter".to_owned(),
|
||||
vec![0.045_f32, 0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Lips".to_owned(), "extended"
|
||||
.to_owned(), vec![0.04_f32, 0.0_f32, 0.002_f32], true), vec![], vec![],
|
||||
vec![0.045_f32, 0.0_f32, 0.0_f32], "avatar_mFaceLipLowerCenter"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceTongueBase".to_owned(),
|
||||
vec![0.039_f32, 0.0_f32, 0.005_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Mouth".to_owned(), "extended"
|
||||
.to_owned(), vec![0.022_f32, 0.0_f32, 0.007_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceTongueTip".to_owned(),
|
||||
vec![0.022_f32, 0.0_f32, 0.007_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Mouth".to_owned(), "extended"
|
||||
.to_owned(), vec![0.01_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.022_f32, 0.0_f32, 0.007_f32], "avatar_mFaceTongueTip".to_owned(),
|
||||
true)], vec![0.039_f32, 0.0_f32, 0.005_f32], "avatar_mFaceTongueBase"
|
||||
.to_owned(), false)], vec![0.021_f32, 0.0_f32,- 0.039_f32],
|
||||
"avatar_mFaceTeethLower".to_owned(), false)], vec![- 0.001_f32, 0.0_f32,-
|
||||
0.015_f32], "avatar_mFaceJaw".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceJawShaper".to_owned(),
|
||||
vec![0.0_f32, 0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.017_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.0_f32, 0.0_f32, 0.0_f32], "avatar_mFaceJawShaper".to_owned(),
|
||||
false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceForeheadCenter".to_owned(),
|
||||
vec![0.069_f32, 0.0_f32, 0.065_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.036_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.069_f32, 0.0_f32, 0.065_f32], "avatar_mFaceForeheadCenter"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceNoseBase".to_owned(),
|
||||
vec![0.094_f32, 0.0_f32,- 0.016_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Nose".to_owned(), "extended"
|
||||
.to_owned(), vec![0.014_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.094_f32, 0.0_f32,- 0.016_f32], "avatar_mFaceNoseBase".to_owned(),
|
||||
false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceTeethUpper".to_owned(),
|
||||
vec![0.02_f32, 0.0_f32,- 0.03_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Mouth".to_owned(), "extended"
|
||||
.to_owned(), vec![0.035_f32, 0.0_f32, 0.0_f32], true), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceLipUpperLeft".to_owned(),
|
||||
vec![0.045_f32, 0.0_f32,- 0.003_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Lips".to_owned(), "extended"
|
||||
.to_owned(), vec![0.041_f32, 0.015_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.045_f32, 0.0_f32,- 0.003_f32], "avatar_mFaceLipUpperLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceLipUpperRight".to_owned(),
|
||||
vec![0.045_f32, 0.0_f32,- 0.003_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Lips".to_owned(), "extended"
|
||||
.to_owned(), vec![0.041_f32,- 0.015_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.045_f32, 0.0_f32,- 0.003_f32], "avatar_mFaceLipUpperRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceLipCornerLeft".to_owned(),
|
||||
vec![0.028_f32,- 0.019_f32,- 0.01_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Lips".to_owned(), "extended"
|
||||
.to_owned(), vec![0.045_f32, 0.051_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.028_f32,- 0.019_f32,- 0.01_f32], "avatar_mFaceLipCornerLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceLipCornerRight".to_owned(),
|
||||
vec![0.028_f32, 0.019_f32,- 0.01_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Lips".to_owned(), "extended"
|
||||
.to_owned(), vec![0.045_f32,- 0.051_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.028_f32, 0.019_f32,- 0.01_f32], "avatar_mFaceLipCornerRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceLipUpperCenter".to_owned(),
|
||||
vec![0.045_f32, 0.0_f32,- 0.003_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Lips".to_owned(), "extended"
|
||||
.to_owned(), vec![0.043_f32, 0.0_f32, 0.002_f32], true), vec![], vec![],
|
||||
vec![0.045_f32, 0.0_f32,- 0.003_f32], "avatar_mFaceLipUpperCenter"
|
||||
.to_owned(), false)], vec![0.02_f32, 0.0_f32,- 0.03_f32],
|
||||
"avatar_mFaceTeethUpper".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyecornerInnerLeft".to_owned(),
|
||||
vec![0.075_f32, 0.017_f32, 0.032_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.016_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.075_f32, 0.017_f32, 0.032_f32], "avatar_mFaceEyecornerInnerLeft"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceEyecornerInnerRight".to_owned(),
|
||||
vec![0.075_f32,- 0.017_f32, 0.032_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Face".to_owned(), "extended"
|
||||
.to_owned(), vec![0.016_f32, 0.0_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.075_f32,- 0.017_f32, 0.032_f32], "avatar_mFaceEyecornerInnerRight"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFaceNoseBridge".to_owned(),
|
||||
vec![0.091_f32, 0.0_f32, 0.02_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Nose".to_owned(), "extended"
|
||||
.to_owned(), vec![0.015_f32, 0.0_f32, 0.008_f32], true), vec![], vec![],
|
||||
vec![0.091_f32, 0.0_f32, 0.02_f32], "avatar_mFaceNoseBridge".to_owned(),
|
||||
false)], vec![0.025_f32, 0.0_f32, 0.045_f32], "avatar_mFaceRoot"
|
||||
.to_owned(), false)], vec![0.0_f32,- 0.0_f32, 0.07563_f32],
|
||||
"head avatar_mHead".to_owned(), true)], vec![- 0.009507_f32, 0.0_f32,
|
||||
0.251108_f32], "neck avatar_mNeck".to_owned(), true), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mCollarLeft".to_owned(), vec![-
|
||||
0.021_f32, 0.085_f32, 0.165_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Arms".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32, 0.079_f32, 0.0_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("L_CLAVICLE".to_owned(), vec![0.02_f32,
|
||||
0.0_f32, 0.02_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![0.07_f32,
|
||||
0.14_f32, 0.05_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32, 0.1_f32, 0.0_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mShoulderLeft".to_owned(),
|
||||
vec![0.0_f32, 0.079_f32,- 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Arms".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32, 0.247_f32, 0.0_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("L_UPPER_ARM".to_owned(), vec![0.0_f32,
|
||||
0.12_f32, 0.01_f32], vec![- 5.0_f32, 0.0_f32, 0.0_f32], vec![0.05_f32,
|
||||
0.17_f32, 0.05_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32, 0.13_f32,- 0.003_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mElbowLeft".to_owned(), vec![0.0_f32,
|
||||
0.248_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Arms".to_owned(), "base".to_owned(), vec![0.0_f32,
|
||||
0.205_f32, 0.0_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("L_LOWER_ARM".to_owned(), vec![0.0_f32,
|
||||
0.1_f32, 0.0_f32], vec![- 3.0_f32, 0.0_f32, 0.0_f32], vec![0.04_f32,
|
||||
0.14_f32, 0.04_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32, 0.1_f32,- 0.001_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWristLeft".to_owned(), vec![-
|
||||
0.0_f32, 0.205_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Arms".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32, 0.06_f32, 0.0_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("L_HAND".to_owned(), vec![0.01_f32,
|
||||
0.05_f32, 0.0_f32], vec![- 3.0_f32, 0.0_f32,- 10.0_f32], vec![0.05_f32,
|
||||
0.08_f32, 0.03_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.005_f32, 0.049_f32,- 0.001_f32], false))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandMiddle1Left".to_owned(),
|
||||
vec![0.013_f32, 0.101_f32, 0.015_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.001_f32, 0.04_f32,- 0.006_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandMiddle2Left".to_owned(), vec![-
|
||||
0.001_f32, 0.04_f32,- 0.006_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.001_f32, 0.049_f32,- 0.008_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandMiddle3Left".to_owned(), vec![-
|
||||
0.001_f32, 0.049_f32,- 0.008_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.002_f32, 0.033_f32,- 0.006_f32], false), vec![],
|
||||
vec![], vec![- 0.001_f32, 0.049_f32,- 0.008_f32],
|
||||
"avatar_mHandMiddle3Left".to_owned(), true)], vec![- 0.001_f32,
|
||||
0.04_f32,- 0.006_f32], "avatar_mHandMiddle2Left".to_owned(), true)],
|
||||
vec![0.013_f32, 0.101_f32, 0.015_f32], "avatar_mHandMiddle1Left"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandIndex1Left".to_owned(),
|
||||
vec![0.038_f32, 0.097_f32, 0.015_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.017_f32, 0.036_f32,- 0.006_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandIndex2Left".to_owned(),
|
||||
vec![0.017_f32, 0.036_f32,- 0.006_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.014_f32, 0.032_f32,- 0.006_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandIndex3Left".to_owned(),
|
||||
vec![0.014_f32, 0.032_f32,- 0.006_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.011_f32, 0.025_f32,- 0.004_f32], false), vec![],
|
||||
vec![], vec![0.014_f32, 0.032_f32,- 0.006_f32], "avatar_mHandIndex3Left"
|
||||
.to_owned(), true)], vec![0.017_f32, 0.036_f32,- 0.006_f32],
|
||||
"avatar_mHandIndex2Left".to_owned(), true)], vec![0.038_f32, 0.097_f32,
|
||||
0.015_f32], "avatar_mHandIndex1Left".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandRing1Left".to_owned(), vec![-
|
||||
0.01_f32, 0.099_f32, 0.009_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.013_f32, 0.038_f32,- 0.008_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandRing2Left".to_owned(), vec![-
|
||||
0.013_f32, 0.038_f32,- 0.008_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.013_f32, 0.04_f32,- 0.009_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandRing3Left".to_owned(), vec![-
|
||||
0.013_f32, 0.04_f32,- 0.009_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.01_f32, 0.028_f32,- 0.006_f32], false), vec![],
|
||||
vec![], vec![- 0.013_f32, 0.04_f32,- 0.009_f32], "avatar_mHandRing3Left"
|
||||
.to_owned(), true)], vec![- 0.013_f32, 0.038_f32,- 0.008_f32],
|
||||
"avatar_mHandRing2Left".to_owned(), true)], vec![- 0.01_f32, 0.099_f32,
|
||||
0.009_f32], "avatar_mHandRing1Left".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandPinky1Left".to_owned(), vec![-
|
||||
0.031_f32, 0.095_f32, 0.003_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.024_f32, 0.025_f32,- 0.006_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandPinky2Left".to_owned(), vec![-
|
||||
0.024_f32, 0.025_f32,- 0.006_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.015_f32, 0.018_f32,- 0.004_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandPinky3Left".to_owned(), vec![-
|
||||
0.015_f32, 0.018_f32,- 0.004_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.013_f32, 0.016_f32,- 0.004_f32], false), vec![],
|
||||
vec![], vec![- 0.015_f32, 0.018_f32,- 0.004_f32],
|
||||
"avatar_mHandPinky3Left".to_owned(), true)], vec![- 0.024_f32,
|
||||
0.025_f32,- 0.006_f32], "avatar_mHandPinky2Left".to_owned(), true)],
|
||||
vec![- 0.031_f32, 0.095_f32, 0.003_f32], "avatar_mHandPinky1Left"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandThumb1Left".to_owned(),
|
||||
vec![0.031_f32, 0.026_f32, 0.004_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.028_f32, 0.032_f32, 0.0_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandThumb2Left".to_owned(),
|
||||
vec![0.028_f32, 0.032_f32,- 0.001_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.023_f32, 0.031_f32, 0.0_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandThumb3Left".to_owned(),
|
||||
vec![0.023_f32, 0.031_f32,- 0.001_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.015_f32, 0.025_f32, 0.0_f32], false), vec![], vec![],
|
||||
vec![0.023_f32, 0.031_f32,- 0.001_f32], "avatar_mHandThumb3Left"
|
||||
.to_owned(), true)], vec![0.028_f32, 0.032_f32,- 0.001_f32],
|
||||
"avatar_mHandThumb2Left".to_owned(), true)], vec![0.031_f32, 0.026_f32,
|
||||
0.004_f32], "avatar_mHandThumb1Left".to_owned(), false)], vec![- 0.0_f32,
|
||||
0.204846_f32, 0.0_f32], "lHand avatar_mWristLeft".to_owned(), true)],
|
||||
vec![0.0_f32, 0.248_f32, 0.0_f32], "lForeArm avatar_mElbowLeft"
|
||||
.to_owned(), true)], vec![0.0_f32, 0.079_f32,- 0.0_f32],
|
||||
"lShldr avatar_mShoulderLeft".to_owned(), true)], vec![- 0.020927_f32,
|
||||
0.084665_f32, 0.165396_f32], "lCollar avatar_mCollarLeft".to_owned(),
|
||||
false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mCollarRight".to_owned(), vec![-
|
||||
0.021_f32,- 0.085_f32, 0.165_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Arms".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32,- 0.079_f32, 0.0_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("R_CLAVICLE".to_owned(), vec![0.02_f32,
|
||||
0.0_f32, 0.02_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![0.07_f32,
|
||||
0.14_f32, 0.05_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32,- 0.1_f32, 0.0_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mShoulderRight".to_owned(),
|
||||
vec![0.0_f32,- 0.079_f32,- 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Arms".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32,- 0.247_f32, 0.0_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("R_UPPER_ARM".to_owned(),
|
||||
vec![0.0_f32,- 0.12_f32, 0.01_f32], vec![5.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![0.05_f32, 0.17_f32, 0.05_f32], "Collision".to_owned(), "base"
|
||||
.to_owned(), vec![0.0_f32,- 0.13_f32,- 0.003_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mElbowRight".to_owned(),
|
||||
vec![0.0_f32,- 0.248_f32,- 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Arms".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32,- 0.205_f32, 0.0_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("R_LOWER_ARM".to_owned(),
|
||||
vec![0.0_f32,- 0.1_f32, 0.0_f32], vec![3.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![0.04_f32, 0.14_f32, 0.04_f32], "Collision".to_owned(), "base"
|
||||
.to_owned(), vec![0.0_f32,- 0.1_f32,- 0.001_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWristRight".to_owned(),
|
||||
vec![0.0_f32,- 0.205_f32,- 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Arms".to_owned(), "base".to_owned(),
|
||||
vec![0.0_f32,- 0.06_f32, 0.0_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("R_HAND".to_owned(), vec![0.01_f32,-
|
||||
0.05_f32, 0.0_f32], vec![3.0_f32, 0.0_f32, 10.0_f32], vec![0.05_f32,
|
||||
0.08_f32, 0.03_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.005_f32,- 0.049_f32,- 0.001_f32], false))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandMiddle1Right".to_owned(),
|
||||
vec![0.013_f32,- 0.101_f32, 0.015_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.001_f32,- 0.04_f32,- 0.006_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandMiddle2Right".to_owned(), vec![-
|
||||
0.001_f32,- 0.04_f32,- 0.006_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.001_f32,- 0.049_f32,- 0.008_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandMiddle3Right".to_owned(), vec![-
|
||||
0.001_f32,- 0.049_f32,- 0.008_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.002_f32,- 0.033_f32,- 0.006_f32], false), vec![],
|
||||
vec![], vec![- 0.001_f32,- 0.049_f32,- 0.008_f32],
|
||||
"avatar_mHandMiddle3Right".to_owned(), true)], vec![- 0.001_f32,-
|
||||
0.04_f32,- 0.006_f32], "avatar_mHandMiddle2Right".to_owned(), true)],
|
||||
vec![0.013_f32,- 0.101_f32, 0.015_f32], "avatar_mHandMiddle1Right"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandIndex1Right".to_owned(),
|
||||
vec![0.038_f32,- 0.097_f32, 0.015_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.017_f32,- 0.036_f32,- 0.006_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandIndex2Right".to_owned(),
|
||||
vec![0.017_f32,- 0.036_f32,- 0.006_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.014_f32,- 0.032_f32,- 0.006_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandIndex3Right".to_owned(),
|
||||
vec![0.014_f32,- 0.032_f32,- 0.006_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.011_f32,- 0.025_f32,- 0.004_f32], false), vec![],
|
||||
vec![], vec![0.014_f32,- 0.032_f32,- 0.006_f32],
|
||||
"avatar_mHandIndex3Right".to_owned(), true)], vec![0.017_f32,-
|
||||
0.036_f32,- 0.006_f32], "avatar_mHandIndex2Right".to_owned(), true)],
|
||||
vec![0.038_f32,- 0.097_f32, 0.015_f32], "avatar_mHandIndex1Right"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandRing1Right".to_owned(), vec![-
|
||||
0.01_f32,- 0.099_f32, 0.009_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.013_f32,- 0.038_f32,- 0.008_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandRing2Right".to_owned(), vec![-
|
||||
0.013_f32,- 0.038_f32,- 0.008_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.013_f32,- 0.04_f32,- 0.009_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandRing3Right".to_owned(), vec![-
|
||||
0.013_f32,- 0.04_f32,- 0.009_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.01_f32,- 0.028_f32,- 0.006_f32], false), vec![],
|
||||
vec![], vec![- 0.013_f32,- 0.04_f32,- 0.009_f32],
|
||||
"avatar_mHandRing3Right".to_owned(), true)], vec![- 0.013_f32,-
|
||||
0.038_f32,- 0.008_f32], "avatar_mHandRing2Right".to_owned(), true)],
|
||||
vec![- 0.01_f32,- 0.099_f32, 0.009_f32], "avatar_mHandRing1Right"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandPinky1Right".to_owned(), vec![-
|
||||
0.031_f32,- 0.095_f32, 0.003_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.024_f32,- 0.025_f32,- 0.006_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandPinky2Right".to_owned(), vec![-
|
||||
0.024_f32,- 0.025_f32,- 0.006_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.015_f32,- 0.018_f32,- 0.004_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandPinky3Right".to_owned(), vec![-
|
||||
0.015_f32,- 0.018_f32,- 0.004_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.013_f32,- 0.016_f32,- 0.004_f32], false), vec![],
|
||||
vec![], vec![- 0.015_f32,- 0.018_f32,- 0.004_f32],
|
||||
"avatar_mHandPinky3Right".to_owned(), true)], vec![- 0.024_f32,-
|
||||
0.025_f32,- 0.006_f32], "avatar_mHandPinky2Right".to_owned(), true)],
|
||||
vec![- 0.031_f32,- 0.095_f32, 0.003_f32], "avatar_mHandPinky1Right"
|
||||
.to_owned(), false), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandThumb1Right".to_owned(),
|
||||
vec![0.031_f32,- 0.026_f32, 0.004_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.028_f32,- 0.032_f32, 0.0_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandThumb2Right".to_owned(),
|
||||
vec![0.028_f32,- 0.032_f32,- 0.001_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.023_f32,- 0.031_f32, 0.0_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHandThumb3Right".to_owned(),
|
||||
vec![0.023_f32,- 0.031_f32,- 0.001_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Hand".to_owned(), "extended"
|
||||
.to_owned(), vec![0.015_f32,- 0.025_f32, 0.0_f32], false), vec![],
|
||||
vec![], vec![0.023_f32,- 0.031_f32,- 0.001_f32],
|
||||
"avatar_mHandThumb3Right".to_owned(), true)], vec![0.028_f32,-
|
||||
0.032_f32,- 0.001_f32], "avatar_mHandThumb2Right".to_owned(), true)],
|
||||
vec![0.031_f32,- 0.026_f32, 0.004_f32], "avatar_mHandThumb1Right"
|
||||
.to_owned(), false)], vec![- 0.0_f32,- 0.205_f32,- 0.0_f32],
|
||||
"rHand avatar_mWristRight".to_owned(), true)], vec![0.0_f32,- 0.248_f32,-
|
||||
0.0_f32], "rForeArm avatar_mElbowRight".to_owned(), true)],
|
||||
vec![0.0_f32,- 0.079418_f32,- 0.0_f32], "rShldr avatar_mShoulderRight"
|
||||
.to_owned(), true)], vec![- 0.020927_f32,- 0.085_f32, 0.165396_f32],
|
||||
"rCollar avatar_mCollarRight".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWingsRoot".to_owned(), vec![-
|
||||
0.014_f32, 0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.061_f32, 0.0_f32, 0.0_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing1Left".to_owned(), vec![-
|
||||
0.099_f32, 0.105_f32, 0.181_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.168_f32, 0.169_f32, 0.067_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing2Left".to_owned(), vec![-
|
||||
0.168_f32, 0.169_f32, 0.067_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.181_f32, 0.183_f32, 0.0_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing3Left".to_owned(), vec![-
|
||||
0.181_f32, 0.183_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.171_f32, 0.173_f32, 0.0_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing4Left".to_owned(), vec![-
|
||||
0.171_f32, 0.173_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.146_f32, 0.132_f32, 0.0_f32], true), vec![],
|
||||
vec![], vec![- 0.171_f32, 0.173_f32, 0.0_f32], "avatar_mWing4Left"
|
||||
.to_owned(), true), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing4FanLeft".to_owned(), vec![-
|
||||
0.171_f32, 0.173_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.068_f32, 0.062_f32,- 0.159_f32], true), vec![],
|
||||
vec![], vec![- 0.171_f32, 0.173_f32, 0.0_f32], "avatar_mWing4FanLeft"
|
||||
.to_owned(), true)], vec![- 0.181_f32, 0.183_f32, 0.0_f32],
|
||||
"avatar_mWing3Left".to_owned(), true)], vec![- 0.168_f32, 0.169_f32,
|
||||
0.067_f32], "avatar_mWing2Left".to_owned(), true)], vec![- 0.099_f32,
|
||||
0.105_f32, 0.181_f32], "avatar_mWing1Left".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing1Right".to_owned(), vec![-
|
||||
0.099_f32,- 0.105_f32, 0.181_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.168_f32,- 0.169_f32, 0.067_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing2Right".to_owned(), vec![-
|
||||
0.168_f32,- 0.169_f32, 0.067_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.181_f32,- 0.183_f32, 0.0_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing3Right".to_owned(), vec![-
|
||||
0.181_f32,- 0.183_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.171_f32,- 0.173_f32, 0.0_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing4Right".to_owned(), vec![-
|
||||
0.171_f32,- 0.173_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.146_f32,- 0.132_f32, 0.0_f32], true), vec![],
|
||||
vec![], vec![- 0.171_f32,- 0.173_f32, 0.0_f32], "avatar_mWing4Right"
|
||||
.to_owned(), true), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mWing4FanRight".to_owned(), vec![-
|
||||
0.171_f32,- 0.173_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Wing".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.068_f32,- 0.062_f32,- 0.159_f32], true), vec![],
|
||||
vec![], vec![- 0.171_f32,- 0.173_f32, 0.0_f32], "avatar_mWing4FanRight"
|
||||
.to_owned(), true)], vec![- 0.181_f32,- 0.183_f32, 0.0_f32],
|
||||
"avatar_mWing3Right".to_owned(), true)], vec![- 0.168_f32,- 0.169_f32,
|
||||
0.067_f32], "avatar_mWing2Right".to_owned(), true)], vec![- 0.099_f32,-
|
||||
0.105_f32, 0.181_f32], "avatar_mWing1Right".to_owned(), false)], vec![-
|
||||
0.014_f32, 0.0_f32, 0.0_f32], "avatar_mWingsRoot".to_owned(), false)],
|
||||
vec![- 0.015368_f32, 0.0_f32, 0.204877_f32], "chest avatar_mChest"
|
||||
.to_owned(), true)], vec![0.015368_f32, 0.0_f32,- 0.204877_f32],
|
||||
"avatar_mSpine4".to_owned(), true)], vec![- 0.015368_f32, 0.0_f32,
|
||||
0.204877_f32], "avatar_mSpine3".to_owned(), true)], vec![0.0_f32,
|
||||
0.0_f32, 0.084073_f32], "abdomen avatar_mTorso".to_owned(), true)],
|
||||
vec![0.0_f32, 0.0_f32,- 0.084073_f32], "avatar_mSpine2".to_owned(),
|
||||
true)], vec![0.0_f32, 0.0_f32, 0.084073_f32], "avatar_mSpine1"
|
||||
.to_owned(), true), crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHipRight".to_owned(),
|
||||
vec![0.034_f32,- 0.129_f32,- 0.041_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Legs".to_owned(), "base".to_owned(),
|
||||
vec![- 0.001_f32, 0.049_f32,- 0.491_f32], true), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("R_UPPER_LEG".to_owned(), vec![-
|
||||
0.02_f32, 0.05_f32,- 0.22_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![0.09_f32, 0.09_f32, 0.32_f32], "Collision".to_owned(), "base"
|
||||
.to_owned(), vec![0.0_f32, 0.0_f32,- 0.2_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mKneeRight".to_owned(), vec![-
|
||||
0.001_f32, 0.049_f32,- 0.491_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Legs".to_owned(), "base".to_owned(),
|
||||
vec![- 0.029_f32, 0.0_f32,- 0.469_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("R_LOWER_LEG".to_owned(), vec![-
|
||||
0.02_f32, 0.0_f32,- 0.2_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![0.06_f32, 0.06_f32, 0.25_f32], "Collision".to_owned(), "base"
|
||||
.to_owned(), vec![- 0.01_f32, 0.0_f32,- 0.15_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mAnkleRight".to_owned(), vec![-
|
||||
0.029_f32, 0.0_f32,- 0.468_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Legs".to_owned(), "base".to_owned(),
|
||||
vec![0.112_f32, 0.0_f32,- 0.061_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("R_FOOT".to_owned(), vec![0.077_f32,
|
||||
0.0_f32,- 0.041_f32], vec![0.0_f32, 10.0_f32, 0.0_f32], vec![0.13_f32,
|
||||
0.05_f32, 0.05_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.089_f32, 0.0_f32,- 0.026_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFootRight".to_owned(),
|
||||
vec![0.112_f32,- 0.0_f32,- 0.061_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Extra".to_owned(), "base".to_owned(),
|
||||
vec![0.105_f32,- 0.01_f32, 0.0_f32], true), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mToeRight".to_owned(), vec![0.109_f32,
|
||||
0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Extra".to_owned(), "base".to_owned(), vec![0.02_f32,
|
||||
0.0_f32, 0.0_f32], false), vec![], vec![], vec![0.105399_f32,-
|
||||
0.010408_f32,- 0.000104_f32], "avatar_mToeRight".to_owned(), false)],
|
||||
vec![0.111956_f32,- 0.0_f32,- 0.060637_f32], "avatar_mFootRight"
|
||||
.to_owned(), true)], vec![- 0.028869_f32, 0.0_f32,- 0.468494_f32],
|
||||
"rFoot avatar_mAnkleRight".to_owned(), true)], vec![- 0.00078_f32,
|
||||
0.048635_f32,- 0.490922_f32], "rShin avatar_mKneeRight".to_owned(),
|
||||
true)], vec![0.03362_f32,- 0.128806_f32,- 0.041086_f32],
|
||||
"rThigh avatar_mHipRight".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHipLeft".to_owned(), vec![0.034_f32,
|
||||
0.127_f32,- 0.041_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Legs".to_owned(), "base".to_owned(), vec![-
|
||||
0.001_f32,- 0.046_f32,- 0.491_f32], true), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("L_UPPER_LEG".to_owned(), vec![-
|
||||
0.02_f32,- 0.05_f32,- 0.22_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![0.09_f32, 0.09_f32, 0.32_f32], "Collision".to_owned(), "base"
|
||||
.to_owned(), vec![0.0_f32, 0.0_f32,- 0.2_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mKneeLeft".to_owned(), vec![-
|
||||
0.001_f32,- 0.046_f32,- 0.491_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Legs".to_owned(), "base".to_owned(),
|
||||
vec![- 0.029_f32, 0.001_f32,- 0.469_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("L_LOWER_LEG".to_owned(), vec![-
|
||||
0.02_f32, 0.0_f32,- 0.2_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![0.06_f32, 0.06_f32, 0.25_f32], "Collision".to_owned(), "base"
|
||||
.to_owned(), vec![- 0.01_f32, 0.0_f32,- 0.15_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mAnkleLeft".to_owned(), vec![-
|
||||
0.029_f32, 0.001_f32,- 0.468_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Legs".to_owned(), "base".to_owned(),
|
||||
vec![0.112_f32, 0.0_f32,- 0.061_f32], false), vec![crate
|
||||
::skeleton::CollisionVolume::from_base(crate
|
||||
::skeleton::JointBase::from_parts("L_FOOT".to_owned(), vec![0.077_f32,
|
||||
0.0_f32,- 0.041_f32], vec![0.0_f32, 10.0_f32, 0.0_f32], vec![0.13_f32,
|
||||
0.05_f32, 0.05_f32], "Collision".to_owned(), "base".to_owned(),
|
||||
vec![0.089_f32, 0.0_f32,- 0.026_f32], true))], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mFootLeft".to_owned(),
|
||||
vec![0.112_f32,- 0.0_f32,- 0.061_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Extra".to_owned(), "base".to_owned(),
|
||||
vec![0.105_f32, 0.008_f32, 0.001_f32], true), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mToeLeft".to_owned(), vec![0.109_f32,
|
||||
0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Extra".to_owned(), "base".to_owned(), vec![0.02_f32,
|
||||
0.0_f32, 0.0_f32], false), vec![], vec![], vec![0.105387_f32,
|
||||
0.00827_f32, 0.000871_f32], "avatar_mToeLeft".to_owned(), false)],
|
||||
vec![0.111956_f32,- 0.0_f32,- 0.06062_f32], "avatar_mFootLeft"
|
||||
.to_owned(), true)], vec![- 0.028887_f32, 0.001378_f32,- 0.468449_f32],
|
||||
"lFoot avatar_mAnkleLeft".to_owned(), true)], vec![- 0.000887_f32,-
|
||||
0.045568_f32,- 0.491053_f32], "lShin avatar_mKneeLeft".to_owned(),
|
||||
true)], vec![0.033757_f32, 0.126765_f32,- 0.040998_f32],
|
||||
"lThigh avatar_mHipLeft".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mTail1".to_owned(), vec![- 0.116_f32,
|
||||
0.0_f32, 0.047_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Tail".to_owned(), "extended".to_owned(), vec![-
|
||||
0.197_f32, 0.0_f32, 0.0_f32], true), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mTail2".to_owned(), vec![- 0.197_f32,
|
||||
0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Tail".to_owned(), "extended".to_owned(), vec![-
|
||||
0.168_f32, 0.0_f32, 0.0_f32], true), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mTail3".to_owned(), vec![- 0.168_f32,
|
||||
0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Tail".to_owned(), "extended".to_owned(), vec![-
|
||||
0.142_f32, 0.0_f32, 0.0_f32], true), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mTail4".to_owned(), vec![- 0.142_f32,
|
||||
0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Tail".to_owned(), "extended".to_owned(), vec![-
|
||||
0.112_f32, 0.0_f32, 0.0_f32], true), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mTail5".to_owned(), vec![- 0.112_f32,
|
||||
0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Tail".to_owned(), "extended".to_owned(), vec![-
|
||||
0.094_f32, 0.0_f32, 0.0_f32], true), vec![], vec![crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mTail6".to_owned(), vec![- 0.094_f32,
|
||||
0.0_f32, 0.0_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Tail".to_owned(), "extended".to_owned(), vec![-
|
||||
0.089_f32, 0.0_f32, 0.0_f32], true), vec![], vec![], vec![- 0.094_f32,
|
||||
0.0_f32, 0.0_f32], "avatar_mTail6".to_owned(), true)], vec![- 0.112_f32,
|
||||
0.0_f32, 0.0_f32], "avatar_mTail5".to_owned(), true)], vec![- 0.142_f32,
|
||||
0.0_f32, 0.0_f32], "avatar_mTail4".to_owned(), true)], vec![- 0.168_f32,
|
||||
0.0_f32, 0.0_f32], "avatar_mTail3".to_owned(), true)], vec![- 0.197_f32,
|
||||
0.0_f32, 0.0_f32], "avatar_mTail2".to_owned(), true)], vec![- 0.116_f32,
|
||||
0.0_f32, 0.047_f32], "avatar_mTail1".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mGroin".to_owned(), vec![0.064_f32,
|
||||
0.0_f32,- 0.097_f32], vec![0.0_f32, 0.0_f32, 0.0_f32], vec![1.0_f32,
|
||||
1.0_f32, 1.0_f32], "Groin".to_owned(), "extended".to_owned(),
|
||||
vec![0.004_f32, 0.0_f32,- 0.066_f32], false), vec![], vec![],
|
||||
vec![0.064_f32, 0.0_f32,- 0.097_f32], "avatar_mGroin".to_owned(), false),
|
||||
crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHindLimbsRoot".to_owned(), vec![-
|
||||
0.2_f32, 0.0_f32, 0.084_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Limb".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.204_f32, 0.0_f32, 0.0_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHindLimb1Left".to_owned(), vec![-
|
||||
0.204_f32, 0.129_f32,- 0.125_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Limb".to_owned(), "extended"
|
||||
.to_owned(), vec![0.002_f32,- 0.046_f32,- 0.491_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHindLimb2Left".to_owned(),
|
||||
vec![0.002_f32,- 0.046_f32,- 0.491_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Limb".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.03_f32,- 0.003_f32,- 0.468_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHindLimb3Left".to_owned(), vec![-
|
||||
0.03_f32,- 0.003_f32,- 0.468_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Limb".to_owned(), "extended"
|
||||
.to_owned(), vec![0.112_f32, 0.0_f32,- 0.061_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHindLimb4Left".to_owned(),
|
||||
vec![0.112_f32, 0.0_f32,- 0.061_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Limb".to_owned(), "extended"
|
||||
.to_owned(), vec![0.105_f32, 0.008_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.112_f32, 0.0_f32,- 0.061_f32], "avatar_mHindLimb4Left".to_owned(),
|
||||
true)], vec![- 0.03_f32,- 0.003_f32,- 0.468_f32], "avatar_mHindLimb3Left"
|
||||
.to_owned(), true)], vec![0.002_f32,- 0.046_f32,- 0.491_f32],
|
||||
"avatar_mHindLimb2Left".to_owned(), true)], vec![- 0.204_f32, 0.129_f32,-
|
||||
0.125_f32], "avatar_mHindLimb1Left".to_owned(), false), crate
|
||||
::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHindLimb1Right".to_owned(), vec![-
|
||||
0.204_f32,- 0.129_f32,- 0.125_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Limb".to_owned(), "extended"
|
||||
.to_owned(), vec![0.002_f32, 0.046_f32,- 0.491_f32], true), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHindLimb2Right".to_owned(),
|
||||
vec![0.002_f32, 0.046_f32,- 0.491_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Limb".to_owned(), "extended"
|
||||
.to_owned(), vec![- 0.03_f32, 0.003_f32,- 0.468_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHindLimb3Right".to_owned(), vec![-
|
||||
0.03_f32, 0.003_f32,- 0.468_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Limb".to_owned(), "extended"
|
||||
.to_owned(), vec![0.112_f32, 0.0_f32,- 0.061_f32], false), vec![],
|
||||
vec![crate ::skeleton::Joint::from_parts(crate
|
||||
::skeleton::JointBase::from_parts("mHindLimb4Right".to_owned(),
|
||||
vec![0.112_f32, 0.0_f32,- 0.061_f32], vec![0.0_f32, 0.0_f32, 0.0_f32],
|
||||
vec![1.0_f32, 1.0_f32, 1.0_f32], "Limb".to_owned(), "extended"
|
||||
.to_owned(), vec![0.105_f32,- 0.008_f32, 0.0_f32], true), vec![], vec![],
|
||||
vec![0.112_f32, 0.0_f32,- 0.061_f32], "avatar_mHindLimb4Right"
|
||||
.to_owned(), true)], vec![- 0.03_f32, 0.003_f32,- 0.468_f32],
|
||||
"avatar_mHindLimb3Right".to_owned(), true)], vec![0.002_f32, 0.046_f32,-
|
||||
0.491_f32], "avatar_mHindLimb2Right".to_owned(), true)], vec![-
|
||||
0.204_f32,- 0.129_f32,- 0.125_f32], "avatar_mHindLimb1Right".to_owned(),
|
||||
false)], vec![- 0.2_f32, 0.0_f32, 0.084_f32], "avatar_mHindLimbsRoot"
|
||||
.to_owned(), false)
|
||||
],
|
||||
vec![0.0_f32, 0.0_f32, 1.067015_f32],
|
||||
"hip avatar_mPelvis".to_owned(),
|
||||
false,
|
||||
),
|
||||
2.0_f32,
|
||||
false,
|
||||
"133".to_owned(),
|
||||
"26".to_owned(),
|
||||
)
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn generated_default_shape() {
|
||||
let skeleton = default_skeleton();
|
||||
assert_eq!(skeleton.version(), 2.0);
|
||||
assert_eq!(skeleton.num_bones(), "133");
|
||||
assert_eq!(skeleton.num_collision_volumes(), "26");
|
||||
assert_eq!(skeleton.bone().base.name(), "mPelvis");
|
||||
}
|
||||
}
|
||||
208
crates/libremetaverse/tests/generated_avatar_catalogs.rs
Normal file
208
crates/libremetaverse/tests/generated_avatar_catalogs.rs
Normal file
@@ -0,0 +1,208 @@
|
||||
//! Golden fixtures for skeleton, attention, and genepool generation.
|
||||
|
||||
#![allow(clippy::float_cmp)] // Golden XML values must retain their exact f32 representation.
|
||||
|
||||
use libremetaverse::rendering::Joint;
|
||||
use libremetaverse::{Genepool, LindenAttentions, LookAtType};
|
||||
|
||||
fn skeleton_counts(root: &Joint) -> (usize, usize) {
|
||||
let mut bones = 1;
|
||||
let mut collision_volumes = root.collision_volume().len();
|
||||
if let Some(children) = root.bone() {
|
||||
for child in children {
|
||||
let (child_bones, child_collision_volumes) = skeleton_counts(&child);
|
||||
bones += child_bones;
|
||||
collision_volumes += child_collision_volumes;
|
||||
}
|
||||
}
|
||||
(bones, collision_volumes)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_skeleton_matches_the_complete_pinned_hierarchy() {
|
||||
let skeleton = libremetaverse::rendering::LindenSkeleton::get_default().unwrap();
|
||||
assert_eq!(skeleton.version(), 2.0);
|
||||
assert!(!skeleton.version_specified());
|
||||
assert_eq!(skeleton.num_bones(), "133");
|
||||
assert_eq!(skeleton.num_collision_volumes(), "26");
|
||||
assert_eq!(skeleton_counts(&skeleton.bone()), (133, 26));
|
||||
assert_eq!(skeleton.get_all_joints().unwrap().count(), 133);
|
||||
|
||||
let pelvis = skeleton.bone();
|
||||
assert_eq!(pelvis.base.name(), "mPelvis");
|
||||
assert_eq!(pelvis.base.pos(), vec![0.0, 0.0, 1.067]);
|
||||
assert_eq!(pelvis.base.rot(), vec![0.0, 0.0, 0.0]);
|
||||
assert_eq!(pelvis.base.scale(), vec![1.0, 1.0, 1.0]);
|
||||
assert_eq!(pelvis.base.end(), vec![0.0, 0.0, 0.084]);
|
||||
assert_eq!(pelvis.pivot(), vec![0.0, 0.0, 1.067_015]);
|
||||
assert_eq!(pelvis.base.group(), "Torso");
|
||||
assert_eq!(pelvis.base.support(), "base");
|
||||
assert!(pelvis.base.reposition());
|
||||
assert!(!pelvis.connected());
|
||||
assert_eq!(
|
||||
pelvis.get_aliases_list().unwrap(),
|
||||
["hip", "avatar_mPelvis"]
|
||||
);
|
||||
assert_eq!(pelvis.collision_volume().len(), 2);
|
||||
assert_eq!(pelvis.collision_volume()[0].base.name(), "PELVIS");
|
||||
|
||||
let by_alias = skeleton.get_bone("hip".to_owned()).unwrap().unwrap();
|
||||
assert_eq!(by_alias.base.name(), "mPelvis");
|
||||
assert_eq!(
|
||||
libremetaverse::rendering::LindenSkeleton::load_with_method().unwrap(),
|
||||
skeleton
|
||||
);
|
||||
assert_eq!(
|
||||
libremetaverse::rendering::LindenSkeleton::load_with_string(None).unwrap(),
|
||||
skeleton
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skeleton_records_preserve_mutable_mapped_properties() {
|
||||
let mut base = libremetaverse::rendering::JointBase::new().unwrap();
|
||||
base.set_name("joint".to_owned());
|
||||
base.set_pos(vec![1.0, 2.0, 3.0]);
|
||||
base.set_rot(vec![4.0, 5.0, 6.0]);
|
||||
base.set_scale(vec![7.0, 8.0, 9.0]);
|
||||
base.set_group("group".to_owned());
|
||||
base.set_support("extended".to_owned());
|
||||
base.set_end(vec![10.0, 11.0, 12.0]);
|
||||
base.set_reposition(true);
|
||||
assert_eq!(base.name(), "joint");
|
||||
assert_eq!(base.pos(), vec![1.0, 2.0, 3.0]);
|
||||
assert_eq!(base.rot(), vec![4.0, 5.0, 6.0]);
|
||||
assert_eq!(base.scale(), vec![7.0, 8.0, 9.0]);
|
||||
assert_eq!(base.group(), "group");
|
||||
assert_eq!(base.support(), "extended");
|
||||
assert_eq!(base.end(), vec![10.0, 11.0, 12.0]);
|
||||
assert!(base.reposition());
|
||||
|
||||
let mut joint = libremetaverse::rendering::Joint::new().unwrap();
|
||||
joint.base = base;
|
||||
joint.set_aliases("one two".to_owned());
|
||||
joint.set_pivot(vec![13.0, 14.0, 15.0]);
|
||||
joint.set_connected(true);
|
||||
joint.set_collision_volume(vec![
|
||||
libremetaverse::rendering::CollisionVolume::new().unwrap(),
|
||||
]);
|
||||
joint.set_bone(None);
|
||||
assert_eq!(joint.aliases(), "one two");
|
||||
assert_eq!(joint.pivot(), vec![13.0, 14.0, 15.0]);
|
||||
assert!(joint.connected());
|
||||
assert_eq!(joint.collision_volume().len(), 1);
|
||||
assert!(joint.bone().is_none());
|
||||
|
||||
let mut skeleton = libremetaverse::rendering::LindenSkeleton::new().unwrap();
|
||||
skeleton.set_bone(joint);
|
||||
skeleton.set_version(3.0);
|
||||
skeleton.set_version_specified(true);
|
||||
skeleton.set_num_bones("1".to_owned());
|
||||
skeleton.set_num_collision_volumes("1".to_owned());
|
||||
assert_eq!(skeleton.version(), 3.0);
|
||||
assert!(skeleton.version_specified());
|
||||
assert_eq!(skeleton.num_bones(), "1");
|
||||
assert_eq!(skeleton.num_collision_volumes(), "1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attention_catalogs_match_default_and_updated_fixtures() {
|
||||
let default = LindenAttentions::default();
|
||||
let updated = LindenAttentions::updated();
|
||||
assert_eq!(default.len(), 2);
|
||||
assert_eq!(updated.len(), 2);
|
||||
assert_eq!(default[0].name(), "Masculine");
|
||||
assert_eq!(default[1].name(), "Feminine");
|
||||
assert!(
|
||||
default
|
||||
.iter()
|
||||
.chain(&updated)
|
||||
.all(|set| set.entries().len() == 11)
|
||||
);
|
||||
|
||||
let none = default[0].get(LookAtType::None).unwrap();
|
||||
assert_eq!(none.priority(), 0.0);
|
||||
assert_eq!(none.timeout(), 0.0);
|
||||
let clear = default[0].get(LookAtType::Clear).unwrap();
|
||||
assert_eq!(clear.priority(), 0.0);
|
||||
assert_eq!(clear.timeout(), 0.0);
|
||||
let default_conversation = default[0].get(LookAtType::Conversation).unwrap();
|
||||
assert_eq!(default_conversation.priority(), 0.0);
|
||||
assert_eq!(default_conversation.timeout(), -1.0);
|
||||
let updated_conversation = updated[0].get(LookAtType::Conversation).unwrap();
|
||||
assert_eq!(updated_conversation.priority(), 5.0);
|
||||
assert_eq!(updated_conversation.timeout(), 3.0);
|
||||
assert_eq!(
|
||||
LindenAttentions::updated_feminine()
|
||||
.get(LookAtType::Focus)
|
||||
.unwrap()
|
||||
.timeout(),
|
||||
10.0
|
||||
);
|
||||
assert_eq!(LindenAttentions::default_masculine(), default[0]);
|
||||
assert_eq!(LindenAttentions::default_feminine(), default[1]);
|
||||
assert_eq!(LindenAttentions::updated_masculine(), updated[0]);
|
||||
assert_eq!(LindenAttentions::updated_feminine(), updated[1]);
|
||||
|
||||
let mut changed = updated_conversation;
|
||||
changed.set_priority(8.0);
|
||||
changed.set_timeout(9.0);
|
||||
assert_eq!(changed.priority(), 8.0);
|
||||
assert_eq!(changed.timeout(), 9.0);
|
||||
let mut set = default[0].clone();
|
||||
set.set_name("Changed".to_owned());
|
||||
set.set_entries(vec![changed.clone()]);
|
||||
assert_eq!(set.name(), "Changed");
|
||||
assert_eq!(set.entries(), vec![changed]);
|
||||
assert_eq!(
|
||||
set.get(LookAtType::Clear),
|
||||
Err(libremetaverse::Error::IndexOutOfRange)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn genepool_matches_every_pinned_archetype_and_supports_lookup() {
|
||||
let archetypes = Genepool::archetypes();
|
||||
assert_eq!(archetypes.len(), 24);
|
||||
assert!(
|
||||
archetypes
|
||||
.iter()
|
||||
.all(|archetype| archetype.params().len() == 140)
|
||||
);
|
||||
assert_eq!(
|
||||
archetypes
|
||||
.iter()
|
||||
.map(|archetype| archetype.params().len())
|
||||
.sum::<usize>(),
|
||||
3360
|
||||
);
|
||||
assert_eq!(archetypes[0].name(), "M W Skinny");
|
||||
assert_eq!(Genepool::find_index("M W Skinny".to_owned()).unwrap(), 0);
|
||||
assert_eq!(Genepool::find_index("missing".to_owned()).unwrap(), -1);
|
||||
assert_eq!(Genepool::get(0).unwrap(), archetypes[0]);
|
||||
assert_eq!(
|
||||
Genepool::get(-1),
|
||||
Err(libremetaverse::Error::IndexOutOfRange)
|
||||
);
|
||||
assert_eq!(
|
||||
Genepool::get(24),
|
||||
Err(libremetaverse::Error::IndexOutOfRange)
|
||||
);
|
||||
|
||||
let mut first = archetypes[0].params()[0].clone();
|
||||
assert_eq!(first.id(), 1);
|
||||
assert_eq!(first.name(), "Big_Brow");
|
||||
assert_eq!(first.value(), 1.54);
|
||||
first.set_id(99);
|
||||
first.set_name("Changed".to_owned());
|
||||
first.set_value(0.25);
|
||||
assert_eq!(first.id(), 99);
|
||||
assert_eq!(first.name(), "Changed");
|
||||
assert_eq!(first.value(), 0.25);
|
||||
|
||||
let mut archetype = archetypes[0].clone();
|
||||
archetype.set_name("Changed archetype".to_owned());
|
||||
archetype.set_params(vec![first.clone()]);
|
||||
assert_eq!(archetype.name(), "Changed archetype");
|
||||
assert_eq!(archetype.params(), vec![first]);
|
||||
}
|
||||
10
tests/api-compile/Cargo.lock
generated
10
tests/api-compile/Cargo.lock
generated
@@ -193,6 +193,7 @@ dependencies = [
|
||||
"libremetaverse-imaging",
|
||||
"libremetaverse-structured-data",
|
||||
"libremetaverse-types",
|
||||
"roxmltree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -372,6 +373,15 @@ version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||
|
||||
[[package]]
|
||||
name = "roxmltree"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1964b10c76125c36f8afe190065a4bf9a87bf324842c05701330bba9f1cacbb"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.23"
|
||||
|
||||
881
tools/codegen/src/avatar_catalog.rs
Normal file
881
tools/codegen/src/avatar_catalog.rs
Normal file
@@ -0,0 +1,881 @@
|
||||
//! Schema-validated generators for skeleton, attention, and genepool catalogs.
|
||||
|
||||
use super::{InputSpec, generated_rust, normalize_text, verify_inputs};
|
||||
use roxmltree::{Document, Node};
|
||||
use std::collections::BTreeSet;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct JointBaseRecord {
|
||||
name: String,
|
||||
pos: Vec<f32>,
|
||||
rot: Vec<f32>,
|
||||
scale: Vec<f32>,
|
||||
group: String,
|
||||
support: String,
|
||||
end: Vec<f32>,
|
||||
reposition: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct CollisionRecord {
|
||||
base: JointBaseRecord,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct JointRecord {
|
||||
base: JointBaseRecord,
|
||||
collision_volumes: Vec<CollisionRecord>,
|
||||
bones: Vec<JointRecord>,
|
||||
pivot: Vec<f32>,
|
||||
aliases: String,
|
||||
connected: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct SkeletonRecord {
|
||||
version: f32,
|
||||
num_bones: String,
|
||||
num_collision_volumes: String,
|
||||
root: JointRecord,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
struct AttentionRecord {
|
||||
priority: f32,
|
||||
timeout: f32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct AttentionSetRecord {
|
||||
name: String,
|
||||
entries: [AttentionRecord; 11],
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct ArchetypeParamRecord {
|
||||
id: i32,
|
||||
name: String,
|
||||
value: f32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct ArchetypeRecord {
|
||||
name: String,
|
||||
params: Vec<ArchetypeParamRecord>,
|
||||
}
|
||||
|
||||
const ATTENTION_NAMES: [&str; 9] = [
|
||||
"idle",
|
||||
"auto_listen",
|
||||
"freelook",
|
||||
"respond",
|
||||
"hover",
|
||||
"conversation",
|
||||
"select",
|
||||
"focus",
|
||||
"mouselook",
|
||||
];
|
||||
|
||||
fn location(path: &str, node: Node<'_, '_>, code: &str, message: &str) -> String {
|
||||
let position = node.document().text_pos_at(node.range().start);
|
||||
format!(
|
||||
"{path}:{}:{}: error[{code}]: {message}",
|
||||
position.row, position.col
|
||||
)
|
||||
}
|
||||
|
||||
fn required_attribute(
|
||||
path: &str,
|
||||
node: Node<'_, '_>,
|
||||
name: &str,
|
||||
code: &str,
|
||||
) -> Result<String, String> {
|
||||
node.attribute(name)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(str::to_owned)
|
||||
.ok_or_else(|| {
|
||||
location(
|
||||
path,
|
||||
node,
|
||||
code,
|
||||
&format!("<{}> requires attribute {name:?}", node.tag_name().name()),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_f32(path: &str, node: Node<'_, '_>, name: &str, code: &str) -> Result<f32, String> {
|
||||
let value = required_attribute(path, node, name, code)?;
|
||||
let parsed = value.parse::<f32>().map_err(|_| {
|
||||
location(
|
||||
path,
|
||||
node,
|
||||
code,
|
||||
&format!("attribute {name:?} must be a finite float, found {value:?}"),
|
||||
)
|
||||
})?;
|
||||
if parsed.is_finite() {
|
||||
Ok(parsed)
|
||||
} else {
|
||||
Err(location(
|
||||
path,
|
||||
node,
|
||||
code,
|
||||
&format!("attribute {name:?} must be a finite float, found {value:?}"),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_i32(path: &str, node: Node<'_, '_>, name: &str, code: &str) -> Result<i32, String> {
|
||||
let value = required_attribute(path, node, name, code)?;
|
||||
value.parse::<i32>().map_err(|_| {
|
||||
location(
|
||||
path,
|
||||
node,
|
||||
code,
|
||||
&format!("attribute {name:?} must be a signed 32-bit integer, found {value:?}"),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_usize(path: &str, node: Node<'_, '_>, name: &str, code: &str) -> Result<usize, String> {
|
||||
let value = required_attribute(path, node, name, code)?;
|
||||
value.parse::<usize>().map_err(|_| {
|
||||
location(
|
||||
path,
|
||||
node,
|
||||
code,
|
||||
&format!("attribute {name:?} must be a non-negative integer, found {value:?}"),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn vector_attribute(
|
||||
path: &str,
|
||||
node: Node<'_, '_>,
|
||||
name: &str,
|
||||
code: &str,
|
||||
) -> Result<Vec<f32>, String> {
|
||||
let Some(value) = node.attribute(name) else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
let values = value
|
||||
.split_ascii_whitespace()
|
||||
.map(str::parse::<f32>)
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|_| {
|
||||
location(
|
||||
path,
|
||||
node,
|
||||
code,
|
||||
&format!("attribute {name:?} must contain three finite floats"),
|
||||
)
|
||||
})?;
|
||||
if values.len() != 3 || values.iter().any(|value| !value.is_finite()) {
|
||||
return Err(location(
|
||||
path,
|
||||
node,
|
||||
code,
|
||||
&format!("attribute {name:?} must contain three finite floats"),
|
||||
));
|
||||
}
|
||||
Ok(values)
|
||||
}
|
||||
|
||||
fn boolean_attribute(
|
||||
path: &str,
|
||||
node: Node<'_, '_>,
|
||||
name: &str,
|
||||
code: &str,
|
||||
) -> Result<bool, String> {
|
||||
match node.attribute(name) {
|
||||
None => Ok(false),
|
||||
Some(value) if value.eq_ignore_ascii_case("true") => Ok(true),
|
||||
Some(value) if value.eq_ignore_ascii_case("false") => Ok(false),
|
||||
Some(value) => Err(location(
|
||||
path,
|
||||
node,
|
||||
code,
|
||||
&format!("attribute {name:?} must be true or false, found {value:?}"),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_joint_base(
|
||||
path: &str,
|
||||
node: Node<'_, '_>,
|
||||
name_code: &str,
|
||||
) -> Result<JointBaseRecord, String> {
|
||||
let support = node.attribute("support").unwrap_or_default().to_owned();
|
||||
if !support.is_empty()
|
||||
&& !support.eq_ignore_ascii_case("base")
|
||||
&& !support.eq_ignore_ascii_case("extended")
|
||||
{
|
||||
return Err(location(
|
||||
path,
|
||||
node,
|
||||
"SK018",
|
||||
&format!("unknown skeleton support category {support:?}"),
|
||||
));
|
||||
}
|
||||
Ok(JointBaseRecord {
|
||||
name: required_attribute(path, node, "name", name_code)?,
|
||||
pos: vector_attribute(path, node, "pos", "SK011")?,
|
||||
rot: vector_attribute(path, node, "rot", "SK012")?,
|
||||
scale: vector_attribute(path, node, "scale", "SK013")?,
|
||||
group: node.attribute("group").unwrap_or_default().to_owned(),
|
||||
support,
|
||||
end: vector_attribute(path, node, "end", "SK014")?,
|
||||
reposition: boolean_attribute(path, node, "reposition", "SK015")?,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_joint(
|
||||
path: &str,
|
||||
node: Node<'_, '_>,
|
||||
identifiers: &mut BTreeSet<String>,
|
||||
collision_names: &mut BTreeSet<String>,
|
||||
) -> Result<JointRecord, String> {
|
||||
let base = parse_joint_base(path, node, "SK010")?;
|
||||
if !identifiers.insert(base.name.clone()) {
|
||||
return Err(location(
|
||||
path,
|
||||
node,
|
||||
"SK016",
|
||||
&format!("duplicate skeleton joint identifier {:?}", base.name),
|
||||
));
|
||||
}
|
||||
let aliases = node.attribute("aliases").unwrap_or_default().to_owned();
|
||||
for alias in aliases.split_ascii_whitespace() {
|
||||
if !identifiers.insert(alias.to_owned()) {
|
||||
return Err(location(
|
||||
path,
|
||||
node,
|
||||
"SK016",
|
||||
&format!("duplicate skeleton joint identifier {alias:?}"),
|
||||
));
|
||||
}
|
||||
}
|
||||
let mut collision_volumes = Vec::new();
|
||||
let mut bones = Vec::new();
|
||||
for child in node.children().filter(Node::is_element) {
|
||||
if child.has_tag_name("collision_volume") {
|
||||
if child.children().any(|node| node.is_element()) {
|
||||
return Err(location(
|
||||
path,
|
||||
child,
|
||||
"SK019",
|
||||
"<collision_volume> may not contain child elements",
|
||||
));
|
||||
}
|
||||
let collision = CollisionRecord {
|
||||
base: parse_joint_base(path, child, "SK017")?,
|
||||
};
|
||||
if !collision_names.insert(collision.base.name.clone()) {
|
||||
return Err(location(
|
||||
path,
|
||||
child,
|
||||
"SK020",
|
||||
&format!("duplicate collision-volume name {:?}", collision.base.name),
|
||||
));
|
||||
}
|
||||
collision_volumes.push(collision);
|
||||
} else if child.has_tag_name("bone") {
|
||||
bones.push(parse_joint(path, child, identifiers, collision_names)?);
|
||||
} else {
|
||||
return Err(location(
|
||||
path,
|
||||
child,
|
||||
"SK021",
|
||||
"<bone> may contain only <bone> and <collision_volume> elements",
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(JointRecord {
|
||||
base,
|
||||
collision_volumes,
|
||||
bones,
|
||||
pivot: vector_attribute(path, node, "pivot", "SK022")?,
|
||||
aliases,
|
||||
connected: boolean_attribute(path, node, "connected", "SK023")?,
|
||||
})
|
||||
}
|
||||
|
||||
fn joint_counts(root: &JointRecord) -> (usize, usize) {
|
||||
let mut bones = 1;
|
||||
let mut collision_volumes = root.collision_volumes.len();
|
||||
for child in &root.bones {
|
||||
let (child_bones, child_collision_volumes) = joint_counts(child);
|
||||
bones += child_bones;
|
||||
collision_volumes += child_collision_volumes;
|
||||
}
|
||||
(bones, collision_volumes)
|
||||
}
|
||||
|
||||
fn parse_skeleton(path: &str, text: &str) -> Result<SkeletonRecord, String> {
|
||||
let document = Document::parse(text).map_err(|error| format!("{path}: {error}"))?;
|
||||
let root = document.root_element();
|
||||
if !root.has_tag_name("linden_skeleton") {
|
||||
return Err(location(
|
||||
path,
|
||||
root,
|
||||
"SK001",
|
||||
"root element must be <linden_skeleton>",
|
||||
));
|
||||
}
|
||||
let version = parse_f32(path, root, "version", "SK002")?;
|
||||
let expected_bones = parse_usize(path, root, "num_bones", "SK003")?;
|
||||
let expected_collision_volumes = parse_usize(path, root, "num_collision_volumes", "SK004")?;
|
||||
let children = root.children().filter(Node::is_element).collect::<Vec<_>>();
|
||||
if children.len() != 1 || !children[0].has_tag_name("bone") {
|
||||
return Err(location(
|
||||
path,
|
||||
root,
|
||||
"SK005",
|
||||
"skeleton requires exactly one root <bone>",
|
||||
));
|
||||
}
|
||||
let mut identifiers = BTreeSet::new();
|
||||
let mut collision_names = BTreeSet::new();
|
||||
let joint = parse_joint(path, children[0], &mut identifiers, &mut collision_names)?;
|
||||
let (actual_bones, actual_collision_volumes) = joint_counts(&joint);
|
||||
if actual_bones != expected_bones || actual_collision_volumes != expected_collision_volumes {
|
||||
return Err(location(
|
||||
path,
|
||||
root,
|
||||
"SK006",
|
||||
&format!(
|
||||
"declared skeleton counts are {expected_bones} bones/{expected_collision_volumes} collision volumes but parsed {actual_bones}/{actual_collision_volumes}"
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(SkeletonRecord {
|
||||
version,
|
||||
num_bones: expected_bones.to_string(),
|
||||
num_collision_volumes: expected_collision_volumes.to_string(),
|
||||
root: joint,
|
||||
})
|
||||
}
|
||||
|
||||
fn attention_index(name: &str) -> Option<usize> {
|
||||
ATTENTION_NAMES
|
||||
.iter()
|
||||
.position(|candidate| candidate.eq_ignore_ascii_case(name))
|
||||
.map(|index| index + 1)
|
||||
}
|
||||
|
||||
fn parse_attentions(path: &str, text: &str) -> Result<Vec<AttentionSetRecord>, String> {
|
||||
let document = Document::parse(text).map_err(|error| format!("{path}: {error}"))?;
|
||||
let root = document.root_element();
|
||||
if !root.has_tag_name("linden_attentions") {
|
||||
return Err(location(
|
||||
path,
|
||||
root,
|
||||
"AT001",
|
||||
"root element must be <linden_attentions>",
|
||||
));
|
||||
}
|
||||
let _version = parse_f32(path, root, "version", "AT002")?;
|
||||
let genders = root.children().filter(Node::is_element).collect::<Vec<_>>();
|
||||
if genders.len() != 2 {
|
||||
return Err(location(
|
||||
path,
|
||||
root,
|
||||
"AT003",
|
||||
"attention catalog requires Masculine and Feminine gender sets",
|
||||
));
|
||||
}
|
||||
let mut sets = Vec::new();
|
||||
for (gender_index, gender) in genders.into_iter().enumerate() {
|
||||
if !gender.has_tag_name("gender") {
|
||||
return Err(location(
|
||||
path,
|
||||
gender,
|
||||
"AT004",
|
||||
"<linden_attentions> may contain only <gender> elements",
|
||||
));
|
||||
}
|
||||
let name = required_attribute(path, gender, "name", "AT005")?;
|
||||
let expected_name = if gender_index == 0 {
|
||||
"Masculine"
|
||||
} else {
|
||||
"Feminine"
|
||||
};
|
||||
if name != expected_name {
|
||||
return Err(location(
|
||||
path,
|
||||
gender,
|
||||
"AT006",
|
||||
&format!("gender set {gender_index} must be named {expected_name:?}"),
|
||||
));
|
||||
}
|
||||
let mut entries = [AttentionRecord {
|
||||
priority: 0.0,
|
||||
timeout: 0.0,
|
||||
}; 11];
|
||||
let mut seen = BTreeSet::new();
|
||||
for param in gender.children().filter(Node::is_element) {
|
||||
if !param.has_tag_name("param") {
|
||||
return Err(location(
|
||||
path,
|
||||
param,
|
||||
"AT007",
|
||||
"<gender> may contain only <param> elements",
|
||||
));
|
||||
}
|
||||
let attention = required_attribute(path, param, "attention", "AT008")?;
|
||||
let Some(index) = attention_index(&attention) else {
|
||||
return Err(location(
|
||||
path,
|
||||
param,
|
||||
"AT009",
|
||||
&format!("unknown attention name {attention:?}"),
|
||||
));
|
||||
};
|
||||
if !seen.insert(index) {
|
||||
return Err(location(
|
||||
path,
|
||||
param,
|
||||
"AT010",
|
||||
&format!("duplicate attention name {attention:?}"),
|
||||
));
|
||||
}
|
||||
entries[index] = AttentionRecord {
|
||||
priority: parse_f32(path, param, "priority", "AT011")?,
|
||||
timeout: parse_f32(path, param, "timeout", "AT012")?,
|
||||
};
|
||||
}
|
||||
if seen.len() != ATTENTION_NAMES.len() {
|
||||
return Err(location(
|
||||
path,
|
||||
gender,
|
||||
"AT013",
|
||||
"gender set must define each of the nine attention parameters exactly once",
|
||||
));
|
||||
}
|
||||
sets.push(AttentionSetRecord { name, entries });
|
||||
}
|
||||
Ok(sets)
|
||||
}
|
||||
|
||||
fn parse_genepool(path: &str, text: &str) -> Result<Vec<ArchetypeRecord>, String> {
|
||||
let document = Document::parse(text).map_err(|error| format!("{path}: {error}"))?;
|
||||
let root = document.root_element();
|
||||
if !root.has_tag_name("linden_genepool") {
|
||||
return Err(location(
|
||||
path,
|
||||
root,
|
||||
"GP001",
|
||||
"root element must be <linden_genepool>",
|
||||
));
|
||||
}
|
||||
let _version = parse_f32(path, root, "version", "GP002")?;
|
||||
let mut names = BTreeSet::new();
|
||||
let mut archetypes = Vec::new();
|
||||
for archetype in root.children().filter(Node::is_element) {
|
||||
if !archetype.has_tag_name("archetype") {
|
||||
return Err(location(
|
||||
path,
|
||||
archetype,
|
||||
"GP003",
|
||||
"<linden_genepool> may contain only <archetype> elements",
|
||||
));
|
||||
}
|
||||
let name = required_attribute(path, archetype, "name", "GP004")?
|
||||
.trim()
|
||||
.to_owned();
|
||||
if name.is_empty() || !names.insert(name.clone()) {
|
||||
return Err(location(
|
||||
path,
|
||||
archetype,
|
||||
"GP005",
|
||||
&format!("empty or duplicate archetype name {name:?}"),
|
||||
));
|
||||
}
|
||||
let mut ids = BTreeSet::new();
|
||||
let mut texture_slots = BTreeSet::new();
|
||||
let mut params = Vec::new();
|
||||
for child in archetype.children().filter(Node::is_element) {
|
||||
if child.has_tag_name("texture") {
|
||||
let slot = parse_i32(path, child, "te", "GP013")?;
|
||||
let uuid = required_attribute(path, child, "uuid", "GP014")?;
|
||||
if !texture_slots.insert(slot) {
|
||||
return Err(location(
|
||||
path,
|
||||
child,
|
||||
"GP015",
|
||||
&format!("duplicate texture-entry slot {slot} in archetype {name:?}"),
|
||||
));
|
||||
}
|
||||
if !valid_uuid(&uuid) {
|
||||
return Err(location(
|
||||
path,
|
||||
child,
|
||||
"GP016",
|
||||
&format!("invalid archetype texture UUID {uuid:?}"),
|
||||
));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if !child.has_tag_name("param") {
|
||||
return Err(location(
|
||||
path,
|
||||
child,
|
||||
"GP006",
|
||||
"<archetype> may contain only <param> and <texture> elements",
|
||||
));
|
||||
}
|
||||
let id = parse_i32(path, child, "id", "GP007")?;
|
||||
if !ids.insert(id) {
|
||||
return Err(location(
|
||||
path,
|
||||
child,
|
||||
"GP008",
|
||||
&format!("duplicate parameter ID {id} in archetype {name:?}"),
|
||||
));
|
||||
}
|
||||
params.push(ArchetypeParamRecord {
|
||||
id,
|
||||
name: required_attribute(path, child, "name", "GP009")?,
|
||||
value: parse_f32(path, child, "value", "GP010")?,
|
||||
});
|
||||
}
|
||||
if params.is_empty() {
|
||||
return Err(location(
|
||||
path,
|
||||
archetype,
|
||||
"GP011",
|
||||
"archetype must contain at least one parameter",
|
||||
));
|
||||
}
|
||||
archetypes.push(ArchetypeRecord { name, params });
|
||||
}
|
||||
if archetypes.is_empty() {
|
||||
return Err(location(
|
||||
path,
|
||||
root,
|
||||
"GP012",
|
||||
"genepool must contain at least one archetype",
|
||||
));
|
||||
}
|
||||
Ok(archetypes)
|
||||
}
|
||||
|
||||
fn valid_uuid(value: &str) -> bool {
|
||||
value.len() == 36
|
||||
&& value.bytes().enumerate().all(|(index, byte)| match index {
|
||||
8 | 13 | 18 | 23 => byte == b'-',
|
||||
_ => byte.is_ascii_hexdigit(),
|
||||
})
|
||||
}
|
||||
|
||||
fn rust_f32(value: f32) -> String {
|
||||
format!("{value:?}_f32")
|
||||
}
|
||||
|
||||
fn vector_expression(values: &[f32]) -> String {
|
||||
format!(
|
||||
"vec![{}]",
|
||||
values
|
||||
.iter()
|
||||
.map(|value| rust_f32(*value))
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")
|
||||
)
|
||||
}
|
||||
|
||||
fn base_expression(base: &JointBaseRecord) -> String {
|
||||
format!(
|
||||
"crate::skeleton::JointBase::from_parts({:?}.to_owned(), {}, {}, {}, {:?}.to_owned(), {:?}.to_owned(), {}, {})",
|
||||
base.name,
|
||||
vector_expression(&base.pos),
|
||||
vector_expression(&base.rot),
|
||||
vector_expression(&base.scale),
|
||||
base.group,
|
||||
base.support,
|
||||
vector_expression(&base.end),
|
||||
base.reposition
|
||||
)
|
||||
}
|
||||
|
||||
fn joint_expression(joint: &JointRecord) -> String {
|
||||
let collision_volumes = joint
|
||||
.collision_volumes
|
||||
.iter()
|
||||
.map(|volume| {
|
||||
format!(
|
||||
"crate::skeleton::CollisionVolume::from_base({})",
|
||||
base_expression(&volume.base)
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
let bones = joint
|
||||
.bones
|
||||
.iter()
|
||||
.map(joint_expression)
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
format!(
|
||||
"crate::skeleton::Joint::from_parts({}, vec![{collision_volumes}], vec![{bones}], {}, {:?}.to_owned(), {})",
|
||||
base_expression(&joint.base),
|
||||
vector_expression(&joint.pivot),
|
||||
joint.aliases,
|
||||
joint.connected
|
||||
)
|
||||
}
|
||||
|
||||
fn render_skeleton(skeleton: &SkeletonRecord) -> String {
|
||||
format!(
|
||||
"#![allow(clippy::float_cmp, clippy::too_many_lines, clippy::unreadable_literal)]\n\n\
|
||||
pub(crate) fn default_skeleton() -> crate::skeleton::LindenSkeleton {{\n\
|
||||
crate::skeleton::LindenSkeleton::from_parts({}, {}, false, {:?}.to_owned(), {:?}.to_owned())\n\
|
||||
}}\n\n\
|
||||
#[cfg(test)] mod tests {{ use super::*; #[test] fn generated_default_shape() {{ let skeleton = default_skeleton(); assert_eq!(skeleton.version(), 2.0); assert_eq!(skeleton.num_bones(), \"133\"); assert_eq!(skeleton.num_collision_volumes(), \"26\"); assert_eq!(skeleton.bone().base.name(), \"mPelvis\"); }} }}\n",
|
||||
joint_expression(&skeleton.root),
|
||||
rust_f32(skeleton.version),
|
||||
skeleton.num_bones,
|
||||
skeleton.num_collision_volumes
|
||||
)
|
||||
}
|
||||
|
||||
fn render_attentions(default: &[AttentionSetRecord], updated: &[AttentionSetRecord]) -> String {
|
||||
fn sets_expression(sets: &[AttentionSetRecord]) -> String {
|
||||
sets.iter()
|
||||
.map(|set| {
|
||||
let entries = set
|
||||
.entries
|
||||
.iter()
|
||||
.map(|entry| {
|
||||
format!(
|
||||
"AttentionData {{ priority: {}, timeout: {} }}",
|
||||
rust_f32(entry.priority),
|
||||
rust_f32(entry.timeout)
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
format!(
|
||||
"AttentionSet {{ name: {:?}.to_owned(), entries: vec![{entries}] }}",
|
||||
set.name
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")
|
||||
}
|
||||
|
||||
format!(
|
||||
"#![allow(clippy::missing_errors_doc, clippy::must_use_candidate, clippy::should_implement_trait)]\n\n\
|
||||
use std::sync::OnceLock;\n\n\
|
||||
#[derive(Clone, Debug, Default, PartialEq)] pub struct AttentionData {{ priority: f32, timeout: f32 }}\n\
|
||||
impl AttentionData {{ pub fn priority(&self) -> f32 {{ self.priority }} pub fn set_priority(&mut self, value: f32) {{ self.priority = value; }} pub fn timeout(&self) -> f32 {{ self.timeout }} pub fn set_timeout(&mut self, value: f32) {{ self.timeout = value; }} }}\n\n\
|
||||
#[derive(Clone, Debug, Default, PartialEq)] pub struct AttentionSet {{ name: String, entries: Vec<AttentionData> }}\n\
|
||||
impl AttentionSet {{ pub fn get(&self, type_: crate::LookAtType) -> Result<AttentionData, crate::Error> {{ self.entries.get(type_ as usize).cloned().ok_or(crate::Error::IndexOutOfRange) }} pub fn entries(&self) -> Vec<AttentionData> {{ self.entries.clone() }} pub fn set_entries(&mut self, value: Vec<AttentionData>) {{ self.entries = value; }} pub fn name(&self) -> String {{ self.name.clone() }} pub fn set_name(&mut self, value: String) {{ self.name = value; }} }}\n\n\
|
||||
fn default_sets() -> &'static [AttentionSet] {{ static SETS: OnceLock<Vec<AttentionSet>> = OnceLock::new(); SETS.get_or_init(|| vec![{}]).as_slice() }}\n\
|
||||
fn updated_sets() -> &'static [AttentionSet] {{ static SETS: OnceLock<Vec<AttentionSet>> = OnceLock::new(); SETS.get_or_init(|| vec![{}]).as_slice() }}\n\n\
|
||||
pub struct LindenAttentions; impl LindenAttentions {{ pub fn default() -> Vec<AttentionSet> {{ default_sets().to_vec() }} pub fn updated() -> Vec<AttentionSet> {{ updated_sets().to_vec() }} pub fn default_masculine() -> AttentionSet {{ default_sets()[0].clone() }} pub fn default_feminine() -> AttentionSet {{ default_sets()[1].clone() }} pub fn updated_masculine() -> AttentionSet {{ updated_sets()[0].clone() }} pub fn updated_feminine() -> AttentionSet {{ updated_sets()[1].clone() }} }}\n\n\
|
||||
#[cfg(test)] mod tests {{ use super::*; #[test] fn generated_attention_shape() {{ assert_eq!(default_sets().len(), 2); assert_eq!(updated_sets().len(), 2); assert!(default_sets().iter().chain(updated_sets()).all(|set| set.entries.len() == 11)); assert_eq!(default_sets()[0].name, \"Masculine\"); assert_eq!(default_sets()[1].name, \"Feminine\"); }} }}\n",
|
||||
sets_expression(default),
|
||||
sets_expression(updated)
|
||||
)
|
||||
}
|
||||
|
||||
fn render_genepool(archetypes: &[ArchetypeRecord]) -> String {
|
||||
let values = archetypes
|
||||
.iter()
|
||||
.map(|archetype| {
|
||||
let params = archetype
|
||||
.params
|
||||
.iter()
|
||||
.map(|param| {
|
||||
format!(
|
||||
"ArchetypeParam {{ id: {}, name: {:?}.to_owned(), value: {} }}",
|
||||
param.id,
|
||||
param.name,
|
||||
rust_f32(param.value)
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
format!(
|
||||
"GenepoolArchetype {{ name: {:?}.to_owned(), params: vec![{params}] }}",
|
||||
archetype.name
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
format!(
|
||||
"#![allow(clippy::missing_errors_doc, clippy::must_use_candidate, clippy::needless_pass_by_value, clippy::too_many_lines)]\n\n\
|
||||
use std::sync::OnceLock;\n\n\
|
||||
#[derive(Clone, Debug, Default, PartialEq)] pub struct ArchetypeParam {{ id: i32, name: String, value: f32 }}\n\
|
||||
impl ArchetypeParam {{ pub fn id(&self) -> i32 {{ self.id }} pub fn set_id(&mut self, value: i32) {{ self.id = value; }} pub fn name(&self) -> String {{ self.name.clone() }} pub fn set_name(&mut self, value: String) {{ self.name = value; }} pub fn value(&self) -> f32 {{ self.value }} pub fn set_value(&mut self, value: f32) {{ self.value = value; }} }}\n\n\
|
||||
#[derive(Clone, Debug, Default, PartialEq)] pub struct GenepoolArchetype {{ name: String, params: Vec<ArchetypeParam> }}\n\
|
||||
impl GenepoolArchetype {{ pub fn name(&self) -> String {{ self.name.clone() }} pub fn set_name(&mut self, value: String) {{ self.name = value; }} pub fn params(&self) -> Vec<ArchetypeParam> {{ self.params.clone() }} pub fn set_params(&mut self, value: Vec<ArchetypeParam>) {{ self.params = value; }} }}\n\n\
|
||||
fn generated_archetypes() -> &'static [GenepoolArchetype] {{ static ARCHETYPES: OnceLock<Vec<GenepoolArchetype>> = OnceLock::new(); ARCHETYPES.get_or_init(|| vec![{values}]).as_slice() }}\n\n\
|
||||
pub struct Genepool; impl Genepool {{ pub fn archetypes() -> Vec<GenepoolArchetype> {{ generated_archetypes().to_vec() }} pub fn find_index(name: String) -> Result<i32, crate::Error> {{ let Some(index) = generated_archetypes().iter().position(|archetype| archetype.name == name) else {{ return Ok(-1); }}; i32::try_from(index).map_err(|_| crate::Error::IndexOutOfRange) }} pub fn get(index: i32) -> Result<GenepoolArchetype, crate::Error> {{ usize::try_from(index).ok().and_then(|index| generated_archetypes().get(index)).cloned().ok_or(crate::Error::IndexOutOfRange) }} }}\n\n\
|
||||
#[cfg(test)] mod tests {{ use super::*; #[test] fn generated_genepool_shape() {{ let archetypes = generated_archetypes(); assert_eq!(archetypes.len(), 24); assert_eq!(archetypes.iter().map(|archetype| archetype.params.len()).sum::<usize>(), 3360); assert_eq!(archetypes[0].name, \"M W Skinny\"); }} }}\n"
|
||||
)
|
||||
}
|
||||
|
||||
fn load_input<'a>(inventory: &'a super::Inventory, id: &str) -> Result<&'a InputSpec, String> {
|
||||
inventory
|
||||
.inputs
|
||||
.iter()
|
||||
.find(|input| input.id == id)
|
||||
.ok_or_else(|| format!("source inventory has no {id} input"))
|
||||
}
|
||||
|
||||
fn load_text(root: &Path, input: &InputSpec) -> Result<String, String> {
|
||||
let path = root.join(&input.vendored_path);
|
||||
let bytes = fs::read(&path).map_err(|error| format!("{}: {error}", path.display()))?;
|
||||
normalize_text(&input.vendored_path, &bytes).map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
fn format_body(body: &str, name: &str) -> Result<String, String> {
|
||||
let syntax = syn::parse_file(body)
|
||||
.map_err(|error| format!("generated {name} Rust is invalid: {error}"))?;
|
||||
Ok(prettyplease::unparse(&syntax))
|
||||
}
|
||||
|
||||
pub(super) fn skeleton_catalog_bytes(root: &Path) -> Result<Vec<u8>, String> {
|
||||
let inventory = super::load_inventory(root)?;
|
||||
verify_inputs(root, &inventory)?;
|
||||
let input = load_input(&inventory, "avatar_skeleton")?;
|
||||
let skeleton = parse_skeleton(&input.vendored_path, &load_text(root, input)?)?;
|
||||
let body = format_body(&render_skeleton(&skeleton), "skeleton")?;
|
||||
Ok(generated_rust("skeleton", &[input], &body))
|
||||
}
|
||||
|
||||
pub(super) fn attention_catalog_bytes(root: &Path) -> Result<Vec<u8>, String> {
|
||||
let inventory = super::load_inventory(root)?;
|
||||
verify_inputs(root, &inventory)?;
|
||||
let default_input = load_input(&inventory, "attentions")?;
|
||||
let updated_input = load_input(&inventory, "attentions_updated")?;
|
||||
let default = parse_attentions(
|
||||
&default_input.vendored_path,
|
||||
&load_text(root, default_input)?,
|
||||
)?;
|
||||
let updated = parse_attentions(
|
||||
&updated_input.vendored_path,
|
||||
&load_text(root, updated_input)?,
|
||||
)?;
|
||||
let body = format_body(&render_attentions(&default, &updated), "attention")?;
|
||||
Ok(generated_rust(
|
||||
"attentions",
|
||||
&[default_input, updated_input],
|
||||
&body,
|
||||
))
|
||||
}
|
||||
|
||||
pub(super) fn genepool_catalog_bytes(root: &Path) -> Result<Vec<u8>, String> {
|
||||
let inventory = super::load_inventory(root)?;
|
||||
verify_inputs(root, &inventory)?;
|
||||
let input = load_input(&inventory, "genepool")?;
|
||||
let archetypes = parse_genepool(&input.vendored_path, &load_text(root, input)?)?;
|
||||
let body = format_body(&render_genepool(&archetypes), "genepool")?;
|
||||
Ok(generated_rust("genepool", &[input], &body))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn skeleton_schema_rejects_bad_counts_vectors_and_duplicate_names() {
|
||||
let bad_count = "<linden_skeleton version=\"1\" num_bones=\"2\" num_collision_volumes=\"0\"><bone name=\"root\"/></linden_skeleton>";
|
||||
assert!(
|
||||
parse_skeleton("bad.xml", bad_count)
|
||||
.unwrap_err()
|
||||
.contains("error[SK006]")
|
||||
);
|
||||
let bad_vector = "<linden_skeleton version=\"1\" num_bones=\"1\" num_collision_volumes=\"0\"><bone name=\"root\" pos=\"1 2\"/></linden_skeleton>";
|
||||
assert!(
|
||||
parse_skeleton("bad.xml", bad_vector)
|
||||
.unwrap_err()
|
||||
.contains("error[SK011]")
|
||||
);
|
||||
let duplicate = "<linden_skeleton version=\"1\" num_bones=\"2\" num_collision_volumes=\"0\"><bone name=\"root\"><bone name=\"root\"/></bone></linden_skeleton>";
|
||||
assert!(
|
||||
parse_skeleton("bad.xml", duplicate)
|
||||
.unwrap_err()
|
||||
.contains("error[SK016]")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attention_schema_rejects_unknown_and_incomplete_sets() {
|
||||
let unknown = "<linden_attentions version=\"1\"><gender name=\"Masculine\"><param attention=\"unknown\" priority=\"1\" timeout=\"1\"/></gender><gender name=\"Feminine\"/></linden_attentions>";
|
||||
assert!(
|
||||
parse_attentions("bad.xml", unknown)
|
||||
.unwrap_err()
|
||||
.contains("error[AT009]")
|
||||
);
|
||||
let incomplete = "<linden_attentions version=\"1\"><gender name=\"Masculine\"/><gender name=\"Feminine\"/></linden_attentions>";
|
||||
assert!(
|
||||
parse_attentions("bad.xml", incomplete)
|
||||
.unwrap_err()
|
||||
.contains("error[AT013]")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn genepool_schema_rejects_bad_values_and_duplicate_ids() {
|
||||
let bad_value = "<linden_genepool version=\"1\"><archetype name=\"A\"><param id=\"1\" name=\"P\" value=\"NaN\"/></archetype></linden_genepool>";
|
||||
assert!(
|
||||
parse_genepool("bad.xml", bad_value)
|
||||
.unwrap_err()
|
||||
.contains("error[GP010]")
|
||||
);
|
||||
let duplicate = "<linden_genepool version=\"1\"><archetype name=\"A\"><param id=\"1\" name=\"P\" value=\"0\"/><param id=\"1\" name=\"Q\" value=\"1\"/></archetype></linden_genepool>";
|
||||
assert!(
|
||||
parse_genepool("bad.xml", duplicate)
|
||||
.unwrap_err()
|
||||
.contains("error[GP008]")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pinned_avatar_catalog_semantics_have_stable_digests() {
|
||||
let root = super::super::workspace_root();
|
||||
let inventory = super::super::load_inventory(&root).expect("pinned inventory");
|
||||
let skeleton_input = load_input(&inventory, "avatar_skeleton").expect("skeleton input");
|
||||
let skeleton = parse_skeleton(
|
||||
&skeleton_input.vendored_path,
|
||||
&load_text(&root, skeleton_input).expect("skeleton text"),
|
||||
)
|
||||
.expect("skeleton");
|
||||
let attentions_input = load_input(&inventory, "attentions").expect("attentions input");
|
||||
let updated_input =
|
||||
load_input(&inventory, "attentions_updated").expect("updated attentions input");
|
||||
let default = parse_attentions(
|
||||
&attentions_input.vendored_path,
|
||||
&load_text(&root, attentions_input).expect("attentions text"),
|
||||
)
|
||||
.expect("attentions");
|
||||
let updated = parse_attentions(
|
||||
&updated_input.vendored_path,
|
||||
&load_text(&root, updated_input).expect("updated attentions text"),
|
||||
)
|
||||
.expect("updated attentions");
|
||||
let genepool_input = load_input(&inventory, "genepool").expect("genepool input");
|
||||
let genepool = parse_genepool(
|
||||
&genepool_input.vendored_path,
|
||||
&load_text(&root, genepool_input).expect("genepool text"),
|
||||
)
|
||||
.expect("genepool");
|
||||
|
||||
assert_eq!(
|
||||
super::super::sha256(format!("{skeleton:#?}").as_bytes()),
|
||||
"912dc35e06ac8f2eed48819f340ea18ab6173437cc251cda52081bc8445db4d6"
|
||||
);
|
||||
assert_eq!(
|
||||
super::super::sha256(format!("{default:#?}\n{updated:#?}").as_bytes()),
|
||||
"a0343e5d473ce2bfa29985e5d98afb066bf282b8786ba099aa76457b0b3d8af8"
|
||||
);
|
||||
assert_eq!(
|
||||
super::super::sha256(format!("{genepool:#?}").as_bytes()),
|
||||
"5e33fecab1a9501113096ee5ec38f52eadb7deb3de05a7c50c42e00c15c24a5b"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use std::fmt::Write as _;
|
||||
use std::fs;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
|
||||
mod avatar_catalog;
|
||||
mod xml_catalog;
|
||||
|
||||
pub const INVENTORY_PATH: &str = "codegen/sources.json";
|
||||
@@ -18,6 +19,9 @@ pub const MANIFEST_OUTPUT: &str = "codegen/generated/source_manifest.rs";
|
||||
pub const PACKET_OUTPUT: &str = "crates/libremetaverse/src/packet_catalog.rs";
|
||||
pub const VISUAL_OUTPUT: &str = "crates/libremetaverse/src/visual_catalog.rs";
|
||||
pub const FOLIAGE_OUTPUT: &str = "crates/libremetaverse/src/foliage_catalog.rs";
|
||||
pub const SKELETON_OUTPUT: &str = "crates/libremetaverse/src/skeleton_catalog.rs";
|
||||
pub const ATTENTION_OUTPUT: &str = "crates/libremetaverse/src/attention_catalog.rs";
|
||||
pub const GENEPOOL_OUTPUT: &str = "crates/libremetaverse/src/genepool_catalog.rs";
|
||||
pub const PUBLIC_API_PATH: &str = "api/public-api.json";
|
||||
const RUST_KEYWORDS: &[&str] = &[
|
||||
"as", "break", "const", "continue", "crate", "else", "enum", "extern", "false", "fn", "for",
|
||||
@@ -2055,6 +2059,18 @@ pub fn regenerate(root: &Path, check: bool) -> Result<(), String> {
|
||||
root.join(FOLIAGE_OUTPUT),
|
||||
xml_catalog::foliage_catalog_bytes(root)?,
|
||||
),
|
||||
(
|
||||
root.join(SKELETON_OUTPUT),
|
||||
avatar_catalog::skeleton_catalog_bytes(root)?,
|
||||
),
|
||||
(
|
||||
root.join(ATTENTION_OUTPUT),
|
||||
avatar_catalog::attention_catalog_bytes(root)?,
|
||||
),
|
||||
(
|
||||
root.join(GENEPOOL_OUTPUT),
|
||||
avatar_catalog::genepool_catalog_bytes(root)?,
|
||||
),
|
||||
];
|
||||
if check {
|
||||
for (path, expected) in outputs {
|
||||
@@ -2099,6 +2115,21 @@ mod tests {
|
||||
let second_foliage =
|
||||
xml_catalog::foliage_catalog_bytes(&root).expect("second foliage generation");
|
||||
assert_eq!(first_foliage, second_foliage);
|
||||
let first_skeleton =
|
||||
avatar_catalog::skeleton_catalog_bytes(&root).expect("first skeleton generation");
|
||||
let second_skeleton =
|
||||
avatar_catalog::skeleton_catalog_bytes(&root).expect("second skeleton generation");
|
||||
assert_eq!(first_skeleton, second_skeleton);
|
||||
let first_attention =
|
||||
avatar_catalog::attention_catalog_bytes(&root).expect("first attention generation");
|
||||
let second_attention =
|
||||
avatar_catalog::attention_catalog_bytes(&root).expect("second attention generation");
|
||||
assert_eq!(first_attention, second_attention);
|
||||
let first_genepool =
|
||||
avatar_catalog::genepool_catalog_bytes(&root).expect("first genepool generation");
|
||||
let second_genepool =
|
||||
avatar_catalog::genepool_catalog_bytes(&root).expect("second genepool generation");
|
||||
assert_eq!(first_genepool, second_genepool);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -38,10 +38,16 @@ TARGETS = {
|
||||
# implementations. The generated module keeps catalog markers and re-exports
|
||||
# the hand-written type so coverage remains deterministic.
|
||||
NATIVE_TYPES = {
|
||||
"T:LibreMetaverse.ArchetypeParam": "crate::genepool_catalog::ArchetypeParam",
|
||||
"T:LibreMetaverse.AttentionData": "crate::attention_catalog::AttentionData",
|
||||
"T:LibreMetaverse.AttentionSet": "crate::attention_catalog::AttentionSet",
|
||||
"T:LibreMetaverse.BitPack": "crate::bit_pack::BitPack",
|
||||
"T:LibreMetaverse.DrivenParamInfo": "crate::visual_catalog::DrivenParamInfo",
|
||||
"T:LibreMetaverse.GrassDefinition": "crate::foliage_catalog::GrassDefinition",
|
||||
"T:LibreMetaverse.GrassDefinitions": "crate::foliage_catalog::GrassDefinitions",
|
||||
"T:LibreMetaverse.Genepool": "crate::genepool_catalog::Genepool",
|
||||
"T:LibreMetaverse.GenepoolArchetype": "crate::genepool_catalog::GenepoolArchetype",
|
||||
"T:LibreMetaverse.LindenAttentions": "crate::attention_catalog::LindenAttentions",
|
||||
"T:LibreMetaverse.Packets.PacketType": "crate::packet_catalog::PacketType",
|
||||
"T:LibreMetaverse.PrimMesher.Coord": "crate::prim_mesher::Coord",
|
||||
"T:LibreMetaverse.PrimMesher.Face": "crate::prim_mesher::Face",
|
||||
@@ -111,6 +117,10 @@ NATIVE_TYPES = {
|
||||
"T:LibreMetaverse.VisualParam": "crate::visual_catalog::VisualParam",
|
||||
"T:LibreMetaverse.VisualParams": "crate::visual_catalog::VisualParams",
|
||||
"T:LibreMetaverse.VolumeMorphInfo": "crate::visual_catalog::VolumeMorphInfo",
|
||||
"T:LibreMetaverse.Rendering.CollisionVolume": "crate::skeleton::CollisionVolume",
|
||||
"T:LibreMetaverse.Rendering.Joint": "crate::skeleton::Joint",
|
||||
"T:LibreMetaverse.Rendering.JointBase": "crate::skeleton::JointBase",
|
||||
"T:LibreMetaverse.Rendering.LindenSkeleton": "crate::skeleton::LindenSkeleton",
|
||||
}
|
||||
|
||||
# Native declarations whose cataloged method implementations are still emitted
|
||||
|
||||
@@ -980,15 +980,18 @@ def validate_generated_shims() -> None:
|
||||
"not_implemented(",
|
||||
"NotImplemented::new(",
|
||||
"crate::byte_order::",
|
||||
"crate::attention_catalog::",
|
||||
"crate::binary::",
|
||||
"crate::dispatch::",
|
||||
"crate::foliage_catalog::",
|
||||
"crate::genepool_catalog::",
|
||||
"crate::json_codec::",
|
||||
"crate::message_codec::",
|
||||
"crate::notation::",
|
||||
"crate::packet_catalog::",
|
||||
"crate::packet_wire::",
|
||||
"crate::protobuf::",
|
||||
"crate::skeleton::",
|
||||
"crate::visual_catalog::",
|
||||
"crate::xml_codec::",
|
||||
"stored_visual_params",
|
||||
|
||||
Reference in New Issue
Block a user