#big_space

1 messages ยท Page 2 of 1

mighty crescent
#

Not really. You just needs LODs.

#

At that distance, you would likely use imposters.

#

Or bake the skybox when travelling. I think this is what Elite:Dangerous does

naive elk
#

you're saying I could really spawn all my stars and planets at the same time?

#

without streaming?

#

and then swap meshes based on distance

mighty crescent
#

Sure. It's just a matter of optimization, your perf budget, and how much time you have.

mighty crescent
naive elk
#

that's encouraging

#

do you maybe have an advice for rendering these giant upclose planets? sure it's supercool they're the real diameter, but .. doesn't that mean lots of triangles for GPU to handle? like really lots

#

is that something Bevy can also automatically LOD somehow
or would I need to chop planets into distinct renderable bits

#

to not render the back side of the planet for example

worthy vector
#

So I can have a whole solar system full of planets with no perf impact at all (in practice I despawn them completely when they're too far away to see)

#

For stars in the sky, the plan is to bake them since you can't move between systems fast enough to see them moving

#

But you could also use billboards or something for very far-away stars so each one is just a single triangle, then batch them

#

With that approach I could see you easily hitting millions of stars without setting the GPU on fire

naive elk
#

How does your approach compare to what someone else suggested elsewhere - modifying the mesh vertices in a compute shader?

#

Or is that too complex and hardcore by comparison

worthy vector
# naive elk How does your approach compare to what someone else suggested elsewhere - modify...

Hmmmm I wouldn't actually know where to start on that one, unless you're doing double-precision in the compute shader. In that case I imagine it'd be a lot like my impl but with GPU acceleration (I'm not really seeing performance problems, but I'm also being very conservative with the resolution). If they're talking about something more complicated, it's a little above my pay grade at the moment.

#

That said, I was planning on making the repo with my planet generator public once it's cleaned up a bit. I'm happy to ping you once I do if you're interested in looking through it

mighty crescent
#

If you are doing all terrain gen on the GPU, you still need to pass it back to the CPU to do physics and stuff

worthy vector
#

You don't necessarily have to pass it back. You might not need the same resolution for physics, so maybe you'd just have the same algorithm run on both CPU and GPU, but run more iterations on the GPU

pastel path
worthy vector
# pastel path I'm looking into implementing an octree structure with big space which i assume ...

I'm not building an octree actually! The closest thing I have is my sphere volume hierarchy, but that's not quite what you're wanting probably. I have considered writing an implementation before, but I was waiting on something like the relations impl coming in 0.16, that way you can create a relationship component where every entity tracks its parent octree cell, and every octree cell knows exactly what entities are in it. For that you probably could use entities as nodes, but since I haven't written the impl, I'm not sure what roadblocks you'd hit.

@celest obsidian's voxel planet does use an octree I believe, I'm sure they'll have better information for you

#

Also: why no threads in posts Discord ๐Ÿ˜ฉ

pastel path
worthy vector
# pastel path Hmm interesting. The lod changes in your method are very similar to an octree. I...

It's fully homebrew, but it's not particularly complicated: the sphere starts as 20 meshes at the lowest LOD. Each mesh is its own entity, and I put a bounding sphere around each that's 1.5x as big as it needs to be to contain it. When the player enters the sphere, I hide the mesh and spawn four child meshes, each with their own bounding spheres. When the player leaves a bounding sphere, I make the parent mesh visible and I despawn its children.

#

The source is here, but I warn you, it's not done yet. I'm working on adding noise octaves right now, and there are a couple places (notably mesh generation) that I've cleaned up but haven't pushed yet

#

Oh I forgot to add a license before I made it public, but I just did that. It's MIT/Apache-2.0, so go ahead and do whatever with it!

celest obsidian
#

I use slotmap to store my octree. I used to use nodes as entities, but there were so many nodes in my octrees that Bevy was lagging. Even entities without rendering components were dropping my FPS, but that's been fixed for a while IIRC. I might try to make the nodes entities again, taking into account the future relations features coming.

worthy vector
#

I love slotmap

celest obsidian
#

Me too, it's very easy to use

worthy vector
celest obsidian
#

I just think it was because even simple entities with a marker component lowered the FPS after ~10,000 entities. But now we can reach more than tens of millions without any issue.

#

Ok, I had forgotten at what number of entities it starts to lag. I slightly underestimated that number. I did this test a long time ago

#

-1000 FPS for 1M entities at the start

worthy vector
#

Wow yeah that tanks surprisingly fast. Does it stay low even if you stop adding entities?

#

I guess this was a while ago

celest obsidian
#

but now it's no longer a problem, at least not when I did a test in october

worthy vector
#

Oh nice! Yeah I wouldn't really expect performance hits just having entities around, glad it's resolved

proper ingot
#

i've just been using .as_ref() and .as_mut() explicitly

naive elk
#

Sounds like the slotmap thing is a more cache friendly version of HashMap? Or is there more to it?

#

...except you don't get to choose keys

worthy vector
#

Stable meaning that, with a Vec, if you remove an element, the others might bounce around. You can't rely on an element staying at index 5, for example.

#

And generational meaning that it'll reuse memory. If you remove an element at slot 1 for example and then insert a new element, it might go in slot 1. But they keys store generations on them so they don't get confused in the map

#

Meaning even if they reuse the same slot, they won't reuse the same key

#

Honestly just play with it. It makes a lot more sense that way than my explanation ๐Ÿ˜…

naive elk
#

It's a fine explanation, thanks

pastel path
# celest obsidian I use [slotmap](https://crates.io/crates/slotmap) to store my octree. I used to ...

ah, okay so you're not creating the actual octree with entities, but the leaf node meshes are still entities right?

My issue, which might be a misunderstanding of the use of big_space, is that when i try to split my node i get precision errors.
I know that when spawning entities or placing the absoloutly, i should be doing so through the grid struct. However, i'm unsure of what the best way to get the nearest Grid of an entity is. My first thought was to loop through the parents until i find one, but it doesn't feel very clean.

proper ingot
#

what reference frame is the entity in?
-# may be the wrong terminology

worthy vector
#

It just means your octree might have to be in double precision all the way until you finalize it into the hierarchy. That's how my giant planet works: I compute meshes and mesh offsets in double precision, then convert it at the last moment to f32 for bevy, but by that point everything is in a grid, so precision stays good

pastel path
#

Yeah i've read about that in the docs, my issues is finding the correct parent grid
Do you know of an easier way of accessing the parent grid entity of an entity than iterating parents until i find one ?

naive elk
mighty crescent
#

if it isn't the parent, it isn't an entity that lives in a grid anyway

pastel path
#

What i'm trying to build is an octree where each node splits into eight child nodes, and it is these child nodes i'm attempting to place correctly within the parent node.
This was fairly easy to do outside of big space, but i'm running into issues placing the child nodes, is that because each node itself should also be a grid for its children ?

mighty crescent
#

You don't need to nest the grids, no.

#

Calculate their position in double precision and set their cell and transform.

pastel path
#

must they all be direct children of the grid?

mighty crescent
#

If you want high precision rendering, yes.

#

Otherwise you will be using bevy's built in Transform propagation limited to f32

mighty crescent
#

You can also just use f32 for everything, and simply set the Transform of all your child entities, with the same parent. The GridCell will be computed for you automatically. There will just be some precision loss compared to using f64, though it depends on your use case if that matters or not.

naive elk
#

I haven't tried integrating myself yet, but I'm not sure whether Rapier or Avian are fully compatible with BigSpace, would be good to know

mighty crescent
#

Nope

#

It's an eventual goal

naive elk
#

In broad strokes, would you recommend hacking either of them for support, or would it be easier to roll my own physics for whatever small scope I might need?

mighty crescent
#

You could probably hack something together

#

There is already an implementation for avian floating around

#

Doing it "right" will take more effort though

ripe reef
#

sad

#

i can do it though

#

how do i spawn an entity in the root_grid outside of the original root_grid definition? Every single instance of an entity being spawned in the examples happens in the setup and not in an update?

hollow sluice
#

@mighty crescent Is there a way to force big_space to update an objects translation-gridcell coordinates? Like how it does automatically between frames when you 'push' it out of a gridcell. Or should I calculate and directly set its gridcell myself?

Meaning - if I update its transform many times during a single frame, the translation will blow up really big - and may have crossed gridcell boundaries.

mighty crescent
hollow sluice
mighty crescent
#

You can add grid cell indices. This can be used relative to your current position as well.

naive elk
#

Can you treat cell xyz like global transform translate? Look_at a cell's xyz, for example?

mighty crescent
#

translation_to_grid is exactly for this case

naive elk
#

@mighty crescent kind Sir, the hierarchy validator doesn't like having a Bevy UI Node in the root grid. Is there really a reason to deny this state of things? I'm trying to place a UI Node on a 3d object deep into the BigSpace hierarchy, to map parts of UI to 3d objects in space, and the UI nodes themselves don't want to be detached from a Node hierarchy, i.e. they want Nodes to be present all the way up to the root as I understand. But BigSpace is against that.

mighty crescent
#

If it's located on a grid, it needs a grid cell

#

But bevy UI probably expects the UI node to be in a non-big space anyway

#

Why are you trying to add a UI node to a 3d entity? The types are the same, but UI transforms have different semantics

naive elk
naive elk
mighty crescent
#

Bevy UI doesn't play nice with mixing UI and 3d transforms, I'd recommend against it

naive elk
#

oh

mighty crescent
#

@umbral ledge usability data^

naive elk
#

man this task of simply drawing a 2d rect around 3d objects is not as simple as I thought

mighty crescent
#

It's super easy in immediate mode ui

umbral ledge
mighty crescent
umbral ledge
#

(I would implement it myself but my rendering skills aren't good enough)

umbral ledge
mighty crescent
#

This is more like having an immediate canvas api

umbral ledge
#

Hmm, okay

naive elk
#

well yeah I thought so, so I took Gizmos and tried that
but Gizmos is really weird, it doesn't want to play nice with my 2d screen coordinate. The game window is 3840 pixels wide, but the 2d rect gizmo is getting positioned at the edge of the screen as soon as it hits x=300, I just can't understand why, how to adjust it properly, ngghh

mighty crescent
#

You need to draw a rectangle that bounds a 3d object

mighty crescent
#

Basically eguis painter

#

Tbh, I would probably reach for egui here

naive elk
#

and mix egui with the rest of the ui being bevy ui? it's probably better than nothing, but..

mighty crescent
naive elk
#

hehe

#

I'll try moving those nodes to the root of the hierarchy.. hope it works this time
thanks

mighty crescent
#

Sorry it isn't easier

worthy vector
#

Is there a simple way to draw gizmos with big space? ๐Ÿค”

naive elk
#

you mean 3d gizmos?

mighty crescent
#

You can use globaltransforms like any other 3d gizmos?

#

See the debug plugin

worthy vector
#

oh hmmmmmmmmmm what the heck was I doing before...

#

My brain is fried sorry guys ๐Ÿ˜…

#

I should be asleep right now probably

naive elk
#

@mighty crescent now that I have hundreds or thousands of spaceships spawned, I wanted to ask about adding a Grid<i64> on each of them. Currently I do simply because my camera has GridCell and I want to easily reparent it between spaceships. But I don't actually need a grid, let alone an i64 grid on each spaceship. Would you say these QOL ship grids are inconsequential and don't really cost anything?

mighty crescent
#

There is a cost to propagation, but if it doesn't show up in a profile then I wouldn't worry about it

worthy vector
#

If the camera isn't far from its parent, you wouldn't need a grid though right? Propagation would cost about the same for low-precision hierarchies and high-precision

#

(well technically probably less for low-precision but probably sixes I'd think)

naive elk
#

like your planetary system got a grid, and a camera can live in that grid. then you want to attach it to a specific object within that grid, so that object ought to have a grid, otherwise BigSpace validator freaks out

#

so you'd need to remove/add camera gridcell depending on where you want the camera, which is um, whats the word, clunky

worthy vector
#

Course that still means all your grids need the same precision

#

If your solar system has a Grid<i64> but your spaceships have a Grid<i8>, you'll run into similar problems

naive elk
#

yep, that too

mighty crescent
#

There's no reason you can't move the floating origin to the ship itself, which is already in a grid.

mighty crescent
celest obsidian
#

๐Ÿ‘€๐Ÿ‘€๐Ÿ‘€๐Ÿ‘€

#

Which editor does this directory tree come from? It looks nice

mighty crescent
#

rustrover

#

I've been giving it a test drive again. Really like it.

celest obsidian
#

is everything running smoothly? I know I had some problem when I tested it a long time ago

mighty crescent
#

Yeah, it seems way, way better than the last few times I've used it. I think I might actually stick with it this time.

celest obsidian
#

interesting, I'll probably also try RustRover again to see if it suits me now

mighty crescent
#

Plus, you can add icons and colors to projects, which is clearly the most useful feature

worthy vector
#

Might have to give it another try myself

mighty crescent
# mighty crescent

I won't have much time to work on this today, but I did some investigation last night and this morning.

#

My plan is to add a physics simulation context entity that handles physics at a partition granularity.

#

This seems pretty easy to do with rapier, because it is built as a plain old rust struct that I can call a method on to step the simulation or update the simulation objects.

#

In a client server setup, the server would tell the client the location of all relevant physics contexts and entities for local prediction.

#

The physics contexts can all be simulated in parallel because they do not overlap.

#

Syncing the results between the two is an open question, but my plan is to let the physics context "own" entities, and update their position relative to the physics context's cell using just Transform, and let big space handle the position if it gets too large. Syncing positions from the ECS back into the physics simulation isn't something I've thought about too hard though.

mighty crescent
#

@celest obsidian @worthy vector any complaints if I change GridPrecision to a feature instead of a generic? At this point it just seems like a footgun to me, and isn't actually useful to have different grid precisions in the same binary.

#

All of those generics would disappear, and you would instead choose it with a feature. I'd probably use i64 as the default.

celest obsidian
#

Personally, I don't use multiple grid precision at once so moving from using generics to features is not a problem for me

mighty crescent
celest obsidian
#

Which grid precision I use? i64

#

I created type aliases to use this precision everywhere in my code

worthy vector
#

Also i64 is what I use as well. That seems a really good default to me

#

The only downside is that for people using multiple grid precision, they now have to use the highest common precision. Honestly doesn't seem like a horrible trade-off to me

mighty crescent
#

Yeah, and mixing precision is already going to cause bugs if you aren't being diligent.

#

Okay, thanks for the input!

worthy vector
#

๐Ÿซก

proper ingot
#

could do an odd overengineered version, with the exported Grid, etc being premade type aliases chosen by feature

#

that ends up sounding pretty simple, but the indirection might be odd

mighty crescent
#

Ended up with

#[cfg(feature = "i8")]
pub type GridPrecision = i8;
#[cfg(feature = "i16")]
pub type GridPrecision = i16;
#[cfg(feature = "i32")]
pub type GridPrecision = i32;
#[cfg(feature = "i64")]
pub type GridPrecision = i64;
#[cfg(feature = "i128")]
pub type GridPrecision = i128;
#[cfg(not(any(
    feature = "i8",
    feature = "i16",
    feature = "i32",
    feature = "i64",
    feature = "i128"
)))]
pub type GridPrecision = i64;

