Esempio n. 1
0
        public void Execute(Entity e, int jobIndex, ref Translation translation, ref VelocityComponent velocity, [ReadOnly] ref ProjectileComponent projectile)
        {
            if (translation.Value.y < 0.15f)
            {
                // find all the entities in the nearby quad and destroy it if within the radius
                int key = QuadrantSystem.GetPositionHashMapKey(translation.Value);

                if (QuadMap.TryGetFirstValue(key, out var data, out var it))
                {
                    do
                    {
                        float distance = distancesq(data.position, translation.Value);
                        if (data.quadEntityData.type == QuadEntityType.Cavalry)
                        {
                            continue;
                        }
                        if (distance < projectile.DamageRadius)
                        {
                            CommandBuffer.DestroyEntity(jobIndex, data.e);
                        }
                    } while (QuadMap.TryGetNextValue(out data, ref it));
                }
                CommandBuffer.DestroyEntity(jobIndex, e);
            }
            // apply gravity
            velocity.Value.y += -0.0098f * projectile.Weight;
            velocity.Value.y  = clamp(velocity.Value.y, -10f, 100f);
            // apply air resistance
            velocity.Value.z += projectile.AirResistance * -0.0001f;
            velocity.Value.z  = clamp(velocity.Value.z, 0.5f, 100f);

            translation.Value += velocity.Value * deltaTime;
        }
        public void Execute([ReadOnly] ref Translation translation, ref TargetComponent target, [ReadOnly] ref QuadrantEntityComponent entityQuadInfo)
        {
            float3 entityPosition = translation.Value;

            // if the entity is so far off the map, it doesn't even need to search for anything
            if (entityPosition.z > 80 || entityPosition.z < -200)
            {
                return;
            }

            float closestDistance = 1000f;

            int hashKey = QuadrantSystem.GetPositionHashMapKey(entityPosition);

            if (EntityHashMap.TryGetFirstValue(hashKey, out var quadData, out var it))
            {
                do
                {
                    if (((ushort)(quadData.quadEntityData.type) & target.targetMask) == 0)
                    {
                        continue;
                    }

                    float3 otherUnitLoc = quadData.position;

                    // only care to find a target that is in the approximate same lane
                    if (abs(otherUnitLoc.x - entityPosition.x) > 25f)
                    {
                        continue;
                    }

                    // check distance after
                    float currentDis = distancesq(entityPosition, otherUnitLoc);

                    // if the distance is closer then the minimum, it found the necessary target,
                    // use that cavalry unit as the target immediately
                    if (closestDistance > currentDis)
                    {
                        if ((ushort)(entityQuadInfo.type & QuadEntityType.Cavalry) != 0)
                        {
                            // if this is a cavalry unit make the entity targeted so that other cavalry units can't take it
                        }
                        closestDistance = currentDis;
                        target.entity   = quadData.e;
                        target.location = otherUnitLoc;
                    }
                } while (EntityHashMap.TryGetNextValue(out quadData, ref it));
            }

            if (closestDistance > 999f)
            {
                target.entity = Entity.Null;
            }
        }
Esempio n. 3
0
        public void Execute(Entity e, int jobIndex, ref Translation translation, ref WidthComponent width)
        {
            int hashKey = QuadrantSystem.GetPositionHashMapKey(translation.Value);

            BlockMap.Add(hashKey, new BlockerData
            {
                entity   = e,
                position = translation.Value,
                width    = width.Value
            });
        }
Esempio n. 4
0
        public void Execute(Entity entity, int index, ref Translation translation, ref PhysicsCollider collider, ref CollisionData collisionData)
        {
            int hashMapKey = QuadrantSystem.GetPositionHashMapKey(translation.Value);

            CheckCollisions(hashMapKey, index, ref entity, ref translation, ref collider, ref collisionData);
            CheckCollisions(hashMapKey + 1, index, ref entity, ref translation, ref collider, ref collisionData);
            CheckCollisions(hashMapKey - 1, index, ref entity, ref translation, ref collider, ref collisionData);
            CheckCollisions(hashMapKey + QuadrantSystem.quadrantYMultiplier, index, ref entity, ref translation, ref collider, ref collisionData);
            CheckCollisions(hashMapKey - QuadrantSystem.quadrantYMultiplier, index, ref entity, ref translation, ref collider, ref collisionData);
            CheckCollisions(hashMapKey + 1 + QuadrantSystem.quadrantYMultiplier, index, ref entity, ref translation, ref collider, ref collisionData);
            CheckCollisions(hashMapKey - 1 + QuadrantSystem.quadrantYMultiplier, index, ref entity, ref translation, ref collider, ref collisionData);
            CheckCollisions(hashMapKey + 1 - QuadrantSystem.quadrantYMultiplier, index, ref entity, ref translation, ref collider, ref collisionData);
            CheckCollisions(hashMapKey - 1 - QuadrantSystem.quadrantYMultiplier, index, ref entity, ref translation, ref collider, ref collisionData);
        }
