Parent Transforms and local rotation

I am exploring the basic rotation system with a bunch of cubes. I wanted to see if I can set a parent transform to the cubes (which rotate along the y axis) a Transform at (0,0,0). Then add the rotation and rotation speed components to it so that it will rotate and rotate all its children as well.

The parent transform (although not rendered) i can see in the debugger that it rotates properly. all the cubes rotate properly and they have the correct entity id set as transform parent, but they do not rotate around the parent transform

Cube = World.Active.GetOrCreateManager<EntityManager>().CreateArchetype(typeof(Position), typeof(CubeComp),
                typeof(MeshInstanceRenderer), typeof(TransformMatrix), typeof(Rotation), typeof(RotationSpeed), typeof(TransformParent));

RotationFocus = World.Active.GetOrCreateManager<EntityManager>().CreateArchetype(typeof(Position), typeof(Rotation)
                , typeof(RotationSpeed), typeof(TransformMatrix));

transform = World.Active.GetOrCreateManager<EntityManager>().CreateEntity(RotationFocus);
        World.Active.GetOrCreateManager<EntityManager>().SetComponentData<Position>(transform, new Position {Value = new float3(0, 0, 0)});
        World.Active.GetOrCreateManager<EntityManager>().SetComponentData<RotationSpeed>(transform, new RotationSpeed { Value = 2});

Below is how i assign the parent

PostUpdateCommands.SetComponent(new TransformParent { Value = Bootstrap.transform});

