Skip to main content

CharacterShape

Struct CharacterShape 

Source
pub struct CharacterShape {
    pub asset_id: AssetId,
    pub target: Option<SkinnedMeshHandle>,
    pub sliders: Vec<ShapeSlider>,
    pub proportions: Vec<JointProportion>,
    pub bake: bool,
}
Expand description

Shape sliders and joint proportions applied to one SkinnedMesh.

Every characteristic of the shape is data on the mesh, not code: a slider drives one or two of the mesh’s morph targets, and a proportion scales or lengthens one joint of its skeleton. The deformation is static and sits under any Animation playing on the same mesh: clip morph tracks are added on top of the slider weights, and clip poses are re-proportioned every frame.

Sliders resolve to morph targets by name. A target named exactly name is unipolar and receives the slider value clamped to [0, 1]. A pair named name+ / name- is bipolar: a positive value drives name+, a negative value drives name- by its magnitude. A slider with no matching target is reported as a build warning and ignored.

Proportions resolve to joints by name. scale is uniform (the skinning shaders transform normals with the plain joint matrix, so a non-uniform scale would shade incorrectly) and propagates to the joint’s descendants; length moves only the joint’s children along the bone, so a longer thigh does not also stretch the shin. Proportions change the posed skeleton, not the bind pose, so clips with translation tracks on the affected joints fight them; keep such rigs rotation-only. When the mesh declares a capsule, the capsule’s half-height follows the skeleton’s height change and its radius follows the root joint’s scale.

target may name a CharacterModel as well as a SkinnedMesh; the model’s emitted mesh is what the shape deforms.

Baking. With bake set, the build flattens the shape into its target: the sliders’ deformation is applied to the vertices and the morph targets dropped, the bind pose is rewritten through the proportions, the capsule is resized, and this asset is consumed. The result is a plain SkinnedMesh with no per-frame shape work, for characters that never change shape.

CharacterShape {
    sliders: vec![ShapeSlider { name: "weight".into(), value: 0.5 }],
    proportions: vec![JointProportion { joint: "spine".into(), scale: 1.1, length: 0.0 }],
    ..Default::default()
};

Fields§

§asset_id: AssetId

Asset identity; injected via inject_name. Not part of args.

§target: Option<SkinnedMeshHandle>

The SkinnedMesh this shape deforms.

§sliders: Vec<ShapeSlider>

Named shape values, each resolved to the mesh’s morph targets.

§proportions: Vec<JointProportion>

Per-joint scale and length changes.

§bake: bool

Flatten the shape into the target mesh at build time and drop this asset, instead of deforming at runtime.

Implementations§

Source§

impl CharacterShape

Source

pub fn resolve_sliders(&self, target_names: &[String]) -> ResolvedSliders

Resolve sliders against target_names (the mesh’s morph targets in target order). Several sliders naming the same target accumulate; the result is clamped to [0, 1] per target.

Source

pub fn unresolved_joints(&self, has_joint: impl Fn(&str) -> bool) -> Vec<String>

The proportion joint names that has_joint does not know.

Trait Implementations§

Source§

impl Clone for CharacterShape

Source§

fn clone(&self) -> CharacterShape

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Component for CharacterShape

Source§

const NAME: &'static str = "CharacterShape"

The registry name a world authors this component under.
Source§

fn inject_name(&mut self, id: AssetId)

Called after construction to inject the asset’s identity from the blob def. Only meaningful for components that look themselves up by id at runtime. The default implementation does nothing.
Source§

fn from_baked(bytes: &[u8]) -> Result<Self, CnResult>

Reconstruct this component from a blob record, whose bytes are the serialized runtime component (cook already ran the asset -> component translation). The default rejects: runtime-only components are never stored in a blob, so only loadable types provide an implementation.
Source§

fn inject_locator(&mut self, _locator: PayloadLocator)

Called after construction to inject the payload locator from the blob def. Only meaningful for components with a compiled payload. The default implementation does nothing (correct for most components).
Source§

impl ComponentSlot for CharacterShape

Source§

const DISCRIMINANT: u8

The component type’s stable id, used as its ComponentId.
Source§

fn slot(s: &ComponentStorage) -> &Column<Self>

Borrow this type’s column out of the storage.
Source§

fn slot_mut(s: &mut ComponentStorage) -> &mut Column<Self>

Mutably borrow this type’s column out of the storage.
Source§

impl Debug for CharacterShape

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for CharacterShape

Source§

fn default() -> CharacterShape

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for CharacterShape

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl From<CharacterShape> for ComponentAsset

Source§

fn from(c: CharacterShape) -> Self

Converts to this type from the input type.
Source§

impl RuntimeComponent for CharacterShape

Source§

impl Serialize for CharacterShape

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.