Exemple #1
0
        public void GetOrCreateSingletonTest()
        {
            EcsWorld world = new EcsWorld();

            ComponentA componentA0 = world.GetOrCreateSingleton <ComponentA>();
            ComponentA componentA1 = world.GetOrCreateSingleton <ComponentA>();

            Assert.AreEqual(componentA0, componentA1);
        }
        public void Update(float deltaTime, EcsWorld world)
        {
            BroadphaseSAPComponent bpChunks =
                world.GetOrCreateSingleton <BroadphaseSAPComponent>();

            foreach (BroadphasePair pair in bpChunks.Pairs)
            {
                IEcsEntity entityA = pair.EntityA;
                IEcsEntity entityB = pair.EntityB;

                TransformComponent ta = entityA.GetComponent <TransformComponent>();
                TransformComponent tb = entityB.GetComponent <TransformComponent>();
                ColliderComponent  ca = entityA.GetComponent <ColliderComponent>();
                ColliderComponent  cb = entityB.GetComponent <ColliderComponent>();

                ContactInfo info;
                if (ca.ColliderType == ColliderType.Circle && cb.ColliderType == ColliderType.Circle)
                {
                    OnCircleCircleCollision(ca, ta, cb, tb, out info);
                }
                else if (ca.ColliderType == ColliderType.Circle && cb.ColliderType == ColliderType.Rect)
                {
                    OnCircleRectCollision(ca, ta, cb, tb, out info);
                }
                else if (ca.ColliderType == ColliderType.Rect && cb.ColliderType == ColliderType.Circle)
                {
                    OnCircleRectCollision(cb, tb, ca, ta, out info);
                    info.Normal = -info.Normal;
                }
                else
                {
                    throw new InvalidOperationException();
                }

                if (!info.Hit)
                {
                    continue;
                }

                RigBodyComponent ra = entityA.GetComponent <RigBodyComponent>();
                RigBodyComponent rb = entityB.GetComponent <RigBodyComponent>();

                float2 rv = rb.Velocity - ra.Velocity;

                float contactVel = math.dot(rv, info.Normal);
                float invMassSum = ra.InvMass + rb.InvMass;

                float  f       = -contactVel / invMassSum;
                float2 impulse = info.Normal * f * deltaTime;

                ra.Velocity -= ra.InvMass * impulse;
                rb.Velocity += rb.InvMass * impulse;

                float2 correction = info.Penetration / (ra.InvMass + rb.InvMass) * info.Normal * 0.5f;
                ta.Position -= correction * ra.InvMass;
                tb.Position += correction * rb.InvMass;
            }
        }
        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++; }
                }
            }
        }
        public void Update(float deltaTime, EcsWorld world)
        {
            BroadphaseSAPComponent bpChunks = world.GetOrCreateSingleton <BroadphaseSAPComponent>();

            bpChunks.Pairs.Clear();
            foreach (SAPChunk chunk in bpChunks.Chunks.Values)
            {
                BroadphaseHelper.BuildChunks(chunk);

                if (chunk.DynamicCounter > 0 || chunk.IsDirty)
                {
                    CalculatePairs(chunk);
                    chunk.IsDirty = chunk.DynamicCounter != 0;
                }

                for (int i = 0; i < chunk.PairLength; i++)
                {
                    bpChunks.Pairs.Add(chunk.Pairs[i]);
                }
            }
        }
Exemple #5
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;
            });
        }
        public void Update(float deltaTime, EcsWorld world)
        {
            BroadphaseSAPComponent bpChunks = world.GetOrCreateSingleton <BroadphaseSAPComponent>();

            bpChunks.Pairs.Clear();
        }
Exemple #7
0
        public unsafe void Update(float deltaTime, EcsWorld world)
        {
            BroadphaseSAPComponent bpChunks = world.GetOrCreateSingleton <BroadphaseSAPComponent>();

            world.Filter(_rayFilter).ForEach((IEcsEntity entity, TransformComponent tr, RayComponent ray) =>
            {
                ray.Hit      = false;
                ray.Source   = tr.Position;
                ray.Rotation = tr.Rotation;

                float minDist = float.MaxValue;
                RayTrace(ray, ref _chunksBuffer, ref _pointsBuffer, out int length);

                for (int i = 0; i < length - 1; i++)
                {
                    SAPChunk chunk = BroadphaseHelper.GetOrCreateChunk(_chunksBuffer[i], bpChunks);
                    float2 p1      = _pointsBuffer[i];
                    float2 p2      = _pointsBuffer[i + 1];

                    AABB sAABB = new AABB
                    {
                        Min = new float2(math.min(p1.x, p2.x), math.min(p1.y, p2.y)),
                        Max = new float2(math.max(p1.x, p2.x), math.max(p1.y, p2.y))
                    };

                    for (int j = 0; j < chunk.Length; j++)
                    {
                        BroadphaseAABB item = chunk.Items[j];
                        if (!item.AABB->Overlap(sAABB))
                        {
                            continue;
                        }

                        if (!_collisionMatrix.Check(ray.Layer, item.Layer))
                        {
                            continue;
                        }

                        IEcsEntity targetEntity = item.Entity;
                        if (entity == targetEntity)
                        {
                            continue;
                        }

                        tr = targetEntity.GetComponent <TransformComponent>();
                        ColliderComponent col = targetEntity.GetComponent <ColliderComponent>();

                        float2 hitPoint = float2.zero;
                        if (col.ColliderType == ColliderType.Circle && !OnCircleIntersection(ray, col, tr, out hitPoint) ||
                            col.ColliderType == ColliderType.Rect && !OnRectIntersection(ray, col, tr, out hitPoint))
                        {
                            continue;
                        }

                        float dist = math.distancesq(p1, hitPoint);
                        if (!(dist < minDist))
                        {
                            continue;
                        }

                        minDist      = dist;
                        ray.HitPoint = hitPoint;
                    }

                    if (!(minDist < float.MaxValue))
                    {
                        continue;
                    }

                    ray.Hit = true;
                    break;
                }
            });
        }