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

Add third person camera #17

Merged
merged 2 commits into from
Apr 14, 2024
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
12 changes: 11 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ edition = "2021"
bevy = "0.13"
bvh_anim = "0.4"
bevy_gltf = "0.13"
bevy_third_person_camera = "0.1.10"
18 changes: 14 additions & 4 deletions src/animation_player.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use bevy::{asset::LoadState, prelude::*};
use bvh_anim::{Bvh, Channel, Frame};

use crate::{animation_loader::BvhData, character_loader::BvhToCharacter};
use crate::{
animation_loader::BvhData,
character_loader::{BvhToCharacter, MainCharacter},
};

pub struct AnimationPlayerPlugin;

Expand Down Expand Up @@ -78,7 +81,8 @@ pub struct TargetTimeEvent {

pub fn match_bones(
mut commands: Commands,
mut q_names: Query<(Entity, &Name, &mut Transform, &GlobalTransform)>,
mut q_names: Query<(Entity, &Name, &mut Transform, &GlobalTransform), Without<MainCharacter>>,
mut q_character: Query<&mut Transform, With<MainCharacter>>,
bvh_data: Res<BvhData>,
mut bvh_to_character: ResMut<BvhToCharacter>,
mut hip_transforms: ResMut<HipTransforms>,
Expand Down Expand Up @@ -164,15 +168,21 @@ pub fn match_bones(
Quat::slerp(current_rotation, next_rotation, interpolation_factor);

transform.rotation = interpolated_rotation;
transform.translation = interpolated_translation;

// transform.translation = interpolated_translation;
if bone_name == "Hips" {
for mut c_transform in q_character.iter_mut() {
c_transform.translation = interpolated_translation * 0.01;
c_transform.translation.y = 0.0;
}
// Store the current position as the previous for the left foot
hip_transforms.hip_previous_transform =
hip_transforms.hip_current_transform;
// Update the current position for the left foot
hip_transforms.hip_current_transform = global_transform.translation();
} else {
transform.translation = interpolated_translation;
}

event_writer.send(HipTransformsEvent {
current_transform: hip_transforms.hip_current_transform,
previous_transform: hip_transforms.hip_previous_transform,
Expand Down
69 changes: 69 additions & 0 deletions src/camera.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use bevy::prelude::*;
use bevy_third_person_camera::{camera::Offset, ThirdPersonCamera, ThirdPersonCameraPlugin};

pub struct CameraPlugin;

impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, spawn_camera)
.add_plugins(ThirdPersonCameraPlugin)
.add_systems(Update, camera_lerp);
}
}

pub fn spawn_camera(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn((
ThirdPersonCamera {
offset_enabled: true,
offset: Offset::new(0.5, 0.8),
offset_toggle_key: KeyCode::KeyE,
offset_toggle_speed: 0.3,
cursor_lock_toggle_enabled: true,
cursor_lock_active: true,
cursor_lock_key: KeyCode::Space,
..Default::default()
},
Transform::default(),
));

commands.spawn(Camera3dBundle::default());

// ground plane
commands.spawn(PbrBundle {
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)),
material: materials.add(Color::SILVER),
..default()
});
}

fn camera_lerp(
mut q_camera: Query<&mut Transform, (With<Camera3d>, Without<ThirdPersonCamera>)>,
q_third_person: Query<&Transform, (With<ThirdPersonCamera>, Without<Camera3d>)>,
time: Res<Time>,
) {
const SPEED: f32 = 15.0;

let Ok(third_person_transform) = q_third_person.get_single() else {
return;
};

let Ok(mut camera_transform) = q_camera.get_single_mut() else {
return;
};

camera_transform.translation = Vec3::lerp(
camera_transform.translation,
third_person_transform.translation,
time.delta_seconds() * SPEED,
);

camera_transform.rotation = Quat::slerp(
camera_transform.rotation,
third_person_transform.rotation,
time.delta_seconds() * SPEED,
);
}
4 changes: 3 additions & 1 deletion src/character_loader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use bevy::prelude::*;
use bevy_third_person_camera::ThirdPersonCameraTarget;

pub struct CharacterLoaderPlugin;

Expand Down Expand Up @@ -33,7 +34,8 @@ pub fn spawn_character(mut commands: Commands, asset_server: Res<AssetServer>) {
scene: scene.clone(),
..default()
})
.insert(MainCharacter);
.insert(MainCharacter)
.insert(ThirdPersonCameraTarget);

commands.insert_resource(BvhToCharacter {
loaded: false,
Expand Down
17 changes: 14 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ use bevy::input::mouse::{MouseMotion, MouseWheel};
use bevy::prelude::*;
use bevy::window::Window;
use bevy::DefaultPlugins;
use camera::CameraPlugin;
use character_loader::CharacterLoaderPlugin;

mod animation_loader;
mod animation_player;
mod camera;
mod character_loader;

fn main() {
Expand All @@ -17,10 +19,12 @@ fn main() {
CharacterLoaderPlugin,
AnimationLoaderPlugin,
AnimationPlayerPlugin,
CameraPlugin,
))
.init_gizmo_group::<MyRoundGizmos>()
.add_systems(Startup, (spawn_camera, setup))
.add_systems(Update, pan_orbit_camera)
.add_systems(Startup, setup)
// .add_systems(Startup, spawn_camera)
// .add_systems(Update, pan_orbit_camera)
.run();
}

Expand Down Expand Up @@ -154,7 +158,7 @@ fn get_primary_window_size(windows: &Query<&Window>) -> Vec2 {
}

/// Spawn a camera like this
fn spawn_camera(mut commands: Commands) {
fn spawn_camera(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
let translation = Vec3::new(-2.0, 2.5, 5.0);
let radius = translation.length();

Expand All @@ -168,4 +172,11 @@ fn spawn_camera(mut commands: Commands) {
..Default::default()
},
));

commands.spawn((PbrBundle {
mesh: meshes.add(Cuboid::new(0.9, 0.5, 0.5)),
// material: materials.add(Color::rgb(10.0, 14.0, 25.0)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
},));
}