This seems to work better than using a default feature, because it means you can run with features=i8, and you don't need to disable default features. That also means the examples that rely on a certain precision can specify this, and have the same feature ergonomics.

#

Removes a ton of sigils, and reduces total line count. Big W.

prime bronze
#

Fairly new to big_space so forgive me if this is a silly question

#

If I have a grid precision of i16 and I wanted to make an area more precise and using multiple grid precisions is risky as you've mentioned. Should I change the grid precision globally?

#

Or thinking about it now, would I just make a smaller sub-grid?

#

Then that way I get more precision at the same grid precision

#

Is that how that works or am I misunderstanding

proper ingot
#

grid precision is how many grid cells there are, you want smaller cells
there's a pretty relevant example with increasing and decreasing -ly sized spheres

mighty crescent
prime bronze
#

Gotcha, makes sense, thanks!

prime bronze
shut cradle
mighty crescent
#

When there is a conflict, choose one feature over another. The cfg-if package can help with writing more complex cfg expressions.
This is an interesting idea.

#

I could nest the compile time features, so that the GridPrecision is the highest precision enabled. E.g. if you have i8 and i64 enabled, the GridPrecision will just be i64.

#

So it is "additive" in the sense that you can only add precision by adding features.

worthy vector
#

Simple solution: no features is i8. Then we add features x2, also_x2, another_x2 and last_x2. If you want i64, you enable three of the x2 features. If you only want i16, you only enable one of them. i128 you enable all 4 /j

shut cradle
shut cradle
mighty crescent
#
  • no features: i64
  • i8: i8
  • i8 + i32: i32
shut cradle
#

I'm personally not a fan of this, but there's also the possibility of doing what Rapier does; different crates for the different types

mighty crescent
#

As far as I can tell, it follows the "additive" model for features. If two crates need different levels of precision, you should use the maximum, and you can fulfil the needs of both.

#

Maybe instead of no features, i64 should be a default feature. That would be more idiomatic.

shut cradle
shut cradle
mighty crescent
#

Lots of compilation errors

#

I don't think it would be crazy to document that you need to select at least one precision to build.

#

Most users won't hit this, my impression is that turning off default features is usually reserved for people who want full control of the features/deps they turn on, and that often comes with understanding what is needed on a per-crate basis.

#

Going this route, adding a compile error macro with a note when no precision feature is enabled would be helpful.

#

hmmm

#

I guess the problem and the reason I avoided this was that if you add the crate and specify i32 or lower, it will end up using i64, which would be very confusing. So maybe default features really are harmful here.

shut cradle
white gate
#

@mighty crescent got a recommended route for using big_space on main bevy? Currently I'm thinking of just vendoring it solely to adjust the Cargo.toml and apply patches, which seems like the correct approach

mighty crescent
#

Ideally, make a branch of the crate and open a PR so others can use it, and we can use as a starting point for the next release

white gate
proper ingot
#

usually just means one of the systems has a non-SystemParam param

white gate
#

yea just a matter of "which??"

proper ingot
#

use a .chain() on each

white gate
#

found it, yippee

white gate
white gate
#

@mighty crescent boo, i'm back
is there a correct way to get the position of one object relative to a specific other object
(with the assumption that those objects are "relatively close" within the overall world space and as such the result is representable as Vec3)

#

(and I understand that this operation Can be very expensive if the two objects are very far apart in the hierarchy)

celest obsidian
#

What is "relatively close" for you? You could just take the two global transform and do the diff of the two translation. But if you mean a stable relative position I think you would have to do operations on grid transform

white gate
#

within a few hundred units tops is "relatively close" here
so yea ig the global xform should Just Work?

celest obsidian
#

I think so. For a few hundred units there will be no floating point precision errors in the difference of the two global translations

white gate
#

gotcha

prime bronze
#

Sorry for the ping, I'm saving this comment for later

naive elk
#

Do I understand it right that big_space comes with spatial hashing built in? So for collisions, you could just query for ships in your cell plus adjacent cells which you can easily get by manipulating the cell's coordinates I guess

#

btw, if you click on the trippy screenshot in the repo's readme, it gives 404 instead of loading a larger version of the image

#

and - uh oh - the link embeds a JWT

mighty crescent
#

that's just an image uploaded to gh... huh

naive elk
# mighty crescent that's just an image uploaded to gh... huh

idk, for me the image is a link that leads to https://private-user-images.githubusercontent.com/2632925/401431930-cff0c58e-766c-41a0-92f7-de174807e447.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE0ODE3NjksIm5iZiI6MTc0MTQ4MTQ2OSwicGF0aCI6Ii8yNjMyOTI1LzQwMTQzMTkzMC1jZmYwYzU4ZS03NjZjLTQxYTAtOTJmNy1kZTE3NDgwN2U0NDcucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDMwOSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAzMDlUMDA1MTA5WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9NzQ4ZTgzMjIyYzBkMTFmMWQ4NDRhMmQxN2RmOWIxY2EzZjFjYjY0OTU4NjRkZjQ1OGI4ZThmM2QxZGU1OTkyOSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.6y7X3xT1mT5pOerS3Yx5eEYS6qN4RU-eLv8Sfef_hVw and it gives 404

mighty crescent
#

I just re-uploaded

#

I have no idea how that even happened

naive elk
#

It's still roughly the same url, but now it loads, I'm guessing because the JWT isn't expired yet

#

gonna save it to local filesystem while I can ๐Ÿ˜…

#

Did big_space use to have a type called BigPosition? I wasn't able to find it in docs, including going through some older docs, but both ChatGPT and Claude keep conjuring that type up like it's a real thing.

#
use big_space::{BigPosition, BigVec3, CellManager};

very bizarre

mighty crescent
#

Nope

naive elk
#

so weird.. why would they hallucinate the exact same thing, and not hallucinate for anything else I've been querying them for. oh well

prime bronze
#

I'm guessing they can't because "grid" is in the name, but can grids and gridcells be shapes other than cuboids?

#

Like if we have a planet, can we make a gridcell a sphere that's slightly bigger than the planet?

#

I'd like to use it as faux collision mesh of sorts so I can query for all entities within the planet's atmosphere

mighty crescent
#

If you made the gridcell the size of the planet, you would lose the entire advantage of cells in the first place.

prime bronze
#

Perhaps I'm using the wrong term

white gate
#

@mighty crescent so when working with the lib, does every parent in the hierarchy need to be a Grid or is having low-precision parents acceptable

mighty crescent
#

Only if you want it to be high precision.

#

Otherwise it is a normal bevy 32bit hierarchy

naive elk
#

which makes camera clunky to reparent.. say if you wanted to attach it to different planets, objects in space. all these objects will have to have their own Grid on them

#

unless I'm missing a simpler solution

mighty crescent
#

If you are reparenting, then you already need to recompute your transforms.

naive elk
#

not sure what you mean by that? I'm mostly referring to the semantic mismatch: you create grids when you want nested space. Adding grids everywhere just for the ease of reparenting your camera easily feels like going against what the Grid component was designed for. maybe I'm wrong

worn nebula
#

(The use case here is a simple "spawn a new entity at position of another entity without assuming that entity is GridCell")

mighty crescent
#

You need to compute your new component values anyway depending on your new parent, so it shouldn't be any more onerous to also decide what to set the cell to. If the parent has no grid, the cell shouldn't (?) do anything.

naive elk
#

so I just put Grid on everything I want my camera to be able to teleport to, even if I don't really need any precision subspace

#

just to satisfy the validator

#

it's not a big deal I guess, just feels hacky

mighty crescent
#

Sounds like a bug in the validator then.

#

The validator is just a linting tool though.

#

It's not required or anything like that.

#

It should probably be a warning though. If you have a cell on an entity not in a grid, 99% of the time it really is a mistake that needs correcting.

naive elk
#

that's an interesting point

#

maybe tweak the validator (give it a param?) to ignore these checks/warns for entities with a Camera on them

#

or is camera required to be under a grid parent because it's a floating origin?

mighty crescent
#

The floating origin is whatever entity has that component

#

And that definitely needs to be a child of a grid.

prime bronze
#

Is there a visual representation of how the big space, grid, entity hierarchy looks? I've been reading the docs but I'm struggling to get it to stick

proper ingot
#

