void ChildLocalToWorld(float4x4 parentLocalToWorld, Entity entity, bool updateChildrenTransform)
            {
                updateChildrenTransform = updateChildrenTransform || LocalToParentFromEntity.DidChange(entity, LastSystemVersion);

                float4x4 localToWorldMatrix;

                if (updateChildrenTransform && LocalToWorldWriteGroupMask.Matches(entity))
                {
                    var localToParent = LocalToParentFromEntity[entity];
                    localToWorldMatrix             = math.mul(parentLocalToWorld, localToParent.Value);
                    LocalToWorldFromEntity[entity] = new LocalToWorld {
                        Value = localToWorldMatrix
                    };
                }
                else //This entity has a component with the WriteGroup(LocalToWorld)
                {
                    localToWorldMatrix      = LocalToWorldFromEntity[entity].Value;
                    updateChildrenTransform = updateChildrenTransform || LocalToWorldFromEntity.DidChange(entity, LastSystemVersion);
                }

                if (ChildFromEntity.HasComponent(entity))
                {
                    var children = ChildFromEntity[entity];
                    for (int i = 0; i < children.Length; i++)
                    {
                        ChildLocalToWorld(localToWorldMatrix, children[i].Value, updateChildrenTransform);
                    }
                }
            }
            void ChildLocalToWorld(float4x4 parentLocalToWorld, Entity entity)
            {
                var localToParent = LocalToParentFromEntity[entity];

                float4x4 localToWorldMatrix;

                if (LocalToWorldWriteGroupMask.Matches(entity))
                {
                    localToWorldMatrix             = math.mul(parentLocalToWorld, localToParent.Value);
                    LocalToWorldFromEntity[entity] = new LocalToWorld {
                        Value = localToWorldMatrix
                    };
                }
                else //This entity has a component with the WriteGroup(LocalToWorld)
                {
                    localToWorldMatrix = LocalToWorldFromEntity[entity].Value;
                }

                if (ChildFromEntity.Exists(entity))
                {
                    var children = ChildFromEntity[entity];
                    for (int i = 0; i < children.Length; i++)
                    {
                        ChildLocalToWorld(localToWorldMatrix, children[i].Value);
                    }
                }
            }
            void ChildLocalToWorld(float4x4 parentLocalToWorld, Entity entity)
            {
                var localToParent      = LocalToParentFromEntity[entity];
                var localToWorldMatrix = math.mul(parentLocalToWorld, localToParent.Value);

                LocalToWorldFromEntity[entity] = new LocalToWorld {
                    Value = localToWorldMatrix
                };

                if (ChildFromEntity.Exists(entity))
                {
                    var children = ChildFromEntity[entity];
                    for (int i = 0; i < children.Length; i++)
                    {
                        ChildLocalToWorld(localToWorldMatrix, children[i].Value);
                    }
                }
            }
