engo icon indicating copy to clipboard operation
engo copied to clipboard

Parenting of SpaceComponent

Open Noofbiz opened this issue 7 years ago • 17 comments

Suggested by @juztme87.

Make SpaceComponents have references to any parent / child components, like a Node. This would be useful for collision detection.

One question I have about implementation is how would it work in practice? Is the position relative to the parent, i.e if I have a parent positioned at (100, 100) and position the child at (100, 100) would the child appear on the screen at (200, 200)? Also, is there inheritance? Does the child by default have the same properties as the parent or does it default to zero?

Noofbiz avatar May 31 '18 17:05 Noofbiz

This issue is related to #556

Some example use cases:

  1. A Tank has a Turret. This Turret needs to be able to rotate independently but the position and rotation should be relative to the parent.

  2. A Unit has a health bar. The health bar is located 10px above the Unit. The position should be relative to the parent but the rotation should be fixed. (The position of the child shouldn't be affected by the Rotation of the parent)

Maybe there are some other use cases that require inheritance.

juztme87 avatar May 31 '18 18:05 juztme87

@Noofbiz this is a fairly common paradigm in game engines and pretty much every major game engine has this concept. The way it works rather universally, is that child enities are transformed in relation to their parent entity. So as an example, if EntityA was at position 100, 100 and Entity B was a child of EntityB and had position 100, 100, it would actually be rendered at global position 200, 200. Generally, most systems expose two types of T/R/S, a local one (100, 100 in this example) and a global one (200, 200 in this example). This is important because sometimes, it's necessary to know the relative or local position, while other times it's important to know the global or world position, depending on what you are trying to do.

jonbonazza avatar Dec 14 '18 07:12 jonbonazza

I agree, I'm only stuck on the implementation. We could either make space components themselves do this by unexporting Point and using Get/Set methods for position. This would allow us to do it all internally, but will change the API for space components quite a bit. Another solution would be to have a SpaceParentSystem or something that does it separately as its own system. This has the advantage of not needing to change the current API, but seems clunkier to me.

Noofbiz avatar Dec 14 '18 17:12 Noofbiz

I'd prefer the former approach personally, but as you said it does break backwards compatibility.

That said, there are a couple other backwards incompatible changes id like to make too, so maybe after 1.1 is out, we can get together and start thinking about 2.0

jonbonazza avatar Dec 14 '18 17:12 jonbonazza

I'm implementing the latter. I can share the code as a gist or a PR.

diwant avatar Mar 25 '20 03:03 diwant

as you said it does break backwards compatibility

I personally don't think this is a gigantic issue for a clean implementation of a core feature.

Asday avatar Mar 25 '20 07:03 Asday

A PR would be pretty great, and the changes shouldn't be too bad now with go modules. We can just make sure to release a version before so anyone who needs to can check out that one. And it'll definitely need be updated for version 2.0 anyway, and it is a pretty useful feature.

Noofbiz avatar Mar 25 '20 22:03 Noofbiz

I've put up a PR here with my latest draft. The math is wrong and I am not seeing expected behavior for heirarchical transformations yet. Would love a second set of eyes on this, perhaps you can see what I'm missing?

https://github.com/EngoEngine/engo/pull/705

diwant avatar Apr 02 '20 02:04 diwant

This gist shows how entities might be added to this TreeNodeSystem: https://gist.github.com/diwant/11b05a3908028ed60377ec6a3ae2c025

In this example, if I run code to increase the LocRot value of the starHandle, it doesn't orbit the moon. It orbits a much larger circle than that, which is not the expected behavior (I'd like the star to orbit the moon.

diwant avatar Apr 02 '20 02:04 diwant

ecs.BasicEntity has a parent/child tree node now, and I've added a demo called parenting that shows how to do this for any component, not just space ^_^!

Noofbiz avatar May 21 '20 16:05 Noofbiz

https://github.com/EngoEngine/engo/tree/c76f7316599b705e8a3655640db2c0cb4b71c1b2/demos/parenting

Asday avatar May 21 '20 16:05 Asday

You know, I'm not certain that really solves the original problem - a tree node layout is only about the relationship during entity creation. At every other time it's about the derived values.

For @diwant's case, he'd still need to implement the derivation calculations for moving, rotating, and scaling SpaceComponents himself.

Asday avatar May 21 '20 16:05 Asday

Yeah, I agree, I’ll reopen this. I think we should expand the demo to include working with space components. Do you think that covers it, or should something be added to common?

Noofbiz avatar May 21 '20 17:05 Noofbiz

Perhaps reopen @diwant's PR? I didn't realise it remained closed.

Interestingly, I just stumbled upon a talk Mike Acton gave about ECS in Unity (which appears to be the direction in which they're moving), and he talks about this exact problem, giving a brief walkthrough the implementation:

https://youtu.be/p65Yt20pw0g?t=3087

Asday avatar Jun 05 '20 21:06 Asday

Yeah, that's why I think updating the example is the best way to do it. It'll show users how to do it themselves, but like how every game is going to have a different control system for obvious reasons, every game is going to have different rules regarding what happens based on parent/child relationships. One may want it to orbit a parent instead of simply follow. Idk if there is a general purpose kinda system for that.

Noofbiz avatar Jun 06 '20 01:06 Noofbiz

I think I need to watch like 30 hours of 3blue1brown videos 'cause I'm sure matrix operations are the general purpose magical answer to everything, and I'm twice as sure that I don't understand them at all.

In the case of an orbiting example, parenting doesn't make sense. Each step of the simulation, the GravitySystem would step through each celestial body and apply a force to them, then the PhysicsSystem would step through each celestial body and calculate the new position and momentum based on the force (off the top of my head and probably entirely incorrectly).

From what I understand, the way all scene graphs work is a transform to a parent happens to all its children. If I scale the tank body up by 2x, the turret is also scaled by 2x. If I rotate the turret by 90°, the barrel is also rotated by 90° (about the parent's point of rotation). If someone wanted to reimplement, let's say, Robotnik's egg forcefield things, the EggForcefieldThingSystem would step over each of them, and modify their position based on perhaps dt modulo something. Separately, the RobotnikAISystem would modify Robotnik's position based on whatever it needs to, and the ParentingSystem would somehow have to know about this, subsequently updating all children.

Difficulty probably comes in when scaling things, as if I scale something by 2x, and its child moves by a local 1, I'd expect it to move globally by 2. I think. It's been a while since I fired Unity up.

Asday avatar Jun 06 '20 02:06 Asday

Just came back to this after following a few trips through other frameworks to see how it's done elsewhere.

As you mentioned above, I'm hoping for the parent child relationship to imply transformation from parent to child. A general purpose system might be something like this: https://webglfundamentals.org/webgl/lessons/webgl-scene-graph.html

I found something implemented on another game engine in Go, g3n (https://github.com/g3n/engine). They have a heirarchical scene graph implemented, which works like the scene graph described above.

(Now I'm moving from there to Magnum as I realized I need to communicate a lot with FFMPEG's libav which is in C++ and I'm not able to do all I need with it via goav, a go wrapper library on libav. So I'm off to C++ land.)

hth

diwant avatar Aug 29 '20 21:08 diwant