Skip to content

Commit

Permalink
Refine the internal walking API, add one layer to the group example
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Jan 4, 2018
1 parent 475c292 commit dce3491
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 17 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ exclude = ["doc", "bors.toml", ".travis.yml", "test_data"]

[lib]

[profile.release]
debug = true

[features]
default = ["opengl"]
"opengl" = ["gfx_device_gl", "gfx_window_glutin", "glutin"]
Expand Down
27 changes: 20 additions & 7 deletions examples/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,19 @@ fn create_cubes(
list
}

const COLORS: [three::Color; 6] = [0xffff80, 0x8080ff, 0x80ff80, 0xff8080, 0x80ffff, 0xff80ff];

const SPEEDS: [f32; 6] = [0.7, -1.0, 1.3, -1.6, 1.9, -2.2];
struct LevelDesc {
color: three::Color,
speed: f32, // in radians per second
}
const LEVELS: &[LevelDesc] = &[
LevelDesc { color: 0xffff80, speed: 0.7 },
LevelDesc { color: 0x8080ff, speed: -1.0 },
LevelDesc { color: 0x80ff80, speed: 1.3 },
LevelDesc { color: 0xff8080, speed: -1.6 },
LevelDesc { color: 0x80ffff, speed: 1.9 },
LevelDesc { color: 0xff80ff, speed: -2.2 },
//LevelDesc { color: 0x8080ff, speed: 2.5 },
];

fn main() {
let mut win = three::Window::new("Three-rs group example");
Expand All @@ -117,11 +127,14 @@ fn main() {
light.set_position([0.0, -10.0, 10.0]);
win.scene.add(&light);

let materials: Vec<_> = COLORS
let materials = LEVELS
.iter()
.map(|&color| three::material::Lambert { color, flat: false })
.collect();
let levels: Vec<_> = SPEEDS.iter().map(|&speed| Level { speed }).collect();
.map(|l| three::material::Lambert { color: l.color, flat: false })
.collect::<Vec<_>>();
let levels = LEVELS
.iter()
.map(|l| Level { speed: l.speed })
.collect::<Vec<_>>();
let mut cubes = create_cubes(&mut win.factory, &materials, &levels);
win.scene.add(&cubes[0].group);

Expand Down
27 changes: 20 additions & 7 deletions src/hub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,45 +282,58 @@ impl Hub {
}
}

pub(crate) fn walk(&self, base: &Option<NodePointer>) -> TreeWalker {
fn walk_impl(
&self, base: &Option<NodePointer>, only_visible: bool
) -> TreeWalker {
let default_stack_size = 10;
let mut walker = TreeWalker {
hub: self,
stack: Vec::new(),
only_visible: true,
only_visible,
stack: Vec::with_capacity(default_stack_size),
};
walker.descend(base);
walker
}

pub(crate) fn walk(&self, base: &Option<NodePointer>) -> TreeWalker {
self.walk_impl(base, true)
}

pub(crate) fn walk_all(&self, base: &Option<NodePointer>) -> TreeWalker {
self.walk_impl(base, false)
}
}

#[derive(Debug)]
pub(crate) struct WalkedNode<'a> {
pub(crate) node: &'a NodeInternal,
pub(crate) world_visible: bool,
pub(crate) world_transform: TransformInternal,
pub(crate) node: &'a NodeInternal,
}

pub(crate) struct TreeWalker<'a> {
hub: &'a Hub,
stack: Vec<WalkedNode<'a>>,
only_visible: bool,
stack: Vec<WalkedNode<'a>>,
}

impl<'a> TreeWalker<'a> {
fn descend(&mut self, base: &Option<NodePointer>) -> Option<&NodeInternal> {
// Note: this is a CPU hotspot, presumably for copying stuff around
// TODO: profile carefully and optimize
let mut node = &self.hub.nodes[base.as_ref()?];

loop {
let wn = match self.stack.last() {
Some(parent) => WalkedNode {
node,
world_visible: parent.world_visible && node.visible,
world_transform: parent.world_transform.concat(&node.transform),
node,
},
None => WalkedNode {
node,
world_visible: node.visible,
world_transform: node.transform,
node,
},
};
self.stack.push(wn);
Expand Down
7 changes: 4 additions & 3 deletions src/scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::mem;
use std::marker::PhantomData;
use std::sync::MutexGuard;


/// Background type.
#[derive(Clone, Debug, PartialEq)]
pub enum Background {
Expand Down Expand Up @@ -166,7 +167,7 @@ impl<'a> SyncGuard<'a> {
/// Panics if `scene` doesn't have this `object::Base`.
///
/// [`Node`]: ../node/struct.Node.html
pub fn resolve<T: Object + 'a>(
pub fn resolve<T: 'a + Object>(
&mut self,
object: &T,
) -> node::Node<node::Local> {
Expand All @@ -180,13 +181,13 @@ impl<'a> SyncGuard<'a> {
/// Panics if the doesn't have this `object::Base`.
///
/// [`Node`]: ../node/struct.Node.html
pub fn resolve_world<T: Object + 'a>(
pub fn resolve_world<T: 'a + Object>(
&mut self,
object: &T,
) -> node::Node<node::World> {
let internal = &self.hub[object] as *const _;
let wn = self.hub
.walk(&self.scene.first_child)
.walk_all(&self.scene.first_child)
.find(|wn| wn.node as *const _ == internal)
.expect("Unable to find objects for world resolve!");
node::Node {
Expand Down

0 comments on commit dce3491

Please sign in to comment.