Esempio n. 5
0
        public void Execute(Entity e, int jobIndex, [ReadOnly] ref Translation translation, [ReadOnly] ref MeleeStrengthComponent strength, ref MovementStateComponent state)
        {
            int hashKey = QuadrantSystem.GetPositionHashMapKey(translation.Value);

            state.Value = (ushort)MovementState.Moving;
            if (BlockerMap.TryGetFirstValue(hashKey, out var blockerData, out var it))
            {
                float zombieX = translation.Value.x;
                do
                {
                    float furthestRight = blockerData.position.x + blockerData.width / 2;
                    float furthestLeft  = blockerData.position.x - blockerData.width / 2;

                    if (zombieX < furthestLeft || zombieX > furthestRight)
                    {
                        continue;
                    }

                    // within the bounds of the blocker
                    // check how far away are you from the blocker
                    if (abs(translation.Value.z - blockerData.position.z) > 2.5f)
                    {
                        continue;
                    }

                    if (!HealthData.Exists(blockerData.entity))
                    {
                        // entity is dead
                        return;
                    }
                    // the zombie is right in front of the blocker
                    state.Value = (ushort)MovementState.Blocked;

                    // detect if the blocker has a DamageTag. If not, add one
                    if (!DamageData.Exists(blockerData.entity))
                    {
                        CommandBuffer.AddComponent(jobIndex, blockerData.entity, new BlockerDamageTag());
                        return;
                    }
                } while(BlockerMap.TryGetNextValue(out blockerData, ref it));
            }
        }
Esempio n. 6
0
        public void Execute(Entity entity, int index, [ReadOnly] ref Sight sight,
                            [ReadOnly] ref LocalToWorld location, [ReadOnly] ref QuadrantEntity quadrantEntity, [ReadOnly] ref Diet diet,
                            [ReadOnly] ref AnimalSize size, [ReadOnly] ref LifeStatus lifeStatus)
        {
            EntityWithPosition closestDangerTarget = new EntityWithPosition {
                entity = Entity.Null
            };
            float closestDangerTargetDistance    = float.MaxValue;
            EntityWithPosition closestFoodTarget = new EntityWithPosition {
                entity = Entity.Null
            };
            float closestFoodTargetDistance = float.MaxValue;
            int   hashMapKey = QuadrantSystem.GetPositionHashMapKey(location.Position);

            var entityDesc = new EntityDescription()
            {
                sight          = sight,
                diet           = diet,
                location       = location,
                quadrantEntity = quadrantEntity,
                size           = size,
                lifeStatus     = lifeStatus
            };


            FindTarget(index, hashMapKey, entityDesc, ref closestDangerTarget, ref closestDangerTargetDistance, ref closestFoodTarget, ref closestFoodTargetDistance);
            FindTarget(index, hashMapKey + 1, entityDesc, ref closestDangerTarget, ref closestDangerTargetDistance, ref closestFoodTarget, ref closestFoodTargetDistance);
            FindTarget(index, hashMapKey - 1, entityDesc, ref closestDangerTarget, ref closestDangerTargetDistance, ref closestFoodTarget, ref closestFoodTargetDistance);
            FindTarget(index, hashMapKey + QuadrantSystem.quadrantYMultiplier, entityDesc, ref closestDangerTarget, ref closestDangerTargetDistance, ref closestFoodTarget, ref closestFoodTargetDistance);
            FindTarget(index, hashMapKey - QuadrantSystem.quadrantYMultiplier, entityDesc, ref closestDangerTarget, ref closestDangerTargetDistance, ref closestFoodTarget, ref closestFoodTargetDistance);
            FindTarget(index, hashMapKey + 1 + QuadrantSystem.quadrantYMultiplier, entityDesc, ref closestDangerTarget, ref closestDangerTargetDistance, ref closestFoodTarget, ref closestFoodTargetDistance);
            FindTarget(index, hashMapKey - 1 + QuadrantSystem.quadrantYMultiplier, entityDesc, ref closestDangerTarget, ref closestDangerTargetDistance, ref closestFoodTarget, ref closestFoodTargetDistance);
            FindTarget(index, hashMapKey + 1 - QuadrantSystem.quadrantYMultiplier, entityDesc, ref closestDangerTarget, ref closestDangerTargetDistance, ref closestFoodTarget, ref closestFoodTargetDistance);
            FindTarget(index, hashMapKey - 1 - QuadrantSystem.quadrantYMultiplier, entityDesc, ref closestDangerTarget, ref closestDangerTargetDistance, ref closestFoodTarget, ref closestFoodTargetDistance);

            closestDangerTargetArray[index] = closestDangerTarget;
            closestFoodTargetArray[index]   = closestFoodTarget;
        }
