float GetColliderPoints(TCCollider collider)
        {
            if (BaseColliders != null && BaseColliders.Contains(collider))
            {
                return(float.MaxValue);
            }

            if (!collider.enabled)
            {
                return(float.MinValue);
            }

            float points = 0.0f;

            if (collider.transform.parent == SystemComp.transform)
            {
                points += 10000;
            }

            if (collider.shape == ColliderShape.Terrain)
            {
                points += 500000;
            }

            points -= (collider.transform.position - SystemComp.transform.position).sqrMagnitude * 100;
            return(points);
        }
        void DistributeColliders()
        {
            if (m_colliderReference == null || MaxColliders == 0)
            {
                return;
            }

            if (m_collidersList == null)
            {
                m_collidersList = new List <TCCollider>();
            }
            else
            {
                m_collidersList.Clear();
            }

            for (int i = 0; i < Tracker <TCCollider> .Count; i++)
            {
                TCCollider c = Tracker <TCCollider> .All[i];

                if (ColliderLayers == (ColliderLayers | (1 << c.gameObject.layer)))
                {
                    m_collidersList.Add(c);
                }
            }

            if (m_collidersList.Count > MaxColliders)
            {
                if (m_colliderSort == null)
                {
                    m_colliderSort = (c1, c2) => GetColliderPoints(c2).CompareTo(GetColliderPoints(c1));
                }

                //TODO: Better sort that takes size into account
                m_collidersList.Sort(m_colliderSort);
            }

            for (int i = 0; i < m_collidersList.Count; i++)
            {
                TCCollider c = m_collidersList[i];

                if (i >= MaxColliders)
                {
                    break;
                }

                int objLayerMask = 1 << c.gameObject.layer;

                if ((ColliderLayers.value & objLayerMask) <= 0)
                {
                    continue;
                }

                m_colliderReference[i] = c;
            }
        }
        protected override void Bind()
        {
            DistributeColliders();

            if (MaxColliders == 0 || m_collidersList.Count == 0)
            {
                return;
            }

            Vector3   parentPosition = Vector3.zero;
            Transform systTransform  = SystemComp.transform;

            if (systTransform.parent != null)
            {
                parentPosition = systTransform.parent.position;
            }

            for (int c = 0; c < NumColliders; ++c)
            {
                TCCollider col = m_colliderReference[c];

                var rc = new Collider {
                    Position = col.Position, Radius = 0.0f, BoxSize = Vector3.zero
                };

                Transform colTransform = col.transform;

                var lscale = colTransform.localScale;

                float xzscale = Mathf.Max(lscale.x, lscale.z);
                float scale   = Mathf.Max(Mathf.Max(lscale.x, lscale.y), lscale.z);
                float yscale  = lscale.y;

                switch (col.shape)
                {
                case ColliderShape.PhysxShape:

                    if (col.SphereCollider != null)
                    {
                        rc.Radius  = col.SphereCollider.radius * scale;
                        rc.BoxSize = Vector3.zero;
                        rc.Vtype   = 0;
                    }
                    else if (col.CapsuleCollider != null)
                    {
                        rc.Radius  = col.CapsuleCollider.radius * xzscale;
                        rc.BoxSize = new Vector3(0.0f,
                                                 Mathf.Max(0, col.CapsuleCollider.height / 2.0f * yscale - rc.Radius * 2.0f),
                                                 0.0f);
                        rc.Vtype = 1;
                    }
                    else if (col.BoxCollider != null)
                    {
                        rc.Radius  = 0.5f;
                        rc.BoxSize = Vector3.Scale(col.BoxCollider.size * 0.5f, lscale);

                        rc.BoxSize = new Vector3(Mathf.Max(0, rc.BoxSize.x - rc.Radius),
                                                 Mathf.Max(0, rc.BoxSize.y - rc.Radius),
                                                 Mathf.Max(0, rc.BoxSize.z - rc.Radius));
                        rc.Vtype = 2;
                    }

                    break;

                case ColliderShape.RoundedBox:
                    rc.Radius  = Mathf.Max(0.1f, col.rounding);
                    rc.BoxSize = Vector3.Scale(col.boxSize * 0.5f, lscale);
                    rc.BoxSize = new Vector3(Mathf.Max(0, rc.BoxSize.x - rc.Radius),
                                             Mathf.Max(0, rc.BoxSize.y - rc.Radius),
                                             Mathf.Max(0, rc.BoxSize.z - rc.Radius));
                    rc.Vtype = 2;
                    break;

                case ColliderShape.Hemisphere:
                    rc.Radius  = 0.05f;
                    rc.BoxSize = new Vector3(col.radius.Max * scale, col.radius.Max * scale, col.radius.Max * scale);
                    rc.Vtype   = 3;
                    break;

                case ColliderShape.Disc:
                    float rMin = col.radius.IsConstant ? 0.0f : col.radius.Min * xzscale;
                    float rMax = col.radius.Max * xzscale;

                    rc.Radius  = Mathf.Max(0.1f, col.rounding);
                    rc.BoxSize = new Vector3(rMin, col.discHeight / 2.0f * yscale - col.rounding, rMax);
                    switch (col.discType)
                    {
                    case DiscType.Full:
                        rc.Vtype = 4;
                        break;

                    case DiscType.Half:
                        rc.Vtype = 5;
                        break;

                    case DiscType.Quarter:
                        rc.Vtype = 6;
                        break;
                    }

                    break;

                case ColliderShape.Terrain:
                    var terrain = col.GetComponent <Terrain>();

                    if (terrain == null)
                    {
                        rc.BoxSize = Vector3.zero;
                    }
                    else
                    {
                        Vector3 terrainScale = terrain.terrainData.heightmapScale;
                        rc.BoxSize = new Vector3(terrainScale.x * terrain.terrainData.heightmapResolution, terrainScale.y,
                                                 terrainScale.z * terrain.terrainData.heightmapResolution);
                    }
                    rc.Vtype = 7;
                    break;

                default:
                    rc.Vtype = 0;
                    break;
                }

                rc.AxisX = colTransform.right;
                rc.AxisY = colTransform.up;
                rc.AxisZ = colTransform.forward;

                const float eps        = 0.01f;
                float       elasticity = 1.0f + eps + Mathf.Lerp(0.0f, 1.0f - eps * 2.0f, overrideBounciness ? Bounciness : col.Bounciness);

                rc.Bounciness = elasticity;
                rc.Velocity   = col.Velocity * col.InheritVelocity * 0.5f;
                rc.LifeLoss   = col.ParticleLifeLoss * Emitter.Lifetime.Max * Manager.ParticleTimeDelta;
                rc.IsInverse  = (uint)(col.inverse ? 1 : 0);

                float s           = overrideStickiness ? Stickiness : col.Stickiness;
                float deltaSticky = Mathf.Clamp01(1.0f - Mathf.Pow(s, 0.05f / Manager.ParticleTimeDelta));
                rc.Stickiness = deltaSticky;

                switch (Manager.SimulationSpace)
                {
                case Space.Local:
                    rc.Position = systTransform.InverseTransformPoint(rc.Position);
                    rc.AxisX    = systTransform.InverseTransformDirection(rc.AxisX);
                    rc.AxisY    = systTransform.InverseTransformDirection(rc.AxisY);
                    rc.AxisZ    = systTransform.InverseTransformDirection(rc.AxisZ);
                    rc.Velocity = systTransform.InverseTransformDirection(rc.Velocity);
                    break;

                case Space.Parent:
                    rc.Position -= parentPosition;
                    break;
                }

                m_colliderStruct[c] = rc;
            }
        }