Ejemplo n.º 1
0
        /// <summary>
        /// Create a new chainshape from the vertices.
        /// </summary>
        /// <param name="vertices">The vertices to use. Must contain 2 or more vertices.</param>
        /// <param name="createLoop">Set to true to create a closed loop. It connects the first vertice to the last, and automatically adjusts connectivity to create smooth collisions along the chain.</param>
        public ChainShape(Vertices vertices, bool createLoop = false)
            : base(0)
        {
            ShapeType = ShapeType.Chain;
            _radius   = Settings.PolygonRadius;

            Debug.Assert(vertices != null && vertices.Count >= 3);
            Debug.Assert(vertices[0] != vertices[vertices.Count - 1]); // FPE. See http://www.box2d.org/forum/viewtopic.php?f=4&t=7973&p=35363

            for (int i = 1; i < vertices.Count; ++i)
            {
                TSVector2 v1 = vertices[i - 1];
                TSVector2 v2 = vertices[i];

                // If the code crashes here, it means your vertices are too close together.
                Debug.Assert(TSVector2.DistanceSquared(v1, v2) > Settings.LinearSlop * Settings.LinearSlop);
            }

            Vertices = new Vertices(vertices);

            if (createLoop)
            {
                Vertices.Add(vertices[0]);
                PrevVertex = Vertices[Vertices.Count - 2]; //FPE: We use the properties instead of the private fields here.
                NextVertex = Vertices[1];                  //FPE: We use the properties instead of the private fields here.
            }
        }
Ejemplo n.º 2
0
            public static void Initialize(ref Manifold manifold, ref Transform xfA, FP radiusA, ref Transform xfB, FP radiusB, out TSVector2 normal, out FixedArray2 <TSVector2> points)
            {
                normal = TSVector2.zero;
                points = default(FixedArray2 <TSVector2>);
                bool flag = manifold.PointCount == 0;

                if (!flag)
                {
                    switch (manifold.Type)
                    {
                    case ManifoldType.Circles:
                    {
                        normal = new TSVector2(1f, 0f);
                        TSVector2 tSVector  = MathUtils.Mul(ref xfA, manifold.LocalPoint);
                        TSVector2 tSVector2 = MathUtils.Mul(ref xfB, manifold.Points[0].LocalPoint);
                        bool      flag2     = TSVector2.DistanceSquared(tSVector, tSVector2) > Settings.EpsilonSqr;
                        if (flag2)
                        {
                            normal = tSVector2 - tSVector;
                            normal.Normalize();
                        }
                        TSVector2 value  = tSVector + radiusA * normal;
                        TSVector2 value2 = tSVector2 - radiusB * normal;
                        points[0] = 0.5f * (value + value2);
                        break;
                    }

                    case ManifoldType.FaceA:
                    {
                        normal = MathUtils.Mul(xfA.q, manifold.LocalNormal);
                        TSVector2 value3 = MathUtils.Mul(ref xfA, manifold.LocalPoint);
                        for (int i = 0; i < manifold.PointCount; i++)
                        {
                            TSVector2 value4 = MathUtils.Mul(ref xfB, manifold.Points[i].LocalPoint);
                            TSVector2 value5 = value4 + (radiusA - TSVector2.Dot(value4 - value3, normal)) * normal;
                            TSVector2 value6 = value4 - radiusB * normal;
                            points[i] = 0.5f * (value5 + value6);
                        }
                        break;
                    }

                    case ManifoldType.FaceB:
                    {
                        normal = MathUtils.Mul(xfB.q, manifold.LocalNormal);
                        TSVector2 value7 = MathUtils.Mul(ref xfB, manifold.LocalPoint);
                        for (int j = 0; j < manifold.PointCount; j++)
                        {
                            TSVector2 value8  = MathUtils.Mul(ref xfA, manifold.Points[j].LocalPoint);
                            TSVector2 value9  = value8 + (radiusB - TSVector2.Dot(value8 - value7, normal)) * normal;
                            TSVector2 value10 = value8 - radiusA * normal;
                            points[j] = 0.5f * (value10 + value9);
                        }
                        normal = -normal;
                        break;
                    }
                    }
                }
            }
