Пример #1
0
        public static void ClampMagnitude(ref FixVec2 vector, Fix maxMagnitude)
        {
            var magnitude = vector.Magnitude;

            if (magnitude > maxMagnitude)
            {
                vector.Normalize();
                vector *= maxMagnitude;
            }
        }
Пример #2
0
    private void FixVec2Test()
    {
        Debug.Log("------------FixVec2Test-----------");
        FixVec2 res1 = new FixVec2(2.222f, 4.444f);

        Debug.Log(res1);
        res1 = res1.Normalize();
        Debug.Log(res1);
        Debug.Log(res1.ToVector2().ToString("f3"));

        Vector2 res2 = new Vector2(2.222f, 4.444f);

        Debug.Log(res2.ToString("f3"));
        res2.Normalize();
        Debug.Log(res2.ToString("f3"));
        Debug.Log("\n");
    }
        public override SteeringVelocity DoCalculate(Entity <Game> owner, ref SteeringVelocity accumulatedSteering)
        {
            _linear   = FixVec2.Zero;
            _position = owner.Get <Position>().Value;

            Proximity.FindNeighbors(owner, _proximityCallback);

            var maxVelocity = owner.Get <MaxVelocity>().Value;

            if (_linear.MagnitudeSqr == 0)
            {
                return(SteeringVelocity.Zero);
            }

            _linear.Normalize();
            _linear.Scale(ref maxVelocity);

            return(new SteeringVelocity(_linear));
        }
Пример #4
0
        public override SteeringVelocity DoCalculate(Entity <Game> owner, ref SteeringVelocity accumulatedSteering)
        {
            _averageVelocity = FixVec2.Zero;

            var neighborCount = Proximity.FindNeighbors(owner, _proximityCallback);

            if (neighborCount > 0)
            {
                var maxVelocity = owner.Get <MaxVelocity>().Value;

                _averageVelocity /= neighborCount;

                if (_averageVelocity.MagnitudeSqr == 0)
                {
                    return(SteeringVelocity.Zero);
                }

                _averageVelocity.Normalize();
                _averageVelocity.Scale(ref maxVelocity);
            }

            return(new SteeringVelocity(_averageVelocity));
        }
Пример #5
0
        public override SteeringVelocity DoCalculate(Entity <Game> owner, ref SteeringVelocity accumulatedSteering)
        {
            _centroid = FixVec2.Zero;

            var neighborCount = Proximity.FindNeighbors(owner, _proximityCallback);

            if (neighborCount > 0)
            {
                _centroid /= neighborCount;
                _centroid -= owner.Get <Position>().Value;

                if (_centroid.MagnitudeSqr == 0)
                {
                    return(SteeringVelocity.Zero);
                }

                _centroid.Normalize();

                var maxVelocity = owner.Get <MaxVelocity>().Value;
                _centroid.Scale(ref maxVelocity);
            }

            return(new SteeringVelocity(_centroid));
        }