grid
\- gridcell (0,1,0)
\- transform
\- gridcell (2,3,4)
\- other transform
\- nested grid, also with transform
then entities are moved between gridcells when one of their transform's translation coordinates exceeds some absolute value

#

the gif on the crate's main pages shows two entities, one moving, in gridcells on a grid

mighty crescent
#

High precision only. If an entity has a GridCell it must have a parent Grid:

(BigSpace, Grid)
  (GridCell, Transform)
  (GridCell, Transform, Grid)
    (GridCell, Transform)
    (GridCell, Transform, Grid)

You can add low precision Transform-only hierarchies wherever

(BigSpace, Grid)
  (GridCell, Transform)
  (Transform)
    (Transform)
  (GridCell, Transform, Grid)
    (GridCell, Transform)
      (Transform)
        (Transform)
    (GridCell, Transform, Grid)
#

tbh, for most cases, you probably don't need to nest grids, you can keep it really simple and use only Transform after the first level:

(BigSpace, Grid)
  (GridCell, Transform)
  (GridCell, Transform)
    (Transform)
    (Transform)
  (GridCell, Transform)
    (Transform)
      (Transform)
  (GridCell, Transform)
proper ingot
#

yeah that's way better than mine

prime bronze
#

What would be an example of a case where you would nest grids? Like if you had a "grounded"-like game where you want to shrink to really small in an area?

#

I saw someone mentioning having a spaceship you can go inside having its own grid within the parent solar system or galaxy grid

#

But I don't know if that was because it was nice to have or if it was needed for precision

mighty crescent
#

For the space ship example, unless the ship is huge, you can just use normal Transforms.

#

The only time you need to reach for a grid is if the x/y/z coordinates become very large in your current reference frame.

#

If you are on a ship, you will likely always be within ~100 meters from the center of the ship, so the 32 bit Transform is just fine. If you are on an earth-sized planet, you will be 6,000,000 meters from the center of the planet, and Transform alone will not give you enough precision.

prime bronze
#

That makes more sense then

#

So in my example I would have a grid for the "galaxy", then a grid inside of that for the solar system, then a grid inside of that for the star and planets

mighty crescent
#

Sure

prime bronze
#

Then when a person walks on the planet they would need a gridcell

#

As it'll need high precision

mighty crescent
#

yup

prime bronze
#

Ok that's starting to make sense now

mighty crescent
#

You can also flatten the hierarchy and have everything in the same grid.

#

But nesting grids makes it easy to move all entities inside that grid as one.

prime bronze
#

Right, so in that case I'd just need to make sure I was using a high enough precision right?

#

For the one grid

mighty crescent
#

Yup

#

If you are using i128 there is going to be more precision than you could ever possibly use

prime bronze
#

Yeah, I think the highest I'd ever go is i64

#

Appreciate you taking the time to clear that up for me! Thank you!

prime bronze
#

Is there an example that sets up the big_space hierarchy without using the helper methods? I'm trying to add entites in separate functions but I'm unable to query for the root grid for some reason

proper ingot
#

probably just insert a gridcell and set the parent to a grid

#

and the root grid might have to have BigSpace on it manually

mighty crescent
#

Yup. Same as normal bevy parenting really.

prime bronze
#

Ok then I should have that setup correctly. I'm just unable to query for the root grid/big space entity inside a system

#

I'll keep trying

#

Even when I put a normal custom component and query normally it's complaining

#

Thought it was working, was just giving me a complier error before the runtime panic from single

#

Ran it with query instead of single and it says 0 found

prime bronze
#

With the new Requires component system in .15, should the BigSpace component require GlobalTransform?

#

Ok I've figured it out and it's just me being dumb. Ignore me!

proper ingot
#

what was it, specifically?

prime bronze
#

I was creating the BigSpace in a Startup system and querying for it in a different Startup system

#

Which meant it didn't exist when querying as they were either running in parallel or running in inconsistent ordering

#

I've moved the BigSpace Startup system to PreStartup and the queries are running smoothly now

mighty crescent
#

You need to make sure your systems are ordered relative to each other. Commands are applied at sync points between systems.

prime bronze
#

Yeah, rookie mistake I know

#

Usually I'm better than that haha

naive elk
#

I think maybe at real-scale distances the point lights aren't working properly. The light range and falloff seem perfect, but objects seem to have trouble obstructing that light, for example if my spaceship is behind a planet that's blocking the sun, the spaceship will still reflect light instead of being in total dark. I was told this may be how shadows behave. Is there a common solution to how to deal with that at bigspace distances?

#

Directional light doesn't seem like a good fit at all, because it doesn't have the falloff

white gate
#

at these scales no commodity lighting engine is going to work ootb, you need to be a little clearer to the engine about what you want

naive elk
#

I just watched an explanation on how shadows work and I think JoshValjosh was right - it's the limitation of shadow mapping. The obstructing object isn't even visible on the depth map. How would directional light help with that?

#

Sounds like CSM or PSSM is a solution

worthy vector
#

I'm curious what will end up working. I've thought of a could different solutions, and they either turned out not to work or else I don't much like them.

prime bronze
#

How are people handling textures on planet sized models?

#

Procedurally generated simple textures?

white gate
#

anything large enough to cast a shadow at planetary scales is large enough said shadow can be approximated as something infinitely long

#

(note: you probably need something more clever for multiple shadowcasting bodies, but the fact it has to be done manually stands)

mighty crescent
#

And computing the values for intensity manually

white gate
#

(physically dividing the space with a plane or approximation of the body curve that shades everything 'below' it in depth might do it)

mighty crescent
#

Shadows work using that method.

#

At planetary distances, the sun is a directional light, and isnt going to suffer from the precision or perf issues of a massive point light

#

You will probably need one directional light per star-planet pair in the current system, and use render layers.

naive elk
#

Interesting, thanks

prime bronze
#

Anyone have any idea what the best way to pass the cellgrid offset and precision type to a vertex shader is?
Getting the above on my materials, whether it's a standard material with a texture or a vertex shader

#

Seems to be due to the planet sized mesh, as there's no issue when I test on a 100m diameter mesh, so I think I'm going to have to break up my mesh into a bunch of smaller meshes, which is probably a good decision anyway if I wanted to use meshlets

#

But I was hoping to avoid splitting the mesh and somehow find a way to keep the mesh whole

worthy vector
#

Also just wanted to pop in to say that it's wild that bevy is flexible enough that a 3rd-party lib can completely replace its transform system and have most everything "just work"

mighty crescent
mighty crescent
prime bronze
prime bronze
prime bronze
mighty crescent
#

You need a terrain system. ๐Ÿ™‚

#

Some other people in this chat have posted some WIP terrain systems with big_space, to give you some ideas.

prime bronze
#

I've taken a look at a few already, one of them was by @worthy vector
I'll take another look to see if I'm missing something, but I believe they aren't suitable for what I'm currently building

#

Hopefully I'm wrong and this can easily sort my problem

mighty crescent
#

and the one I think you are referring to: #showcase message

prime bronze
#

I'm testing decreasing the mesh count and I arrive back at the wobbly vertices

#

I'll go back over the terrain systems more in-depth in case I'm missing something, but for context, even with the 10M meshes I had before each one was 1km squared

celest obsidian
#

๐Ÿ˜ฑ you need LOD

prime bronze
#

