public unsafe void Update(float deltaTime, EcsWorld world)
        {
            BroadphaseSAPComponent bpChunks = world.GetOrCreateSingleton <BroadphaseSAPComponent>();

            IEcsEntity[] entities = world.Filter(_entitiesFilter).ToEntityArray();

            for (int i = 0; i < entities.Length; i++)
            {
                IEcsEntity entity   = entities[i];
                uint       entityId = entity.Id;

                TransformComponent tr  = entity.GetComponent <TransformComponent>();
                ColliderComponent  col = entity.GetComponent <ColliderComponent>();
                RigBodyComponent   rig = entity.GetComponent <RigBodyComponent>();

                AABB aabb     = new AABB(col.Size, tr.Position, col.ColliderType == ColliderType.Rect ? tr.Rotation : 0f);
                bool isStatic = MathHelper.Equal(rig.InvMass, 0);
                int  layer    = col.Layer;

                List <SAPChunk> chunks = new List <SAPChunk>(4);
                foreach (int chunkId in BroadphaseHelper.GetChunks(aabb))
                {
                    chunks.Add(BroadphaseHelper.GetOrCreateChunk(chunkId, bpChunks));
                }

                BroadphaseRefComponent bpRef = new BroadphaseRefComponent
                {
                    Chunks     = chunks,
                    ChunksHash = BroadphaseHelper.CalculateChunksHash(aabb),
                    AABB       = aabb
                };
                entity.AddComponent(bpRef);

                foreach (SAPChunk chunk in chunks)
                {
                    if (chunk.Length >= chunk.Items.Length)
                    {
                        Array.Resize(ref chunk.Items, 2 * chunk.Length);

                        fixed(AABB *pAABB = &bpRef.AABB)
                        {
                            chunk.Items[chunk.Length++] = new BroadphaseAABB
                            {
                                AABB     = pAABB,
                                Id       = entityId,
                                IsStatic = isStatic,
                                Layer    = layer,
                                Entity   = entity
                            };
                        }

                        if (!isStatic)
                            chunk.DynamicCounter++; }
                }
            }
        }
Example #2
0
        public unsafe void Update(float deltaTime, EcsWorld world)
        {
            BroadphaseSAPComponent bpChunks = world.GetOrCreateSingleton <BroadphaseSAPComponent>();

            world.Filter(_entitiesFilter).ForEach(
                (IEcsEntity entity, TransformComponent tr, ColliderComponent col, BroadphaseRefComponent bpRef) =>
            {
                AABB aabb = new AABB(col.Size, tr.Position,
                                     col.ColliderType == ColliderType.Rect ? tr.Rotation : 0f);

                fixed(AABB * pAABB = &bpRef.AABB)
                {
                    pAABB->Min = aabb.Min;
                    pAABB->Max = aabb.Max;
                }

                int chunksHash = BroadphaseHelper.CalculateChunksHash(aabb);
                if (bpRef.ChunksHash == chunksHash)
                {
                    return;
                }

                RigBodyComponent rig = entity.GetComponent <RigBodyComponent>();

                uint entityId = entity.Id;
                bool isStatic = MathHelper.Equal(rig.InvMass, 0);
                int layer     = col.Layer;

                List <SAPChunk> chunks    = bpRef.Chunks;
                List <SAPChunk> newChunks = new List <SAPChunk>(4);
                foreach (int chunkId in BroadphaseHelper.GetChunks(aabb))
                {
                    int index = -1;
                    for (int i = 0; i < chunks.Count; i++)
                    {
                        SAPChunk chunk = chunks[i];
                        if (chunk == null || chunk.Id != chunkId)
                        {
                            continue;
                        }

                        index = i;
                        break;
                    }

                    if (index >= 0)
                    {
                        SAPChunk chunk = chunks[index];
                        chunks[index]  = null;
                        newChunks.Add(chunk);
                    }
                    else
                    {
                        SAPChunk chunk = BroadphaseHelper.GetOrCreateChunk(chunkId, bpChunks);

                        if (chunk.Length >= chunk.Items.Length)
                        {
                            Array.Resize(ref chunk.Items, 2 * chunk.Length);
                        }

                        fixed(AABB * pAABB = &bpRef.AABB)
                        {
                            chunk.Items[chunk.Length++] = new BroadphaseAABB
                            {
                                AABB     = pAABB,
                                Id       = entityId,
                                IsStatic = isStatic,
                                Layer    = layer,
                                Entity   = entity
                            };
                        }

                        if (!isStatic)
                        {
                            chunk.DynamicCounter++;
                        }

                        newChunks.Add(chunk);
                    }
                }

                foreach (SAPChunk chunk in chunks)
                {
                    if (chunk == null)
                    {
                        continue;
                    }
                    BroadphaseHelper.RemoveFormChunk(chunk, entityId);
                }

                bpRef.Chunks     = newChunks;
                bpRef.ChunksHash = chunksHash;
            });
        }