Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moving transform data out of Mat4 #596

Merged
merged 8 commits into from
Oct 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/bevy_pbr/src/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ impl LightRaw {
far: light.depth.end,
};

let proj = perspective.get_projection_matrix() * *global_transform.value();
let (x, y, z) = global_transform.translation().into();
let proj = perspective.get_projection_matrix() * global_transform.compute_matrix();
let (x, y, z) = global_transform.translation.into();
LightRaw {
proj: proj.to_cols_array_2d(),
pos: [x, y, z, 1.0],
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_render/src/camera/visible_entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn visible_entities_system(
) {
for (camera, camera_global_transform, mut visible_entities) in &mut camera_query.iter() {
visible_entities.value.clear();
let camera_position = camera_global_transform.translation();
let camera_position = camera_global_transform.translation;

let mut no_transform_order = 0.0;
let mut transparent_entities = Vec::new();
Expand All @@ -41,7 +41,7 @@ pub fn visible_entities_system(

let order =
if let Ok(global_transform) = draw_transform_query.get::<GlobalTransform>(entity) {
let position = global_transform.translation();
let position = global_transform.translation;
// smaller distances are sorted to lower indices by using the distance from the camera
FloatOrd(match camera.depth_calculation {
DepthCalculation::ZDifference => camera_position.z() - position.z(),
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/src/render_graph/nodes/camera_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub fn camera_node_system(

let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
let camera_matrix: [f32; 16] =
(camera.projection_matrix * global_transform.value().inverse()).to_cols_array();
(camera.projection_matrix * global_transform.compute_matrix().inverse()).to_cols_array();

render_resource_context.write_mapped_buffer(
staging_buffer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use bevy_asset::Handle;
use bevy_core::{Byteable, Bytes};
pub use bevy_derive::{RenderResource, RenderResources};
use bevy_math::{Mat4, Vec2, Vec3, Vec4};
use bevy_transform::components::GlobalTransform;

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum RenderResourceType {
Expand Down Expand Up @@ -179,14 +180,33 @@ where
}
}

impl RenderResource for GlobalTransform {
fn resource_type(&self) -> Option<RenderResourceType> {
Some(RenderResourceType::Buffer)
}

fn write_buffer_bytes(&self, buffer: &mut [u8]) {
let mat4 = self.compute_matrix();
mat4.write_bytes(buffer);
}

fn buffer_byte_len(&self) -> Option<usize> {
Some(std::mem::size_of::<[f32; 16]>())
}

fn texture(&self) -> Option<Handle<Texture>> {
None
}
}

impl RenderResources for bevy_transform::prelude::GlobalTransform {
fn render_resources_len(&self) -> usize {
1
}

fn get_render_resource(&self, index: usize) -> Option<&dyn RenderResource> {
if index == 0 {
Some(self.value())
Some(self)
} else {
None
}
Expand Down
223 changes: 106 additions & 117 deletions crates/bevy_transform/src/components/global_transform.rs
Original file line number Diff line number Diff line change
@@ -1,174 +1,163 @@
use bevy_math::{Mat3, Mat4, Quat, Vec3};
use bevy_property::Properties;
use std::fmt;
use std::ops::Mul;

use super::Transform;

#[derive(Debug, PartialEq, Clone, Copy, Properties)]
pub struct GlobalTransform {
value: Mat4,
pub translation: Vec3,
pub rotation: Quat,
pub scale: Vec3,
}

impl GlobalTransform {
#[inline(always)]
pub fn new(value: Mat4) -> Self {
GlobalTransform { value }
}

#[inline(always)]
#[inline]
pub fn identity() -> Self {
GlobalTransform {
value: Mat4::identity(),
translation: Vec3::zero(),
rotation: Quat::identity(),
scale: Vec3::one(),
}
}

pub fn from_translation(translation: Vec3) -> Self {
GlobalTransform::new(Mat4::from_translation(translation))
}
#[inline]
pub fn from_matrix(matrix: Mat4) -> Self {
let (scale, rotation, translation) = matrix.to_scale_rotation_translation();

pub fn from_rotation(rotation: Quat) -> Self {
GlobalTransform::new(Mat4::from_quat(rotation))
}

pub fn from_scale(scale: f32) -> Self {
GlobalTransform::new(Mat4::from_scale(Vec3::splat(scale)))
}

pub fn from_translation_rotation(translation: Vec3, rotation: Quat) -> Self {
GlobalTransform::new(Mat4::from_scale_rotation_translation(
Vec3::splat(1.0),
rotation,
GlobalTransform {
translation,
))
}

pub fn from_translation_rotation_scale(translation: Vec3, rotation: Quat, scale: f32) -> Self {
GlobalTransform::new(Mat4::from_scale_rotation_translation(
Vec3::splat(scale),
rotation,
translation,
))
}

pub fn from_non_uniform_scale(scale: Vec3) -> Self {
GlobalTransform::new(Mat4::from_scale(scale))
}

pub fn with_translation(mut self, translation: Vec3) -> Self {
self.set_translation(translation);
self
}

pub fn with_rotation(mut self, rotation: Quat) -> Self {
self.set_rotation(rotation);
self
}

pub fn with_scale(mut self, scale: f32) -> Self {
self.set_scale(scale);
self
scale,
}
}

pub fn with_non_uniform_scale(mut self, scale: Vec3) -> Self {
self.set_non_uniform_scale(scale);
self
#[inline]
pub fn from_translation(translation: Vec3) -> Self {
GlobalTransform {
translation,
..Default::default()
}
}

pub fn with_translate(mut self, translation: Vec3) -> Self {
self.translate(translation);
self
#[inline]
pub fn from_rotation(rotation: Quat) -> Self {
GlobalTransform {
rotation,
..Default::default()
}
}

pub fn with_rotate(mut self, rotation: Quat) -> Self {
self.rotate(rotation);
self
#[inline]
pub fn from_scale(scale: Vec3) -> Self {
GlobalTransform {
scale,
..Default::default()
}
}

pub fn with_apply_scale(mut self, scale: f32) -> Self {
self.apply_scale(scale);
self
/// Returns transform with the same translation and scale, but rotation so that transform.forward() points at the origin
#[inline]
pub fn looking_at_origin(self) -> Self {
self.looking_at(Vec3::zero(), Vec3::unit_y())
}

pub fn with_apply_non_uniform_scale(mut self, scale: Vec3) -> Self {
self.apply_non_uniform_scale(scale);
/// Returns transform with the same translation and scale, but rotation so that transform.forward() points at target
#[inline]
pub fn looking_at(mut self, target: Vec3, up: Vec3) -> Self {
self.look_at(target, up);
self
}

pub fn value(&self) -> &Mat4 {
&self.value
#[inline]
pub fn compute_matrix(&self) -> Mat4 {
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
}

pub fn value_mut(&mut self) -> &mut Mat4 {
&mut self.value
#[inline]
pub fn forward(&self) -> Vec3 {
self.rotation * Vec3::unit_z()
}

pub fn translation(&self) -> Vec3 {
Vec3::from(self.value.w_axis().truncate())
#[inline]
/// Rotate the transform by the given rotation
pub fn rotate(&mut self, rotation: Quat) {
self.rotation *= rotation;
}

pub fn rotation(&self) -> Quat {
let scale = self.scale();

Quat::from_rotation_mat3(&Mat3::from_cols(
Vec3::from(self.value.x_axis().truncate()) / scale.x(),
Vec3::from(self.value.y_axis().truncate()) / scale.y(),
Vec3::from(self.value.z_axis().truncate()) / scale.z(),
))
#[inline]
pub fn mul_transform(&self, transform: Transform) -> GlobalTransform {
let translation = self.mul_vec3(transform.translation);
let rotation = self.rotation * transform.rotation;
let scale = self.scale * transform.scale;
GlobalTransform {
scale,
rotation,
translation,
}
}

pub fn scale(&self) -> Vec3 {
Vec3::new(
self.value.x_axis().truncate().length(),
self.value.y_axis().truncate().length(),
self.value.z_axis().truncate().length(),
)
#[inline]
pub fn mul_vec3(&self, mut value: Vec3) -> Vec3 {
value = self.rotation * value;
value = self.scale * value;
value += self.translation;
value
}

pub fn set_translation(&mut self, translation: Vec3) {
*self.value.w_axis_mut() = translation.extend(1.0);
#[inline]
pub fn apply_non_uniform_scale(&mut self, scale: Vec3) {
self.scale *= scale;
}

pub fn set_rotation(&mut self, rotation: Quat) {
self.value =
Mat4::from_scale_rotation_translation(self.scale(), rotation, self.translation());
#[inline]
pub fn look_at(&mut self, target: Vec3, up: Vec3) {
let forward = Vec3::normalize(self.translation - target);
let right = up.cross(forward).normalize();
let up = forward.cross(right);
self.rotation = Quat::from_rotation_mat3(&Mat3::from_cols(right, up, forward));
}
}

pub fn set_scale(&mut self, scale: f32) {
self.value = Mat4::from_scale_rotation_translation(
Vec3::splat(scale),
self.rotation(),
self.translation(),
);
impl Default for GlobalTransform {
fn default() -> Self {
Self::identity()
}
}

pub fn set_non_uniform_scale(&mut self, scale: Vec3) {
self.value =
Mat4::from_scale_rotation_translation(scale, self.rotation(), self.translation());
impl From<Transform> for GlobalTransform {
fn from(transform: Transform) -> Self {
Self {
translation: transform.translation,
rotation: transform.rotation,
scale: transform.scale,
}
}
}

pub fn translate(&mut self, translation: Vec3) {
*self.value.w_axis_mut() += translation.extend(0.0);
}
impl Mul<GlobalTransform> for GlobalTransform {
type Output = GlobalTransform;

pub fn rotate(&mut self, rotation: Quat) {
self.value = Mat4::from_quat(rotation) * self.value;
#[inline]
fn mul(self, global_transform: GlobalTransform) -> Self::Output {
self.mul_transform(global_transform.into())
}
}

pub fn apply_scale(&mut self, scale: f32) {
self.value = Mat4::from_scale(Vec3::splat(scale)) * self.value;
}
impl Mul<Transform> for GlobalTransform {
type Output = GlobalTransform;

pub fn apply_non_uniform_scale(&mut self, scale: Vec3) {
self.value = Mat4::from_scale(scale) * self.value;
#[inline]
fn mul(self, transform: Transform) -> Self::Output {
self.mul_transform(transform)
}
}

impl Default for GlobalTransform {
fn default() -> Self {
Self::identity()
}
}
impl Mul<Vec3> for GlobalTransform {
type Output = Vec3;

impl fmt::Display for GlobalTransform {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
#[inline]
fn mul(self, value: Vec3) -> Self::Output {
self.mul_vec3(value)
}
}
Loading