Esempio n. 4
0
            public void Execute(ArchetypeChunk chunk, int chunkIndex, int entityOffset)
            {
                var chunkTranslations       = chunk.GetNativeArray(TranslationType);
                var chunkNonUniformScales   = chunk.GetNativeArray(NonUniformScaleType);
                var chunkScales             = chunk.GetNativeArray(ScaleType);
                var chunkCompositeScales    = chunk.GetNativeArray(CompositeScaleType);
                var chunkRotations          = chunk.GetNativeArray(RotationType);
                var chunkCompositeRotations = chunk.GetNativeArray(CompositeRotationType);
                var chunkLocalToWorld       = chunk.GetNativeArray(LocalToWorldType);
                var hasTranslation          = chunk.Has(TranslationType);
                var hasCompositeRotation    = chunk.Has(CompositeRotationType);
                var hasRotation             = chunk.Has(RotationType);
                var hasAnyRotation          = hasCompositeRotation || hasRotation;
                var hasNonUniformScale      = chunk.Has(NonUniformScaleType);
                var hasScale          = chunk.Has(ScaleType);
                var hasCompositeScale = chunk.Has(CompositeScaleType);
                var hasAnyScale       = hasScale || hasNonUniformScale || hasCompositeScale;
                var count             = chunk.Count;

                // #todo jump table when burst supports function pointers

                if (!hasAnyRotation)
                {
                    // 00 = invalid (must have at least one)
                    // 01
                    if (!hasTranslation && hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var scale = hasNonUniformScale ? float4x4.Scale(chunkNonUniformScales[i].Value) : (hasScale ? float4x4.Scale(new float3(chunkScales[i].Value)) : chunkCompositeScales[i].Value);

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = scale
                            };
                        }
                    }
                    // 10
                    else if (hasTranslation && !hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var translation = chunkTranslations[i].Value;

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = float4x4.Translate(translation)
                            };
                        }
                    }
                    // 11
                    else if (hasTranslation && hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var scale       = hasNonUniformScale ? float4x4.Scale(chunkNonUniformScales[i].Value) : (hasScale ? float4x4.Scale(new float3(chunkScales[i].Value)) : chunkCompositeScales[i].Value);
                            var translation = chunkTranslations[i].Value;

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = math.mul(float4x4.Translate(translation), scale)
                            };
                        }
                    }
                }
                else if (hasCompositeRotation)
                {
                    // 00
                    if (!hasTranslation && !hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var rotation = chunkCompositeRotations[i].Value;

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = rotation
                            };
                        }
                    }
                    // 01
                    else if (!hasTranslation && hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var rotation = chunkCompositeRotations[i].Value;
                            var scale    = hasNonUniformScale ? float4x4.Scale(chunkNonUniformScales[i].Value) : (hasScale ? float4x4.Scale(new float3(chunkScales[i].Value)) : chunkCompositeScales[i].Value);

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = math.mul(rotation, scale)
                            };
                        }
                    }
                    // 10
                    else if (hasTranslation && !hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var rotation    = chunkCompositeRotations[i].Value;
                            var translation = chunkTranslations[i].Value;

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = math.mul(float4x4.Translate(translation), rotation)
                            };
                        }
                    }
                    // 11
                    else if (hasTranslation && hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var rotation    = chunkCompositeRotations[i].Value;
                            var translation = chunkTranslations[i].Value;
                            var scale       = hasNonUniformScale ? float4x4.Scale(chunkNonUniformScales[i].Value) : (hasScale ? float4x4.Scale(new float3(chunkScales[i].Value)) : chunkCompositeScales[i].Value);

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = math.mul(math.mul(float4x4.Translate(translation), rotation), scale)
                            };
                        }
                    }
                }
                else // if (hasRotation) -- Only in same WriteGroup if !hasCompositeRotation
                {
                    // 00
                    if (!hasTranslation && !hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var rotation = chunkRotations[i].Value;

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = new float4x4(rotation, float3.zero)
                            };
                        }
                    }
                    // 01
                    else if (!hasTranslation && hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var rotation = chunkRotations[i].Value;
                            var scale    = hasNonUniformScale ? float4x4.Scale(chunkNonUniformScales[i].Value) : (hasScale ? float4x4.Scale(new float3(chunkScales[i].Value)) : chunkCompositeScales[i].Value);

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = math.mul(new float4x4(rotation, float3.zero), scale)
                            };
                        }
                    }
                    // 10
                    else if (hasTranslation && !hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var rotation    = chunkRotations[i].Value;
                            var translation = chunkTranslations[i].Value;

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = new float4x4(rotation, translation)
                            };
                        }
                    }
                    // 11
                    else if (hasTranslation && hasAnyScale)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var rotation    = chunkRotations[i].Value;
                            var translation = chunkTranslations[i].Value;
                            var scale       = hasNonUniformScale ? float4x4.Scale(chunkNonUniformScales[i].Value) : (hasScale ? float4x4.Scale(new float3(chunkScales[i].Value)) : chunkCompositeScales[i].Value);

                            chunkLocalToWorld[i] = new LocalToWorld
                            {
                                Value = math.mul(new float4x4(rotation, translation), scale)
                            };
                        }
                    }
                }
            }
Esempio n. 5
0
            public void Execute(int index, TransformAccess transform)
            {
                if (!ChangedIndices.TryGetValue(index, out var selfChanged))
                {
                    return;
                }
                int  id      = Hierarchy.GetInstanceIdForIndex(index);
                var  iter    = ConvertedEntities.GetEntities(id);
                bool isFirst = true;

                while (iter.MoveNext())
                {
                    var e = iter.Current;
                    if (!LocalToWorld.HasComponent(e))
                    {
                        continue;
                    }

                    // check whether this is a primary entity or needs to have its transform copied from the primary
                    if (!isFirst && !CopyTransformFromRoot.HasComponent(e))
                    {
                        continue;
                    }
                    isFirst = false;

                    LocalToWorld[e] = new LocalToWorld {
                        Value = transform.localToWorldMatrix
                    };
                    if (selfChanged)
                    {
                        if (!Translation.HasComponent(e))
                        {
                            // static entity
                            continue;
                        }

                        Translation[e] = new Translation {
                            Value = transform.localPosition
                        };
                        if (Rotation.HasComponent(e))
                        {
                            Rotation[e] = new Rotation {
                                Value = transform.localRotation
                            }
                        }
                        ;

                        float3 scale;
                        if (Parent.HasComponent(e))
                        {
                            scale = CalculateLossyScale(transform.localToWorldMatrix, transform.rotation);
                        }
                        else
                        {
                            scale = transform.localScale;
                        }

                        if (math.any(scale != new float3(1)))
                        {
                            var scaleComponent = new NonUniformScale {
                                Value = transform.localScale
                            };
                            if (NonUniformScale.HasComponent(e))
                            {
                                NonUniformScale[e] = scaleComponent;
                            }
                            else
                            {
                                Ecb.AddComponent(index, e, scaleComponent);
                            }
                        }
                        else
                        {
                            if (NonUniformScale.HasComponent(e))
                            {
                                Ecb.RemoveComponent <NonUniformScale>(index, e);
                            }
                        }
                    }
                }
            }