and the rotation system is here (most of you probably know it from the example

public void Execute(ref Rotation rotation, [ReadOnly]ref RotationSpeed speed){
            rotation.Value = math.mul(math.normalize(rotation.Value), math.axisAngle(math.up(), speed.Value * dt ));
        }

The expected behavior is for all cubes to rotate along their y axis and along the unitys origin point. The second part doesnt happen. Any insights?

Change your cubes’ Rotation and Position components to LocalRotation and LocalPosition so they are interpreted in local coordinates.

We are discussing issues related to simplifying the transform process (among other related things) now. So expect that to get cleaned up a lot.

5 Likes

I just tried it. I left rotation on the parent, the rotation values change as i see in entity debugger.
I changed the system and the cube to use local rotation for the cubes. And they rotate.
Still though they do not rotate around the parent entity. I am setting transformparent on all cubes, maybe i need some extra component ?

EDIT: i tried putting the parent on local rotation just in case. didnt do anything

EDIT2: I am stupid, managed to figure it out. Holy crap its convoluted! :smile:
Which begs the question, how does one sort this out in a more complex environment, or will it be sorted out on the engine side later?
I can see the cleaning up of the system that is needed but to what extent?

Holy shit!! I saw a performance hit that was MAD! 8fps. I got something like 40ms more, is there a way to avoid this ? Or some pointers to understand how to do this better
I have declared the parent to run before the children.

EDIT: adding a github in case someone wants to look in detail REPO

Having a sample is great. I’ll need to take a look at this.

It’s not immediately obvious from your screenshot why the job would take as long as it is. However, why it’s only one job is known: having 50k transformed parented under a single root isn’t the expected common case. (Or at least it’s expected if you have one of those hierarchies, you probably have more than one) - each sub-hierarchy is currently running in it’s own job. But I can have a look at that too.

I’ve got it updating, but it looks like you’re using other preview packages, so I may need to get on a different branch to compare correctly. What build are you using?

From the Entity Debugger, I also see you’re actually updating 200,000 transforms here. Is that the number you were expecting?

I am trying to push ECS and my computer and see the edges, I think this might be helpful to more than me, so yes my tests 200k on my pc (most times i remember to lower it to 50k.
200k help me see and understand more in the profiler

I am using unity 2018.1.0f2.
Although i am playing around in this project the packages that arent just loaded into the project, but i actually expect them to do things is the Lightweight renderer pipeline, so i could explore a little bit of shadergreaph, although that is not my thing.
and the Incremental compiler along with Entities
“com.unity.incrementalcompiler”: “0.0.41”,
“com.unity.entities”: “0.0.12-preview.1”

I will make a clean version without the lightweight rendering pipeline and leave just the ECS and burst. Made a new branch on the same git called Stripped, performance is the same. Can’t use preview.2 when the entity manager gets created even in an empty project i get reflection exceptions.

It bugs me that on a 1080ti and 1060gtx the framerate is identical and the utilization of the cards are at 20%. Might not be relevant to this problem, but i thought i would mention it just in case it points at something.
The 1080 is running a ryzen 1700 and the 1060 system on an i7 7700. both with ample amounts of ram.

Yeah, I see what’s happening. In this particular case if you write to the TransformMatrix yourself, it would be much faster. You can specifically know what you’re trying to do here and do it all in one place without the transform system trying to update a general purpose hierarchy (which is actually what I had expected for a case like this.) But that being said, I think we can do quite a lot to improve this example anyway so I’ll have a look at that.

3 Likes

Oh please do. that will help my learning curve a whole lot especially this early! <3 Ill try to figure out what sort of calculation i need to on the transformation matrix to get it right

1 Like

It doesnt write to the transform matrix for some reason

struct RotationSpeedParent : IJobProcessComponentData<TransformMatrix, Rotation, RotationFocus>{
        public float dt;

        public void Execute(ref TransformMatrix tranformMatrix, [ReadOnly]ref Rotation rotation, [ReadOnly]ref RotationFocus tp){
            quaternion q = math.mul(math.normalize(rotation.Value), math.axisAngle(math.up(), 2 * dt ));
            float4x4 m = tranformMatrix.Value;

            float x = q.value.x * 2.0F;
float y = q.value.y * 2.0F;
float z = q.value.z * 2.0F;
float xx = q.value.x * x;
float yy = q.value.y * y;
float zz = q.value.z * z;
float xy = q.value.x * y;
float xz = q.value.x * z;
float yz = q.value.y * z;
float wx = q.value.w * x;
float wy = q.value.w * y;
            float wz = q.value.w * z;

            m.m0.x = 1.0f - (yy + zz); m.m1.x = xy + wz; m.m2.x = xz - wy; m.m3.x = 0.0F;
m.m0.y = xy - wz; m.m1.y = 1.0f - (xx + zz); m.m2.y = yz + wx; m.m3.y = 0.0F;
m.m0.z = xz + wy; m.m1.z = yz - wx; m.m2.z = 1.0f - (xx + yy); m.m3.z = 0.0F;
            m.m0.w = 0.0F; m.m1.w = 0.0F; m.m2.w = 0.0F; m.m3.w = 1.0F;

            tranformMatrix.Value = m;
            // rotation.Value = math.mul(math.normalize(rotation.Value), math.axisAngle(math.up(), speed.Value * dt ));
        }

Edit 3: I tried to put [UpdateAfter(typeof(TransformSystem))] but that didnt do anything. I thought that the transform system was overwriting the TransformMatrix, but nothing changed in the end

Edit4: After some testing i saw that the due to me reading the rotation value i would only change the numbers slightly on the first frame and then the rotation in the transform wouldnt get updated. So i tried updating it, still using after the transform system. In this case it would rotate everything around the pivot but if i disabled the transform system then the transform matrix would get updated normaly but nothing would hapen, which i guess is expected

Add VoidSystem components which will tell the transform system to ignore them.

2 Likes

Sorry for the late reply.

I updated the stripped branch.
I know my math isnt right - yet, but I do all the work having disabled the TransformSystem. I dont see any improvement though. In editor i get like 22-25ms+8ms where everything is idle from editor overhead from what the profiler is showing me. On the built executable it renders at what appears to be a more clunky version of the editor.

Looked at your latest version. Things actually do look much better. Your main transform update is ~7ms - some room to speed that up, but it’s reasonable for how much you’re transforming.

Most of the time is in the MeshInstanceRenderSystem right now. That’s expected since that system is really just placeholder until we get rendering hooked up and it’s doing a lot of copies from native arrays to managed arrays on the main thread. (You can see the breakdown from the timeline view in the profiler.)

Ok then i will have to wait until that happens! Thanks a lot @mike_acton
Are there any plans currently on when such a thing will roll out with the MeshInstanceRenderSystem?

Edit: Also if someone can point out to me where i go wrong with the math it would be appreciated. Its the first time I actually have to do the matrix transformations (blindness due to inexperience ehehe)