#skein
1 messages · Page 3 of 1
some progress in the lightmap department
weirdly aesthetic image
anyone have issues with blender forgetting export settings
it seems I have to reselect all my options when I reopen the blend file.
I'm considering embedding settings into skein partially because of this sort of thing
I remember this not being an issue at one point
but maybe that was something blenvy was doing
I don't really have enough context to say why this happened to you this time, and I tend to flip between a lot of blendfiles myself for different tests and demoes so would have to test it more to figure it out
but enough people have wanted a "hotkey export" that this would pair well with that anyway
it would be unfortunate to depart from the main file export dialog settings, but having "relative to blendfile" settings would also help multi-computer users, etc
have you thought at all of the possibility of integrating bevy flair into a skein workflow
I haven't. What's the pitch for it?
I keep defining components like BlenderRigidBody which are just markers. Why? because mostly what I need in blender is the ability to mark what objects have what role. The actual data (ie. ColliderConstructor::ConvexDecomposition + CollisionMargin + Damping etc etc) is more of a code-side implementation detail.
but there is still alot of churn on the blender side, as I refactor code... etc.
meanwhile I have to recompile code alot.
normally when I find I have a interface between systems where the coupling is chafing, it means a layer of indirection is needed.
(re: churn, what kind of churn do you mean? api paths changing?)
yes, or adding / removing / splitting up / merging structs (since I'm not super disciplined about the marker method outlined above)
using bevy flair or something like it, I could mark the roles in the blender files with classes
blender now OWNS those class names (of course I can also still use components directly where I want to)
the css file is now the mapping from class names (roles) to components. blender files owns their namespace, bevy code owns its namespace, and the css file is the mapping to be maintained.
the css file also would work on names (as per css selectors) and components (allowing matching on a #my_name > Mesh etc). Bevy_flair already supports this
I really thought I documented this already, but for changing type paths, especially if you're already declaring "blender marker components" use the type_path attribute
#[derive(Component, Reflect, Debug)]
#[reflect(Component)]
#[type_path = "api"]
#[type_name = "Something"]
struct Character {
name: String,
}
this type comes into blender as api::Something no matter where it is in the source code
yes, I've used that
it seems like you could do this with regular custom properties and a GltfExtras observer, since all the classes are all strings
this is more for the case of wanting something like bundles declared outside of source code (because recompile is slow) and outside of blender because I want to minimize how much of the code surface my art assets depend on.
yes, I can also use skein to attach bevy_flair classes, I am pretty sure
to be clear, I was not suggesting that the skein tooling would need to change to support this
right, so you want to effectively define "marker components" outside of your bevy application, then have the application register them when a given asset includes them
yeah I haven't even gotten to whether its skein related or not, just working through the pitch and using examples to understand if that's what you mean
yes, in spirit. Though my idea to do it with bevy_flair would not actually register any dynamic components.
bevy_flair is just UI right? so this would basically be unrelated to that crate in implementation
bevy_flair supports custom properties and components, but it's currently undocumented
I think you'd end up with one giant observer to deal with all the strings 🤔
probably, but idk if that's an issue. observers run sequentially anyway iirc. So one big observer on CssClass is no different from many observers on various BlenderXXX components
people just don't like it when observers do that sort of thing is all lol
its a human effect
what's the alternative ?
well components are the first thing that come to mind
on_add hook?
yeah, or postprocessing the scene, etc
you still need to "attach" the strings to sets of components anyway right?
so you don't get rid of your recompile with this approach
the way I am thinking of it, a CSS file (or something similar) would declare what selectors (name, class, component) would have what components attached.
right, so thinking of it this way:
strings and marker components have the same effect on recompilation. If you define a new string in Blender, you need to associate that with some set of components in Bevy, which requires code. Similarly if you define a new Marker component that is code. Both trigger a recompile.
it could be processed as scene postprocessing, or could be kept in sync live (like bevy_flair is)
If you define a new string in Blender, you need to associate that with some set of components in Bevy, which requires code.
no, it would require an new rule in the css file
which is an asset
the classes do not appear in code
I think there's some crossed wires there. We're saying the same thing.
for pre-existing components, there is no recompile needed
for new components, recompile is needed
the difference in usage is for marker components you'd add multiple marker components in blender.
for strings, you'd adding multiple components in the css file
so with that said, this doesn't really change the calculus of if a recompile is needed, which is why I said it doesn't really change that earlier.
ah, I see what you mean.
I am saying to use CSS classes INSTEAD of marker components
the css file would directly specify the low/mid level components
can you write an example in pseudo-css so we're on the same page?
I am looking at the bevy_flair docs, so I do see the implementation there already
but bevy_flair's ui support contains pre-defined components afaict.
so this refactoring that you're talking about would also affect the css rules and such, from what I can tell
.dynamic {
RigidBody::Dynamic,
LinearDamping(0.8),
AngularDamping(0.1),
MaxAngularVelocity(0.9),
ColliderConstructor::ConvexDecomposition,
}
yes
the support for custom properties and components is undocumented afaict
and ideally I'd want something that just uses reflection and lets you attach any component
right, but this is what skein already does
right, within blender, but I want a layer in between for the above-mentioned reasons
another usecase, is that you could swap out and compose the css files. Useful for things like camera properties.
two things:
first: this css-based solution feels like a solution that is covering up the core issue, which to me seems like managing components in blender feels too cumbersome.
second: the feature that I can identify here is basically bundle presets defined outside of bevy's rust code
so to that second point, is this bsn templates (or a similar bsn concept)
bundle presets
I think what I am talking about is more expressive. in the same sense that css selectors are more expressive than justclassname => properties
the .dynamic you showed above is just a bundle preset. is there another example?
sure a quick one could be
#my_lamp Mesh3d {
ColliderConstructor::TriMeshFromMesh
}
so you're looking for hierarchy traversal here as well
yes
where #my_lamp is the parent entity of all Mesh3ds in its descendents
although even without it. things like this are useful
Mesh3d.collider {
ColliderConstructor::TriMeshFromMesh
}
.collider {
ColliderConstructor::Cuboid
}
this would require implementing specificity and a context in which to apply it
by itself, this would say that all mesh3ds with a collider tag are trimeshfrommesh, and also all colliders are cuboid
specificity is well defined/documented, I believe bevy_flair already implements it
I don't think it being well defined is the issue (also I'm not sure it is. css depends on the order of stylesheet inclusion, for example)
the css syntax here would apply to everything ever spawned then right?
which requires traversing every entity and doing css lookup checks for every spawn.
I was imagining the stylesheet being attached to a root, like in bevy flair
most likely a SceneRoot
what happens if you have a sceneroot under a sceneroot?
I was thinking about that. Obviously the two choices are to stop traversal or to continue. I think stopping traversal is more often what you want
adding selectors for the alternative behavior is an option, I'd file that under a bridge to cross later.
I think this is getting dangerously close to needing to touch every entity on every spawn and do css lookups
and the benefits listed currently are: not needing to recompile if you add a new bundle preset.
- it's every spawn under a root with a stylesheet.
- I don't think that's necessarily unacceptable performance wise for the vast majority of cases. The browser does css lookups on every dom element, which is probably comperable to entities in a game scene. (Of course, the browser is very optimized for that)
the browser does lookups, but no browser is spawning N thousand dom elements in a physics simulation
The basic form of this feels like regular Bundle presets. while the advanced form of this also feels extremely close to bsn's work (templates, etc)
I think the css angle is probably not relevant. its just a syntax for defining the bundle presets in the basic case.
I am skeptical of that for the same reason that bevy_flair is not expected to be obsoleted by bsn
oh? where's that discussion?
only the readme for bevy_flair, implies to me the author views it as orthogonal
yeah I see there's one sentence about the crate "working as before" when bsn lands
that doesn't mean it won't be obsolete afaict
(not saying it will be either)
but bsn is getting an asset format, and that format has to be able to do basically everything described here and more
fair enough, though I've not seen people suggest it will be obsolete and it's brough up frequently
would be nice to get a better sense for that
yeah I don't use the bevy_flair crate myself, so I would have to do more exploration to have a definitive answer for that personally
as for this, I think that's a valid reason to apply the stylesheet at sceneload (postprocess) instead of scenespawn
its worth noting there's more complexity than originally suggested in the sceneroot hierarchy approach, etc too. You don't need to use SceneRoot to spawn scenes, its just a common convenience. So there's effectively no way to always stop traversal
yeah I want to get around to building generic extensions support in the gltf loader, which could also solve that
hoping that I can put a pr up before 0.18 but I've been incredibly busy lately
I would say that if you spawn a scene without a SceneRoot you have modified the scene instead of spawning another within it.
so traversing in that case is "correct"
I would not. SceneRoot is weird and adds additional entities that aren't necessary. The scene already has a scene root entity. the SceneRoot entity is just "extra"
I use SceneRoot all over my code for encapsulation purposes (or SceneInstance, need to sort that one out)
(and SceneRoot means that you can not put multiple scenes as children, because it is a single component)
I think there should be a standard component which means "this entity and it's children belong to an encapsulation unit"
SceneEntities/SceneEntityOf
idk if that would be accepted with the changes bsn is pushing through tbh
~~on main?~~nvm this is a hypothetical thing?
no, just a formalization of the idea
other problems with that are things like: entities can be removed from a scene/ inserted into a scene, etc. and then should the css apply to that entity?
I'm not saying all these things can't be arbitrarily chosen, but its not very simple either
for css as sceneload postprocessing -- easy enough to say if you change the scene you have to manually rerun the css processor
for css on scenespawn -- more tricky. bevy_flair is live sync
re: including this in skein, that would be a point against it unless it could be simplified. One of my core goals for skein is having a dependable piece of infrastructure that is easy to migrate to future bevy versions.
the gltf extension processing opens up some more approaches, and would also enable this css approach as a separate crate too
I think I definitely wouldn't take a dependency on bevy_flair in skein
would it be specifically gltf postprocessing or generic scene load postprocessing.
enabling arbitrary gltf extensions in userland is my goal
I think arbitrary scene preprocessing is a step I might take with skein first, but the whole sub-assets thing makes that a bit awkward too
there's some work to be done to guarantee that scene modifications wouldn't be overridden, or if an asset "reloaded" that it would be correctly re-processed, etc
and for skein, you can also use the sub-assets directly, which requires that gltf extension (what is currently skein in gltf extras) data sticking around somehow.
I have often felt that bevy was missing some sort of asset postprocessing. ie. the ability to load something with a default loader and then get a callback to modify it before the handle can show up as Ready anywhere else. (the LoadTransformAndSave machinery is so clunky I never use it, tbh I don't understand it's rationale)
the gltf asset currently doesn't have "a place" for arbitrary extension data. not in the same way GltfExtras has "a place"
yeah, there are multiple people working on this sort of thing right now. andriy in the assets-dev channel, and malek/the async group with the new async_access function
re: this. gltf extension data can be global and also anywhere extras can be, so ideally we'd be able to store the data in all of those places, just like extras is today
technically I think extensions can also add new arrays, but I'm kinda ignoring that for the moment since I don't see a need for it. Maybe a use case pops up though
arrays as in meshes[0], materials[3], nodes[5], etc
so a lightmaps[2], etc
does it make more sense to have generic gltf extension support or just implement the extensions and give them their own components?
my understanding was that the extensions were supplements to the spec made by the same group
is the scene root entity (the one which is a child of the SceneRoot) required because of how bevy represents scenes or is it because gltf scenes always have a root?
my understanding of bevy scenes is they were just a world, so did not require a root entity. I assume this is a gltf thing
re the earlier conversation, I filed an issue. feel free to share thoughts on it if you want to: https://github.com/rust-adventure/skein/issues/79
I will meditate on this conversation a day and add my thoughts tomarrow.
generic support. Without generic support, you can't write extensions in userland. Some extensions are currently used in the loader (for lights, etc), but they are hardcoded in
and by extensions I mean literally gltf extensions, like this list: https://github.com/KhronosGroup/glTF/tree/7bbd90978cad06389eee3a36882c5ef2f2039faf/extensions
a bunch of these are experimental (physics rigid bodies, etc) and can't be implemented without upstreaming the code or forking the loader right now
extensions can be made by arbitrary users. We could both define extensions right now, and they exist.
that's kind of the point. There's a list of semi-official extensions because the purpose is to share the extension structure across implementations, but they're almost entirely arbitrary otherwise
the SceneRoot component entity is "the entity under which we will spawn the scene". It is a helper component and works with any scene, not just gltf scenes.
the "scene root entity" is the Scene node in blender. Every Scene already has a root entity that contains all of the other entities.
this is, afaik, also true in bsn. scenes have a root node similar to the Blender Scene node.
this node is not the SceneRoot entity, which is just a container for the scene to be spawned under
Anyway, a quick check of my code. It looks like I check for SceneRoot in three places.
Two are on_add observers to convert a BlenderThing(pointer: String) into a relation by resolving String to Name within the same scene.
The third is to stop traversal when looking for a parent RigidBody
yeah, inside of a single application if you commit to using SceneRoot you can rely on that, but like skein probably couldn't
maybe SceneInstance would work, but would need some testing
Also, I am very interested in supporting bsn-isms in skein fwiw
looking forward to seeing what kind of asset format comes out of the current work, which we could potentially produce from blender
both in scene cases and smaller, template cases
In a similar vein to the above, I am interested in a skein type workflow that saves component data to a file (probably bsn) instead of inside the blend file, because it would be better for migration purposes.
Although alternatively I've been looking into writing a cli tool to sync a blend file's skein data to/from a json file
what do you mean by "sync a blend file's skein data"? the registry information?
I mean to dump the skein data attached to datablocks, ie, the components
dumping seems feasible, but the blend rust crate does not support writing
I wouldn't even try to attempt parsing the blendfile
its not a stable format, and is declared as such
other engines that have, for example: "blendfile import" , actually just run the gltf export operator
and require blender to be installed
it's not stable but it's more or less self describing
We already have the scaffolding for migration tooling CLI commands: https://github.com/rust-adventure/skein/blob/c922d34717f10f4cdac2989eef62a6cadeab1930/extension/cli_dump_component_data.py
can that be run headless?
yes, that is the intended usecase
interesting.
for example:
blender --background -b replace_material.blend -c dump_component_data -o test.json -p "replace_material::UseDebugMaterial"
there's no guarantee the current commands work as expected, as I've been the only one interested in them so far. but all the scaffolding to do this kind of stuff is in place
I think fully serializing the components to disk and back into blender could be a bit sketchy depending on the serialization code. We'd need tests.
but I'm happy for anything to be investigated in this direction
that runs surprisingly quickly for having to spin up blender
yep
I think the dump command specifically has to be updated with a few of the types we've added support for
but that's not a difficult thing to do
dump was just a test to get the scaffolding in place. I really do want things like "move component", etc to be possible from the cli
nobody spoke up when 0.17 came around so I kinda figured everyone was fine doing it manually for the moment
As we add lightmap support and such I think it would be cool to be able to trigger those workflows headlessly too
FYI @regal tapir
I wrote a command today that can replace the type_path of a component from the cli (and I updated the dump_components command to be more comprehensive)
This PR implements a new CLI command that can change the type_path of a component in a blendfile.
The command requires the old and new path, which must match the intended old/new component paths re...
Random question that's been on my mind. Is it possible to have a placeholder for the Entity ID of an object in Blender that can be used to reference that Entity in other Blender components?
As a contrived example, let's say you have a button and a door. Can you insert a component into the button that can represent the eventual Entity ID of the door?
you're asking for Relationships here indirectly right?
Probably
long answer short: maybe, I've looked into it and I intend to keep looking into it.
the longer answer is basically I've looked into it and there's a couple of things that need to happen. I don't have an immediate solution but it's constantly on my mind.
Using Entity IDs in Blender is somewhat a possibility, but we'd have to do a number of things which make it less than simple. For example: restrict where the entity ids can be placed, and keep track of all the entity ids in use. Then on the Bevy side there's a disconnect unless we build support either into the loader directly or enable arbitrary extension support. This is because the gltf entities don't actually exist until the gltf loader spawns them, which is different to how other scenes behave (which have all entities available pre-spawn).
We can potentially use different ids in Blender, then propagate those to gltf which could use indices, and then apply them using arbitrary gltf extension processing when loading the gltf
if you have a smaller use case, and want to store UUIDs in a component, then hook into that to find the entities when spawning that's totally possible today.
Ok. Cool. Just wanted to know if it was a current possibility.
One other question. Can I specify an observer system in a component?
you should be able to specify event data. What do you mean by observer system?
writing the actual observer in blender would require the equivalent of modding-level scripting support I think? maybe not
Just thinking about an idea. Like, being about to specify what observer I want attached to an Entity in Blender. The observer would be prewritten of course
Obviously the actual attaching would probably be coffee side
if the observer is already pre-written, you can associate it however you want, including an enum of observer system options that you process in a lifecycle on_add observer I think 🤔
Alright. I've just been thinking about ways I can abstract stuff upwards and into Blender I guess.
I mostly stick to global observers for that kind of use case, which is why I'm not sure.
yeah, totally reasonable. and I expect more people will want more "scripty-level" things over time
Just trying to think of methods that don't create a million different marker components that exist only to be translated into something more meaningful on importation.
if we can gather concrete use cases in github issues that would help a lot
I'll keep it in mind if I have anything general enough.
I think specific things are useful too, even if you don't have an idea for how to generalize them
like "I want to be able to specify this lever relates to that door more easily"
then at least we can document current approaches, and maybe work towards better abstractions
The FlailBailer, it flails the bail
Does blender have a "type" for object relations?
I think so. I recall interfaces with an eyedrop picker
It has parenting specifically, and an interface for selecting fields on another object
If we could somehow gain access to that... Perhaps by having the skein library define a BlenderPointer, which would get turned into a object select in the skein addon via some special handling
Open question how we would export that
But name(+type?) could work, since the are unique in blender
Names are only unique in blender per type at best, and only under certain conditions (like no multi blend file workflows)
It doesn't actually enforce unique names
The user could do whatever they want with the BlenderPointer types, but at least the blender ui would be a bit less fragile.
Could be type+name+file
There's some other hurdles I ran into too, like the fact that you can make a relationship to a mesh or a material but those are the same entity in bevy, but only if it's not a multi material mesh
Fwiw the unique id conversation has a lot of history: https://github.com/KhronosGroup/glTF/issues/2337
So the chain needs to be something like:
- IDs in blender
- IDs in glTF
- Entities in bevy
glTF seems solvable by using indices
So that leaves blender and a way to transfer that data to the indices when exporting
Then the lesser problem of translating the index positions to actual relationship components on gltf import in bevy (which is very solvable)
For Relationships as well, we don't get the metadata in the reflection schema right now. Which means we don't know which component is the "source of truth", etc. (we only get the regular component data, so we know it contains an Entity or a Vec<Entity>)
Right now everything is serialized as the "correct data", by which I mean a JSON object with the { type: data } structure in the gltf file... but the entities that these relationships would reference don't exist until the gltf loader creates them.
When deserializing, the Entities in the relationship components need to exist or the deserialization will fail in bevy. This means we have to write a custom version of MapEntities that can deal with this delayed instantiation, and we have to process the component data to change the entities.
That's all to say if anyone wants to experiment and report back that's totally helpful.
I generally keep this post up to date on the topic: https://www.christopherbiscardi.com/bevy-components-and-gltf
how tricky would it be to add custom ui / serialization for a specific type.
Can you give an example? Right now the way to get custom UI is to define a component in the way you want the UI to show up.
^
the interface you recall with an eyedrop picker is either a PointerProperty or a prop_search
Making Entity a PointerProperty(type=bpy.types.Object) would potentially work for a subset of use cases
I was thinking of just defining a type BlenderPointer in rust. And dealing with resolving in rust.
all types must be Properties
here's the ui layout functions: https://docs.blender.org/api/current/bpy.types.UILayout.html
and here's the property stuff: https://docs.blender.org/api/current/bpy.props.html#module-bpy.props
here's a demo
the "BlenderPointer" needs to be attached to something, in this case I threw it on the Scene, but that's not viable for Entity use cases, it would need to be defined on the PropertyGroups we define for the component data
(something I didn't mention about this PointerProperty earlier is that I have no idea how to make it general enough to be able to target "more stuff", for example: meshes, materials, etc. Using the underlying bpy.types.ID class doesn't work)
I'm curious, how hard is it to port Blender addons to new versions?
Depends on the addon and whether the apis you use changed, etc. Skein is specifically engineered to be easy to port, so it was a one line change due to some changes in how blender stores custom properties vs id data.
I know how to setup the blender export to not have that root collection node, but is there a straight forward way to flatten this hierarchy even more?
like, have the "body" and "chain_link" mesh entities up one level and get rid of the GltfSceneExtras node
its somewhat unclear what doing here or why you want to get rid of that node.
Scenes have a root node though, that's how they work. That's encoded here: https://github.com/bevyengine/bevy/blob/7ad5fb703c71b49f9cc91a7ea2684050c256394e/crates/bevy_gltf/src/loader/mod.rs#L952-L954
if you really wanted to get rid of it you could have an observer or similar reparent the children after spawning in SceneInstanceReady.
yeah, I'm trying to flatten the hierarchy of these entities and remove superfluous nodes to reduce the cost of transform propagation. I think I might be able to get away with that reparenting strategy 🤔
if transform propagation is showing up in your profiling, its worth making an issue with your profiles on the bevy repo
if its not showing up in your profiling, its not worth worrying about
hmm, it is showing up quite a bit, but I think I did recently add a 5 or 6 level hierarchy to these entities, so I'm going to see how it looks once I clean it up
(I know prepare windows is because of the gpu)
doesn't that say its taking two frames?
or like 00:00:015 amount of time
the flags show the start and end of an update system that took just about 16ms. I think transform propagation happens at least twice
sorry, I'm not trying to go too offtopic into this 😅
no worries. I'm pretty sure transform propagation happens once per frame, so seeing it twice in a frame would be weird
Source of the Rust file src/plugins.rs.
PostUpdate has the propagate system
I'm using avian and iirc, Jondolf had to have it run.. at least twice? I think he had it running 4 times before
#1124043933886976171 message
what does the statistics panel look like for the transforms propagation system?
what do you mean?
oh are you using chrome profiling?
tracy comes with a statistics panel and such that gives more info
ex:
I was wondering why the timestamps weren't labelled...
yeah, I believe tracy doesn't work on my version of ubuntu (22.04) and I am putting off updating until I have more free time
the chrome profiler is pretty limiting
idk if you saw it, but there's builds built now, so you don't have to wonder about building it or whatnot (you can find them from the bevy repo's profiling docs on tracy whenever you find time)
I maintain that if you think this is an issue for your application you should file an issue on the bevy project with your chrome profiling logs/screenshots
needing to slice-and-dice the hierarchy to achieve performance is weird and would be considered a bug
yeah, I actually asked about this the same day they were added #1428488077470601227 message
oh perfect
yeah, but the libraries I need to run the tracy-linux-x11 one require upgrading. I am hoping to do that soon.
yeah, agreed
it's about 1.5gigs. I've already deleted the one from the screenshot but I could generate a new one
yeah no worries. 1.5g is a lot to ask to send
apologies for nerdsniping you a bit 😅
no worries. This is basically what I'm looking at right now:
you're so zoomed in that you're showing 1-2 "ticks". 698,000,000 - 700,000,000. And in the perfetto demos, that's one millisecond.
I'm somewhat unconvinced that transform propagation is taking 16ms for you
especially with the caching that happens for static trees of transforms
OH I was saying that's a whole update frame. That whole picture is 16ms
ok yeah, so you're optimizing for one millisecond right now
🤔 ... I'm going to run another profile
the very topmost timestamps are not the measurements for the transform system area, they're the measurements for the entire profile
the 00:00::11 and 698,000,000 numbers are your zoomed in view measurements
so that's like a 16-17 second profile, and you're zoomed in to a few milliseconds of it
I think it does generally take around 1ms, but sometimes it gets higher
Have you by any chance found an ergonomic workflow for adding components to SceneRoot both programmatically from the Bevy side, and from Blender? My understanding is that the top-most entity "level" you can add components to with Skein is the immediate child of SceneRoot, this also has the disadvantage of requiring an entire Blender scene for that asset, which makes it more cumbersome to batch export ("Export All Collections" only works for the current scene).
I have a bunch of vehicles that I thought I'd annotate with stastic geometrical attributes (such as RearHitch { distance: f32 }) in Blender, while populating the SceneRoot entity with dynamic components, driving controllers. Either I move the constants to the Bevy side, move everything down one layer (driving components, but keep the marker on the root for despawn), or I can do some SceneInstanceReadey pre-processing. I'm thinking about settling for option 1 at he moment
On the blender side we can add new export configurations for pretty much any workflow that Blender doesn't support that people want to use. I think right now on my list is:
- an operator for a scene exporter for a configurable set of scenes (that can expand to be configurable per-scene)
- an "export all collections in blendfile" operator.
The SceneRoot is poorly named, as the comment you're replying to indicates. Its more like SceneInstanceParent, since the scene already has a root entity. In the way people typically use it its kind of unfortunate because it means "only one scene can be spawned on this entity like this" because of Component restrictions.
Realistically this is something that is going to change with BSN, as far as I can tell, where you'll be able to "patch" scenes as deeply as is needed when spawning.
You can however just avoid SceneRoot entirely. By doing this you retain full control over your spawning logic, and you can encapsulate any behavior you want into a custom command. Here's a full program: https://github.com/rust-adventure/skein/issues/50#issuecomment-3564619956
At the end of the day, assuming you've got a loaded scene, then your usage looks like this:
commands.queue(SpawnMyCar {
scene: scene_handle.clone(),
components: (SomethingElse(1),),
});
A "Trigger all Collection Exporters" button was just pushed to main and will be in the next release. It will trigger all collection exporters in all scenes
That's pretty brilliant actually, cheers for that! I'm not personally sold on having one Blender scene per asset, I prefer having everything laid out in front of you, exporting everything all at once when you're done.
Now I'm wondering if with this manual spawning approach it would be feasible to pluck a particular "collection" from a multi-asset GLTF file.
A few months back I tried to pack into the same GLTF to reduce duplication between materials, I have one main palette material. Gave up quite quickly when this didn't seem to be the recommended way to do it, now I patch loaded assets when the AssetEvent::Added with a global material handle, and swap the material out once that loads. An advantage of doing this is that they can share the same shader uniforms (single material) for quick multi-scene effects, at least in my case with the palette material
"a scene" in this sense is just a collection of entities, so the collection exporter produces multiple gltfs with a scene that contain whatever meshes/etc are relevant for that one collection.
technically yes, but there's no "GltfNode as Scene" infrastructure built up, and collections don't exist by default when exporting from blender. So it would be a niche workflow in that you'd require both the "keep collections" gltf export option and the creation of Scenes (or faux-scenes) from those collections. Basically its technically speaking possible, but is an alternative workflow that hasn't been built out to be made easy.
Blender -> glTF -> Bevy basically makes it easy to spawn Scenes, whether those are Scenes in a Blender file or a separate glTF made from a collection exporter.
but Scenes are just "collections of entities", and a GltfNode could be the root of a transform hierarchy of multiple entities, etc. Whether that was pre-constructed as a Scene on import or done ad-hoc with dedicated recursive spawning logic
I am very baffled right now. Doing something like this, and then doing the exact same at a later stage will produce different results. Where the first time it sets the scene transform nicely, and the second time it also sets the Object transform to the inverse translation.
commands.spawn((
SceneRoot(asset_server.load(
GltfAssetLabel::Scene(0).from_asset("prefabs/Tree.Beech/Tree.Beech0.glb#Tree.Beech0"),
)),
Transform {
translation: Vec3::new(10.0, 0.0, 10.0),
..Default::default()
},
));
Might not be related to Skein. Just feels like a very odd thing.
skein doesn't modify transforms. It must be something you have happening in a different system.
I don't have anything 😭
I will just go and cry in the corner for a bit and come back
why are you using the # and the Scene(0) syntax at the same time?
Good question
the docs claim that the previous label will get replaced, so I think you just end up with prefabs/Tree.Beech/Tree.Beech0.glb#Scene0 there
Yeah looks like it
There's nothing else in that code snippet that I can tease out to check. What else is the application doing?
No thank you, I will keep digging and come back when I find something.
The issue is because I am attaching an avian rigidbody and nested collider, not very obvious.
its not entirely clear to me what the issue was, but glad you figured it out!
Instead of inserting Transform to set the position, GlobalTransform should be used instead because RigidBody inserts Transform, Position and Rotation components based on GlobalTransform.
that doesn't sound right
Transform requires GlobalTransform, and a required component won't override a specifically inserted value.
But I guess the GlobalTransform is updated at a later tick?
yes. If you need the propagation to happen you use TransformHelper to force it to happen earlier
and to be specific, its not "a later tick" its in: https://docs.rs/bevy/0.17.3/bevy/prelude/enum.TransformSystems.html#variant.Propagate
which is in PostUpdate in a typical frame: https://docs.rs/bevy_transform/0.17.3/src/bevy_transform/plugins.rs.html#35-43
None of the code you showed earlier indicates an issue though. Placing a Transform on a SceneRoot where the Scene being spawned includes a rigid body and colliders should "just work"
Hi, I don't know what I am doing wrong, but suddenly blender does not export components for new objects I create
Here is an example, Wall is spawned but without the components in the skein panel
Could be a problem with blender 5.0?
I checked the gltf file and the components aren't there, so I think it's a blender problem, or maybe I am doing something wrong
Did you upgrade to blender 5 without updating the addon?
That was the problem, thank you. Out of everything I checked that was something I didn't 🤦♂️
Random question: how are components stored on objects? I'm making a blender plugin to procedurally create object hierarchies but it would be nice if could in future support skein type things
They're defined and stored as custom properties. Every type supported gets a collectionproperty of components defined on the type: https://github.com/rust-adventure/skein/blob/9685eb346a0c89645b32eb75e1e23437ba08c89e/extension/op_registry_loading.py#L260
Heya, great plugin. I don't know if I'm doing anything wrong, but components added to Blender's cameras and lights aren't getting propagated to Bevy
are you exporting the cameras and lights?
Something's wrong with Skein on my end. I'm having a hard time isolating what's going wrong, but for some reason, any new exports of my blender scene aren't recognizing some of the components. Checking the gltf, it does say they exist, but when importing the scene they aren't added to the Entity. Conversly, using an old version of the level still works. Anything I should look at?
did you upgrade to blender 5 without upgrading skein?
if you think its rust-side, you can enable skeins trace-level logs: https://github.com/rust-adventure/skein/blob/9685eb346a0c89645b32eb75e1e23437ba08c89e/src/lib.rs#L266
which will dump some information about when extras and components are being attempted
Made sure both were up to date
It's worth noting that the logic for inserting component data has not changed
I'll try the trace logs, as the gltf file send to be ok
The other thing I would check, which is going to sound silly, is to make sure you're loading the gltf file you think you are and such
Is there a way to "purge" and refresh the component database? Just want to eliminate that as an issue.
You mean in blender?
Yeah
Go to the scripting panel and find the text block that says it's the skein registry and delete it
How do I enable it? Is it a feature?
Skein integrates with Rust's tracing crate, you just need to set up a tracing subscriber ("consumer") in your application. You can then selectively choose what to display from different libraries, a filter like bevy_skein=trace. Bevy's LogPlugin sets this up I think, I'm overriding the configuration like this:
DefaultPlugins.set(
LogPlugin {
level: Level::INFO,
filter: "wgpu=error,naga=warn,airpoly=debug".into(),
..default()
}
)
Skein stores the fully qualified type name as JSON, if you move around your component definitions on the Rust side (without fixing them with type_path), you'll definitely get mismatches and logged errors
Ok, now this is even more confusing.
Looking at the trace logs, it should be adding the component, but looking at egui-inspector it isn't there.
Comparing that with the working file it is there for some reason.
Aaaaand, nevermind
I did something and it's working again
yeah this is correct. and additionally you don't have to configure the log plugin as this would work (if you aren't already hard-coding overrides in your logplugin source code):
RUST_LOG=skein=trace,info cargo run
this is also correct, but its somewhat important to note that the format stored in the blendfile and the format stored in the gltf when exported are slightly different. There are some weirdnesses around what blender allows as keys in a blendfile for example, that mean we often have to hash the type_path keys. And enums aren't directly supported, so we have to store additional indexing data about which enum variant is selected.
if the logs say the components are being added, then there might be something happening outside of skeins control. If you're making it to the insert_reflect call as expected, then basically tldr everything from the blender plugin to the final skein insert action has succeeded, and if the insert_reflect fails it panics so you would see a crash.
All I can say is that removing and readding components fixed things, even though from all other ways of looking at it, it's output is the same.
removing and re-adding in blender?
that literally can't make a difference if the data existed in the gltf
I don't understand either.
Maybe some slight difference with the component metadata or something.
right, what I'm saying is that there is no additional metadata
if the data existed correctly in the gltf file, the removing and re-adding components would produce the same gltf file
and there is no other way that the data gets to bevy. Its only what you see in the gltf file.
so if the gltf file has the data, removing/re-adding the same components just produces the same gltf file
given what you've said, removing/re-adding components in blender is not what fixed this for you
my guess, from the symptoms described, is that there was some confusion about which gltf file was being loaded/spawned. I've seen people export gltf files to the wrong directory and think they were updating a different specific file before, or use an old path, etc
I've been working on arbitrary gltf extension processing, hoping to get it into 0.18 so skein can port to use it. I already have the code on the skein side for exporting data using extensions instead of gltf extras.
I've been working through a couple features in my head for awhile now, and I think extensions is the only reasonable way to support things like Relationship components and also supports things like Lightmap data application.
I don't plan to remove extras support in the near term, so extensions should be additive for the time being, but its likely that newer functionality like Lightmaps will only be supported by the extensions-style export.
I finally got to update the scene and it was not a coincidence or a fluke
All TrimeshFromMesh constructors got renamed to VoxelizedTrimesh in skein export
I guess the index in some enum changed or something.
Fixable to just sed -s '/VoxelizedTrimesh/TrimeshFromMesh' on gltf, but I have no idea how to mass rename it in blender.
If I had a huge scene I would be so fucked
you wouldn't really be fucked. We have the infrastructure in place to do renames in the blender file.
is this the same project as Yappy? using the same scene?
do you have a reproduction?
The enums values are identified by string key, so its unlikely to be "the index in some enum changed"
I just tried inserting an avian collider constructor with a TrimeshFromMesh and it works via export just fine
Not really sure if it's the same, but something like this happend with me the other day. Basically when there is already an enum component assigned by skein in blender and a value is prepended to the enum and then the new remote type registry is fetched, than blender will change what actual value is assigned.
Think the issue is that blender combo-boxes / items work by ID.
Not really sure if I make myself very clear or if I am even talking about the same issue as might be happening above.
That would be a bit surprising, since the python interaction is all by string: https://github.com/rust-adventure/skein/blob/9685eb346a0c89645b32eb75e1e23437ba08c89e/extension/property_groups.py#L93-L94
(also: the identifier docs: https://docs.blender.org/api/current/bpy.types.EnumPropertyItem.html#bpy.types.EnumPropertyItem.identifier )
It most definitely did happen with me, but I can try to reproduce it with the latest version of skein and get back to you.
That at least gives me something to test though
theoretically that could explain it. I think the Voxels and Voxelized Trimesh account for 2 positions in the avian update
that would mean that blender is storing them as integers even though all the user apis are string ids
I am not sure if there were any changes and I was only discussing this with my co-worker / he complained about that blender in the end uses the index and not the name.
yeah that's a useful note, thank you
Would you like me to try to reproduce the issue?
I'll ask if I can't do it myself. I think I have enough information from what you've said
nope, my project
I guess the reproduction would be to save the .blend file with 0.1.12 with blender lower than 5.0(not really sure if the blender version is even relevant), open it in blender 5.0 and skein 0.1.13 and viola - TrimeshMromMesh becomes VoxelisedTrimesh
lemme try reproduce it
I would be incredibly surprised if updating skein caused this issue, considering the format has not changed
it may be something blender changed, I did not keep close track of the changes in 5.0, there are a lot
and there was nothing else? like an avian upgrade for example?
hmm, may be, I upgraded to the latest everything to be honest
that is extremely critical information fwiw
ok, so when I fetch the registry, it fetches every single component available, including transitive dependencies, right?
transient? do you mean transitive?
so that means that changes in avian3d directly broke the sequence somewhere, correct
when you fetch the registry all types that have been registered as components (and their type dependencies, which is things like Vec3), including those from bevy and from third party crates, are fetched
so whatever you have installed at the time you fetch defines how the component interface is built in blender.
so if you upgraded avian and it caused a change in the data that's a much more reasonably where the issue stems from
that would align with what Erebus was saying earlier, and likely indicates a bug in skein. The bug being that Blender, despite using string ids for enums in its python API, actually stores the discriminant in the blend file and not the string ids.
so it is an indexing issue, assuming that pans out when I build the test case. The index of the voxel collider is exactly 2 indices away from the trimesh, and two new voxel colliders were added.
which means I have to figure out how to store the data so that it is not index based, and hopefully figure out a migration strategy that doesn't require user action
but that means this is an issue for all enums too, not just avian's
yes, exciting!
haha that's one word for it 😆
I appreciate you bringing it up again
it wasn't clear to me before that an avian upgrade had occurred
I am yet to read skein python code, but I'll try to throw a helping hand if I come up with something decent
yeah if you think of something feel free to let me know. I think I'm going to avoid enums entirely in the blender storage, and try to opt for a collectionproperty and string key instead. I should be able to attach this to the same property group the enum lives on, and then it'll be a matter of if I can write an automatic migration that runs when opening the blend file or not.
The ui code will have to be handled differently too, but I think its all going to work out
while we are on it, what is the blender way of mass renaming stuff in attributes you mentioned?
the infrastructure I mentioned is the infrastructure we use for the change_component_path and dump_component_data CLI commands: https://bevyskein.dev/docs/migration-tools
which is basically this segment of python: https://github.com/rust-adventure/skein/blob/9685eb346a0c89645b32eb75e1e23437ba08c89e/extension/cli_change_component_path.py#L94
and we have the ability to go from json value to component as well, which is already required for applying presets and defaults
so we have all the pieces we need to build whatever kind of processing we want. and we can also build ui in the skein sidepanel in blender to re-use the same stuff
oooh, nice, I did not know that, thats actually awesome!
I haven't made too much noise about it but migration tooling like this has been a goal of mine since I started the project, so I've been building with that in mind
If I understand correctly the population of the enums in blend file is happening here, right?
that function is the type creation for the property groups that represent components yes
the one below that is the one you care about for avian
but both will have the same problem because they're both enums
Skein can attach component to a Mesh or an object but what’s "Object" in bevy term? Or Collection ? Or bone? What are the equivalence for Blender term in Bevy?. Since mesh is Mesh3d
collections are removed by blender when exporting, so they don't exist. (there's an option to keep them but I don't suggest enabling it unless you really know what you're doing).
Object is an Entity, and is a parent of the Entity that ends up with the Mesh and Material.
The Mesh and Material are different in Blender, but get combined into one Entity in Bevy.
A Bone doesn't exist. Its the space between two joints. The Joints are Entities with Transforms (and there's additional things about skinning but I'm going to skip that explanation).
So the default cube is
- Parent Entity (The Object in Blender)
- Entity with
Mesh3d/MeshMaterial3d<StandardMaterial>
- Entity with
The Scene itself is also the top level parent entity that contains all other entities in the scene
So if I attach a competent to the object in blender, I’ll end up having an entity at the same level as the mesh right?
Not an entity, better competent my bad
I'm not sure I understand what you're asking
if you attach a component to the object in blender, that component will be on the Parent Entity I described above.
perhaps this will be more clear:
commands.spawn((
TheComponentOnAnObject,
children![(
Mesh3d(..),
MeshMaterial3d(..),
)]
));
The default cube will always result in two entities: The Object Entity, which is the parent, and the one with the Mesh3d/Material, which is the child.
And basically if I put no components on the object it will be an entity with only children nothing else ?
Thanks this is clearer !
The object will actually have a Transform on it, but otherwise basically yeah
Oh okay thank you !
@woven frost Saw you mention that you had some trouble adding colliders from avian. My guess is you didn't use ColliderConstructor which is Avian's Reflect-able collider component.
It doesn’t seem to appear in the type registry
did you install avian into your project?
In the cargo.toml yeh
and the plugin is added?
the plugin skein ?
oh you mean registered
yes it is
no, the Avian plugin
yes it is
and you fetched the registry after running the application with the plugin added?
i forgot to refetch, im just dumb as fuck
kk. I was surprised you had trouble since that's a really common use case.
@snow heron, by any chance did you make a way to copy paste components between sections in blender ?
nope. copy/paste is entirely possible just not implemented yet.
quick question that is not tied to skein, but a little bit. How do i embed glb safely in my game so that player can edit it ?
So that if i have a component called "Health" with 20, i don't want them to put it at 10000 ?
You don't. Even if you encrypted it and stored it in the binary you still have to have the keys to decrypt it on the users computer, and you have to use those keys to decrypt it to actually use it, at which point it's in memory and modifiable.
If you're making a multiplayer game you enforce things like that on the server
good point
for solo game, that kinda sound like soft modding
so basically i will have an executable with a folder assets/ with all my glb file on the computer of the user ?
Yeah I mean Hades just has a directory of lua scripts
that's nice
really nice
never dived deep in game, i mean my last engine was unity sooooo
Personally I don't think attempting to prevent single player game players from modifying stuff is worth the time or complexity, but you could make it harder if you wanted to. Never impossible for a motivated player though
ok, so I reproduced the index thing with this dumb plugin:
use bevy::prelude::*;
pub fn plugin(app: &mut App) {
app.register_type::<MyCustomComponent>();
app.add_systems(Startup, startup);
}
#[derive(Clone, Debug, PartialEq, Reflect, Component)]
#[reflect(Component)]
pub enum MyCustomComponent {
One,
// OneAndAHalf
Two,
Three,
}
uncomment, rerun, refetch - and it automatically renamed.
I've managed to make it work, but not sure if its the method you'd want to leave.
So far I did not see anything breaking. I'll create a PR
I won't accept ai generated code in the repo unfortunately, for the same reasons Bevy doesn't.
its not generated by it, I just asked lots of questions, aand learned some blender API which is cool
I also added a detailed issue explaining the bug
anyway do with it what you will
thanks for the issue and the reproduction case in it
Dumb question: Why the changing the orientation should be even relevant to skein?
I'm using the flag with no issues since it became available.
it's not in the sense that skein doesn't have to care about it. Its a user choice and skein is specifically designed to not impact user choices like that.
The comment in #general was the people authoring the flag looking for more feedback from users of the flag.
which "people using Blender" is a userbase that might care about the flag and be using it
if its working well for you that's probably good info for @south patrol to know (ping for awareness)
node conversion was removed in https://github.com/bevyengine/bevy/pull/20394 which you'll want to be aware of for 0.18
my intuition is that the
My guess is that most users just want to spawn a scene with the correct orientation and don't worry about individual node transforms
is incorrect, since building scenes in blender, especially with skein, means that you can place a bunch of objects which are not top-level scene nodes
So the trivial case would be: put a component on an object in the scene and move it forward(), what happens?
Tranchbroom's restrictions around how things can be spawned, on the other hand, force you into using the scene root for objects in a level
I guess cc/ @ocean burrow too since I said more about it here
I spent some time thinking more deeply about this and I've come to the conclusion that it was actually a bug in Avian, since they changed the meaning of the discriminants by putting the Voxel colliders in the middle of the enum.
That doesn't mean we can't/won't do anything on the skein side to help with it, but the issue is fundamentally that the ColliderConstructor representation actually shipped a breaking change (accidentally I believe). What was previously valid became invalid because Avian changed the meaning of the discrinimants, which is not just a skein/blender enum issue but an issue in Rust as well.
The new variants should've been added to the end of the enum, or given explicit discriminants.
This is relevant because if we move forward with a string-based solution the same issue can happen if the variant is renamed, so we're not really "fixing" the problem and adding complexity to the codebase to do it.
A string based solution is definitely more stable though. And it can't really become "accidentally valid" which is worse IMO
hmm, true, I did not think about renames
but the same can happen for any plugin you use, and you can discover it way too late to try to fix it in the dependency repo
which overall leads to a much more fragile migration IMO
I genuinely don't know what would be the best solution, I do not know the downside of switching to keeping strings
depends on the kind of change, both handle different changes. discriminant is stable in the face of renames, string is stable in the face of discriminant changes. Discriminant changes shouldn't be happening and are easily preventable for crates that offer types that are intended to be used externally to Rust code... whereas people rename variants all the time during development.
Neither strings nor discriminants prevent the "accidental validity" you're talking about, in the Blender Python environment. if it gets as far as needing to load data against a broken schema, string based will silently fail if a key doesn't exist because of the nature of the python environment, which provides no user feedback. I know you're evaluating "discriminant vs string" more abstractly, such as against what would be the equivalent of a .ron file or whatnot, but blender's python environment does have additional constraints and initializes data at different times as well.
Yeah my point there is that we can't fix the general problem of "breaking change upstream" by using a different data storage model here. A breaking change breaks downstream consumers, which is why it's called a breaking change 😅 . Neither discriminants nor strings fix that.
Its perfectly reasonable for Avian (or any other plugin) to say they're going to break consumers, but the fix for consumers isn't data model storage changes, it's validation of new registry fetches, better migration tools, etc
But like if a variant changes name, it's unlikely to semantically be the same thing. Whereas the discriminant can change for all sorts of reasons not related to that variant
that is very much not true. People rename things all the time on a whim.
adding an s to a variant for example
or removing it
Bevy itself changes names of items all the time just for consistency reasons, and not for semantic changes
I suppose, but I think it's much better for your variant string to fail to match, rather than trying to deserialize as an unrelated variant, right? The former at least "fails closed" rather than "failing open"
blender does its absolutely best to initialize data whenever
so if the string is invalid or whatnot, that's not a guarantee that it won't "match" something else
more likely you'd end up with Default-style values
Fair enough!
the discriminant can really only change for one reason: the provider broke the data model and chose to ignore/didn't know that discriminants exist.
but regardless of the data storage (which to be clear, we might still switch to strings. This isn't a conversation about how we shouldn't, just that it really isn't a bug in skein; it was a breaking change upstream), the solution is a combination of validating new registry fetches against stored data and better migration tools. The fix for the Trimesh/Voxel case could've been as easy as "mass change all Voxel colliders to Trimesh" in a button in the UI.
(not those values specifically, but "change this component value to that one" kind of operator)
we could also have a "crater-like" process for automating schema compatibility of popular crates
it can be helpful when rust panics because the variant not found though, I also think it's better than silently use wrong one
that's implying that we can detect and correct data compared to a breaking but valid schema before blender tries to
skein will not export invalid data generally, so if an export works, it is valid against the schema used
blender also tries to initialize data when used in, for example, the UI
on the contrary, if you deal with the string of variant that has been renamed, you then move the validity check from the semver to the import, which might be a much faster feedback loop.
what is "from the semver"?
if you want Rust to panic, then the data has to make it through the entire pipeline back to the Bevy application
I'd agree that's it's incorrect for Skein users. And there's a risk that 0.18 is a step back for any Skein users who enabled use_model_forward_direction. Which isn't great but unfortunately how things turned out for now. There's potential to improve it in 0.19 so I'm interested in any feedback.
As far as I can tell, Blender's preferred forward for scenes is negative Y, or "Y back" (but cameras and lights are different). If that scene is exported to glTF with "Y-up" then it becomes positive Z forward in the glTF. Then in Bevy, without conversion, it stays as positive Z - and this doesn't match Bevy's standard scene forward of negative Z.
So my guess is that most Skein users want use negative Y forward for scenes and entities in Blender, because that's Blender's standard. And they'd like Bevy to apply conversion to turn that into Bevy's negative Z forward.
But there could be other Skein users who want to use positive Y forward in Blender - maybe that's just their preference, or they want to avoid depending on conversion.
Does that guess match up to reality?
Hello there!
Using Blender 5.0, bevy_skein 0.4, Blender plugin Bevy Skein 0.1.13
Confirmed light being properly imported from gltf scene into bevy scene (e.g. removing light object in blender and re-exporting to bevy leads to light not to appear).
But the issue is that properties on light component inside blender do not affect what I see in bevy (light should be blue, or not be present due to illuminance set to 0 (i guess)).
Should I do some prep work in code for that to work?
And are there any other examples besides skein repo folder?
This is a DirectionalLight component on an empty?
or is it on a light, etc
The component is set on a light object under green light bulb icon tab, I do export the scene with Punctual Light checkbox ticked in export settings
bevy project is based on template-minimal branch from skein repo, fyi
Well, the thing I didn't actually try is setting the light color directly in blender, not in bevy light component api - it worked, after re-export I see the desired color in bevy scene.
This makes me question are default bevy registry component apis that accessible in blender via skein plugin meant to be automatically working or should I re-apply light properties myself just like with replacing blender material on scene load?
yes, the KHR_lights_punctual gltf extension has hardcoded support in Bevy's gltf loader. So if you use the lights in Blender they should export as you expect (with some caveats) without any additional components
I'm trying to design a system allowing one entity to "activate" if slotted into the right collision zone. The best analogy I can think of is inserting a VHS into a player, or this clip from Elebits:
https://youtu.be/XGEfv2JApAE?t=471
Obviously, I don't expect the finesse of motion controls. I do want to know what would be a good way to design this with Blender/Skein in mind without relationships (as that seems to be still off the table for now).
Elibits is one part first person shooter, one part lightgun shooter, and one part Katamari Damacy.
Players have movement and aiming control like a first person shooter, zapping the mass of Elibits that flood the areas is reminiscent of a light gun game, and the more Elibits you zap, the more powerful your zapper becomes, allowing you to move la...
This category includes:
- Cameras get a
Cameracomponent - lights, when exported with the
KHR_lights_punctualextension get their respective *Light component (Point, Spot, Directional) - materials turn into a
MeshMaterial3d<StandardMaterial>
Thanks, now I see: components set via Skein do not override bevy gltf import settings with this particular set of objects, right?
Tried to attach light component on an empty, it worked in bevy scene.
they should, which is why I was asking where you put the component
its basically the same as inserting a new component of the same type, so leads to a new component value
you mean the cd into the trash can part?
Yes
one component for "thing that can be inserted" and one for "thing that can receive"
avian sensors and such
this doesn't strictly speaking need to be a relationship
I was thinking about, using a VCR as a model, that the receiving device has an invisible collider mesh that detects is if the inserting object is inside of it. From there, triggering some kind of Entity event in the receiving object.
But for some reason, what's tripping up my thought process is cases where the inserted object is still visible, and in some sense "intractable" while being connected with the receiver object?
The Elebits example is easy, as the CD is deleted after being inserted into the disc-shredder.
A step up from that is something like tapes in Voices of the Void, which are inserted and ejected.
this sounds like more component data? like CD into a CD player is a collider/sensor situation, and the data for what track to play is on the colliding CD, etc
Maybe I've missed it in the docs, but is there a way to add a component to multiple objects at once? Or change a value for multiple objects? If I select multiple objects and hit the button, only one object gets the component.
there is not, but I'm working on it: https://github.com/rust-adventure/skein/pull/67
That's great!
yeah I'm planning on building out some example cases (I have to anyway to even document the various handlings for skein users who would want to use it). I will share these with you when I get around to it. Hopefully it will provide a comprehensive suite of examples.
You're generally correct with your thoughts on how Blender ends up in Bevy (neg Y is forward, exported with Y-up, without conversion, is positive Z). and the idea that "forward should match" across applications seems correct to me.
The thing that feels weird from the current PR behavior in 0.18 is having different behaviors for some entities and not others. For example: the default cube in Blender comes into Bevy as an Object with a Mesh/Material child, so 2 entities. The Object entity is no longer processed in 0.18, so forward moves "backwards". The mesh entity and the object entity move in opposite directions, which is a strict downgrade from without the flag where it is rotated 180, but everything moves in the same forward if you use forward(). I do think this is incorrect handling in general, not just "for skein users". At the very least it is incorrect for all Blender users but effecting differing forward behavior on different nodes feels wrong globally. A parent node of a mesh should not move backwards when forwards is used. This will be very confusing for people.
As for if people want positive Y forward, in blender, etc. idk. I can come up with use cases as much as anyone but I generally try not to deviate personally.
Yes, but my issue isn't about the data, but defining how they relate to each other in 3D space. Should one hold a relative transformation indicating how the other should be placed?
Maybe a point in Blender?
This sounds like it could be a parent child relationship, which would give you relative Transform
Examples cases would be excellent, thanks!
On the mesh weirdness, yeah, this is an awkward compromise to try and maintain backwards compatibility with 0.17 where possible. The hope is that node conversion goes back in at some point, and then the separate mesh conversion option either fades away or is left as a niche feature.
That is my use-case, and suspect that was the reason that some of the empties / pivots were facing the opposite direction compared to the mesh. This is the issue what I was referring to in the #general as well. But that was in in 0.17.3.
are you using the flag in 0.17? or the default impl
This is the reason that I am only using my own components, making them assign the appropriate third party or bevy components. Thus if those are changing or get moved, it does not break something that can be only noticed during runtime.
I am using now the default one, I checked the flag briefly and it was flipping so many things around that after the brief conversation with you and ~~Greeble ~~ Jan Hohenheim I've turned it off and didn't investigate deeply.
yeah makes sense
I think the flag functionality that ships in 0.18 is going to be considered broken on release, since forward() will move you in different directions based on which entity its called on, and you won't know anything about which direction that will be
Yeah, that's kind of an issue for me, I rely, maybe a bit too much, on .forward()
I think the goal of the flag is to make "forward" match across software, so one day that should be fine
I have not thought about that use-case yet, but you are right
also today, forward always moves in the same direction without the flag
I think I'm going to file an issue on the repo (that we can optionally close out) for documentation purposes so that this is more searchable. Do you think there's a better place to put that info?
on the flag itself, no?
yeah good call
ping me if you PR it so I can approve 🙂
As of the enum issue:
I am not really sure if it really can be considered a bug when an new variant is defined not as the last member.
Could skein perhaps somehow try to match the variant by string first and if it fails than by the discriminant? Supporting both reordering and renames (just not both in the same time).
Also can you tell me more what are the current issues you are facing with notifying the users of potential issues? Is python throwing an exception or silently failing without any exception?
I've see for how long you were typing now, also experienced how fast you can type, I am very curious what's on your mind 😄
tldr; for the enum issue: Enums in blender are stored essentially by the discriminant using the order they're defined. So while we use strings to refer to the enum values in python, that is not how they're actually stored in the blendfile.
If the upstream data format changes in a breaking way (such as a re-ordering or a middle-insertion of a variant), then the order of the enums can change, which results in the previously stored integer referring to a different variant.
Its important to not that at this point, no data loss has occurred. The data for the variant and the variant choice are both retained. If the data breakage is fixed, the blendfile will again show the data correctly.
This sort of thing might be mitigated by storing a string instead, but when we're talking about data that was already stored and breaking upstream data model changes, there are also breaking changes for string values that can happen. So using strings doesn't absolve us of needing to deal with this.
The avian issue specifically was that two new collider types were added to an enum in the middle of the ColliderConstructor variant list, shifting the order/discriminant "backward 2", which meant TrimeshFromMesh's index became VoxelizedTrimesh. TrimeshFromMesh doesn't include any data anyway, so the index is the only value stored, and VoxelizedTrimesh's data exported to the file instead (Which is semi-related to the fact that Blender will initialize any data used at different times, such as when viewed in the UI).
--
The reason it is not a bug is that a breaking upstream change is not a bug in skein. Even if we use strings, there's no way for us to discern that a string match is or is not a breaking change.
--
As for how we can fix it or prevent it:
We don't currently validate all of the data in the blendfile when a new registry is fetched. We could theoretically do a diff for breaking changes on the registry and warn, but I also believe in practice people choose to break their own schemas all the time intentionally.
We could do something like two-stage registry fetching where we fetch, validate, then store the schema. (incidentally we could also do things like "the registry fetched had no changes" which might help people who forget to reflect)
We could move to a string-based solution, but this wouldn't cover cases like the removal of a variant, a data change for the variant's data, etc (non-exhaustive list, just making the point).
The other thing we can do is move migration tools forward more. The original report didn't include a reproduction (or really any context), but knowing what we know about it now, this is as easy as replacing the index with the corrected index in the avian case. We have the infrastructure set up for this but it is not currently exposed to users. We only expose component type_path changes right now.
blender --background -b art/tunic.blend -c change_component_path --old_path tunic_bush::BushSensor --new_path api::BushSensor
We fully have the capability to serialize to json and back to blender storage. This is require already for Defaults/Presets and exporting workflows. So we could allow people to export to json, modify, and re-import for data changes
yeah, it is context that is currently loaded into my head lmao
Thanks for the detailed description. Perhaps providing an automatic fix for all cases is indeed not feasible given the many different scenarios that can occur.
Had a number of differnt solutions in my mind, but in the end the migration tools look promissing (along with some asset validation). The migration tool would benefit a lot form an --glb_export_path argument. If that would be added I could write some scripts for myself that fix all the assets when I make breaking changes.
Ideally I'd write all that in python I think, but CLI is fine, I suppose it gives flexibility the users.
what would --glb-export-path do? export the gltf?
yes, to the provided path
and yeah, I think most people aren't familiar with python, so at least letting them use whatever their preferred json processing is would be fine
ideally this kind of migration tooling is also accessible in the UI
Why is gather function body commented out in cli_change_comopnent_path.py by the way?
I am browsing through the code a bit trying to familiarize myself with how it works.
the cli tools originally copied some code from the export function and iirc that original json export function was called gather
which is why its now called like skein_two, etc
Yes that'd be wonderfull, but given that it's just a few arguments it would not be that big deal I think. But you would need to do this during fetching right? As that is the point when you know what components were in the scene / previous type registry and which new ones are comming in.
yeah, there's still some open questions. If you want to retain the old data, you need to "export it" before you apply the new schema. and if you want to use the new data you need to be using the new schema.
its basically just regular data model hygiene, but done in an ad-hoc way that means the user can break their code and fix it later.
@south patrol @ocean burrow tagged you both on https://github.com/bevyengine/bevy/pull/22209
also notable that the avian Trimesh case really isn't like, data related. its just an integer. So completely breaking it doesn't require saving any data and you can skip directly to using the new schema and mutating the values afterwards
pass go, collect $200, move on with your day
I know what the issue is and your docs convey it correctly, but I don't think the way you wrote it would convey it to someone who didn't know already.
it's a bit confusing taking about "forwards" and "other direction" in this case
I'd like to mention that I am not familiar with Avian, skein is actually the only non-upstreamed bevy crate I am using.
maybe a very specific example like "the model has its nose pointing to (0, 0, -1), and will move in the direction (0, 0, -1)" would help
hmm, well the mesh isn't really relevant here either. Its Transform::forward
fair
then again, the whole point of the feature is to make sure that "forward" corresponds to "where the nose is pointing"
so it is kiiiiiinda relevant
if i want a directional light in bevy, is it an area light in blender ?
oh hey krisp, you here too? 😄
im everywhere
sun IIRC
yesss much better 
ok will change
thanks 🙂
is blender camera automatically transfered to camera 3d ?
it doesn't seem to work on my side
yes, you have to check the export camera button
pushed update
approved with minor suggestions
the SceneRoot suggestion is incorrect
SceneRoot and scene's root are different entities
I know, but that doesn't make the suggestion incorrect, does it?
I just want to clarify that this is specifically the case for glTF scenes
otherwise it reads a little bit as if this changed the meaning globally
Replied here, unfortunately negatively: https://github.com/bevyengine/bevy/pull/22209#issuecomment-3677884642
I'm open to rethinking the documentation. Need to think it through some more. But I don't agree with the PR's approach.
the location of the documentation or the content? (or both?)
Its important to mention that this results in forward being inconsistent within a scene imo
its ok I know what you were replying to
So yeah, disagree with both. The comment assumes that the user has a particular file setup, but they may not.
what is the particular file setup that is assumed?
that the scene and all the nodes have the same +Z semantics (putting aside camera and light exceptions)
could you clarify what you mean?
Take the fox model as an example. In blender the fox faces negative Y, so its forward matches blender's forward. But the head joint is different - I forget which, but let's say it's +X forward.
when you say the head joint is +X forward, is that a concrete Transform value or are you saying that in theory someone is considering +X to "be forward"
I think concrete transform value? But I'm not entirely sure what you mean.
this is kinda pointing at a previous though I expressed, which is that there aren't enough examples for the behavior in these PRs for someone to rely on the flag
when you say "+X is forward", what does that mean in terms of the Transform values. Or is it that someone pointed it in a direction and called that forward.
When it comes to using software to create models, you can obviously point a model in any direction. Are we considering the user's choice to be "forward"?
Right, so someone pointed it in a direction and called it forward. Users can choose whatever semantics they like, and they may choose different semantics for different parts of the scene or different types of object.
ok so this feature is really "define what forward means to you" not trying to align with gltf, etc
in which case, it really needs more documentation around how to "pick a forward"
I also think the explanation stands. For the most common gltf file, these flags result in flipping the forward direction of the mesh/scene, and not of the nodes. which will result in different forward directions for different entities
Yes. But the current options are so limited that it may only be partially right.
Which they already do to some extent - both options state that they only touch particular entities and don't affect nodes (except indirectly through inheritance). But I can consider expanding them to make it clearer. Or as you suggest, go through the specific example of a "standard" gltf where nodes and scenes and meshes all have +Z forward semantics.
I might not be able to get this done before the holidays though. I'm assuming 0.18 isn't going to ship until Jan at the earliest, although I don't think anyone's explicitly said that.
Also forgot to mention one thing on this point - the eventual goal is to let the user specify their semantics and have Bevy automatically work out the conversion. So even if the file is "wrong" and uses +X forward then they can correct on import. Although there's also a counter argument that it's too much complication.
(oh hey that's me)
so your issue with the PR seems to be that people can choose to invalidate the gltf standard forward and arbitrarily choose a different forward. I don't think this is a reason to block the PR. If someone is choosing to not follow the gltf standard then they should understand the implications already
I also believe it makes sense to write the docs with the assumption that the glTFs are following the glTF spec
Strictly speaking the glTF spec doesn't specify node semantics. It says +Z is the scene forward - nothing about nodes (except for cameras/lights).
oh really?
Interesting 
Even if it's true, the person breaking the standard might not be the person choosing the Bevy import options - they might have got it from an asset pack.
I checked the Kenney packs and while most have +Z forward (for the scene), a few have -Z forward.
do we have an example of that?
I feel like we're blocking this PR because the actual functionality isn't documented for edge cases
glTF uses a right-handed coordinate system. glTF defines +Y as up, +Z as forward, and -X as right; the front of a glTF asset faces +Z.
I'm interpreting "glTF asset" to mean "glTF scene" there. You might interpret it as meaning nodes as well, but that doesn't fit well with cameras and lights being -Z forward.
I think it's reasonable to assume that +Z forward for scenes and nodes will be the most common case for users that do care about nodes. So the docs could explain more of the background and say "if you care about nodes then these options don't do what you want".
I expect that if I did this I'd probably tweak the migration guide as well to be clearer that the options don't cover all use cases
is it normal that the on_add function doesn't work with skein ?
I have a #[component(on_add=CharacterController::on_add)]
impl CharacterController {
pub fn on_add(mut world: DeferredWorld, ctx: HookContext) {
let has_collider = world.entity(ctx.entity).contains::<Collider>();
let has_constructor = world.entity(ctx.entity).contains::<ColliderConstructor>()
|| world
.entity(ctx.entity)
.contains::<ColliderConstructorHierarchy>();
if has_collider {
let entity = ctx.entity;
world.commands().queue(move |world: &mut World| {
setup_collider(entity, world);
});
} else if has_constructor {
world
.commands()
.entity(ctx.entity)
.observe(on_collider_ready);
} else {
panic!("CharacterController requires a Collider or ColliderConstructor");
}
}
}
but i didn't but a Collider in my blender so it should have panic, but it doesn't
My guess is that Skein doesn’t Even add my component, and for some reason other components are not as well when I add this specific component
What versions are you using? Software Version OS macOS Tahoe 26.2 (25C56) Blender 4.5 Bevy 0.17.3 bevy_skein (Rust Crate) ex: 0.1.4 Skein Blender Extension 0.4.0 Describe the bug A component doesn&...
@snow heron I'm trying to reproduce the above issue and noticed that this screenshot is outdated FYI 🙂
sorry I would've gotten to this but power in all of SF was out 😅
oh whaaaaat
same here I beileve
Its either the EntityHashSet or another value that isn't being handled properly afaict
I can take some new screenshots. I'm working on the docs a bit for the next release anyway
the bug report links to a fork which has since updated and the link is dead now
can confirm I can reproduce it
yeah, if you start Blender from the CLI it should print some logs
indeed!
it's printing this error about a dozen times
yeah so that looks like its in the part of the code that is responsible for creating the propertygroup types and such
using Blender 5.0.1 + Skein 0.1.13
(unless its printing when you're mousing over the ui)
no render_two is the ui
so it prints every mouse move
this is when I click "Insert Component Data"
oooh
no
yeahh
I see what you mean
lmao
high percentage chance the export will fail if the ui is failing
no logs there FYI
oh nvm
I'm just a silly bean
where is MoveAndSlideConfig?
its either SpatialQueryFilter or MoveAndSliceConfig causing the issue
everything else is an f32 or Duration
as you probably know, Scalar becomes f32 and Dir becomes Dir3
my guess was SpatialQueryFilter, but didnt test much there tbh
(not to be a pedant, just mentioning in case it got lost due to this 🙂 )
yeah appreciate the callout
here's the filter
where LayerMask is
#[derive(Reflect, Clone, Copy, Debug, Deref, DerefMut, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
#[reflect(Debug, PartialEq)]
pub struct LayerMask(pub u32);
yeah the EntityHashSet would be the potential issue, not the mask
@ocean burrow also might be relevant for your search result cares
heh
lmao
which example were you running? the minimal example seems to fail
eek, thanks for the report
playground
fixed 
@snow heron completely unrelated to this bug, I'm now starting the Bevy -> S2 step. Meaning I need to generate some component definitions in a specific format (FGD) from the type registry.
Do you have thoughts on how this should be done? My go-to would have been
- starting the game dumps the registry somewhere on disk
- the S2 integration tools run a file watcher for this registry file
- whenever it changes, regenerate the FGDs and put them where S2 expects them
- the user has to manually click on "reload FGDs" in the Hammer editor in the end, no way around that
But I was also thinking whether this should be BRP based instead
that way, mayyyybe there doesn't even need to be a special Bevy plugin (beyond Skein, which is needed to load the S2 output anyways)
I'm thinking the S2 integration tools (called BS2) could then call the exact same endpoint that the Skein Blender addon calls
if its BRP based the application still has to run for the registry info to be queried
and generate their FGDs from there
Yep, AFAIK you cache it somewhere in the Blender workflow, right?
so the tradeoff is: is the application currently current or not.
If its currently running BRP is an option, if its not then you have to run the application once anyway to write the file
yeah in a text block. You can just go to the scripting tab and read it
what does "application currently current" mean?
I wrote the code to write out the registry file. its in a PR on the skein repo
"currently running"
ah gotcha
typoo
The thing I'm unsure about is how this would work when the type registry changes
in Blender, you just click a button to ask for the newest info, easy
In Hammer you do that too, but I don't think I can really intercept that button click
so I'd need to periodically ask the app over BRP for something
and that sounds a bit crap
Thanks a bunch for that. What's the API for doing so?
i.e. how do I tell SkeinPlugin to please dump the file
A new write_manifest_and_exit feature will write out a manifest file when enabled. This is also configurable in the Skein plugin options. So you can:
enable the feature (writes the file and exits)
enable the feature and set the skein plugin option to false/true which will then control the write out behavior at runtime. Users can use this to distribute development binaries that can write out the manifest.
is the description I wrote in the PR
and the actual code is just a system add, flagged.
#[cfg(feature = "write_manifest_and_exit")]
app.add_systems(Startup, write_manifest_and_exit);
That system is currently:
#[cfg(feature = "write_manifest_and_exit")]
fn write_manifest_and_exit(
mut world: &mut bevy_ecs::world::World,
) -> bevy_ecs::error::Result {
use crate::safelist::export_registry_types;
use bevy_app::AppExit;
use bevy_ecs::{
event::EventWriter, system::SystemState,
};
let types_schema = world
.run_system_cached_with(
export_registry_types,
None,
)?
.map_err(|brp_error| format!("{:?}", brp_error))?;
let registry_save_path = std::path::Path::new(
"skein.manifest.registry.json",
);
let manifest = SkeinManifest {
crate_safelist: vec![],
presets: None,
registry: types_schema,
..Default::default()
};
let writer = std::fs::File::create(registry_save_path)?;
serde_json::to_writer_pretty(writer, &manifest)?;
let mut system_state: SystemState<
EventWriter<AppExit>,
> = SystemState::new(&mut world);
let mut exit_event = system_state.get_mut(&mut world);
exit_event.write(AppExit::Success);
Ok(())
}
oh lovely lovely lovely
that's excellent news
this is a PR I have to update, so its a bit out of date and refers to a "SkeinManifest" that I was thinking of packing all the relevant data into, and versioning
export_registry_types in that PR is a light fork of the upstream brp function
effectively the same as the registry schema endpoint
basically the same as: https://docs.rs/bevy/0.17.3/bevy/remote/builtin_methods/fn.export_registry_types.html
Handles a registry.schema request (list all registry types in form of schema) coming from a client.
I was adding a safelist/filtering feature in that PR too, which is why it was forked
So by committing to being Skein-bound, I could get away with not requiring any other Bevy plugin at all!
- Tell the user to use bevy_skein with that flag enabled
- To get data into S2, file-watch the registry export and convert it to FGDs
- Those FGDs can be used to set prefabs in Hammer
- Additionally, artists can annotate their models with components using Skein for Blender and exporting it as FBX (which has that metadata somewhere) which can be easily loaded in S2
- On map compilation, I can convert all Valve data formats to glTF, and use the metadata found in the FGDs and in the FBX to annotate everything as Skein would expect
- The glTFs are then moved into
assets/ - The Bevy app loads them as Skein-flavored glTFs
this is brilliant!
yeah, skein having a blender plugin is kind of a fakeout because its really the glTF extension format and some tools for fetching/etc the registry data 😆
this is so cool
thanks for creating this 
wonder if it would make sense to upstream the non-Blender parts
my goal is to upstream the extension format itself actually
we're not at a point where that makes sense without the Relationship component support though
the core components format is very stable though, it hasn't needed to change since it was first implemented
(because well, its really just an array of reflected component data)
but making it like that and not building random features on top was intentional
@ocean burrow @woven frost it was EntityHashSet. Just testing some more but I should be able to put the fix in the next addon release
Do you know when is that ?
today hopefully
i have a jam in 7 min lol
oh lmao, let me see what I can do
heck yeah, thanks!
take your time, it's a long jam, ill need to brainstorm idea before hand
is this "collider or colliderconstrctor" hook trying to force an order of operations for component insertion order?
panic'ing the application seems kind of extreme
nope, it's just dealing with the fact that the KCC for now lazily assumes that the collider is on the same entity as the rigid body and the KCC component
yeah that's definitely a "patch that up later" kind of deal haha
worth noting that if you panic the application like this, BRP can't run unless the gltf file is changed to not be loaded
because well, the application panics
I assumed it would work fine when I set up a KCC + ColliderConstructor + RigidBody on the same object in Skein?
Oh, I suppose they aren't inserted together, but one after the other
presumably. but if you try to insert the character controller without knowing, see the error message, and then have to go back, I hope you had all the requisite dependencies already installed, etc
yeah totally
I'll at some point change it so you can insert the collider at a later point
I would just change it to an error log now?
I don't see why it should even be a panic
that's fair
because about 5 seconds of thought went into that bit 😄
yeah, the order of insertion is critical because of the panic
so you have to have a ColliderConstructor, then a CharacterController
the other order crashes
Fixed, I hope
Thanks for bringing it to my attention
@snow heron how ready is the offline manifest branch?
i.e., can I start tinkering with it already?
@snow heron did you publish the release, or not yet ?
yes its out as 0.1.14
I haven't published the release notes, etc yet.
probably not. I need to update it since its been there a bit. It works and such but I need to do a pass on it.
Alright I’ll wait then 🙂 could you ping me when it’s updated? Doesn’t need to be polished or even merged yet
yeah will do
perf, i just need to replace all the python file in blender addons folder or theres an easier way ?
I would just install it from the website: https://bevyskein.dev/
if you've already installed it you can just click "update" in the extensions tab
thank you, i didn't check on the website :-
the 0.1.14 addon/0.5 bevy_skein releases supports extensions, but blender's gltf exporter needs a fix before marker components will be included in the output: https://github.com/KhronosGroup/glTF-Blender-IO/pull/2631
If other software produces the extension format, bevy_skein can read it/process it just fine.
Good news for me hehe
Sorry if this has been asked, but couldn't find anything.
Are relationships supported? For instance, I want to design a power distribution system with power sources, consumers, etc. I have my relationship components added to my source and my consumer, but can't seem to find a way to actually link them together.
relationships are not currently supported. I had to upstream gltf extension processing into bevy for that, which just shipped with 0.18, and I need to get a fix merged upstream into the blender gltf exporter which probably won't make it in until 5.1.
we're on-the-way to them being supported, but not right now.
in the meantime you can use placeholder components and connect them with your own ids in SceneInstanceReady, etc. Its... not relationship components but it works and you can insert the relationship components when spawning the scene
@snow heron it's great to hear that this feature is in sight, thanks for confirming! And thanks for the suggestion, I'll probably go that route in the meantime.
Thanks for the great work by the way! Other than the current lack of relationship support, the crate and add-on are really easy and enjoyable to work with!
awesome, that's lovely to hear
hey! qq, is it possible to export a mesh without a default material? i'm attempting to export a model and its collision mesh at the same time and have the collision mesh hidden; currently it looks to be assingning a default material in bevy anyways.
I believe the bevy gltf loader applies a default material to all meshes regardless of how they're exported
Setting visibility hidden on the collision mesh is probably the easiest fix
User indication of whether an entity is visible. Propagates down the entity hierarchy.
hi im trying to use skein with the avian ColliderConstructor component for level geometery and its ignoring the mesh scaling i did in blender for whatever reason
ive seen people have issue with the constructor but not this one this is bizzare
on the top, cylinder that is scaled, on the bottom identical cylinder where i set the scale to all 1s
and i added the components into the mesh
other way around results in a crash predictably
is this even known?
looks like you didn't update the cylinder values for the collider
is this a TrimeshFromMesh? or what kind of collider is it?
speaking generally, if this is trimeshfrommesh and the component is being inserted then its something that should be reproducible without skein for an Avian bug report
oddly enough skein sees more variants of comsteuctor than the docs know
what docs are you looking at and what version of avian are you using
latest
and which variant are you seeing that isn't in the docs?
did you build the docs locally or something?
yep, that is not the docs
because the docs that cargo generates all look the same, which is why the docs on docs.rs across crates look the same
if you run cargo doc you'll even get a local html that looks the same
tnua needs to get their own logo
re: the scaling issue, that makes me think avian doesn't account for scale when creating the trimesh collider
most people "apply scale" in blender, which is where I would start
whats even worse is that it worked correctly one time but i have no idea why
i had weird stuff with my collider until i applied scale+rot in obj mode
idk if its related
weird like w hat
as far as I've seen, reasoning about scaled objects is Hard and people generally try to skip it rather than deal with it. including in bevy's ecosystem
yeah i think it seems somewhat expected that all that should be applied beforehand
or at least that is my experience with other editors and exporters
speaking of exports 😅 is it expected that the components assigned to a scene do not export with that scene?
no, scene exports should come through.
are you not seeing them at all? or are you just not seeing them on SceneRoot
voilla....
thanks chris
now i just have to..... find a way to do this on export or ill go insane
not seeing at all, inspecting the gltf and the component appears only if I add it to an object within the scene (using the multiple scene exporter thing, I haven't tried a normal export yet)
youd think itd be an option here
I just ran the export and saw components on my scene
it definitely doesn't for scenes. are you using and exporting collections?
this is what my outline looks like
(excuse the empty extensions list, that's a blender gltf exporter bug I have a PR in for)
yes ok, snowplow is a collection, not a scene
scene is the rootest of root entities there
the one labelled "Scene Collection"
ah whoops
another issue is that the pillars are actually supposed to have colliders also, but dont, probably because theyre under an array modifier
im guessing thats downstream
theres an option to apply modifiers on export
and its on
ah
yeah modifiers are the modifier stack, not the scale/etc
the new array modifier in blender 5 yeah?
this might still be a bug. I'm seeing the root scene components when using a collection exporter instead of the collection components. I'm actually not sure and will have to check.
yeah 5.0.1
let me try array legacy
oh i see why they wanted a new one theres no option to arrange in a circle
yes lol
the legacy one doesn't do what you want
the new one uses geometry nodes behind the scenes is why I asked
do you have "realize instances" checked?
def not cause i dont know what that is
it is checked by default
then yes because i havent touched it
so I think what you're exporting is one mesh with many columns in it
applying the new array modifier gives me "one mesh" with 3 cubes in it
theres a decomposition variant for the constructor let me see what that does
decomposition how? ill see in a second ig
I know you can go from having the array modifier to "separate by loose parts" and you'll get multiple independent copies
but I don't think there's a modifier stack version of that
decomposition didnt improve anything
it seems it really wants me to apply every destructive change
luckily the skein components survived the separation
yes, they also surivive when doing duplication of objects, etc
just when i had my back turned
this is a scene from evangelion
but it works
very perculiar mesh it builds
thanks again chris
yeah no problem. I'm hoping to get some geometry nodes docs up at some point and this is a good case to document
i can make you a blend file with all the horrors here for demonstration
haha I think I can recreate them. its scaling and an array modifier right? I don't think there was anything else
pretty much
cool yeah, I can reproduce that easily
bonus horror of forgetting to set rigidbody to static and watching it fall
otherwise skein has been extremely smooth sailing even the error logs
unlike bevy itself at one point where it tried to normalize a null vector
nice, that's great to hear about the error logs too
in particular ive been changing a Player component from empty to containing some enums
it told me i didnt derive reflect on the enums and all
in classic rust fashion
after failing to make qevy work this is very pleasant
question: do I need to use the gltf split option or can I just export the glb file?
glb works fine
question: is it possible to set assets via editor in bevy skein or will I need to create my own system to load the asset and just set the path?
because I'm trying to use assets to handle data whenever possible instead of hard coding values
generally speaking, Handles don't exist outside of Bevy, so you're down to setting things like paths in-editor, which can then be processed and loaded with the AssetServer, for example in hooks, observers, or SceneInstanceReady, etc
its a reasonably common pattern to have components with paths for in-editor use that then have OnAdd hooks or observers that do the swap to an actual asset.
okay, so like have a characterpath component that adds the actual character component with the handle when it's added?
yeah.
That sounds like you might be looking at doing multiple glTF files? which is notable to mention that glTF doesn't have external references in the spec. There was some work on an extension that used to be called glxf but it is currently not even a spec.
oh no I'm loading a .ron file, not another GLTF file currently
coolcool, just figured I'd mention it
Does the remote plugin is only in debug compilation profile ?
the default is to only start BRP in development, yes: https://github.com/rust-adventure/skein/blob/0c18f8728c1c9e39ef059516216444fc24c0bc95/src/lib.rs#L69
you can either set that option or set up brp yourself, both will work
I don't expect everyone to know the skein codebase 🙂 so asking is also fine
I updated the plugin to delay adding the actual endpoints, so users can completely configure BRP themselves, and skein will still work
Bevy skein is so usefull I use it all the time as an editor
awesome, glad you're finding it useful
Keep it up lmao
hello, is there a way to set same metrics that used in bevy in blender ? I tried to make an cuboid collider to my plane, but its too large in bevy. How can i match the metrics, also is there a way to draw gizmos in blender ?
I added drivers to my cuboid in blender
to my plane
but the collider in game is huge
Are you expecting it to be 100x100?
The metrics should be the same. You might have a scale on the plane that you haven't applied?
idk if it's even possible, but can an addons show ui/3d element in the scene without being object in blender ?
To some extent yeah. Deeper customization requires writing C.
i was about to say would be nice to show colliders, however it's dumb cause youll depend on things like avian3d or smtg
Yes, I would prefer a generic solution
One that allowed more crates to take advantage rather than just safe listing/depending on a specific version of avian
the other solution i have in mind is allowing intermediate crate, like a skein_avian3d so we can extends something like "blenderbox3d" that will render in blender, but that sounds overkill
altough im not sure rust allow to implement function on struct outside of the current crate
i dont feel like it's necessary
there are potential options, but it's unclear if any of them are better than the current state. One thing that would be concretely better is better driver support in skein, which could have some presets for application
so for example, you could drive a field by "its calculated x size", which would take into account scale and such.
another possibility is empties as assets with data, but that comes with some implications that people who are newer haven't wrapped their heads around yet (ex: the collider asset would be a child of the rigidbody in some way)
this makes sense, but a lot of people struggle with the idea that the default cube is two entities and try to put in wasted effort to collapse the hierarchy (which in turn means you can't put multiple components on an entity, etc)
yeah i get it
it needs some investigation i guess
yeah. in general I'm interested in workflow improvements, but not at the cost of hardcoding specific crate versions in the blender addon
i totally get it and totally understand !
the green is mesh, the orange is collider
in game collider is very big
the plane has scale but
i don't know
yes, but you haven't shared any of the metrics in blender that contribute to your driver.
let me share one sec
the driver's resulting value is 100x100, which will get multiplied by scale if one exists when spawned in bevy
most people "apply scale" in the menu and perform scaling operations in edit mode
yes, a scale of 50 means 100 * 50 basically
is there a better way to do it ?
I would apply the scale and then ignore scale entirely
okay okay thank you
using scale is confusing (not just in bevy/etc but in general). It affects things at a distance and most people working in blender will apply scale and do scaling operations in edit mode as a result
it is totally valid to use scale, it is just something most people choose not to do
which results in more straightforward numbers
hmmm okay nice to know !
I just started developing this game with my friend and he is new to blender so i am
nice!
glad you're enjoying it! feel free to ask any other questions if you have them.
I have one more btw some of the objects we are adding creates to many triangels when we set trimesh collider
what should i do when its the case ?
since you're new: if you use tab to enter edit mode and scale there, the "scale" value in the transform won't change
what do you mean by "too many triangles"? is there a different collider that would work better?
let me show you give me a sec
colliders don't necessarily need to match objects exactly. A box crate with a bunch of wood planks can be a cuboid collider instead of a trimesh, for example
okay
yeah these are great examples of "could be a cuboid" and not a trimesh
assuming they don't open, etc
if they open you have options. Such as "more cubiod colliders" attached to the sub-entities that are moving.
okay
you can also remove the collider if a player is going to pass through it at runtime
I want to make it like physics based using prisma joints for example
I will create a link component between the door and frame
and connect them with joint in runtime
yeah if you're doing stuff like that you can attach different colliders to different parts.