Esempio n. 7
0
        // todo: maybe intelligent ones should avoid not only the blockers but also each other?
        public void Execute([ReadOnly] ref Translation translation, [ReadOnly] ref TargetComponent target, ref MovementComponent movement)
        {
            int    hashKey               = QuadrantSystem.GetPositionHashMapKey(translation.Value);
            float3 dir                   = new float3(0, 0, -1);
            float  closestDis            = 1000f;
            float3 closestPos            = float3(10000f, 1000f, 1000f);
            bool   bFoundPotentialThreat = false;

            if (BlockerMap.TryGetFirstValue(hashKey, out var data, out var it))
            {
                float zombieX = translation.Value.x;
                do
                {
                    // todo: maybe you should first find the closest target first and then determine if it's worth avoiding
                    // are you close enough to care?
                    float furthestRight = data.position.x + data.width / 2 + 2f;
                    float furthestLeft  = data.position.x - data.width / 2 - 2f;

                    if (zombieX < furthestLeft || zombieX > furthestRight)
                    {
                        continue;
                    }

                    float disSq = distancesq(translation.Value, data.position);
                    if (disSq > closestDis)
                    {
                        continue;
                    }

                    closestDis            = disSq;
                    closestPos            = data.position;
                    bFoundPotentialThreat = true;
                } while (BlockerMap.TryGetNextValue(out data, ref it));
            }
            if (!bFoundPotentialThreat)
            {
                movement.defaultDirection = dir;
                // todo: cause an irrational movement
                return;
            }
            if (closestDis > 150f)
            {
                movement.defaultDirection = dir;
                return;
            }

            // yes avoid
            float3 vFromAiToBlocker = normalize(closestPos - translation.Value);
            float  dotProd          = dot(dir, vFromAiToBlocker);

            // is it behind?
            if (dotProd < 0f)
            {
                movement.defaultDirection = dir;
                return;
            }

            // detect if to the left or to the right
            float3 right = new float3(1, 0, 0);
            float  side  = dot(right, vFromAiToBlocker);

            if (side > 0f)
            {
                // to the right, go left
                movement.defaultDirection.x -= ((movement.direction.x - 0.1) < -1) ? 0 : 0.1f;
                movement.defaultDirection.z += ((movement.direction.z + 0.1) > 0) ? 0 : 0.1f;
                return;
            }
            // to the left, go right
            movement.defaultDirection.x += ((movement.direction.x + 0.1) > 1) ? 0 : 0.1f;
            movement.defaultDirection.z += ((movement.direction.z + 0.1) > 0) ? 0 : 0.1f;
        }