Ejemplo n.º 3
0
 public ChainShape(Vertices vertices, bool createLoop = false) : base(0)
 {
     base.ShapeType = ShapeType.Chain;
     this._radius   = Settings.PolygonRadius;
     Debug.Assert(vertices != null && vertices.Count >= 3);
     Debug.Assert(vertices[0] != vertices[vertices.Count - 1]);
     for (int i = 1; i < vertices.Count; i++)
     {
         TSVector2 value  = vertices[i - 1];
         TSVector2 value2 = vertices[i];
         Debug.Assert(TSVector2.DistanceSquared(value, value2) > Settings.LinearSlop * Settings.LinearSlop);
     }
     this.Vertices = new Vertices(vertices);
     if (createLoop)
     {
         this.Vertices.Add(vertices[0]);
         this.PrevVertex = this.Vertices[this.Vertices.Count - 2];
         this.NextVertex = this.Vertices[1];
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// 检测圆是否和线段的端点相交,参考了俩个动态圆的动态相交测试,都是转化为射线和圆的相交测试
        /// </summary>
        /// <returns></returns>
        public static bool CheckCircle_tableEdgeEndContact(CircleRunData runCircle, tableEdge segement, ref FP _percent, ref TSVector2 _nearestPos)
        {
            TSVector2 cirPos     = runCircle.cur_pos;
            TSVector2 nearestPos = TSVector2.zero;

            //先确定圆的起始位置离哪个端点最近
            if (TSVector2.DistanceSquared(runCircle.cur_pos, segement.start) < TSVector2.DistanceSquared(runCircle.cur_pos, segement.end))
            {
                _nearestPos = nearestPos = segement.start;
            }
            else
            {
                _nearestPos = nearestPos = segement.end;
            }
            //TSVector2 VA = runCircle.next_pos - runCircle.cur_pos;
            //TSVector2 VB = staticCircle.next_pos - staticCircle.cur_pos;
            //两个运动方向描述为一方运动另一方静止 so
            //TSVector2 VAB = VA - VB;//runCircle相对于staticCircle的运动方向pc
            TSVector2 VAB  = runCircle.next_pos - runCircle.cur_pos; //动态圆射线运动方向
            TSVector2 Idir = nearestPos - cirPos;                    //射线起点到静态圆的方向
            //FP Idir_length_square = TSVector2.Dot(Idir, Idir);
            FP Idir_length_square   = Idir.LengthSquared();
            FP static_radius_square = runCircle.radius * runCircle.radius;

            if (Idir_length_square < static_radius_square)//射线起点在圆心内部,相交
            {
                //_percent =  calHitInfo();
                //_percent = 1;//一开始就相交的
                //Debug.Log("射线起点在圆心内部");
                return(false);
            }
            else//射线起点在圆心外部的情况
            {
                FP a_projvalue = TSVector2.Dot(Idir, VAB.normalized);
                if (a_projvalue < 0)//球体位于射线原点的后面 不相交
                {
                    return(false);
                }
                else
                {
                    FP m_square = Idir_length_square - a_projvalue * a_projvalue; //球心到投影点距离的平方
                    if (m_square - static_radius_square > 0)                      //预测不相交
                    {
                        return(false);
                    }
                    else//有可能有交点,因为有可能距离不够
                    {
                        //var t = calHitInfo(Idir, a_projvalue);
                        FP   b_squar = m_square;
                        FP   f       = TSMath.Sqrt(static_radius_square - b_squar); //理论上来说 f是开跟后的结果,应该有俩个值?
                        FP   t1      = a_projvalue - f;                             //碰撞到静态圆所走的路程,总路程是runCircle.cur_pos+VAB*delataTime;
                        FP   t2      = a_projvalue + f;
                        FP   per     = 0;
                        bool isFlag  = false;
                        if (t1 > 0 && t1 - VAB.magnitude < FP.EN8)
                        {
                            isFlag = true;
                            if (VAB.magnitude < 0)
                            {
                                Debug.Log("除数不能为0");
                            }
                            per = t1 / VAB.magnitude;
                        }

                        if (t2 > 0 && t2 - VAB.magnitude < 0)
                        {
                            isFlag = true;
                            if (VAB.magnitude < 0)
                            {
                                Debug.Log("除数不能为0");
                            }
                            var per2 = t2 / VAB.magnitude;
                            if (per2 < per)
                            {
                                per = per2;
                            }
                        }
                        _percent = per;
                        if (_percent > 1)
                        {
                            Debug.Log("路程百分比大于1,注意!");
                        }

                        if (isFlag && _percent < FP.EN4)
                        {
                            return(false);
                        }
                        return(isFlag);
                    }
                }
            }
        }
            /// <summary>
            /// Evaluate the manifold with supplied transforms. This assumes
            /// modest motion from the original state. This does not change the
            /// point count, impulses, etc. The radii must come from the Shapes
            /// that generated the manifold.
            /// </summary>
            /// <param name="manifold">The manifold.</param>
            /// <param name="xfA">The transform for A.</param>
            /// <param name="radiusA">The radius for A.</param>
            /// <param name="xfB">The transform for B.</param>
            /// <param name="radiusB">The radius for B.</param>
            /// <param name="normal">World vector pointing from A to B</param>
            /// <param name="points">Torld contact point (point of intersection).</param>
            public static void Initialize(ref Manifold manifold, ref Transform xfA, FP radiusA, ref Transform xfB, FP radiusB, out TSVector2 normal, out FixedArray2 <TSVector2> points)
            {
                normal = TSVector2.zero;
                points = new FixedArray2 <TSVector2>();

                if (manifold.PointCount == 0)
                {
                    return;
                }

                switch (manifold.Type)
                {
                case ManifoldType.Circles:
                {
                    normal = new TSVector2(1.0f, 0.0f);
                    TSVector2 pointA = MathUtils.Mul(ref xfA, manifold.LocalPoint);
                    TSVector2 pointB = MathUtils.Mul(ref xfB, manifold.Points[0].LocalPoint);
                    if (TSVector2.DistanceSquared(pointA, pointB) > Settings.EpsilonSqr)
                    {
                        normal = pointB - pointA;
                        normal.Normalize();
                    }

                    TSVector2 cA = pointA + radiusA * normal;
                    TSVector2 cB = pointB - radiusB * normal;
                    points[0] = 0.5f * (cA + cB);
                }
                break;

                case ManifoldType.FaceA:
                {
                    normal = MathUtils.Mul(xfA.q, manifold.LocalNormal);
                    TSVector2 planePoint = MathUtils.Mul(ref xfA, manifold.LocalPoint);

                    for (int i = 0; i < manifold.PointCount; ++i)
                    {
                        TSVector2 clipPoint = MathUtils.Mul(ref xfB, manifold.Points[i].LocalPoint);
                        TSVector2 cA        = clipPoint + (radiusA - TSVector2.Dot(clipPoint - planePoint, normal)) * normal;
                        TSVector2 cB        = clipPoint - radiusB * normal;
                        points[i] = 0.5f * (cA + cB);
                    }
                }
                break;

                case ManifoldType.FaceB:
                {
                    normal = MathUtils.Mul(xfB.q, manifold.LocalNormal);
                    TSVector2 planePoint = MathUtils.Mul(ref xfB, manifold.LocalPoint);

                    for (int i = 0; i < manifold.PointCount; ++i)
                    {
                        TSVector2 clipPoint = MathUtils.Mul(ref xfA, manifold.Points[i].LocalPoint);
                        TSVector2 cB        = clipPoint + (radiusB - TSVector2.Dot(clipPoint - planePoint, normal)) * normal;
                        TSVector2 cA        = clipPoint - radiusA * normal;
                        points[i] = 0.5f * (cA + cB);
                    }

                    // Ensure normal points from A to B.
                    normal = -normal;
                }
                break;
                }
            }