Пример #6
0
        internal TFRaycastHit2D Raycast(ITreeRaycastCallback callback, FixVec2 pointA, FixVec2 pointB, TFLayerMask mask)
        {
            TFRaycastHit2D hit = new TFRaycastHit2D();
            FixVec2        r   = pointB - pointA;

            if (r.GetMagnitudeSquared() <= Fix.zero)
            {
                return(hit);
            }
            r.Normalize();

            // v is perpendicular to the segment.
            FixVec2 v     = FixVec2.Cross(Fix.one, r);
            FixVec2 abs_v = FixVec2.Abs(v);

            // Separating axis for segment (Gino, p80).
            // |dot(v, p1 - c)| > dot(|v|, h)
            Fix maxFraction = Fix.one;

            // Build a bounding box for the segment.
            AABB    segmentAABB = new AABB();
            FixVec2 t           = pointA + maxFraction * (pointB - pointA);

            segmentAABB.min = FixVec2.Min(pointA, t);
            segmentAABB.max = FixVec2.Max(pointA, t);

            Stack <int> stack = new Stack <int>();

            stack.Push(rootIndex);

            List <TFRaycastOutput> hitNodes = new List <TFRaycastOutput>(2);

            while (stack.Count > 0)
            {
                var nodeId = stack.Pop();
                if (nodeId == nullNode)
                {
                    continue;
                }

                var node = nodes[nodeId];

                if (!node.aabb.Overlaps(segmentAABB))
                {
                    continue;
                }

                // Separating axis for segment (Gino, p80).
                // |dot(v, p1 - c)| > dot(|v|, h)
                var c          = node.aabb.GetCenter();
                var h          = node.aabb.GetExtents();
                var separation = FixMath.Abs(FixVec2.Dot(v, pointA - c)) - FixVec2.Dot(abs_v, h);
                if (separation > Fix.zero)
                {
                    continue;
                }

                if (node.IsLeaf())
                {
                    // If value is >= 0, then we hit the node.
                    TFRaycastHit2D rHit;
                    Fix            value = callback.RayCastCallback(pointA, pointB, maxFraction, nodeId, out rHit, mask);

                    if (value == Fix.zero)
                    {
                        // The client has terminated the ray cast.
                        if (rHit)
                        {
                            // We actually hit the node, add it to the list.
                            hitNodes.Add(new TFRaycastOutput(nodeId, rHit));
                        }
                        break;
                    }

                    if (value == maxFraction)
                    {
                        if (rHit)
                        {
                            // We actually hit the node, add it to the list.
                            hitNodes.Add(new TFRaycastOutput(nodeId, rHit));
                        }
                    }
                    else if (value > Fix.zero)
                    {
                        if (rHit)
                        {
                            // We actually hit the node, add it to the list.
                            hitNodes.Add(new TFRaycastOutput(nodeId, rHit));
                        }
                        // Update segment bounding box.
                        maxFraction = value;
                        FixVec2 g = pointA + maxFraction * (pointB - pointA);
                        segmentAABB.min = FixVec2.Min(pointA, g);
                        segmentAABB.max = FixVec2.Max(pointA, g);
                    }
                }
                else
                {
                    stack.Push(node.leftChildIndex);
                    stack.Push(node.rightChildIndex);
                }
            }

            // Decide which node was the closest to the starting point.
            Fix closestNode = maxFraction;

            for (int i = 0; i < hitNodes.Count; i++)
            {
                if (hitNodes[i].hit.fraction < closestNode)
                {
                    closestNode = hitNodes[i].hit.fraction;
                    hit         = hitNodes[i].hit;
                }
            }
            return(hit);
        }
Пример #7
0
        internal void Raycast(ITreeRaycastCallback callback, FixVec2 pointA, FixVec2 pointB)
        {
            FixVec2 r = pointB - pointA;

            if (r.GetMagnitudeSquared() <= Fix.zero)
            {
                return;
            }
            r.Normalize();

            // v is perpendicular to the segment.
            FixVec2 v     = FixVec2.Cross(Fix.one, r);
            FixVec2 abs_v = FixVec2.Abs(v);

            // Separating axis for segment (Gino, p80).
            // |dot(v, p1 - c)| > dot(|v|, h)

            Fix maxFraction = Fix.one;

            // Build a bounding box for the segment.
            AABB    segmentAABB = new AABB();
            FixVec2 t           = pointA + maxFraction * (pointB - pointA);

            segmentAABB.min = FixVec2.Min(pointA, t);
            segmentAABB.max = FixVec2.Max(pointA, t);

            Stack <int> stack = new Stack <int>();

            stack.Push(rootIndex);

            while (stack.Count > 0)
            {
                var nodeId = stack.Pop();
                if (nodeId == nullNode)
                {
                    continue;
                }

                var node = nodes[nodeId];

                if (!node.aabb.Overlaps(segmentAABB))
                {
                    continue;
                }

                // Separating axis for segment (Gino, p80).
                // |dot(v, p1 - c)| > dot(|v|, h)
                var c          = node.aabb.GetCenter();
                var h          = node.aabb.GetExtents();
                var separation = FixMath.Abs(FixVec2.Dot(v, pointA - c)) - FixVec2.Dot(abs_v, h);
                if (separation > Fix.zero)
                {
                    continue;
                }

                if (node.IsLeaf())
                {
                    Fix value = callback.RayCastCallback(pointA, pointB, maxFraction, nodeId);

                    if (value == Fix.zero)
                    {
                        // The client has terminated the ray cast.
                        return;
                    }

                    if (value > Fix.zero)
                    {
                        // Update segment bounding box.
                        maxFraction = value;
                        FixVec2 g = pointA + maxFraction * (pointB - pointA);
                        segmentAABB.min = FixVec2.Min(pointA, g);
                        segmentAABB.max = FixVec2.Max(pointA, g);
                    }
                }
                else
                {
                    stack.Push(node.leftChildIndex);
                    stack.Push(node.rightChildIndex);
                }
            }
        }