Esempio n. 8
0
    protected override void OnUpdate()
    {
        var   quadrantMultiHashMap = quadrantMultiHashMap2;
        float deltaTime            = Time.DeltaTime;

        var ecb = m_EndSimulationEcbSystem.CreateCommandBuffer().ToConcurrent();

        NativeArray <long> localInfectedCounter = new NativeArray <long>(1, Allocator.TempJob);

        localInfectedCounter[0] = 0;

        NativeArray <long> localTotalInfectedCounter = new NativeArray <long>(1, Allocator.TempJob);

        localTotalInfectedCounter[0] = 0;

        NativeArray <long> localSymptomaticCounter = new NativeArray <long>(1, Allocator.TempJob);

        localSymptomaticCounter[0] = 0;

        NativeArray <long> localAsymptomaticCounter = new NativeArray <long>(1, Allocator.TempJob);

        localAsymptomaticCounter[0] = 0;

        NativeArray <long> localDeathCounter = new NativeArray <long>(1, Allocator.TempJob);

        localDeathCounter[0] = 0;

        NativeArray <long> localRecoveredCounter = new NativeArray <long>(1, Allocator.TempJob);

        localRecoveredCounter[0] = 0;

        NativeArray <long> localTotalRecoveredCounter = new NativeArray <long>(1, Allocator.TempJob);

        localTotalRecoveredCounter[0] = 0;

        //job -> each element, if not infected, check if there are infected in its same quadrant
        var jobHandle = Entities.ForEach((Entity entity, int nativeThreadIndex, Translation t, ref QuadrantEntity qe, ref HumanComponent humanComponent, ref InfectionComponent ic) => {
            //for non infected entities, a check in the direct neighbours is done for checking the presence of infected
            if (ic.status == Status.susceptible)
            {
                //not infected-> look for infected in same cell
                int hashMapKey = QuadrantSystem.GetPositionHashMapKey(t.Value);
                //Debug.Log("Infected false");
                QuadrantData quadrantData;
                NativeMultiHashMapIterator <int> nativeMultiHashMapIterator;
                if (quadrantMultiHashMap.TryGetFirstValue(hashMapKey, out quadrantData, out nativeMultiHashMapIterator))
                {
                    //cycle through all entries oh hashmap with the same Key
                    do
                    {
                        //Debug.Log(quadrantData.position);
                        if (math.distance(t.Value, quadrantData.position) < 2f)
                        {
                            //TODO consider also social resp other human involved
                            //increment infectionCounter if one/more infected are in close positions (infected at quadrantData.position)
                            //infection counter is determined by time and human responsibility
                            ic.contagionCounter += 1f * deltaTime * (1 - humanComponent.socialResposibility);
                        }
                        //TODO we could add a cap here to speed up the check
                    } while (quadrantMultiHashMap.TryGetNextValue(out quadrantData, ref nativeMultiHashMapIterator));
                }
                else
                {
                    //no infected in same cell -> human is safe
                    ic.contagionCounter = 0f;
                }
            }
            //infection happened
            if (ic.contagionCounter >= contagionThreshold && ic.status == Status.susceptible)
            {
                //human become infected
                unsafe {
                    Interlocked.Increment(ref ((long *)localInfectedCounter.GetUnsafePtr())[0]);
                    Interlocked.Increment(ref ((long *)localTotalInfectedCounter.GetUnsafePtr())[0]);
                }
                qe.typeEnum       = QuadrantEntity.TypeEnum.exposed;
                ic.status         = Status.exposed;
                ic.exposedCounter = 0;
            }

            //Infectious status -> symptoms vs non-symptoms
            if (ic.exposedCounter > ic.exposedThreshold && ic.status == Status.exposed)
            {
                qe.typeEnum = QuadrantEntity.TypeEnum.infectious;
                ic.status   = Status.infectious;
                ic.infected = true;

                if (ic.humanSymptomsProbability > (100 - ic.globalSymptomsProbability))
                {
                    //symptomatic -> lasts between 0.5 and 1.5 day
                    ic.symptomatic = true;
                    unsafe
                    {
                        Interlocked.Increment(ref ((long *)localSymptomaticCounter.GetUnsafePtr())[0]);
                    }
                    ic.infectiousCounter = 0;
                }
                else
                {
                    //asymptomatic
                    ic.symptomatic = false;
                    unsafe
                    {
                        Interlocked.Increment(ref ((long *)localAsymptomaticCounter.GetUnsafePtr())[0]);
                    }
                    ic.infectiousCounter = 0;
                }
            }

            if (ic.infectiousCounter > ic.infectiousThreshold && ic.status == Status.infectious)
            {
                if (ic.humanDeathProbability > (100 - ic.globalDeathProbability))
                {
                    //remove entity
                    unsafe
                    {
                        Interlocked.Increment(ref ((long *)localDeathCounter.GetUnsafePtr())[0]);
                        Interlocked.Decrement(ref ((long *)localInfectedCounter.GetUnsafePtr())[0]);
                    }


                    if (ic.symptomatic)
                    {
                        unsafe
                        {
                            Interlocked.Decrement(ref ((long *)localSymptomaticCounter.GetUnsafePtr())[0]);
                        }
                    }
                    else
                    {
                        unsafe
                        {
                            Interlocked.Decrement(ref ((long *)localAsymptomaticCounter.GetUnsafePtr())[0]);
                        }
                    }
                    ic.status   = Status.removed;
                    qe.typeEnum = QuadrantEntity.TypeEnum.removed;
                    ecb.DestroyEntity(nativeThreadIndex, entity);
                }
                else
                {
                    //recovery time set up
                    unsafe {
                        Interlocked.Decrement(ref ((long *)localInfectedCounter.GetUnsafePtr())[0]);
                        Interlocked.Increment(ref ((long *)localRecoveredCounter.GetUnsafePtr())[0]);
                        Interlocked.Increment(ref ((long *)localTotalRecoveredCounter.GetUnsafePtr())[0]);
                    }
                    if (ic.symptomatic)
                    {
                        unsafe
                        {
                            Interlocked.Decrement(ref ((long *)localSymptomaticCounter.GetUnsafePtr())[0]);
                        }
                    }
                    else
                    {
                        unsafe
                        {
                            Interlocked.Decrement(ref ((long *)localAsymptomaticCounter.GetUnsafePtr())[0]);
                        }
                    }

                    ic.status   = Status.recovered;
                    ic.infected = false;
                    //qe.typeEnum = QuadrantEntity.TypeEnum.recovered;
                    ic.recoveredCounter = 0;
                }
            }

            if (ic.recoveredCounter > ic.recoveredThreshold && ic.status == Status.recovered)
            {
                ic.status   = Status.susceptible;
                qe.typeEnum = QuadrantEntity.TypeEnum.susceptible;
                unsafe {
                    Interlocked.Decrement(ref ((long *)localRecoveredCounter.GetUnsafePtr())[0]);
                }
            }

            if (ic.status == Status.exposed)
            {
                ic.exposedCounter += 1f * deltaTime;
            }
            if (ic.status == Status.infectious)
            {
                ic.infectiousCounter += 1f * deltaTime;
            }
            if (ic.status == Status.recovered)
            {
                ic.recoveredCounter += 1f * deltaTime;
            }
        }).WithReadOnly(quadrantMultiHashMap).ScheduleParallel(Dependency);

        m_EndSimulationEcbSystem.AddJobHandleForProducer(jobHandle);
        this.Dependency = jobHandle;

        jobHandle.Complete();

        unsafe {
            Interlocked.Add(ref infectedCounter, Interlocked.Read(ref ((long *)localInfectedCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref totalInfectedCounter, Interlocked.Read(ref ((long *)localTotalInfectedCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref symptomaticCounter, Interlocked.Read(ref ((long *)localSymptomaticCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref asymptomaticCounter, Interlocked.Read(ref ((long *)localAsymptomaticCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref recoveredCounter, Interlocked.Read(ref ((long *)localRecoveredCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref deathCounter, Interlocked.Read(ref ((long *)localDeathCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref populationCounter, -Interlocked.Read(ref ((long *)localDeathCounter.GetUnsafePtr())[0]));
        }

        //Write some text to the test.txt file
        writer.WriteLine(Interlocked.Read(ref populationCounter) + "\t"
                         + Interlocked.Read(ref infectedCounter) + "\t"
                         + Interlocked.Read(ref totalInfectedCounter) + "\t"
                         + Interlocked.Read(ref symptomaticCounter) + "\t"
                         + Interlocked.Read(ref asymptomaticCounter) + "\t"
                         + Interlocked.Read(ref deathCounter) + "\t"
                         + Interlocked.Read(ref recoveredCounter) + "\t"
                         + Interlocked.Read(ref totalRecoveredCounter) + "\t"
                         + (int)Datetime.total_minutes);

        localInfectedCounter.Dispose();
        localTotalInfectedCounter.Dispose();
        localAsymptomaticCounter.Dispose();
        localSymptomaticCounter.Dispose();
        localRecoveredCounter.Dispose();
        localTotalRecoveredCounter.Dispose();
        localDeathCounter.Dispose();
    }
Esempio n. 9
0
        public void Execute(Entity entity, int index, ref Translation translation, [ReadOnly] ref Rotation rotation, [ReadOnly] ref NonUniformScale nonUniformScale, [ReadOnly] ref MotionProperties motionProperties, ref Planetoid planetoidCrashInfo)
        {
            float3 position   = translation.Value;
            float3 scale      = nonUniformScale.Value;
            float  qRotationZ = rotation.Value.value.z;
            float  axisA      = nonUniformScale.Value.x / 2f;
            float  axisB      = nonUniformScale.Value.y / 2f;
            //TODO read the angle from quaternion
            //float angleZ = GameHandler.ToEulerAngles(q).z;
            //angleZ = angleZ % (2 * math.PI);
            // read z angle of entity rotation by multiplying right vector by quaternion:
            float3 rotationRightVectorN = math.normalize(qRotationZ * new float3(0, 0, 1));

            int hashMapKey = QuadrantSystem.GetPositionHashMapKey(position);

            if (quadrantMultiHashMap.TryGetFirstValue(hashMapKey, out EntityWithProps inspectedEntityWithProps, out NativeMultiHashMapIterator <int> it)) //TODO check the neighbouring quadrants
            {                                                                                                                                             //TODO find the closest entity and only monitor that one
                do
                {
                    float distance = math.distancesq(position, inspectedEntityWithProps.position);
                    //TODO for ellipses:
                    // calculate angle vector to the target
                    //float3 vectorToTarget = inspectedEntityWithProps.position - position;
                    //float distanceToTargetSq = vectorToTarget.x * vectorToTarget.x + vectorToTarget.y + vectorToTarget.y;
                    float3 vectorToTargetN = math.normalize(inspectedEntityWithProps.position - position);
                    // add angle to rotation angle of active ellipse collider
                    float radiaeAngle    = math.acos(math.dot(rotationRightVectorN, vectorToTargetN));
                    float sinRadiaeAngle = math.sin(radiaeAngle);
                    float cosRadiaeAngle = math.cos(radiaeAngle);
                    // calculate radius in line of target of active ellipse collider
                    float radiusToTarget = axisA * axisB / math.sqrt(axisA * axisA * sinRadiaeAngle * sinRadiaeAngle + axisB * axisB * cosRadiaeAngle * cosRadiaeAngle);
                    // do the same with passive ellipse collider
                    float qRotationZofInspectedEntity = inspectedEntityWithProps.rotation.value.z;

                    float3 rotationRightVectorNofInspectedEntity = math.normalize(qRotationZofInspectedEntity * new float3(0, 0, 1));

                    float axisAofInspectedEntity = inspectedEntityWithProps.nonUniformScale.x / 2f;

                    float axisBofInspectedEntity = inspectedEntityWithProps.nonUniformScale.y / 2f;

                    float radiaeAngleOfInspectedEntity = math.acos(math.dot(rotationRightVectorNofInspectedEntity, -vectorToTargetN));

                    float sinRadiaeAngleOfInspectedEntity = math.sin(radiaeAngleOfInspectedEntity);
                    float cosRadiaeAngleOfInspectedEntity = math.cos(radiaeAngleOfInspectedEntity);

                    float radiusFromTarget = axisAofInspectedEntity * axisBofInspectedEntity / math.sqrt(axisAofInspectedEntity * axisAofInspectedEntity * sinRadiaeAngleOfInspectedEntity * sinRadiaeAngleOfInspectedEntity
                                                                                                         + axisBofInspectedEntity * axisBofInspectedEntity * cosRadiaeAngleOfInspectedEntity * cosRadiaeAngleOfInspectedEntity);
                    // sum the radiae to get the distance
                    float radiaeSum   = radiusToTarget + radiusFromTarget;
                    float radiaeSumSq = radiaeSum * radiaeSum;
                    // set the longer axis of ellipse to be the zero degrees rotation vector
                    // or make it so that the x axis of ellipse is always longer

                    // calculate the rotation of the asteroid % 360
                    // calculate the rotation of the asteroid upon which the check is being made

                    // calculate the vector between two of the asteroids (maybe make it the normal vector)

                    // calculate the angle between asteroid rotation and the connecting vector
                    // and calculate for the radius at that point

                    // same for the other asteroid

                    // sum up the radii to obtain the collision distance

                    // check for the collision distance (below)



                    if (distance < radiaeSumSq && inspectedEntityWithProps.entity != entity && !(inspectedEntityWithProps.planetoidCrashData.crashTime > 0))// TODO and if entity that is being collided with has crashTime zero
                    {
                        planetoidCrashInfo.crashTime = realTimeSinceStartUp;
                        inspectedEntityWithProps.planetoidCrashData.crashTime = realTimeSinceStartUp;
                        destroyedPlanetoidsQueue.Enqueue(entity);
                        destroyedPlanetoidsQueue.Enqueue(inspectedEntityWithProps.entity);
                        //explosion location, TODO put exlosion locations into a persistent queue
                        float3 explosionPoint = position - (position - inspectedEntityWithProps.position) / 2;
                        explosionCoordsQueue.Enqueue(explosionPoint);
                        break;
                    }
                }while (quadrantMultiHashMap.TryGetNextValue(out inspectedEntityWithProps, ref it));
            }
        }