8个重大版本

0.9.0 2024年7月12日
0.8.0 2024年2月22日
0.7.0 2023年12月2日
0.6.0 2023年7月20日
0.2.0 2022年5月19日

#130 in 游戏开发

Download history 3/week @ 2024-05-31 3/week @ 2024-06-07 1/week @ 2024-06-28 7/week @ 2024-07-05 116/week @ 2024-07-12 1/week @ 2024-07-19 79/week @ 2024-07-26 11/week @ 2024-08-02

207 每月下载量

MIT 许可证

95KB
1.5K SLoC

Bevy Silk

workflow MIT licensed unsafe forbidden Crates.io Docs.rs dependency status

使用Verlet积分的Bevy CPU驱动布料引擎。

入门

依赖

Cargo.toml中将bevy_silk添加为依赖项

bevy_silk= "0.9"

或者跟随主git分支

bevy_silk= {git= "https://github.com/ManevilleF/bevy_silk" }

支持的Bevy版本

bevy_silk bevy
0.1.0 0.7
0.2.0 0.7
0.3.0 0.8
0.4.0 0.9
0.5.0 0.10
0.6.0 0.11
0.7.0 0.12
0.8.0 0.13
0.9.0 0.14

插件

ClothPlugin添加到您的bevy应用中

use bevy::prelude::*;
use bevy_silk::prelude::*;

fn main() {
  App::new()
    .add_plugins((DefaultPlugins, ClothPlugin))
    // ... Add your resources and systems
    .run();
}

将布料添加到网格

要将网格用作布料,请将ClothBuilder组件添加到具有Handle<Mesh>组件的任何实体中。

注意:还需要TransformGlobalTransform。注意:网格渲染资产的使用必须允许对主世界进行编辑

将自动从关联的Handle<Mesh>中填充的布料数据。

use bevy::prelude::*;
use bevy_silk::prelude::*;

fn spawn(mut commands: Commands) {
    commands.spawn((
        PbrBundle {
            // Add your mesh, material and your custom PBR data
            ..Default::default()
        },
        ClothBuilder::new()
            // Define pinned vertices ids using an Iterator
            .with_pinned_vertex_ids(0..9)
            // Define the stick generation mode
            .with_stick_generation(StickGeneration::Quads)
            // Defines the sticks target length option
            .with_stick_length(StickLen::Auto)
            // The cloth will compute flat mesh normals
            .with_flat_normals(),
    ));
}

顶点锚定

指定顶点锚点允许将一些布料顶点锚定到各种实体。ClothBuilder有多个方法,允许通过其id或颜色锚定顶点。

例如,您可以锚定一些布料顶点到布料实体的GlobalTransform

use bevy::color::{palettes::css::*, Color};
use bevy_silk::prelude::*;

let cloth = ClothBuilder::new()
    // Adds pinned vertices ids using an Iterator
    .with_pinned_vertex_ids(0..9)
    // Adds a single pinned vertex id
    .with_pinned_vertex_id(10)
    // Adds pinned vertex colors using an Iterator
    .with_pinned_vertex_colors([Color::from(WHITE), Color::from(BLACK)].into_iter())
    // Adds a single pinned vertex color
    .with_pinned_vertex_color(Color::from(YELLOW))
    // Adds pinned vertex positions
    .with_pinned_vertex_positions(|pos| pos.x > 0.0 && pos.z <= 5.0);

对于更多锚定选项,例如指定一个自定义实体来锚定顶点

use bevy::{color::palettes::css::*, prelude::*};
use bevy_silk::prelude::*;

fn spawn(mut commands: Commands) {
    // Spawn an entity and get its id
    let entity_a = commands
        .spawn((
            // Add your components
            // ...
        ))
        .id();
    let anchor_to_a = VertexAnchor {
        // The anchor will pin the vertices to `entity_a`
        custom_target: Some(entity_a),
        // Specify an extra offset from the target's `GlobalTransform`
        custom_offset: Some(Vec3::new(1.0, 1.2, 0.0)),
        ..Default::default()
    };
    let anchor_to_self = VertexAnchor {
        // The anchor will pin the cloth entity
        custom_target: None,
        // Specify an extra offset from the target's `GlobalTransform`
        custom_offset: Some(Vec3::new(-1.0, 0.0, -0.1)),
        ..Default::default()
    };

    let cloth = ClothBuilder::new()
        // Adds pinned vertices ids using an Iterator
        .with_anchored_vertex_ids(0..9, anchor_to_a)
        // Adds a single pinned vertex id
        .with_anchored_vertex_id(10, anchor_to_self)
        // Adds pinned vertex colors using an Iterator
        .with_anchored_vertex_colors(
            [Color::from(WHITE), Color::from(BLACK)].into_iter(),
            anchor_to_a,
        )
        // Adds a single pinned vertex color
        .with_anchored_vertex_color(Color::from(YELLOW), anchor_to_self)
        // Adds pinned vertex positions
        .with_anchored_vertex_positions(|pos| pos.x > 0.0 && pos.z <= 5.0, anchor_to_self);
}

