-
Notifications
You must be signed in to change notification settings - Fork 46
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
Template System and Reworked glTF Handling #203
Conversation
Amazing work! I'm happy to see this moving forward 👍 Reviewed 10 of 10 files at r1. examples/gltf-pbr-shader.rs, line 35 at r1 (raw file):
does that look ok when running the example with no parameters? src/template.rs, line 4 at r1 (raw file):
nit: hierarchy of objects src/template.rs, line 5 at r1 (raw file):
make "three" distinguishable here, by either appending the -rs prefix, or applying some formatting src/template.rs, line 22 at r1 (raw file):
big thanks for writing the docs up front! src/template.rs, line 47 at r1 (raw file):
should be called src/template.rs, line 114 at r1 (raw file):
perhaps, we could me more consistent in naming here and call it src/template.rs, line 158 at r1 (raw file):
perhaps, we should re-use src/template.rs, line 210 at r1 (raw file):
Note that we can technically simplify the structure complexity here if we reverse the relationships: have all the specific templates to just have src/factory/mod.rs, line 574 at r1 (raw file):
we need to hide this step for anything but advanced use of the engine src/factory/mod.rs, line 633 at r1 (raw file):
similarly, this should be called with a verb ("instantiate_") Comments from Reviewable |
Review status: all files reviewed at latest revision, 10 unresolved discussions. examples/gltf-pbr-shader.rs, line 35 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
I've actually only tested this running it with no parameters. The Lantern file (which gets loaded by default) happens to be setup such that lantern is in direct focus of the camera's default view, so it looks good when run without parameters. src/template.rs, line 47 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
For src/template.rs, line 210 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
I'm not sure I'm following what you're suggesting. Could you clarify further, maybe provide a rough sketch of what you're imagining? src/factory/mod.rs, line 574 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Agreed that this only necessary for advanced usage. Is there anything I should do to "hide" it for less advanced users? Comments from Reviewable |
Review status: all files reviewed at latest revision, 9 unresolved discussions. src/template.rs, line 47 at r1 (raw file): Previously, randomPoison (David LeGare) wrote…
we should probably rename everything to align better with rust conventions, e.g. create_mesh, etc src/template.rs, line 210 at r1 (raw file): Previously, randomPoison (David LeGare) wrote…
What I'm saying is that we can get away without the src/factory/mod.rs, line 574 at r1 (raw file): Previously, randomPoison (David LeGare) wrote…
not really Comments from Reviewable |
Review status: all files reviewed at latest revision, 9 unresolved discussions. src/template.rs, line 4 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Is there an established convention for not using second person in Rust docs? I did a quick look through the standard library docs, and it seems like second person is used pretty commonly, especially in module-level docs (e.g. src/template.rs, line 5 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. src/template.rs, line 22 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
No problem! It was only the most time consuming portion of the entire PR... src/template.rs, line 47 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Ah, that's reasonable. I updated them, but I don't think it would make sense to change the other methods in this PR. For the two methods in this PR, I went with src/template.rs, line 114 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. src/template.rs, line 158 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. src/template.rs, line 210 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
So, if I'm understanding correctly, you're suggesting something like this:
That makes sense to me. My only question at this point is how do group templates specify their children?
They can't just specify children as a
Do you have a preference as to what approach to take? I'd lean towards the enum, personally. Or is there another approach that I'm not seeing? src/factory/mod.rs, line 633 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. Comments from Reviewable |
Reviewed 3 of 3 files at r2. src/template.rs, line 4 at r1 (raw file): Previously, randomPoison (David LeGare) wrote…
Interesting findings! I'll withdraw my nit then, for now at least :) src/template.rs, line 47 at r1 (raw file): Previously, randomPoison (David LeGare) wrote…
sounds good src/template.rs, line 210 at r1 (raw file): Previously, randomPoison (David LeGare) wrote…
Yeah, in this approach the group would not specify it's children (so, neither of the points in your list). This would be implicit, based on which objects point to the node associated with the group. I'm not 100% sure this is feasible, but it does feel important to explore here. src/factory/mod.rs, line 2 at r2 (raw file):
why does it need to be Comments from Reviewable |
Review status: all files reviewed at latest revision, 4 unresolved discussions. src/template.rs, line 210 at r1 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Totally, I'm down to play in the (design) space. Let me give a concrete example to see if I'm understanding. Let's say I want to create a template for a Group at position (1, 2, 3) and give it two children, a mesh and a light. To describe this I would create a Assuming that's right, how would I specify a different transform for the mesh or the node (e.g. I want the mesh to have a local position of (4, 5, 6))? As I understand it, An alternative that occurs to me now: Instead of having groups list their children, have all the types have a src/factory/mod.rs, line 2 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Woops, I'm pretty sure this is an artifact of an earlier iteration where I was defining types in that module that I wanted to be accessible within the crate. I'll revert this since it's not necessary. Comments from Reviewable |
204: Add node names r=kvark a=randomPoison This PR adds the ability to set the name of `Object` types, and retrieve those names when using `SyncGuard` to query the current state of an object. * Add new member `name: Option<String>` to `NodeInternal` and `Node`. * Add new trait method `Object::set_name` to allow users to set the name of an object. This is something that has been discussed in relation to the new template functionality I'm adding in #203. In discussing it with @kvark, he stated that he'd like nodes to be named directly, rather than attempting to have to look up nodes based on their names in a template. Co-authored-by: David LeGare <[email protected]>
Reviewed 4 of 4 files at r3. src/template.rs, line 210 at r1 (raw file): Previously, randomPoison (David LeGare) wrote…
Sounds like you are on the right track :) let's follow up on Gitter with further concerns and findings Comments from Reviewable |
@kvark I've updated the PR to remove |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for all the hard work!
Let's get this merged. Do you think there are a few commits (where you go back and forth, for example) to squash?
Sure! I'll squash out all the unimportant commits. |
* TemplateNode -> NodeTemplate * instanced_geometry -> upload_geometry * instanced_mesh -> create_instanced_mesh
* Replace NodeTemplate with ObjectTemplate. * Make each object its own template type, pointing to an object template. * Update Factory::instantiate_template. * Add type alias for InverseBindMatrix.
🚀 🐑 it |
203: Template System and Reworked glTF Handling r=kvark a=randomPoison This PR adds a new system for creating templates for hierarchies of objects. Templates describe many objects and their relationships to each other, and allow the user to instantiate the entire hierarchy of objects at once. Templates can be instantiated an arbitrary number of times. All instances of a template will use the same GPU resources for each instance of a mesh, reducing duplication of GPU resources and allowing for efficient instanced rendering. * Adds a new module `template` with type declarations for `Template` and its various sub-objects. * Adds `Factory::instantiate_template` for creating concrete objects from a template. * Adds `Factory::instanced_geometry` to allow users to upload a `Geometry` to the GPU (this is needed to allow templates to reuse GPU resources). * Removes `Factory::instantiate_mesh` and replace it with `Factory::instanced_mesh`, which allows the user to create a mesh given an `InstancedGeometry` and a `Material`. The removal of `instantiate_mesh` was suggested by @kvark, I opted to also add `instanced_mesh` as a convenience function for cases where constructing a full-blown `Template` is overkill. * Reworks `Factory::load_gltf` to return a list of `Template` objects, returning one `Template` for each scene in the glTF file. * Adds `Factory::camera` as a helper method to create a `Camera` from a `Projection`. Adding this simplified some of the logic in instantiating templates, since the template stores camera projections as `Projection`. * Adds the option to set an up direction for the `Orbit` controller. I wound up not needing this for any of the examples, but I opted to leave it in the PR because it's useful functionality to have. Sorry this took so long. <sub>Hopefully this attempt sticks. <sub>I'm gonna go to bed now.</sub></sub> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/three-rs/three/203) <!-- Reviewable:end --> Co-authored-by: David LeGare <[email protected]>
Build succeeded |
205: Resolve internal object data with SyncGuard r=kvark a=randomPoison This PR increases the utility of `SyncGuard` by increasing the information that it can be used to retrieve. In addition to retrieving the `Node` data for any object, it is now possible to: * Downcast a `Base` to its concrete object type. * Retrieve internal state data for various object types (e.g. the list of children for `Group`, the projection for `Camera`, etc.). * Walk the hierarchy of objects under a `Group`. * Search the hierarchy of objects under a `Group` for specific objects based on their name or type. This functionality is especially important in conjunction with the `Template` functionality added in #203, as this now allows users to retrieve the objects in a template instance, which drastically increases the utility of templates to create re-usable object hierarchies. # Changes * Adds a new trait `DowncastObject`, which marks object types that can be downcast from `Base`. * This is done as a new trait (instead of adding the functionality to `Object`) so that it could be implemented for all type *but* `Base`. This makes attempting to downcast to `Base` a compile error, since doing so is a meaningless operation. * Implements `DowncastObject` for all existing `Object` types in three-rs. * Adds `Data` type member to `Object`, and adds new trait method `resolve_data` which allows an object to retrieve its internal data using a `SyncGuard`. * Updates the `three_object!` macro to specify `type Data = ()` and provide a basic implementation for `resolve_data`. * Adds a macro `derive_DowncastObject!`, which provides a shorthand for implementing `DowncastObject` for internal types. * Adds `ObjectType` enum, which represents all of the possible concrete objects types that a `Base` can be downcast to. * Adds the following new methods to `SyncGuard`: * `resolve_data` * `walk_hierarchy` * `find_child_by_name` * `find_children_by_name` * `find_child_of_type` * `find_children_of_type` * `find_child_of_type_by_name` * `find_children_of_type_by_name` * `downcast` * Removes `Camera::projection` and replace `SubNode::Empty` with `SubNode::Camera(Projection)`. Moving the projection data for a camera into the `Hub` ensures that there is a single, canonical projection for the `Camera`, even if there are multiple (or zero) concrete instances of the camera in existence (i.e. the camera was a added to a group/scene and then dropped). * Adds `Camera::set_projection` to allow users to update a camera's projection. * Adds functionality to `WalkedNode` and `TreeWalker` to keep track of the `NodePointer` for each node, allowing us to reconstruct the `Base` object for walked nodes. * Removes `Directional::shadow`, since it was already duplicating the internal shadow data tracked in the `Hub`. * Adds new structs `LightData`, for retrieving the internal data for `Point`, `Ambient`, and `Directional`; And `HemisphereLightData`, for retrieving the internal data for `Hemisphere`. * Marks `three_object!` with `#[macro_export]` and adds support for the default variant described in its documentation. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/three-rs/three/205) <!-- Reviewable:end --> Co-authored-by: David LeGare <[email protected]>
205: Resolve internal object data with SyncGuard r=kvark a=randomPoison This PR increases the utility of `SyncGuard` by increasing the information that it can be used to retrieve. In addition to retrieving the `Node` data for any object, it is now possible to: * Downcast a `Base` to its concrete object type. * Retrieve internal state data for various object types (e.g. the list of children for `Group`, the projection for `Camera`, etc.). * Walk the hierarchy of objects under a `Group`. * Search the hierarchy of objects under a `Group` for specific objects based on their name or type. This functionality is especially important in conjunction with the `Template` functionality added in #203, as this now allows users to retrieve the objects in a template instance, which drastically increases the utility of templates to create re-usable object hierarchies. # Changes * Adds a new trait `DowncastObject`, which marks object types that can be downcast from `Base`. * This is done as a new trait (instead of adding the functionality to `Object`) so that it could be implemented for all type *but* `Base`. This makes attempting to downcast to `Base` a compile error, since doing so is a meaningless operation. * Implements `DowncastObject` for all existing `Object` types in three-rs. * Adds `Data` type member to `Object`, and adds new trait method `resolve_data` which allows an object to retrieve its internal data using a `SyncGuard`. * Updates the `three_object!` macro to specify `type Data = ()` and provide a basic implementation for `resolve_data`. * Adds a macro `derive_DowncastObject!`, which provides a shorthand for implementing `DowncastObject` for internal types. * Adds `ObjectType` enum, which represents all of the possible concrete objects types that a `Base` can be downcast to. * Adds the following new methods to `SyncGuard`: * `resolve_data` * `walk_hierarchy` * `find_child_by_name` * `find_children_by_name` * `find_child_of_type` * `find_children_of_type` * `find_child_of_type_by_name` * `find_children_of_type_by_name` * `downcast` * Removes `Camera::projection` and replace `SubNode::Empty` with `SubNode::Camera(Projection)`. Moving the projection data for a camera into the `Hub` ensures that there is a single, canonical projection for the `Camera`, even if there are multiple (or zero) concrete instances of the camera in existence (i.e. the camera was a added to a group/scene and then dropped). * Adds `Camera::set_projection` to allow users to update a camera's projection. * Adds functionality to `WalkedNode` and `TreeWalker` to keep track of the `NodePointer` for each node, allowing us to reconstruct the `Base` object for walked nodes. * Removes `Directional::shadow`, since it was already duplicating the internal shadow data tracked in the `Hub`. * Adds new structs `LightData`, for retrieving the internal data for `Point`, `Ambient`, and `Directional`; And `HemisphereLightData`, for retrieving the internal data for `Hemisphere`. * Marks `three_object!` with `#[macro_export]` and adds support for the default variant described in its documentation. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/three-rs/three/205) <!-- Reviewable:end --> Co-authored-by: David LeGare <[email protected]>
205: Resolve internal object data with SyncGuard r=kvark a=randomPoison This PR increases the utility of `SyncGuard` by increasing the information that it can be used to retrieve. In addition to retrieving the `Node` data for any object, it is now possible to: * Downcast a `Base` to its concrete object type. * Retrieve internal state data for various object types (e.g. the list of children for `Group`, the projection for `Camera`, etc.). * Walk the hierarchy of objects under a `Group`. * Search the hierarchy of objects under a `Group` for specific objects based on their name or type. This functionality is especially important in conjunction with the `Template` functionality added in #203, as this now allows users to retrieve the objects in a template instance, which drastically increases the utility of templates to create re-usable object hierarchies. # Changes * Adds a new trait `DowncastObject`, which marks object types that can be downcast from `Base`. * This is done as a new trait (instead of adding the functionality to `Object`) so that it could be implemented for all type *but* `Base`. This makes attempting to downcast to `Base` a compile error, since doing so is a meaningless operation. * Implements `DowncastObject` for all existing `Object` types in three-rs. * Adds `Data` type member to `Object`, and adds new trait method `resolve_data` which allows an object to retrieve its internal data using a `SyncGuard`. * Updates the `three_object!` macro to specify `type Data = ()` and provide a basic implementation for `resolve_data`. * Adds a macro `derive_DowncastObject!`, which provides a shorthand for implementing `DowncastObject` for internal types. * Adds `ObjectType` enum, which represents all of the possible concrete objects types that a `Base` can be downcast to. * Adds the following new methods to `SyncGuard`: * `resolve_data` * `walk_hierarchy` * `find_child_by_name` * `find_children_by_name` * `find_child_of_type` * `find_children_of_type` * `find_child_of_type_by_name` * `find_children_of_type_by_name` * `downcast` * Removes `Camera::projection` and replace `SubNode::Empty` with `SubNode::Camera(Projection)`. Moving the projection data for a camera into the `Hub` ensures that there is a single, canonical projection for the `Camera`, even if there are multiple (or zero) concrete instances of the camera in existence (i.e. the camera was a added to a group/scene and then dropped). * Adds `Camera::set_projection` to allow users to update a camera's projection. * Adds functionality to `WalkedNode` and `TreeWalker` to keep track of the `NodePointer` for each node, allowing us to reconstruct the `Base` object for walked nodes. * Removes `Directional::shadow`, since it was already duplicating the internal shadow data tracked in the `Hub`. * Adds new structs `LightData`, for retrieving the internal data for `Point`, `Ambient`, and `Directional`; And `HemisphereLightData`, for retrieving the internal data for `Hemisphere`. * Marks `three_object!` with `#[macro_export]` and adds support for the default variant described in its documentation. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/three-rs/three/205) <!-- Reviewable:end --> Co-authored-by: David LeGare <[email protected]>
205: Resolve internal object data with SyncGuard r=kvark a=randomPoison This PR increases the utility of `SyncGuard` by increasing the information that it can be used to retrieve. In addition to retrieving the `Node` data for any object, it is now possible to: * Downcast a `Base` to its concrete object type. * Retrieve internal state data for various object types (e.g. the list of children for `Group`, the projection for `Camera`, etc.). * Walk the hierarchy of objects under a `Group`. * Search the hierarchy of objects under a `Group` for specific objects based on their name or type. This functionality is especially important in conjunction with the `Template` functionality added in #203, as this now allows users to retrieve the objects in a template instance, which drastically increases the utility of templates to create re-usable object hierarchies. # Changes * Adds a new trait `DowncastObject`, which marks object types that can be downcast from `Base`. * This is done as a new trait (instead of adding the functionality to `Object`) so that it could be implemented for all type *but* `Base`. This makes attempting to downcast to `Base` a compile error, since doing so is a meaningless operation. * Implements `DowncastObject` for all existing `Object` types in three-rs. * Adds `Data` type member to `Object`, and adds new trait method `resolve_data` which allows an object to retrieve its internal data using a `SyncGuard`. * Updates the `three_object!` macro to specify `type Data = ()` and provide a basic implementation for `resolve_data`. * Adds a macro `derive_DowncastObject!`, which provides a shorthand for implementing `DowncastObject` for internal types. * Adds `ObjectType` enum, which represents all of the possible concrete objects types that a `Base` can be downcast to. * Adds the following new methods to `SyncGuard`: * `resolve_data` * `walk_hierarchy` * `find_child_by_name` * `find_children_by_name` * `find_child_of_type` * `find_children_of_type` * `find_child_of_type_by_name` * `find_children_of_type_by_name` * `downcast` * Removes `Camera::projection` and replace `SubNode::Empty` with `SubNode::Camera(Projection)`. Moving the projection data for a camera into the `Hub` ensures that there is a single, canonical projection for the `Camera`, even if there are multiple (or zero) concrete instances of the camera in existence (i.e. the camera was a added to a group/scene and then dropped). * Adds `Camera::set_projection` to allow users to update a camera's projection. * Adds functionality to `WalkedNode` and `TreeWalker` to keep track of the `NodePointer` for each node, allowing us to reconstruct the `Base` object for walked nodes. * Removes `Directional::shadow`, since it was already duplicating the internal shadow data tracked in the `Hub`. * Adds new structs `LightData`, for retrieving the internal data for `Point`, `Ambient`, and `Directional`; And `HemisphereLightData`, for retrieving the internal data for `Hemisphere`. * Marks `three_object!` with `#[macro_export]` and adds support for the default variant described in its documentation. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/three-rs/three/205) <!-- Reviewable:end --> Co-authored-by: David LeGare <[email protected]>
This PR adds a new system for creating templates for hierarchies of objects. Templates describe many objects and their relationships to each other, and allow the user to instantiate the entire hierarchy of objects at once. Templates can be instantiated an arbitrary number of times. All instances of a template will use the same GPU resources for each instance of a mesh, reducing duplication of GPU resources and allowing for efficient instanced rendering.
template
with type declarations forTemplate
and its various sub-objects.Factory::instantiate_template
for creating concrete objects from a template.Factory::instanced_geometry
to allow users to upload aGeometry
to the GPU (this is needed to allow templates to reuse GPU resources).Factory::instantiate_mesh
and replace it withFactory::instanced_mesh
, which allows the user to create a mesh given anInstancedGeometry
and aMaterial
. The removal ofinstantiate_mesh
was suggested by @kvark, I opted to also addinstanced_mesh
as a convenience function for cases where constructing a full-blownTemplate
is overkill.Factory::load_gltf
to return a list ofTemplate
objects, returning oneTemplate
for each scene in the glTF file.Factory::camera
as a helper method to create aCamera
from aProjection
. Adding this simplified some of the logic in instantiating templates, since the template stores camera projections asProjection
.Orbit
controller. I wound up not needing this for any of the examples, but I opted to leave it in the PR because it's useful functionality to have.Sorry this took so long. Hopefully this attempt sticks. I'm gonna go to bed now.
This change is