Skip to content

Commit

Permalink
Loading scenes into a standalone(ish) objects (meirbon#14)
Browse files Browse the repository at this point in the history
* Descriptors-based scene loading.

* Update examples.
  • Loading branch information
tedsta committed Sep 4, 2020
1 parent dc17728 commit 53174d7
Show file tree
Hide file tree
Showing 7 changed files with 352 additions and 304 deletions.
38 changes: 29 additions & 9 deletions examples/animated/src/main.rs
Expand Up @@ -17,6 +17,7 @@ use winit::{
use rfw_gfx::GfxBackend;
use rfw_system::{
scene::{
self,
renderers::{RenderMode, Setting, SettingValue},
Camera, Renderer,
},
Expand Down Expand Up @@ -147,29 +148,40 @@ fn run_application<T: 'static + Sized + Renderer>() -> Result<(), Box<dyn Error>
60.0,
);

let mut cesium_man1 = renderer
let mut cesium_man = renderer
.load("models/CesiumMan/CesiumMan.gltf")?
.scene()
.unwrap();

let mut cesium_man1 = scene::graph::NodeGraph::new();
let mut cesium_man2 = scene::graph::NodeGraph::new();
cesium_man1.load_scene_descriptor(
&cesium_man,
&mut renderer.scene.objects.instances.write().unwrap(),
);
cesium_man2.load_scene_descriptor(
&cesium_man,
&mut renderer.scene.objects.instances.write().unwrap(),
);

for node in cesium_man1.iter_root_nodes_mut() {
node.set_scale(Vec3::splat(3.0));
node.set_rotation(Quat::from_rotation_y(180.0_f32.to_radians()));
}

let mut cesium_man2 = cesium_man1.clone();
for node in cesium_man2.iter_root_nodes_mut() {
node.translate(Vec3::new(-3.0, 0.0, 0.0));
}

let mut cesium_man3 = cesium_man2.clone();
for node in cesium_man3.iter_root_nodes_mut() {
node.translate(Vec3::new(-3.0, 0.0, 0.0));
}

let cesium_man1 = renderer.add_scene(cesium_man1)?;
let cesium_man2 = renderer.add_scene(cesium_man2)?;

let pica = renderer.load("models/pica/scene.gltf")?.scene().unwrap();
let pica_desc = renderer.load("models/pica/scene.gltf")?.scene().unwrap();
let mut pica = scene::graph::NodeGraph::new();
pica.load_scene_descriptor(
&pica_desc,
&mut renderer.scene.objects.instances.write().unwrap(),
);
renderer.add_scene(pica)?;

let settings: Vec<Setting> = renderer.get_settings().unwrap();
Expand Down Expand Up @@ -248,7 +260,15 @@ fn run_application<T: 'static + Sized + Renderer>() -> Result<(), Box<dyn Error>
renderer.remove_scene(id).unwrap();
scene_id = None;
} else {
scene_id = Some(renderer.add_scene(cesium_man3.clone()).unwrap());
let mut cesium_man3 = scene::graph::NodeGraph::new();
cesium_man3.load_scene_descriptor(
&cesium_man,
&mut renderer.scene.objects.instances.write().unwrap(),
);
for node in cesium_man3.iter_root_nodes_mut() {
node.translate(Vec3::new(-6.0, 0.0, 0.0));
}
scene_id = Some(renderer.add_scene(cesium_man3).unwrap());
}

scene_timer.reset();
Expand Down
30 changes: 22 additions & 8 deletions examples/simple/src/main.rs
Expand Up @@ -69,7 +69,10 @@ impl MouseButtonHandler {
}

use glam::*;
use rfw_system::{scene::renderers::RenderMode, scene::Camera, RenderSystem};
use rfw_system::{
scene::{self, Camera, renderers::RenderMode},
RenderSystem,
};
use shared::utils;
use winit::window::Fullscreen;

Expand Down Expand Up @@ -111,31 +114,42 @@ async fn run_application() -> Result<(), Box<dyn Error>> {
let mut synchronize = utils::Averager::new();
let mut resized = false;

let mut node_graph = scene::graph::NodeGraph::new();

match renderer
.load_async("models/CesiumMan/CesiumMan.gltf")
.await?
{
rfw_system::scene::LoadResult::Scene(mut graph) => {
for node in graph.iter_root_nodes_mut() {
rfw_system::scene::LoadResult::Scene(scene) => {
node_graph.load_scene_descriptor(
&scene,
&mut renderer.scene.objects.instances.write().unwrap(),
);

for node in node_graph.iter_root_nodes_mut() {
node.set_scale(Vec3::splat(3.0));
node.set_rotation(Quat::from_rotation_y(180.0_f32.to_radians()));
}
renderer.add_scene(graph)?;
}
_ => panic!("Gltf files should be loaded as scenes"),
};

match renderer.load_async("models/pica/scene.gltf").await? {
rfw_system::scene::LoadResult::Scene(graph) => {
renderer.add_scene(graph)?;
rfw_system::scene::LoadResult::Scene(scene) => {
node_graph.load_scene_descriptor(
&scene,
&mut renderer.scene.objects.instances.write().unwrap(),
);
}
_ => panic!("Gltf files should be loaded as scenes"),
};

let scene_id = renderer.add_scene(node_graph)?;

let app_time = utils::Timer::new();

timer2.reset();
renderer.set_animation_time(0.0);
renderer.set_animation_time(scene_id, 0.0);
renderer.synchronize();
synchronize.add_sample(timer2.elapsed_in_millis());

Expand Down Expand Up @@ -248,7 +262,7 @@ async fn run_application() -> Result<(), Box<dyn Error>> {
}

timer2.reset();
renderer.set_animation_time(app_time.elapsed_in_millis() / 1000.0);
renderer.set_animation_time(scene_id, app_time.elapsed_in_millis() / 1000.0);
renderer.synchronize();
synchronize.add_sample(timer2.elapsed_in_millis());

Expand Down
129 changes: 4 additions & 125 deletions scene/src/graph/animation.rs
Expand Up @@ -13,123 +13,6 @@ pub enum Method {
Step,
}

#[cfg_attr(feature = "object_caching", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
pub struct Sampler {
pub method: Method,
pub key_frames: Vec<f32>,
pub float_frames: Vec<f32>,
pub vec_frames: Vec<Vec3>,
pub rot_frames: Vec<Quat>,
}

impl Default for Sampler {
fn default() -> Self {
Self {
method: Method::Linear,
key_frames: Vec::new(),
float_frames: Vec::new(),
vec_frames: Vec::new(),
rot_frames: Vec::new(),
}
}
}

impl Sampler {
pub fn sample_vec3(&self, time: f32, k: usize) -> Vec3 {
let t0 = self.key_frames[k];
let t1 = self.key_frames[k + 1];
let f = (time - t0) / (t1 - t0);

if f <= 0.0 {
self.vec_frames[0]
} else {
match self.method {
Method::Linear => (1.0 - f) * self.vec_frames[k] + f * self.vec_frames[k + 1],
Method::Spline => {
let t = f;
let t2 = t * t;
let t3 = t2 * t;
let p0 = self.vec_frames[k * 3 + 1];
let m0 = (t1 - t0) * self.vec_frames[k * 3 + 2];
let p1 = self.vec_frames[(k + 1) * 3 + 1];
let m1 = (t1 - t0) * self.vec_frames[(k + 1) * 3];
m0 * (t3 - 2.0 * t2 + t)
+ p0 * (2.0 * t3 - 3.0 * t2 + 1.0)
+ p1 * (-2.0 * t3 + 3.0 * t2)
+ m1 * (t3 - t2)
}
Method::Step => self.vec_frames[k],
}
}
}

pub fn sample_float(&self, time: f32, k: usize, i: usize, count: usize) -> f32 {
let t0 = self.key_frames[k];
let t1 = self.key_frames[k + 1];
let f = (time - t0) / (t1 - t0);

if f <= 0.0 {
self.float_frames[0]
} else {
match self.method {
Method::Linear => {
(1.0 - f) * self.float_frames[k * count + i]
+ f * self.float_frames[(k + 1) * count + i]
}
Method::Spline => {
let t = f;
let t2 = t * t;
let t3 = t2 * t;
let p0 = self.float_frames[(k * count + i) * 3 + 1];
let m0 = (t1 - t0) * self.float_frames[(k * count + i) * 3 + 2];
let p1 = self.float_frames[((k + 1) * count + i) * 3 + 1];
let m1 = (t1 - t0) * self.float_frames[((k + 1) * count + i) * 3];
m0 * (t3 - 2.0 * t2 + t)
+ p0 * (2.0 * t3 - 3.0 * t2 + 1.0)
+ p1 * (-2.0 * t3 + 3.0 * t2)
+ m1 * (t3 - t2)
}
Method::Step => self.float_frames[k],
}
}
}

pub fn sample_rotation(&self, time: f32, k: usize) -> Quat {
let t0 = self.key_frames[k];
let t1 = self.key_frames[k + 1];
let f = (time - t0) / (t1 - t0);

if f <= 0.0 {
self.rot_frames[0]
} else {
match self.method {
Method::Linear => Quat::from(
(Vec4::from(self.rot_frames[k]) * (1.0 - f))
+ (Vec4::from(self.rot_frames[k + 1]) * f),
),
Method::Spline => {
let t = f;
let t2 = t * t;
let t3 = t2 * t;

let p0 = Vec4::from(self.rot_frames[k * 3 + 1]);
let m0 = Vec4::from(self.rot_frames[k * 3 + 2]) * (t1 - t0);
let p1 = Vec4::from(self.rot_frames[(k + 1) * 3 + 1]);
let m1 = Vec4::from(self.rot_frames[(k + 1) * 3]) * (t1 - t0);
Quat::from(
m0 * (t3 - 2.0 * t2 + t)
+ p0 * (2.0 * t3 - 3.0 * t2 + 1.0)
+ p1 * (-2.0 * t3 + 3.0 * t2)
+ m1 * (t3 - t2),
)
}
Method::Step => self.rot_frames[k],
}
}
}
}

#[cfg_attr(feature = "object_caching", derive(Serialize, Deserialize))]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Target {
Expand All @@ -142,8 +25,6 @@ pub enum Target {
#[cfg_attr(feature = "object_caching", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
pub struct Channel {
pub node_id: u32,
pub sampler_ids: Vec<u32>,
pub targets: Vec<Target>,
pub key_frames: Vec<f32>,

Expand All @@ -158,10 +39,8 @@ pub struct Channel {
impl Default for Channel {
fn default() -> Self {
Self {
sampler_ids: Vec::new(),
targets: Vec::new(),
key_frames: Vec::new(),
node_id: std::u32::MAX,

sampler: Method::Linear,
vec3s: Vec::new(),
Expand Down Expand Up @@ -285,7 +164,7 @@ impl Channel {
pub struct Animation {
pub name: String,
pub affected_roots: Vec<u32>,
pub channels: Vec<Channel>,
pub channels: Vec<(u32, Channel)>, // Vec<(node id, channel)>
pub time: f32,
}

Expand Down Expand Up @@ -320,9 +199,9 @@ impl Animation {
self.time = time;
let channels = &mut self.channels;

channels.iter_mut().for_each(|c| {
channels.iter_mut().for_each(|(node_id, c)| {
let current_time = time % c.duration;
let node_id = c.node_id as usize;
let node_id = *node_id as usize;
c.targets.iter().for_each(|t| {
let mut key = 0;
while current_time > c.key_frames[key as usize + 1] {
Expand All @@ -345,7 +224,7 @@ impl Animation {
for i in 0..weights {
node.weights[i] = c.sample_weight(current_time, key, i, weights);
}
node.morhped = true;
node.morphed = true;
}
}
});
Expand Down

0 comments on commit 53174d7

Please sign in to comment.