I could probably live with the wobbly meshes far away (it's not noticeable beyond a few hundred meters) and just heavily implement LODs

#

Yeah I know, but each mesh is only 12 vertices (basically cubes)

celest obsidian
#

you had 10M 1km squared meshes?

prime bronze
#

Yeah, it handles it really well, compared to not handling it at all, which is what I expected

prime bronze
#

I think I'll need to look into how spheres and other basic shapes can be vertex perfect even at large sizes Then that way I can go back to a small number of meshes

worthy vector
#

I think the problem is just that Bevy's Mesh uses f32 for vertices. That means with a small number of meshes, many vertices will be very far from the Mesh origin and start to lose precision

prime bronze
#

Yep!

#

It's going to be a balancing act getting this right

proper ingot
worthy vector
#

We all want to know what you're doing that precludes dynamic lod! ๐Ÿ˜…

#

If you can't do dynamic lods, it's worth noting that trying to pick a mesh size that has "good enough" precision but also big enough to keep memory usage down will eventually run into issues with larger and larger planets: your memory usage will go up with the square of the planet radius. A super-earth would use up substantially more memory. By contrast, the dynamic lod scheme increases memory usage linearly as you approach the planet. That means I can actually do almost arbitrarily-sized planets: a planet the radius of the solar system subdivided down to sub-meter polygons will use on average double the memory of an earth-sized planet at the same resolution when viewed from the surface.

#

No lods and your memory usage goes up by a factor of 1 trillion

#

-# not that you'd want planets that big but... just something to keep in mind

mighty crescent
#

I've been making some very slow, incremental progress on physics.

#

It's going to be pretty barebones, but I need to focus on the basics to test the core ideas.

#

It's turning into an ECS wrapper + physics backend trait. I'm implementing the physics trait with rapier to start, because it works standalone, unlike avian. I'm not certain how an avian integration would work, but the trait means you can theoretically add any physics backend you want (e.g. jolt, physx, havok, etc).

#

Oh interesting, went to look at physx, and this is pretty close to the model I'm using for big space physics contexts:

#

(in very broad strokes)

#

From playing with rapier, it seems like rapier is internally doing a bunch of DoD/ECS-y stuff, so it's probably very similar to if an avian physics context was just avian running in its own little World.

full magnet
#

(Curse markdown and the underscore in no_std)

mighty crescent
#

Big space on the Gameboy, here we come

full magnet
full magnet
mighty crescent
#

Just one more nostd bro

#

Just one more bro

mighty crescent
full magnet
#

Yeah it's probably impractical to merge as a single big PR

mighty crescent
#

Also, I'm going to be forever salty about Parent -> ChildOf

full magnet
#

Yeah I preferred Parent too. Could just type alias it lol

mighty crescent
#

I an seriously considering it for this crate especially

#

I need to query for the child and... childof of this entity

#

C'est la vie

full magnet
#

The only "real" change I had to make (aside from general 0.16 migrations) was just making a singlethreaded alternative to GridHash::update because bevy_utils::Parallel is a thread-local and that just doesn't exist outside std

naive elk
#

Speaking of naming, just sharing my 2ยข ... With Bigspace there are three different transforms now: Transform, GlobalTransform, GridTransform. If you like reflecting that in var names to avoid confusion you'll be perplexed that the latter two abbreviate to the same "gt" acronym. But, looking at GridTransform, it's made of Cell + Transform, so it kinda makes sense to call it CellTransform instead. Which is what I'm type aliasing to, which makes for very nice disambiguated var names, especially if you're querying for both GlobalTransform and GridTransform: foo_t, foo_gt, foo_ct as opposed to foo_gt and foo_gt (???).

Probably doesn't bother anyone else though. ๐Ÿ˜… But, type aliases are sure nice.

naive elk
#

Weird. Just noticed the camera's global rotation quat stays the same no matter how I rotate the parent the camera is attached to. Is that how it's supposed to be under Bigspace?

mighty crescent
#

Is the camera the floating origin?

#

I would expect the cameras global transform would not be affected by rotating the parent in that case. The parent grid is the relative root of the hierarchy - it defines what the root coordinate system is for the purposes of computing global transforms.

#

Like, let's say your floating origin camera is on a ship, moving through space. That ship is now the root coordinate system, it doesn't matter what rotation your ship has, or the rotation of the planet the ship is on. The ship is the fixed reference frame for the entire universe, and global transforms are computed relative to it.

#

If that wasn't the case, nested reference frames would accumulate error.

naive elk
#

Can't say I truly understood the reasoning in all its details, but I'll just remember that this is normal, thanks.

#

This seems to work, but I was wondering if there's an easier way? Or is that idiomatic enough:

pub fn camera_global_orientation(
    ship_camera: Single<(Entity, &Transform), (With<PilotingShipCamera>)>,
    ancestors: Query<&Parent>,
    transforms: Query<&Transform>,
) {
    let (camera_id, camera_t) = ship_camera.into_inner();

    let mut camera_hierarchy = SmallVec::<[Quat; 4]>::new();
    camera_hierarchy.push(camera_t.rotation);
    for entity_id in ancestors.iter_ancestors(camera_id) {
        if let Ok(ancestor_t) = transforms.get(entity_id) {
            camera_hierarchy.push(ancestor_t.rotation);
        }
    }
    camera_hierarchy.reverse();

    // Find out camera's global transform orientation by multiplying quaternions
    // for each transform in the entity hierarchy. The order should be from the root
    // to the camera (leaf).
    let camera_gt_orientation = camera_hierarchy.into_iter().reduce(|acc, quat| acc * quat).unwrap();

    // TODO now do something with the real camera's orientation
}
#

Feels like I'm reinventing the wheel and this function must exist somewhere already

mighty crescent
#

What are you trying to accomplish?

mighty crescent
naive elk
mighty crescent
naive elk
#

That object is part of the UI render layer with its own camera. So, the UI object syncs with the main 3d world camera.

mighty crescent
#

What do you mean by "sync" here? Is there some reason you can't look at the GlobalTransform of the things you want to show in the UI?

#

e.g. if you want the orientation of the ship in its reference frame, take the difference of the two transforms

#

or in any reference frame

naive elk
#

In the UI layer, I have a sphere (a minimap basically) onto which I project the surrounding objects/spaceships. I want that sphere to rotate along with my main world camera, to align the cockpit view direction with the minimap direction.

mighty crescent
#

Yeah, then I would look at the difference of the two globaltransforms you care about, that way you aren't trying to replicate transform propagation yourself.

naive elk
#

Bear with me here, I'm slow lol. Between which two globaltransforms? Give an example?

mighty crescent
#

Transforms are just a way to map between reference frames, right?

#

So, to go from the root to the ship's origin, you apply the ships transform.

#

To get to the players origin on the ship, you apply the players transform relative to the ship

#

etc etc

#

The global transform is absolute. This plugin (and bevy's) do all that relative transformation for you to compute the position of all entities in the root reference frame.

#

In the case of this plugin, the global reference frame is the grid the floating origin is located in

#

This maximizes precision, because all transforms are computed outward from that point

#

But, the GlobalTransform for all entities is in the same reference frame, regardless, that is the important bit

#

That is why rendering works, you can directly compare all entities by looking at their GlobalTransform, you don't need to worry about hierarchy or anything, that has been handled for you

#

So, if you are trying to draw a minimap, the question is, what is your frame of reference for the minimap?

#

If you can answer that, you can apply the inverse of this "static" reference frame to any GlobalTransform, and you will know its position relative to that reference frame (the minimap)

naive elk
#

The center of the minimap is my spaceship

#

The camera sits on the spaceship, fixed, immovable. I turn the ship, and the camera turns as well.

#

And I just need to orient the minimap into the same direction that the camera is looking in

#

But the camera doesn't update its gt.rotation() at all .. which is where I'm lost in the explanations

mighty crescent
#

if the minimap's reference frame is the spaceship, and the camera rotates with the spaceship, then how can your minimap rotate?

#

You just said they are fixed relative to each other

#

So, what is "north" on the minimap, if not the spaceship's forward direction?

#

It sounds like it is actually the reference frame that the ship itself is located in

naive elk
#

So, the camera is always looking into some direction in the world space, right? Doesn't matter what makes the camera turn - either it's the camera's own transform that's changed, or its parent's (spaceship's).

The minimap sphere, if it's fixed, then when the ship turns, so must the ship in the middle of it. That's called "no minimap rotation". Usually games also have the other mode, where the ship (player) in the middle of the minimap always looks up, and it's the minimap itself that rotates around the player. Which is what I'm doing.

Makes sense that way?

mighty crescent
#

the world space, right?
This is what I'm getting at - what is "world space"?

#

The reference frame that your map measures. It's probably the grid that your ship sits in.

#

Not the ship itself.

#

And the map rotation is the difference beetween that grid's orientation and you cameras.

#

Even if your camera orientation is zero/identity, the orientation of this "world" reference frame will not be.

#

The minimap sphere, if it's fixed, then when the ship turns, so must the ship in the middle of it. That's called "no minimap rotation". Usually games also have the other mode, where the ship (player) in the middle of the minimap always looks up, and it's the minimap itself that rotates around the player. Which is what I'm doing.
You do this by picking your reference frame (ship reference frame vs space reference frame) and you compute the position of all objects on the map relative to that reference frame.

naive elk
#

Like, Sun?

mighty crescent
#

Again, all that you need to do for this is to take the object you are projecting, and apply the inverse transform of the reference frame you want to be in.

#

This transforms the object into that reference frame.

#

If your map projection is a sphere, you then project those transformed objects onto the sphere

#

But you need to make sure you are computing their position in the correct reference frame first

#

I can make an example, I'm not sure when I will have time though.

naive elk
#

I feel like I'm missing some fundamental understanding, after which it'll auto-click. Maybe I need to think some more. Appreciate the explanation.

#

Without Bigspace, the reference frame would be the origin. With Bigspace, it has to be a spawned object or otherwise chosen coordinates. A local star like Sun would work, right?

mighty crescent
#

it should be something like

// some awful psuedocode
let map_reference_frame: GlobalTransform = sun; // can be any object
let gt_to_map_frame = map_reference_frame.inverse();

// compute position of all map objects relative to the map reference frame
for object_pos in map_objects {
    let map_pos = object_pos * gt_to_map_frame;
    // you now have the position of the object relative to your chosen map reference frame
    let sphere_pos = map_pos.translation().normalize(); //idk haven't thought about this one too hard
}
mighty crescent
#

But it doesn't matter what is used as the reference frame, because GlobalTransforms are in the same reference frame (the "global" part), you can compare them directly.

#

To reiterate this point, that is why I always say "use GlobalTransform". It doesn't matter how that GT is being produced, it will work in bevy or big space. That's why rendering works, it uses GT. All the magic big space is doing, all of that amounts to the same GT at the end of the day, but in the case of big space, it is making sure that GT has maximum precision near the floating origin, that's it.

naive elk
#

How can the floating origin camera not have a global orientation? Sorry I don't get it. When I turn the camera (via turning its parent), it is turning.

#

I can see the world shifting in my view!

mighty crescent
#

The world is shifting around you

#

because you are the global reference frame/orientation in this case

#

the floating origin, is, well, the origin of the coordinate system.

naive elk
#

hehe yeah

#

oh man, this is heavy

mighty crescent
#

(technically, the origin is the cell the floating origin is inside)

#

It's really, really, easy to overcomplicate this in your head, because there is no fixed global reference frame. That's why I'm constantly suggesting people use the GT, because then the complexity of big space (mostly) dissolves away.

#

It's also why rendering works! it doesn't care what the root reference frame is, it just computes the position of everything relative to the camera! It's the same exact concept. In the case of rendering, it chooses the camera to be the reference frame it cares about, because it wants to project everythign onto your screen.

naive elk
#

sounds like I should align my visual 3d grid on the minimap sphere with Sun's axes .. and that would be the reference frame. And the player would see the grid rotating as the camera is turning, which is kinda important for the vibe

#

ok I don't know how many hours you just saved me, but thanks ๐Ÿ˜„

mighty crescent
#

The minimap is actually a really great example case I should write, and would really help if you had more rendering familiarity, I'm guessing. It's pretty much identical to the concept of the view transform in rendering.

#

Drawing a map is just transforming things into a particular reference frame.

naive elk
#

Just to clarify: each GridCell has an xyz. These coordinates are static inside of a Grid, right? Therefore, they can be used as reference frames. Meaning, I don't necessarily need to spawn Sun in a random location and then use that as reference to spawn the rest of the objects around it. And "north" can be .. Grid's (GridCell's) Y or something?

#

Or is that exactly what you're discouraging from

proper ingot
#

doesn't seem easy to get a vec3 from a gridcell directly

#

if you wanted to do a spherical minimap without globaltransforms, you'd probably have to loop through everything in a different gridcell and add the difference between the two gridcells to some kind of cached transform
then to make it simpler, you might as well just compute that for everything
oh hey, that's globaltransform

mighty crescent
#

Not sure I'm understanding the question.

naive elk
# proper ingot if you wanted to do a spherical minimap without globaltransforms, you'd probably...

No, I understand, I love globaltransform, it's my friend. I only have trouble with figuring out what my camera is looking at, because its globaltransform is toast due to Bigspace. It's not about the location of the camera in space, it's about how it's oriented in space. Yes, it's always 0,0,0 (not always because the origin is actually the cell, yes). But it's looking at some specific thing in space. What is that thing in the middle of my screen? Because I want to make another arbitrary 3d object also look (be oriented) at the same thing.

If there were no Bigspace, I'd take my camera's gt.rotation() and that would be it. But this doesn't work with Bigspace, the cam's rotation is fixed in place, and as Aevyrie put it, instead the world rotates around the camera. That's all fine, but it doesn't help me understand my camera's orientation.

And Aevyrie tried best to explain something very important about all this with reference frames, but I haven't digested that yet.

I still don't understand why my "figure out GT" approach is wrong. Doesn't it show correct data? If it doesn't, why? If it does, why is it wrong? And the answer seems to be "because you don't need to compute your own gt, just take any other one to do the same thing" - but this is where I think I still don't get it conceptually. Say, I take the Sun's gt. How would that help me understand where my camera is oriented at? In code, I don't even know if the Sun is in front of the camera or behind it or what. It's not about translation, it's about camera's orientation. I don't need the Sun's orientation, I need my camera's. And my camera's orientation is apparently non-existent and it's driving me nuts lol.

Like, how do I know where the Sun is even thought I'm always at 0,0,0? Easy! Just take Sun's gt.translate. But the same logic doesn't apply to my camera's orientation, whenever the world is "shifting around me instead". Or if it does, I don't see how.

proper ingot
#

well, you can get orientation with just the camera's local Transform

#

assuming it's a direct child of the grid

naive elk
#

Ah-ha! That's the thing! The camera's local transform is immutable basically, because it sits on the spaceship, with fixed translate and orientation. I turn the camera by turning the ship.

proper ingot
#

then get the ship's local transform's rotation

naive elk
#

Or is that not the same thing

#

Wait, did I just need to take my camera's parent local transform all this time, without going all the way up the hierarchy?

proper ingot
#

probably
whichever is the moving part you're actually accounting for

naive elk
#

I'm just thinking, what if the ship gets a parent. Like... a mothership. For gameplay reasons. I'll need the full hierarchy then, no?

proper ingot
#

well who's got the minimap on them?

naive elk
#

I got on me

proper ingot
#

๐ŸŽถ i got that minimap on me

naive elk
#

When I created the minimap mesh, suppose I put a visual indicator for one side of it (the "north"). I want that north to always be pointing the exact same direction as the player is looking at in the "real" world.

proper ingot
#

if globaltransform rotates, isn't that just -z

naive elk
#

So if my spaceship is child of a mothership and my main 3d camera is looking at Sun, I want the minimap's north to be also pointing at the sun

naive elk
# proper ingot if globaltransform rotates, isn't that just -z

Two very disturbing questions about that statement:

  1. Whose globaltransform? The player's main camera doesn't have one, because it's the floating origin.
  2. What does it mean "just -z"? Sorry I'm a noob at spatial math. Aren't rotations expressed as either Euler angles or quaternion multiplications?
proper ingot
#

the minimap's viewpoint, and its z coordinate

#

direction, rather than rotation, is what i was saying

naive elk
#

What do you mean? The minimap's coordinates are fixed, it only rotates

proper ingot
#

to be clear my interpretation is "fixed minimap, with moving pointer for your look direction"

#

you might've meant the opposite

naive elk
#

I need to figure out how to make these short videos of a portion of the screen for a short demo.

proper ingot
#

obs vkcapture + ffmpeg works pretty well for me

naive elk
#

Sorry for the size, I don't have anything fancy set up.

mighty crescent
# naive elk No, I understand, I love globaltransform, it's my friend. I only have trouble wi...

To try and restate what I was saying earlier.

If there were no Bigspace, I'd take my camera's gt.rotation() and that would be it.

This works if your map's reference frame is the root in bevy, which has a GT == identity. Applying the inverse to objects to transform them into this space does nothing, so you can just omit it entirely, this is a special case.

If you want to use any other reference frame for your map (a mothership, a planet, etc), or use big_space, you need to do that inverse, always. But it works everywhere, including using stock bevy and the root of the hierarchy.

naive elk
#

You see how the minimap aligns itself?

mighty crescent
#

This would probably be 100x clearer in code. I'll try to make something when I have time. This weekend, if I'm lucky.

#

But I know exactly what you are trying to achieve.

#

The elite dangerous minimap, pretty much

naive elk
#

In the sense that you're in the middle of it, and the objects around you in the cockpit space and also around you on the minimap, yes. But I don't remember how exactly ED shows it. You might be right.

mighty crescent
#

I might be misremembeering too, lol

naive elk
#

And so, rendering surrounding objects on that map is not a problem. The problem was figuring out how to rotate the map in sync with the 0,0,0 FO player camera.

mighty crescent
#

You want the map to rotate so the orientation matches the way the camera is facing, and the map should always be centered on the camera

#

right?

#

(like a compass)

naive elk
#

You want the map to rotate so the orientation matches the way the camera is facing,
Exactly.

and the map should always be centered on the camera
Yep.

mighty crescent
#

And the fixed reference frame is the grid that the ship/camera are in?

naive elk
#

Yes

mighty crescent
#

e.g. the grid spins/translates underneath the static ship

naive elk
#

tbh I'm still not sure how the grid underneath it all works, I'm blanking at that

mighty crescent
#

I would imagine it should match the grid you are flying through

#

so if you drew the grid in 3d space around the ship, it should match

naive elk
#

Yeah, that's a good way to put it. But I didn't use that in my explanations because like I said, it's still a blank space in my head how the parent Grid works

naive elk
naive elk
mighty crescent
#

Of the globaltransform, yeah. Though, that could lead to some nasty floting point precision issues if it is far away, so you might be forced to do some grid math.

naive elk
mighty crescent
mighty crescent
#

idk, at some point I need to write the code, it's a bit hard to discuss the details with words lel

#

It's probable that I am also missing something or there is a gap in the API for this use case.

naive elk
#

๐Ÿ™ I'd appreciate you giving it a conceptual review

mighty crescent
#

I think you should be able to do

map_orientation = (camera_gt * grid_gt.inverse()).rotation()
#

my brain is a terrible IDE though

naive elk
#

grid_gt.rotation().inverse() probably

#

there's no inverse() on GT

mighty crescent
#

you would need to get the affine/mat4 inside the gt iirc

#

but dealing with the rotations alone should work

#
map_orientation = camera_gt.rotation() * grid_gt.rotation().inverse();
#

I can never remember quat/mat multiplication though

naive elk
#

Thanks, I'll try that.

Btw, while the topic's hot, something I wanted to ask for a long time. If working directly with two gts is too erroneous due to large distances, is it fair to take GridCells of those objects instead? Or even GridTransformOwned for which std::ops are also implemented and work with that? Like subtract them etc, like two vec3s.

mighty crescent
#

yeah, that's totally valid

naive elk
#

wow that's awesome

#

I wasn't sure

mighty crescent
#

only issue is it only works if they are both in the same grid, but that's no different than trying to do math ops on Transforms

naive elk
#

yeah yeah that goes without saying, same grid

#

that's super handy

mighty crescent
#

You are free to modify or do math with the (GridCell, Transform) pair. Big space will renormalize it every frame.

naive elk
#

๐ŸŽ‰

naive elk
#

That doesn't seem to do anything, the minimap (tacsphere) is locked in place no matter what.

pub fn sync_sphere_to_camera(
    ship_camera: Single<(Entity, &GlobalTransform), With<PilotingShipCamera>>,
    grid_gts: Query<&GlobalTransform, With<Grid<GP>>>,
    grids: Grids<GP>,
    mut tacsphere: Single<&mut Transform, With<Tacsphere>>,
) {
    let (camera_id, camera_gt) = ship_camera.into_inner();
    let mut tacsphere_t = tacsphere.into_inner();

    let grid_id = grids.parent_grid_entity(camera_id).unwrap();
    let grid_gt = grid_gts.get(grid_id).unwrap();

    let camera_gt_rotate = camera_gt.rotation() * grid_gt.rotation().inverse();

    tacsphere_t.rotation = camera_gt_rotate;
}
#

The camera's parent Grid in this case is the spaceship's Grid (which has to exist on the spaceship, otherwise a FO camera doesn't want to be there saying it has to be under a Grid directly).

And the spaceship itself is under the Sun's Grid.

It's Bigspace standard stuff -> Sun (Grid) -> Spaceship (Grid) -> Camera.

proper ingot
#

you could put the FO on the ship directly

naive elk
#

True, but that would make switching camera to other objects clunky I imagine. Like when you want to temporarily "look at" some object other than your space ship, up close. Maybe an enemy or a planet or some other object.

#

Idk maybe the camera wasn't designed for how I'm trying to use it. I parent it to whatever thing I want to look at.

proper ingot
#

my system's set up for siblings, copies the transform and modifies it instead of trying to compensate for character rotation

naive elk
#

Thought I found a really cool-sounding name for the minimap: Tactical Sphere, aka tacsphere in the code. I was happy right until the moment I realized TacphereObject abbreviates into taco, and now the code's all in tacos...

proper ingot
#

-# extremely dirty, but

fn apply_camera_transform(
   habit: Single<&Transform, With<crate::player::Inhabited>>,
   camera: Single<
       (&mut Transform, &ForwardFromCamera, &CameraControl),
       (
           With<crate::player::Inhabitor>,
           Without<crate::player::Inhabited>,
       ),
   >,
) {
   let player_transform = habit.into_inner();
   let (mut transform, ffc, opts) = camera.into_inner();

   let pos = player_transform.translation.adjust_precision()
       + opts.fade * opts.height * ffc.up
       + opts.fade * opts.back * -ffc.forward;
   *transform = (&*ffc).into();
   transform.translation = pos.f32();
   let pitch_axis = transform.left().adjust_precision();
   transform.rotate_around(
       pos.f32(),
       Quaternion::from_axis_angle(pitch_axis, ffc.pitch_angle).f32(),
   );
   let back = (opts.back_rel * opts.fade) as f32 * -transform.forward();
   transform.translation += back;
}
#

kind of a body/soul dichotomy thing, since the 'habit' can be destroyed or swapped to another entity

mighty crescent
proper ingot
#

can probably justify it in lore: the viewscreen is concave and uses a mirror hologram to project the map

naive elk
#

What's really cool is once you've got hard sci-fi constraints going on, game mechanics crystallize all by themselves. You don't make up arbitrary things like in Everspace (even though it's fun), or in EVE Online (which is also fun). But idk, when I see spaceships warping into an arbitrary point in space, it immediately breaks immersion because warp bombing. And why does all body contact lead to "bumping" instead of destruction? So yeah, I spent a long time on the design part to avoid things like that. Could almost forget about the game and just write a book instead it feels like. ...but I'm getting carried away.

proper ingot
#

imo, the arbitrary point in space repels from gravity wells and is highly telegraphed

#

kronchy ships my beloved

worthy vector
#

I wanted to make a hard sci fi expanse-like game, but it ended up being kinda... difficult. Still working on it but it turned out to be much easier to turn into a DnD campaign

#

(reminded me because you said you should just write a book)

naive elk
# worthy vector Someone's been on projectrho.com

Idk what that is, but this was funny: "This site started out as a small sheet of equations I wrote in 1997", because "1997" is exactly what I thought by looking at the design. Like time travel, that's how web was 25 years ago. ๐Ÿ˜… Nostalgia

proper ingot
naive elk
mighty crescent
#

(it's me, I am that nerd)

worthy vector
# naive elk Ugh, can't create a thread here... quick question then to avoid heavy offtopicki...

Difficult deciding what kind of game I wanted it to be. I like first person games with a lot of action, but I also wanted the turbo realism. It's still in the works, but very much a fantasy project. Basically it's an MMO with realistic physics (besides warp travel and torch drives), and the goal is player-driven everything: no in-game economy or government, procedural infinite tech tree, voxel ships, procedural 1:1 galaxy. Part of it is already built out, mostly the backend, and the thing I'm most proud of is that the location of every object is computed from static parameters: rather than ticking the position of every ship every frame, I store data like "departed from X station for Y destination at Z time on W trajectory". The backend schedules an update that fires at the calculated arrival time to update the ship's position to "at Y". This way I can persist large numbers of ships without using much processing power

#

-# That was a bit more than the answer you wanted

naive elk
#

procedural 1:1 galaxy
๐Ÿซ 

worthy vector
proper ingot
#

galactic dwarf fortress you say?

naive elk
#

Sounds like a lot. Might even suspect Chris Roberts behind the account name!

proper ingot
#

(pronounced with a long 'o')

worthy vector
#

Making everything player-driven removes the need for me to make content ๐Ÿ˜‚ except the procgen. But I'm already partway there haha

#

Anyway there's a reason this is a fantasy project

#

I don't put a whole lot of time towards it, just when I need a break from my more realistic projects

proper ingot
#

why put the granularity at 'individual point-to-point trip'?

naive elk
#

Torch drives are interesting. They're a great story element. Because low-level tech nations should ban them, since they're basically the most powerful weapons ever, and if you want your station to accept torch drive ships for docking, you either gotta believe in reincarnation or be on a tech level where your station can shrug off an accidental 100km plasma exhaust.

worthy vector
worthy vector
naive elk
#

Nooo

proper ingot
#

'on x schedule from y time with z complication'

#

or wider, but that's the easiest *difference

naive elk
#

The only thing I hand-w..woven? Waved? Was the new physics field that allows for Mach Effect Thruster drives to meaningfully operate and allow for the Lentz soliton.

worthy vector
# naive elk Nooo

"Our ships have neutrino drives. We figured out how to emit neutrinos in a single direction. Most of them don't interact with anything so the exhaust is not dangerous, but we still get all the momentum from firing them off"

proper ingot
#

wimp drive

mighty crescent
#

When I started this lib, I was playing with the idea of a game entirely based on interplanetary travel. KSP's flight planning and execution is really fun, so I thought, what if route planning itself was something you could build a multiplayer experience around? Part of the idea was to make the timewarp part of the route planning mechanic, instead of a problem for multiplayer, it becomes a feature.

#

Depending on your route and distance to bodies, you could find more optimal routes by getting clever with your route planning to maximize the amount of timewarp you could use. It would be interesting if that was somehow part of player economy too, selling route plans. If the planets moved over time, those routes would be constantly invalidated, driving demand for new routes.

proper ingot
#

ships with preplanned routes for the next hundred thousand years belonging to massive trading groups

naive elk
#

Wow.. I just realized. What is plasma exhaust? That's basically a huge plasma shield, so it would even protect against high energy weapons.

#

Yeah initially I wanted to ban torch drives altogether, but the more I think about them, the more they look like very juicy game mechanic with tradeoffs and interesting stories around them.

naive elk
mighty crescent
#

Desync - if one player wants to timewarp, everyone needs to timewarp to be consistent.

#

At least in a world with slower-than-light travel.

naive elk
#

you mean fast forward the server time?

mighty crescent
#

Have you played KSP?

naive elk
#

nop, sorry

#

timewarp is a concept from it?

mighty crescent
#

You can fast forward physics, so travel to mars doesn't take 4 irl years

naive elk
#

oh yeah

mighty crescent
#

But if you have multiplayer, how do you resolve that? You would need everyone on the server to fast forward together

#

This really came about because I find straight-line FTL pretty uninteresting. Another way to frame it is FTL with orbital mechanics.

naive elk
#

Off the top, introduce sync points. Like every so often the server fast-forwards the time, making it a turn-based game with real time action in between the turns ๐Ÿ˜„ Sounds silly, I must admit...

#

But how could you solve that?

naive elk
#

But what does it mean?

proper ingot
#

i once played a game that had the mechanic of being realtime for a week and multiplayer

mighty crescent
#

You can travel FTL, but you have to follow orbital paths. You aren't speeding up time, you are just moving FTL thanks to some handwavium scifi

proper ingot
#

speeding up your ship's trajectory?

mighty crescent
#

Pretty much

#

I find most interplanetary traversal uninteresting - point ship at destination and press button

#

It would be more like all the scifi where they have to plan a route, before a jump

naive elk
#

Ahhh yeah. I see what you mean. Yeah arbitrary FTL breaks everything, warfare first of all, if that's what you meant. So what you end up needing is constrained FTL. I came up with these space highways for that reason.

mighty crescent
#

and based on playing lots of KSP, that route planning turns out to be a ton of fun

naive elk
#

Oh you mean actively search for specific paths. Yeah that's something different.

mighty crescent
#

Orbital mechanics - slingshotting yourself around bodies, etc

proper ingot
#

yk speeding up your trajectory (in newtonian mechanics) is just increasing your velocity and the force gravity exerts on you

mighty crescent
#

Applying a force during transit is different than coasting, you will follow a different trajectory

naive elk
#

I can see that being fun, yep

#

But somehow this feels like.. um.. more like an engineering/exploring game, rather than good old action combat game. But you did say it was inspired by KSP, so that makes sense ๐Ÿ™‚

mighty crescent
#

totally

#

I wish we saw more scifi games that explored traversal, instead of hopping from setpiece to setpiece instantaneously.

#

LIke, instead of "dropping in" from ftl somehow with the exact same velocity as the ships magically hovering stationary over a planet, what if you dropped in going 7km/s lel

proper ingot
#

play exo one

mighty crescent
#

Could you use that to your advantage with kinetic weapons inheriting all your velocity?

mighty crescent
proper ingot
mighty crescent
#

Oh, I thought you were saying something completely different

naive elk
mighty crescent
#

That sounds fast enough to ruin somoene's day.

proper ingot
#

is there a reason you can't strap a time accelerator to a brick and toss it

mighty crescent
#

where do I get a time accelerator

proper ingot
#

whatever the ftl is that technically doesn't

naive elk
#

Can't believe I just said that to the creator of Bigspace

mighty crescent
mighty crescent
proper ingot
mighty crescent
#

computers ruin all the fun

#

real trajectory planners use slide rules and snort space spice

proper ingot
#

see what you do is add more phlebtonium that makes the exact multiplier random every time it turns on

#

an n-radius hole through a manifold seems more computationally difficult than a single path

naive elk
hollow sluice
naive elk
#

If you simply remove those lines, it will mess up the system ordering though

#

@crude dagger if you just want to run the example, you can

cargo run --example planets
crude dagger
# naive elk <@321008917658206208> if you just want to run the example, you can ``` cargo run...

Checking out 0.9.1 release tag, this does not work. Gives the same weird runtime error and crashes:

thread 'main' panicked at /home/damccull/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_ecs-0.15.3/src/schedule/schedule.rs:383:33:
Error when initializing schedule PostUpdate: Tried to order against `SystemTypeSet(fn FunctionSystem<fn(Query<(Entity, Children, Ref<Transform>, &mut GlobalTransform), Without<Parent>>, RemovedComponents<Parent>, Query<(Ref<Transform>, &mut GlobalTransform, Option<Children>), With<Parent>>, Query<(Entity, Ref<Parent>), With<GlobalTransform>>, Local<Vec<Entity>>), propagate_transforms>())` in a schedule that has more than one `SystemTypeSet(fn FunctionSystem<fn(Query<(Entity, Children, Ref<Transform>, &mut GlobalTransform), Without<Parent>>, RemovedComponents<Parent>, Query<(Ref<Transform>, &mut GlobalTransform, Option<Children>), With<Parent>>, Query<(Entity, Ref<Parent>), With<GlobalTransform>>, Local<Vec<Entity>>), propagate_transforms>())` instance. `SystemTypeSet(fn FunctionSystem<fn(Query<(Entity, Children, Ref<Transform>, &mut GlobalTransform), Without<Parent>>, RemovedComponents<Parent>, Query<(Ref<Transform>, &mut GlobalTransform, Option<Children>), With<Parent>>, Query<(Entity, Ref<Parent>), With<GlobalTransform>>, Local<Vec<Entity>>), propagate_transforms>())` is a `SystemTypeSet` and cannot be used for ordering if ambiguous. Use a different set without this restriction.
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
#

But the main branch removes those lines and doing so on 0.9.1 also runs it seemingly fine.

naive elk
mighty crescent
#

ruh roh

#

Oh, it's a runtime panic, that's why CI didn't catch it. ๐Ÿ’ข

proper ingot
#

was there no test for it or does ci not run tests

mighty crescent
#

It's an example.

#

I've never run examples in CI before due to rendering issues, but if that has changed, I'd love to know about it.

#

I'd also need a way to kill them after N frames or N time.

prime bronze
#

Rotating my DirectionalLight 180 degrees seems to give the same result so I'm guessing that is all it does

#

Not sure why it's a whole system, Is there some interaction with the GlobalTransform there I'm missing?

#

Weird that it doesn't work when I do Transform::from_translation(Vec3::ZERO).looking_at(planet_position, Vec3::Y)

#

But I'll chalk that up to my inexperience with Bevy

mighty crescent
#

oh good, big_space is completely broken on bevy 0.16 pain2

umbral ledge
mighty crescent
#

transform prop is disabled, best guess is the change to parenting ChildOfing is breaking stuff

#

it looks like a transform hierarchy validation resource disappeared into the ether

full magnet
mighty crescent
#

welp, this is very confusing

#

what the heck is RelatedSpawnerCommands, looks like I have some reading to do

#

I've never even seen this kind of failure before. It really, really, does not like moving between cells.

#

Just wait, it's totally gonna be my own fault with transform prop changes lel

#

oh god, it is

#

I bet it's the leaf transforms

#

yuuuuuup

#

welp

#

๐ŸŽถ it's me, hi, I'm the problem it's me ๐ŸŽต

#

@umbral ledge FYI everything works fine on main

#

The issue was the released version (that did not have the dirty tree PR), has an optimization that updates leaf nodes. It's not strictly a problem, because you can work around it if you are disabling the transform plugin already. It is an annoyance because you can't reuse the built in systems.

mighty crescent
umbral ledge
mighty crescent
#

I'm simulating millions of entities, and I noticed a stutter when moving between cells - update_mesh_previous_global_transforms is taking over 100 ms

umbral ledge
#

Why on earth are we always using commands there??

#

We should be mutating if possible

#

Waaay faster

#

Lemme PR that...

mighty crescent
#

oh, good catch, yeah that is in commands

#
for (entity, transform) in &meshes {
    commands
        .entity(entity)
        .try_insert(PreviousGlobalTransform(transform.affine()));
}
#

oof, that's not great

mighty crescent
umbral ledge
#

I beat you :p

mighty crescent
#

I avoided branching statically:

pub fn update_mesh_previous_global_transforms(
    mut commands: Commands,
    views: Query<&Camera, Or<(With<Camera3d>, With<ShadowView>)>>,
    new_meshes: Query<
        (Entity, &GlobalTransform),
        (PreviousMeshFilter, Without<PreviousGlobalTransform>),
    >,
    mut meshes: Query<(&GlobalTransform, &mut PreviousGlobalTransform), PreviousMeshFilter>,
) {
    let should_run = views.iter().any(|camera| camera.is_active);

    if should_run {
        for (entity, transform) in &new_meshes {
            let new_previous_transform = PreviousGlobalTransform(transform.affine());
            commands.entity(entity).try_insert(new_previous_transform);
        }
        for (transform, mut previous) in &mut meshes {
            previous.set_if_neq(PreviousGlobalTransform(transform.affine()));
        }
    }
}
#

you use the command if it is missing the component, and just mutate it when it has it

mighty crescent
#

I left an approval, gonna patch and test quick

mighty crescent
umbral ledge
#

Let's wait on benches for that?

#

I'd also prefer using required components to avoid the insertions if possible

umbral ledge
mighty crescent
#

unless you can add foriegn req components?

umbral ledge
#

Yeah you can ๐Ÿ˜„

#

Slap it in the plugin

mighty crescent
#

oh, I thought you meant on GT

mighty crescent
#

lol

#

it's stupidly parallel

umbral ledge
mighty crescent
#

it takes longer than spawning the meshes

#

but good news, it is down to 3ms from 115ms on main

#

(this is with the par query)

umbral ledge
mighty crescent
#

oof check_entities_needing_specialization is also very slow

#

it is doing a linear scan as well

#

It looks trivially parallelizable too

#

same with visibility ranges, though I doubt it would be trivial

umbral ledge
#

But bug me and I can slap some par_iter on that too if you want

mighty crescent
#

this is not urgent, do your thing

umbral ledge
#

Especially in terms of effect to effort

mighty crescent
#

to give a sense for how much perf bevy is leaving on the table by not unifying the thread pool, this is what it looks like if I force the compute task pool to actually use my cores

#

I get double the cores to work with

wild tangle
#

yeah I see that in Avian too, collision detection is way faster if I force it to actually use enough cores

#

(or use Rayon which also uses all the cores)

inland hull
#

More excellent validation for the release candidate process.

#

So cool to see these regressions getting caught.

flint onyx
naive elk
#

how are you "forcing" Bevy to use more cores?

#

and what is that pretty profiling tool?

prime bronze
mighty crescent
#

Tracy, and using custom settings for the task pool in the task plugin on setup.

worthy vector
#

I'm considering throwing together a crate to simplify using gizmos with big_space. Is there already such a thing? And if not, am I overcomplicating things?

mighty crescent
#

Not that I know of. What kinda stuff are you doing?

#

I use gizmos pretty often, using the GT, everything seems to work normally.

worthy vector
#

When you say using the GT, you're talking about positioning gizmos relative to object with a GT right? I'm finding it's sometimes a pain to grab the GT, like when you get absolute coordinates from a picking backend

mighty crescent
#

wdym by absolute coords from picking?

celest obsidian
#

you assume that there is an entity :p

mighty crescent
#

I would expect you could just do everything in global space like normal bevy

mighty crescent
worthy vector
#

Like if I want to put a gizmo at the world origin

#

What on earth do I pass to the gizmo function?

mighty crescent
#

the bigspace entity's globaltransfrom?

worthy vector
#

Huh

mighty crescent
#

or the grid entity's globaltransform

#

you can see that in action with the built in debug plugin iirc

#

it draws coordinate axes at each grid

worthy vector
#

The fact that the root bigspace has a gt slipped my mind

naive elk
#

Bigspace continues to be mind-bending. ๐Ÿ˜„

#

In a good way

mighty crescent
#

What happened? ๐Ÿ˜†

naive elk
# mighty crescent What happened? ๐Ÿ˜†

The fact that the root bigspace has a gt slipped my mind
This. I sometimes make the mistake of thinking I finally understood how to work with Bigspace, and then there's another "ohhhhh, riiight" moment.

prime bronze
#

I find myself confused by grids again haha

#

I have a planet sized mesh with a grid and a gridcell

#

Let's say for examples sake the mesh has 20 sides, and each of those sides has a grid

#

I'm then trying to get the "real" position of the player (which lives on one of the 20 planet surface meshes)

#

I'm trying to do this following the demo.rs example, using grid.grid_position_double

#

But everyway I try it I'm being given the position of the player in relation to the surface grid

#

Which is basically 0, 0, 0 as the player is on the surface

#

I can get the "real" position of the planet using the same method and that works without issues, but the moment I move to the player it fails

#

Should I not have a grid within a grid?

mighty crescent
#

Why do you have 20 child grids? ๐Ÿ˜…

prime bronze
#

Ages back you said having a planet sized grid defeats the purpose big space

#

So I made them smaller

#

Might have misunderstood what you meant though lol

mighty crescent
#

You must've misunderstood or I misspoke

#

But that sounds really overcomplicated.

#

Let me try to understand what you're doing

#

Grid_position_double just combines the index with the cell translation to give you the position of something in a single double precision float.

#

So, it's like you are now working with a double precision Transform.

#

But it's still a Transform which is relative to its parent transform.

#

So, this is AI working as intended as far as I can see. You are asking it to give you the position of the entity as a double, relative to its parent, and it is.

prime bronze
#

Right ok

mighty crescent
#

The setup you have here is equivalent to having a deeply nested tree of transforms to represent a planet, and all of your entities are now in different reference frames

prime bronze
#

I guess from the demo I would've expected the "real" position to always be absolute*, but it's just the position relative to the parent

#

Is there anyway to get the absolute position?

#

Without traversing all the parents and combining the transforms

#

Actually no, that's not what I want

#

I want to get the relative position of the player to the planet grid

mighty crescent
#

You really just want a single planet grid

prime bronze
prime bronze
mighty crescent
#

Everything in a grid moves together, I would only add more nested grids if there is a subset of things moving together that should inherit from the parent grid.

mighty crescent
#

You could use the root as your global reference frame, but there is likely no need to traverse all the way to the root, losing precision along the way

prime bronze
#

I'll definitely want to go back and figure out why I couldn't get the position relative to the planet grid eventually, but for now having a single planet grid will likely suffice

mighty crescent
#

What you probably care about is finding some common ancestor

prime bronze
#

And hopefully make things easier

mighty crescent
#

One issue I don't see you mentioning is rendering the planet mesh itself

prime bronze
#

Yeah, thankfully I've solved that (mostly)

#

I've got the mesh split into 360 chunks, each with 4 faces

#

Each face vertex has colour on it and seems to be stable

mighty crescent
#

Those meshes should probably also be in the planets grid

prime bronze
#

Yeah they are

mighty crescent
#

Wow, phone autocorrect is terrible today

prime bronze
#

Hahah

#

They were grids nested inside the planet grid, but now they're just directly in the planet grid

mighty crescent
#

If your objects/players/terrain are all in the same reference frame, that should make your life easier

prime bronze
#

Probably yeah. There were a couple of optimisations I was hoping to do by having each face be it's own grid, but it's probably not worth the hassle

mighty crescent
#

If you use that conversion to doubles, you can compare everything directly. You can also use the wrapper type for (Transform, GridCell) and compared those directly

prime bronze
#

Initially I was using Transform and GridCell but it kept giving me weird outputs, which is why I tested the grid_position_double command

#

Which then gave me the same output, which led me here

mighty crescent
#

Yup, you were on the right track before, I think

prime bronze
#

Oh, I remember why I needed the nested grids

#

My planet isn't actually a planet, it's a ringworld

#

So I've got the ring split into 360 chunks along the circumference

#

Then at the center angle/position of each of the chunks I have an entity that handles the transform from the center of the ring

#

Then from there I have each face of the ring chunk under the chunk entity with a small transform for each of them

#

That way I don't have massive numbers everywhere, only one big transform, then little ones for the faces

mighty crescent
#

It sounds like you are trying to write your own big space inside of big space

#

If everything is in the same grid, you won't need to worry about precision, and you won't need to transform between reference frames.

prime bronze
#

I'm just trying to keep them parented together so I can manage them easily, not for precisions sake

#

And it keeps my code simplified

mighty crescent
#

Parenting is going to require conversions between reference frames, so be prepared for that added complexity.

#

There are other ways to group entities instead of using parenting, which is tied to transform propagation

prime bronze
#

Hmm, okay I'll take a look at that then

mighty crescent
#

I don't know your game as well as you do, but my recommendation would be to keep the transform hierarchy as flat as possible in places where things need to interact or have positions compared to one another.

#

It's not a hard rule or anything, but it's (probably) going to make a lot of things simpler.

#

Otherwise you will need to transform entities into a common reference frame before doing any comparisons.

worthy vector
#

fwiw in my impl, I'm using multiple grids, but only because I have different reference frames: the root grid is for the whole solar system, the sun sits at the origin in this frame. The planets are also in the root frame, but each planet has a pair of grids: one without a rotation for orbiting things, and one that rotates with the planet for things on the surface or in the atmosphere. The planet mesh chunks sit inside the rotating grid. Apart from that, I don't really use parenting at all. Chunks need to know who their superchunks are, but I don't use parent/child for that, I position each sub-chunk in the main planet grid and it makes things much simpler

#

So the short version is: I only use grid parenting for orbiting bodies. In the context of a single planet, everything's in one grid

mighty crescent
worthy vector
#

Weird to say it's intuitive in the same breath that I say it took a bit to understand ๐Ÿ˜†

mighty crescent
#

Always happy to hear how the docs can be improved

#

I think this crate would benefit from tutorials too

#

It's hard to build intuition for concepts in the docs+examples format

prime bronze
#

Not parenting things and instead just putting them on the parent's grid is interesting

#

And having two grids per planet is also interesting

worthy vector
prime bronze
#

I've currently got a sun, with a planet rotating around it, with the ring orbiting around the planet

#

In that case I have them parented like in the planets example

#

And now I've got the meshes and the player on the ring itself, so that'll be easier

#

Thanks for both of your help once again!

mighty crescent
worthy vector
#

I'm still deciding if it's actually helpful. It's really nice to be able to specify world coordinates, like "draw this ellipse to represent this orbit" without needing to look up global transforms. At any rate, I think my brain is fried, I can't make myself understand how to get a local cell/position from a global position when the floating origin is potentially deep in a grid hierarchy. Is there a utility to make that easier or do I just need to copy paste the right code?

mighty crescent
#

No utility no, sorry. I know that is a pain point if you aren't me.

#

Note that every grid stores a local transform in the component, so regardless of where it is in the hierarchy, you could use that to draw things in that coordinate space

#

It allows you to reuse the hierarchy traversal used for floating origin propagation, and jump straight into any grid's reference frame

prime bronze
#

Getting a weird one today

#

I get to what I'm assuming is the edge of my gridcell then get moved to the opposite edge of my gridcell

#

Rather than smoothly continuing on with the grid cell updating behind the scenes

#

Although, I haven't confirmed that is actually what's happening, that's just what it looks like. Let me double check that now

#

Ok, after double checking using the debug text system from the demo example it appears to be working as it should, but when we move gridcells my terrain is being moved to 0 of the new gridcell

#

Which is odd

#

Ok figured it out, error was on my end!

worthy vector
#

Will things break if I have a hierarchy like:

(BigSpace, Grid)
- (Transform, GridCell)
  - (Transform) <-- no `LowPrecisionRoot`
#

Basically when a low-precision entity doesn't have LowPrecisionRoot but its parent is a high-precision entity?

mighty crescent
#

the low precision root is added automatically

#

it's a perf optimization

#

otherwise the plugin would need to traverse the hierarchy every update to find them

#

So, that should be fine

worthy vector
# mighty crescent the low precision root is added automatically

In that case I think I'm hitting a bug. Basically I've got this hierarchy:

(BigSpace, Grid) // planet reference frame
- (Transform, GridCell) // 1st stage
  - (Transform, Mesh, LowPrecisionRoot, ...) // 1st stage graphics
  - Transform // 2nd stage
    - (Transform, Mesh, ...) // 2nd stage graphics

Then at stage separation, I'm unparenting the 2nd stage from the 1st stage, reparenting it to the planet reference frame, and adding a GridCell to it. The graphics wig out and start flying around (wrapping from the left side of the cell to the right). What's weird is the 2nd stage entity itself is in the right place. BRP is showing that none of the 2nd stages children have LowPrecisionRoot. If I manually add them, the graphics look normal.

#

I can try to debug if you help me understand where/under what conditions LowPrecisionRoot is supposed to be auto-added

#

Or I can slap together an MVP

mighty crescent
#

A minimal case would be helpful. I won't have time to debug for a week or so, sorry.

mighty crescent
worthy vector
mighty crescent
#

Thank you.

#

I'll do my best to reply to questions here, but life is a bit too busy for OSS at the moment.

worthy vector
#

It happens! Take care of yourself ๐Ÿ™‚

#

Honestly crazy how much time people do have for OSS considering most work for free

mighty crescent
proper ingot
#

... because you don't have enough time, or..?

mighty crescent
#

I value my time ๐Ÿ˜†

pure sequoia
mighty crescent
#

Oh, entity count?

#

you can just play with the spatial hashing example

#

for maximum perf, disable the parts where the meshes are added to the spawned entities

#

The slowdown is generally on the rendering side if you are relying on the out-of-the-box instancing.

hallow valve
#

@crude dagger

crude dagger
crude dagger
#

So...I am currently writing up a design for an Escape Velocity clone to get my self started in bevy. I wanted to go hard, though, and create an absolutely massive play are with precedural generated stars and planets the size of the milky way.

My original idea for coordinates was to create a grid of sub-grids, with each top-level grid containing an i64 x,y coordinate, and each subgrid containing another i64 x,y coordinate. This would give me an extremely precise coordinate over a huge distance. Then I was going to give the camera its own coordinate within my grid and subtract the positions of the objects within a 'render range' from the position of the camera, math the coordinates into an f32 location relative to the camera, and display them, always keeping things close to avoid jitter/error. I hope I explained this well.

big_space seems to, maybe, solve some of this for me in a similar manner, though it uses a float within an int grid. I did read some info at the top of this about physics at the borders of the gridcells being an issue.

I also read some of the beginning of this discussion forum and ya'll were talking about how big_space can be the source of truth, or another system can, and that confuses me. Why would I make another system the source of truth? How would that even work?

Lastly, is there any tutorials beyond the examples and docs.rs entries that explain how to use this crate in its basics? "by example" is great when the why and how get explained well, and in pieces that build on the previous, but just splatting a bunch of example code into the internet and hoping newbies will understand it makes things much harder. No offsense; I know how hard writing good docs can be. I'm just asking if there's any baby-steps tutorials out there.

Thanks!

naive elk
worthy vector
# crude dagger So...I am currently writing up a design for an Escape Velocity clone to get my s...

Yeah I feel like the best way to explain this crate might be visually. Maybe someone should go make a video explaining how it works.

Well, yes this crate will probably do exactly what you want. It has an example of giving you proton scale across the observable universe, so your milky way isn't an issue at all. The biggest issue you'll run into is making sure rendering/LODs are performant with 400 billion stars.

To try and explain how it works, basically in bevy, the difference between Transform and GlobalTransform is that GlobalTransform can be thought of as "absolute" coordinates, and Transform is like local coordinates. This crate breaks the whole universe into a grid of configurable cell size (say, 1km), then uses Transform to describe local position within your current cell. When rendering, GlobalTransforms are computed relative to the camera's cell. That means you always have precision near the camera where it's needed, and precision increases as you get closer to something.

There aren't really any tutorials I can point to beyond the docs and examples, I think the current best way to learn the crate right now is using it and asking questions here. I'm happy to help try and explain it better, maybe draw up some visuals as well ๐Ÿ™‚

#

For you case, I'd probably use a grid cell size of 1km and a precision of i64. That'll give you a total play area of almost 2 million light years (much larger than our galaxy) with a worst-case precision of about 1/10th of a millimeter. If you want a bit more precision, you could shrink your grid cell down to 50m and still contain the whole galaxy, and your precision would go to about 5 micrometers in the worst case

#

(if I'm doing all my math right haha)

mighty crescent
#

As others have said, for the most part this crate tries to get out of your way and make simple things easy and unsurprising. As long as you follow the guidelines, you can often just work with transform and global transform like normal bevy.

That said, it functions very similarly to what you described.

crude dagger
#

So what's the deal with border physics? I didn't fully understand that conversation from the beginning

worthy vector
# crude dagger So what's the deal with border physics? I didn't fully understand that conversat...

Basically all objects have their transforms constrained to an area the size of the grid cell. That means two objects that are right next to each other and potentially colliding, but are in different grid cells, won't be next to each other as far as the physics engine is concerned. You can write your own collision system if you don't need a robust physics engine, or there are some workarounds. Not sure on the status but @wild tangle was working on simulation islands, which will offer a potential solution I believe. He can probably give you a better idea for how to solve the issue (if he's not busy)

crude dagger
#

So basically, existing physics engines are unaware of the grid and re-origin technique of this library, so they would see two things about to meet at the edge of a gridcell as being on opposite sides of the origin and never even able to touch....that right?

So physics has to be written with the gridcell coordinate in mind as well.

mighty crescent
#

Pretty much.

#

It's something you can solve at the integration level though, the engine itself doesn't need to worry about it.

crude dagger
#

well i'm not even started yet, so i'm not worried about it just yet lol.

mighty crescent
#

Yup

wooden tusk
#

Hey, I'm enjoying this crate as it allows me to make a space game more easily. However, I have one question - how bad/good does it work with existing crates like avian/rapier3D physics?

worthy vector
#

Kind of waiting on avian's simulation islands iiuc

#

If you're willing to hack around I think you can make it work with caveats, but I just built my own physics system since my needs are minimal

wooden tusk
#

Couldnt I manipulate it manually through this? It seems promising (rapier)

wooden tusk
worthy vector
#

Yup those are potentially valid options. Main thing to be aware of is that all your entities will have their translations in the same cell-sized area

proper ingot
#

it might be practical to not even collide things that aren't in the floating origin's cell

wooden tusk
wild tangle
#

it would use big_space's spatial hashing and neighbor flooding to group nearby entities into islands, which would be separate physics simulation instances

#

(different from simulation islands, those are a physics optimization for sleeping/waking and basic solver parallelism, unrelated to big_space support)

mighty crescent
wild tangle
#

Oh, cool!

mighty crescent
worthy vector
#

@naive elk you're currently using big_space right? Have you updated to bevy 0.16? Curious if you're using big_space main and if so how it's working for you

naive elk
# worthy vector <@172284396668321793> you're currently using big_space right? Have you updated t...

I wanted to finally put something inspiring into the 3d world besides a capsule mesh, so started to learn modelling. It completely sucked me in, I haven't touched code in a while. ๐Ÿ˜… The way I see it, the longer I'm busy modelling, the more cool features Bevy/BS gets in background. ๐Ÿ˜‰ Hopefully, that is. Maybe Mr Jondolf integrates with BS, or something. So... I'm gonna migrate later.

#

Why, is it easy?

worthy vector
#

Also yes I get sucked into blender sometimes ๐Ÿ˜†

#

It's on my list of legitimate excuses to pause whatever thing I'm currently sick of

naive elk
worthy vector
#

That's... a great freaking idea

naive elk
#

Somewhere in the future there is a paradise where you get BS, Avian and virtual geometry and it all just works and with good frame rate, too ๐Ÿ˜„

mighty crescent
#

Sorry for the delay in release. Life has been hectic.

worthy vector
quartz thorn
#

Does big_space support multiplayer? Or is that out of scope for the crate?

naive elk
naive elk
#

Oh, forgot I can't create threads because we're in a thread already. But here is a 0.9.1 codebase analysis for non-determinism. Keep in mind that, I'm pretty sure GlobalTransform doesn't need to be replicated across network so how it's calculated shouldn't matter. But the other stuff mentioned in the report might matter, not sure.

mighty crescent
#

this looks pretty accurate to me

mighty crescent
#

It doesn't have the problems that a world-recentering solution might have.

quartz thorn
# mighty crescent That's a pretty open ended question. The short answer is that it supports it jus...

I'm specifically asking because i'm pretty sure a FloatingOrigin doesn't make much sense server-side, is there some way i should turn off GlobalTransform translation propagation, or should i just set it somewhere and ignore the translation? (I'm probably going to replace it with a fixed-point solution for when i need to read global positions anyway)
Also Grid and GridCell don't implement Serialize and Deserialize, and i'm pretty sure i have to replicate those to clients?
I'm not sure i have my head fully wrapped around this crate and am little tired atm, so i might be thinking about things completely wrong here

naive elk
quartz thorn
naive elk
#

Cool, because I haven't ๐Ÿ˜„ So I don't know what it requires. Yeah you definitely need Grid, GridCell serializable. ๐Ÿค” Without their replication, the client's bigspace logic wouldn't work.

#

Well, worst case you could just fork big_space, add serialization to those components, see that multiplayer works, and PR that back to aevyrie ๐Ÿ™‚

mighty crescent
#

that's why I made these changes

#

I believe the gpt thing posted above also mentions this

#

Server doesn't need to compute or care about GlobalTransform, it can just do the gridcell recentering. All the clients need are updates to GridCell and Transform

#

Adding serde derives is a welcome addition. Should stick it behind a feature flag.

quartz thorn
#

Thank you! Adding serde sounds pretty easy, so i shall work on that and PR when i'm done
The server might still care about GlobalTransforms for rotation and scale, and it seems like disabling BigSpacePropagationPlugin will disable the propagation of that as well
that said i can't think of a use case off the top of my head, so it might very well not be a big deal

mighty crescent
#

GlobalTransform is purely client side for rendering and is relative to the floating origin, which will be different for every client.

#

the transform and gridcell (hierarchy) are what is needed to define the position of all entities in space.

devout cliff
#

question: so I'm trying to use big space but I can't initialize it, I have
use big_space::prelude::*; at the top of my file but I keep getting this error
```error[E0425]: cannot find value BigSpaceDefaultPlugins in this scope
--> src\core\mod.rs:27:22
|
27 | .add_plugins(BigSpaceDefaultPlugins)
|

mighty crescent
#

are you using the same version as the one with BigSpaceDefaultPlugins

devout cliff
#

ah

#

yeah I'm on 0.9.1

#

okay, well switching to the 0.16 branch method, I now get this error
```error[E0277]: the trait bound big_space::plugin::BigSpacePlugin<_>: Plugins<_> is not satisfied
--> src\core\mod.rs:27:22
|
27 | .add_plugins(BigSpacePlugin::default())
| ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bevy::bevy_app::plugin::sealed::Plugins<_> is not implemented for big_space::plugin::BigSpacePlugin<_>
| |
| required by a bound introduced by this call
|

proper ingot
#

sync up the bevy version too, probably

devout cliff
#

bevy version is 0.16.1

mighty crescent
#

There is not a released version of big_space that is compatible with bevy 0.16

#

edit: ah I see you said you are using the branch

#

What branch? main?

mighty crescent
#

Yup.

devout cliff
#

ah, I guess I'll wait to include it for bevy 0.17 since I don't like using the main branch for projects

mighty crescent
cobalt yarrow
#

Is there a way to get a GridCommands from a query in a different system? I am trying to spawn additional grids after the root grid has been created.

cobalt yarrow
naive elk
cobalt yarrow
#

maybe this is way easier than I thought it was

naive elk
#

yeah regular Bevy hierarchy

#

and components

cobalt yarrow
#

can I mix grid precision? like if the root is i64 and I want an i32 for some moon or whatever?

naive elk
#

yep

#

https://docs.rs/big_space/latest/big_space/

Grids can be nested, like Transforms.

Uhh I don't remember where it says you can nest different precisions though but I'm sure you can from previous discussions on this channel.

cobalt yarrow
#

Well that's neat! I'm still getting my head around how this actually works. I maybe need a big_brain plugin

naive elk
cobalt yarrow
#

HA

naive elk
#

big_space is actually very easy to use. Place Grid where you want your grids.. children under these entities will be within that grid's coordinate system (if these entities also have a GridCell along with the usual Transform)

cobalt yarrow
#

I'm trying to make this work using the openxr VR plugin thing and having to do some weird stuff to make it work. I went and parented the root grid to the vr_tracking_root and had to change how the library finds floatingorigins. I think that is working correctly now.

If I create an entity that is a child of a grid, and that child entity has a Grid of it's own, does that child also need a GridCell that somehow references the parent grid?

naive elk
#

uhh not sure

cobalt yarrow
#

one way to find out! haha, thank you for taking the time to answer my weird questions!

naive elk
#

if you run big space with the validator enabled it will try to verify the archetypes of your entities and complain if something logically doesn't make sense

#

I think it's on by default

cobalt yarrow
#

Yep! I made it unhappy a few times now

#

I think I should go play with a simpler example and get my head around it before i go off the deep end in VR

mighty crescent
#

If you can describe what you are trying to accomplish, I might be able to help.

cobalt yarrow
cobalt yarrow
#

If I have an entity that is a child of the grid and has a gridcell component, do all of it's child entities need to have that component too?

mighty crescent
#

no

#

all of its parents do, but not children

#

you can only decrease in precision as you move away from the BigSpace root toward children, otherwise the plugin would not be able to reliably transform between grid coordinate systems.

#

In many cases you can get away with only a single grid at the root, and all entities at that level having a gridcell

#

but all grandchildren and decendants could just be normal Transform hierarchies without high precision

cobalt yarrow
#

That makes sense

#

That's kinda what I'm starting out with now, trying to learn it

mighty crescent
#

the only time you need to nest grids is if you have moving reference frames that are themselves huge scale that require huge precision

#

the canonical example is a planet might be placed in a solar system grid, and objects on the planet would need to be in the planet's grid

#

But once you get down to normal 3d game scene scales, you really shouldn't need to reach for grids any more

cobalt yarrow
#

That makes intuitive sense. I'm looking at the translation_to_grid function and it's starting to click

#

Thanks for helping out!

worthy vector
cobalt yarrow
#

I assume it's a scheduling issue but haven't ran it down yet

#

That wasn't supposed to be a reply, hold on

mighty crescent
#

The picking system has a helper that gives you all pointer rays precomputed, that should also work.

cobalt yarrow
#

I think my issue was something in the bevy vr mod messing with my rotation there. Wasn't a scheduling issue at all

#

by not parenting it to the tracked controller space anymore, and manually updating the position and rotation, it's working fine. I was just blaming bigspace because I have no idea what im doing ๐Ÿ™ƒ

naive elk
#

Attempt to explain no 2. A collision island is simply a list of entities (or a list of a bunch of relevant components in ECS sense) that are suspected to be close enough to each other. The only thing different for the collision solver would have to do is work with grid coordinates (cell + xyz), instead of just global xyz, right? I'm thinking it would have to work with grid coords and not FO-relative coords because what if you're trying to collide planets. I guess then you could use f64, it's happening on the CPU anyway so who cares? But just sticking to grid coords that, when subtracted, give you an f64 difference, still feels more universal and precise than translating coords of all island entities into a single FO-relative coord system like for renderer.

mighty crescent
#

big_space v 0.10.0 has (finally) been released on crates.io!