自定义锚定允许

  • 将顶点锚定到各种实体,例如骨骼网格关节
  • 定义自定义偏移量以自定义锚定顶点和目标之间的距离
  • 使用世界空间锚定并忽略目标的旋转,例如
  • 使用偏移量覆盖顶点位置

配置

您可以通过将ClothConfig资源插入到您的应用程序中来自定义全局布料物理。

use bevy::prelude::*;
use bevy_silk::prelude::*;

fn main() {
  App::new()
    .add_plugins((DefaultPlugins, ClothPlugin))
    .insert_resource(ClothConfig {
        gravity: Vec3::new(0.0, -9.81, 0.0),
        friction: 0.02,
        sticks_computation_depth: 5,
        acceleration_smoothing: AccelerationSmoothing::default()
    })
    // ... Add your resources and systems
    .run();
}

ClothConfig也可以用作组件以覆盖全局配置。

您可以为模拟添加风力,以实现更动态的服装效果。对于每个力,您可以选择

  • Wind::Constant 用于恒定的风力
  • Wind::SinWave 用于随风力强度变化的正弦波,具有自定义力和频率。

Wind 力可以通过 Winds 容器添加到您的应用程序中

use bevy::prelude::*;
use bevy_silk::prelude::*;

fn main() {
  App::new()
    .add_plugins((DefaultPlugins, ClothPlugin))
    .insert_resource(Winds {
        wind_forces: vec![Wind::SinWave {
            max_velocity: Vec3::new(10.0, 15.0, -5.0),
            frequency: 3.0,
            normalize: false,
            abs: false
        }]
    })
    // ... Add your resources and systems
    .run();
}

查看标志示例以了解简单的风力效果。

碰撞

支持 bevy_rapieravian,用于与碰撞体进行布料交互。它们分别可以通过 rapier_collisionsavian_collisions 功能启用。

注意:目前碰撞支持仍然是实验性的,不适合用于生产。欢迎提供反馈!

bevy_rapier

bevy_rapier3d::RapierPhysicsPlugin 添加到您的应用程序,并将 ClothCollider 添加到您的实体中,以启用碰撞

use bevy::prelude::*;
use bevy_silk::prelude::*;

fn spawn(mut commands: Commands) {
    commands.spawn((
        PbrBundle {
            // Add your mesh, material and your custom PBR data
            ..default()
        },
        ClothBuilder::new(),
        ClothCollider::default(),
    ));
}

将自动插入三个 bevy_rapier 组件

  • 一个 RigidBody::KinematicPositionBased
  • 一个将每帧更新以跟随布料边界(AABB)的 Collider
  • SolverGroup 设置为 0(Group::NONE),在所有情况下都避免默认的碰撞解决。

您可以通过指定 CollisionGroups 来自定义要检查哪些碰撞。(请参阅 bevy_rapier 文档)。

avian(之前为 bevy_xpbd

avian3d::PhysicsPlugins 添加到您的应用程序,并将 ClothCollider 添加到您的实体中,以启用碰撞

use bevy::prelude::*;
use bevy_silk::prelude::*;

fn spawn(mut commands: Commands) {
    commands.spawn((
        PbrBundle {
            // Add your mesh, material and your custom PBR data
            ..default()
        },
        ClothBuilder::new(),
        ClothCollider::default(),
    ));
}

将自动插入三个 avian3d 组件

  • 一个 RigidBody::Kinematic
  • 一个将每帧更新以跟随布料边界(AABB)的 Collider
  • 一个用于避免默认碰撞解决的 Sensor

您可以通过指定 CollisionLayers 来自定义要检查哪些碰撞。(请参阅 avian 文档)。

网格工具

bevy_silk 提供了一个平面网格生成函数 rectangle_mesh,这对于像旗帜或斗篷这样的经典布料用途很有用。

问答

  • 当我添加布料组件时,我的网格立即无限下落,如何修复?

    您可能没有指定任何 固定点,这意味着没有顶点锚定到您的实体的 GlobalTransform

  • 我的布料抖动得很厉害/突然掉落/有奇怪的反常行为

    默认情况下,重力和风力通过帧率进行平滑处理,如果帧率突然下降,重力和风力会变得很强。如果您的模拟因此受到影响,您可以在 ClothConfig::acceleration_smoothing 中指定一个自定义平滑值。

待办事项列表

  • 世界和每个布料模拟暂停/过滤布料更新
  • 布料更新批处理
  • 布料剪切?

示例

Bevy Flag

  1. 旗帜示例

    运行 cargo run --example flag

  2. 气球示例

    运行 cargo run --example balloon

  3. 移动示例

    运行 cargo run --example moving

  4. bevy_rapier 碰撞示例

    运行 cargo run --example rapier_collision --features rapier_collisions

  5. bevy_xpbd 碰撞示例

    运行 cargo run --example xpbd_collision --features xpbd_collisions

  6. 锚点示例

    运行 cargo run --example anchors

依赖项

~33–71MB
~1M SLoC