Skinned extraction speedup (#4428)
# Objective - While animating 501 https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/BrainStem, I noticed things were getting a little slow - Looking in tracy, the system `extract_skinned_meshes` is taking a lot of time, with a mean duration of 15.17ms ## Solution - ~~Use `Vec` instead of a `SmallVec`~~ - ~~Don't use an temporary variable~~ - Compute the affine matrix as an `Affine3A` instead - Remove the `temp` vec | |mean| |---|---| |base|15.17ms| |~~vec~~|~~9.31ms~~| |~~no temp variable~~|~~11.31ms~~| |removing the temp vector|8.43ms| |affine|13.21ms| |all together|7.23ms|
This commit is contained in:
parent
c5963b4fd5
commit
9d54f33974
@ -29,4 +29,3 @@ bevy_window = { path = "../bevy_window", version = "0.7.0-dev" }
|
|||||||
bitflags = "1.2"
|
bitflags = "1.2"
|
||||||
# direct dependency required for derive macro
|
# direct dependency required for derive macro
|
||||||
bytemuck = { version = "1", features = ["derive"] }
|
bytemuck = { version = "1", features = ["derive"] }
|
||||||
smallvec = "1.0"
|
|
||||||
|
@ -26,7 +26,6 @@ use bevy_render::{
|
|||||||
RenderApp, RenderStage,
|
RenderApp, RenderStage,
|
||||||
};
|
};
|
||||||
use bevy_transform::components::GlobalTransform;
|
use bevy_transform::components::GlobalTransform;
|
||||||
use smallvec::SmallVec;
|
|
||||||
use std::num::NonZeroU64;
|
use std::num::NonZeroU64;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -192,15 +191,16 @@ impl SkinnedMeshJoints {
|
|||||||
let inverse_bindposes = inverse_bindposes.get(&skin.inverse_bindposes)?;
|
let inverse_bindposes = inverse_bindposes.get(&skin.inverse_bindposes)?;
|
||||||
let bindposes = inverse_bindposes.iter();
|
let bindposes = inverse_bindposes.iter();
|
||||||
let skin_joints = skin.joints.iter();
|
let skin_joints = skin.joints.iter();
|
||||||
let mut temp =
|
let start = buffer.len();
|
||||||
SmallVec::<[Mat4; MAX_JOINTS]>::with_capacity(bindposes.len().min(MAX_JOINTS));
|
|
||||||
for (inverse_bindpose, joint) in bindposes.zip(skin_joints).take(MAX_JOINTS) {
|
for (inverse_bindpose, joint) in bindposes.zip(skin_joints).take(MAX_JOINTS) {
|
||||||
let joint_matrix = joints.get(*joint).ok()?.compute_matrix();
|
if let Ok(joint) = joints.get(*joint) {
|
||||||
temp.push(joint_matrix * *inverse_bindpose);
|
buffer.push(joint.compute_affine() * *inverse_bindpose);
|
||||||
|
} else {
|
||||||
|
buffer.truncate(start);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = buffer.len();
|
|
||||||
buffer.extend(temp);
|
|
||||||
// Pad to 256 byte alignment
|
// Pad to 256 byte alignment
|
||||||
while buffer.len() % 4 != 0 {
|
while buffer.len() % 4 != 0 {
|
||||||
buffer.push(Mat4::ZERO);
|
buffer.push(Mat4::ZERO);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::Transform;
|
use super::Transform;
|
||||||
use bevy_ecs::{component::Component, reflect::ReflectComponent};
|
use bevy_ecs::{component::Component, reflect::ReflectComponent};
|
||||||
use bevy_math::{const_vec3, Mat3, Mat4, Quat, Vec3};
|
use bevy_math::{const_vec3, Affine3A, Mat3, Mat4, Quat, Vec3};
|
||||||
use bevy_reflect::Reflect;
|
use bevy_reflect::Reflect;
|
||||||
use std::ops::Mul;
|
use std::ops::Mul;
|
||||||
|
|
||||||
@ -128,6 +128,13 @@ impl GlobalTransform {
|
|||||||
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
|
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the 3d affine transformation from this transforms translation,
|
||||||
|
/// rotation, and scale.
|
||||||
|
#[inline]
|
||||||
|
pub fn compute_affine(&self) -> Affine3A {
|
||||||
|
Affine3A::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the unit vector in the local x direction
|
/// Get the unit vector in the local x direction
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn local_x(&self) -> Vec3 {
|
pub fn local_x(&self) -> Vec3 {
|
||||||
|
Loading…
Reference in New Issue
Block a user