Пример #1
0
        public static ColliderPrefab CreateColliderPrefab(ColliderData data)
        {
            CBaseShape collider = null;

            if (LMath.Abs(data.deg - 45) < 1)
            {
            }

            //warning data.deg is unity deg
            //changed unity deg to ccw deg
            var collisionDeg = -data.deg + 90;

            if (data.radius > 0)
            {
                //circle
                collider = new CCircle(data.radius);
            }
            else
            {
                //obb
                collider = new COBB(data.size, collisionDeg);
            }

            collider.high = data.high;
            var colFab = new ColliderPrefab();

            colFab.parts.Add(new ColliderPart()
            {
                transform = new CTransform2D(data.pos, data.y, data.deg),
                collider  = collider
            });
            return(colFab);
        }
Пример #2
0
        public bool ContainsCircle(LVector2 circleCenter, LFloat radius)
        {
            var center = _bounds.center;
            var dx     = LMath.Abs(circleCenter.x - center.x);
            var dy     = LMath.Abs(circleCenter.y - center.y);

            if (dx > (_bounds.width / 2 + radius))
            {
                return(false);
            }

            if (dy > (_bounds.height / 2 + radius))
            {
                return(false);
            }

            if (dx <= (_bounds.width / 2))
            {
                return(true);
            }

            if (dy <= (_bounds.height / 2))
            {
                return(true);
            }

            var dsx        = (dx - _bounds.width / 2);
            var dsy        = (dy - _bounds.height / 2);
            var cornerDist = dsx * dsx + dsy * dsy;

            return(cornerDist <= (radius * radius));
        }
Пример #3
0
        public static bool TestAABBAABB(LVector2 posA, LFloat rA, LVector2 sizeA, LVector2 posB, LFloat rB,
                                        LVector2 sizeB)
        {
            var diff      = posA - posB;
            var allRadius = rA + rB;

//circle 判定
            if (diff.sqrMagnitude > allRadius * allRadius)
            {
                return(false);
            }

            var absX = LMath.Abs(diff.x);
            var absY = LMath.Abs(diff.y);

//AABB and AABB
            var allSize = sizeA + sizeB;

            if (absX > allSize.x)
            {
                return(false);
            }
            if (absY > allSize.y)
            {
                return(false);
            }
            return(true);
        }
Пример #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="o">射线起点</param>
        /// <param name="d">射线终点</param>
        /// <param name="min">矩形的左下角坐标</param>
        /// <param name="max">矩形的右上角坐标</param>
        /// <param name="tmin">返回距离</param>
        /// <returns></returns>
        public static bool TestRayAABB(LVector2 o, LVector2 d, LVector2 min, LVector2 max, out LFloat tmin)
        {
            tmin = LFloat.zero;
            LFloat tmax = LFloat.FLT_MAX;

            for (int i = 0; i < 2; i++)
            {
                if (LMath.Abs(d[i]) < LFloat.EPSILON)
                {
                    if (o[i] < min[i] || o[i] > max[i])
                    {
                        return(false);
                    }
                }
                else
                {
                    LFloat ood = LFloat.one / d[i];
                    LFloat t1  = (min[i] - o[i]) * ood;
                    LFloat t2  = (max[i] - o[i]) * ood;
                    if (t1 > t2)
                    {
                        var temp = t1;
                        t1 = t2;
                        t2 = temp;
                    }
                    tmin = LMath.Max(tmin, t1);
                    tmax = LMath.Min(tmax, t2);
                    if (tmin > tmax)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Пример #5
0
        public static bool TestAABBOBB(LVector2 posA, LFloat rA, LVector2 sizeA, LVector2 posB, LFloat rB, LVector2 sizeB,
                                       LVector2 upB)
        {
            var diff      = posA - posB;
            var allRadius = rA + rB;

            //circle 判定
            if (diff.sqrMagnitude > allRadius * allRadius)
            {
                return(false);
            }

            var absUPX = LMath.Abs(upB.x); //abs(up dot aabb.right)
            var absUPY = LMath.Abs(upB.y); //abs(right dot aabb.right)

            {
                //轴 投影 AABBx
                var distX = absUPX * sizeB.y + absUPY * sizeB.x;
                if (LMath.Abs(diff.x) > distX + sizeA.x)
                {
                    return(false);
                }

                //轴 投影 AABBy
                //absUPX is abs(right dot aabb.up)
                //absUPY is abs(up dot aabb.up)
                var distY = absUPY * sizeB.y + absUPX * sizeB.x;
                if (LMath.Abs(diff.y) > distY + sizeA.y)
                {
                    return(false);
                }
            }

            {
                var right     = new LVector2(upB.y, -upB.x);
                var diffPObbX = LVector2.Dot(diff, right);
                var diffPObbY = LVector2.Dot(diff, upB);

                //absUPX is abs(aabb.up dot right )
                //absUPY is abs(aabb.right dot right)
                //轴 投影 OBBx
                var distX = absUPX * sizeA.y + absUPY * sizeA.x;
                if (LMath.Abs(diffPObbX) > distX + sizeB.x)
                {
                    return(false);
                }

                //absUPX is abs(aabb.right dot up )
                //absUPY is abs(aabb.up dot up)
                //轴 投影 OBBy
                var distY = absUPY * sizeA.y + absUPX * sizeA.x;
                if (LMath.Abs(diffPObbY) > distY + sizeB.y)
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #6
0
        public LFloat height; // 高

        /**
         * 数据检测,客户端的顶点坐标和三角形数据有可能是重复的ç∂
         * TODO 小三角形合并成大三角形或多边形;判断顶点是否在寻路层中,寻路层中的顶点不能作为路径点;两点所连线段是否穿过阻挡区,不穿过,直接获取坐标点
         */
        public void check(int scale)
        {
            amendmentSameVector(pathTriangles, pathVertices);
            scaleVector(pathVertices, scale);

            this.width  = LMath.Abs(this.getEndX() - this.getStartX());
            this.height = LMath.Abs(this.getEndZ() - this.getStartZ());
        }
Пример #7
0
    public static LFloat RoundIfNear(LFloat val, LFloat roundDist)
    {
        var roundVal = LMath.Round(val);
        var diff     = LMath.Abs(val - roundVal);

        if (diff < roundDist)
        {
            return(roundVal);
        }

        return(val);
    }
Пример #8
0
    public static bool CheckCollision(LVector2 posA, LFloat rA, LVector2 sizeA, LVector2 posB, LFloat rB,
                                      LVector2 sizeB)
    {
        var diff      = posA - posB;
        var allRadius = rA + rB;

        //circle 判定
        if (diff.sqrMagnitude > allRadius * allRadius)
        {
            return(false);
        }

        var isBoxA = sizeA != LVector2.zero;
        var isBoxB = sizeB != LVector2.zero;

        if (!isBoxA && !isBoxB)
        {
            return(true);
        }
        var absX = LMath.Abs(diff.x);
        var absY = LMath.Abs(diff.y);

        if (isBoxA && isBoxB)
        {
            //AABB and AABB
            var allSize = sizeA + sizeB;
            if (absX > allSize.x)
            {
                return(false);
            }
            if (absY > allSize.y)
            {
                return(false);
            }
            return(true);
        }
        else
        {
            //AABB & circle
            var size   = sizeB;
            var radius = rA;
            if (isBoxA)
            {
                size   = sizeA;
                radius = rB;
            }

            var x = LMath.Max(absX - size.x, LFloat.zero);
            var y = LMath.Max(absY - size.y, LFloat.zero);
            return(x * x + y * y < radius * radius);
        }
    }
Пример #9
0
        public static LVector2 GetIntersectPoint(LVector2 p0, LVector2 p1, LVector2 p2, LVector2 p3)
        {
            var diff = p2 - p0;
            var d1   = p1 - p0;
            var d2   = p3 - p2;
            var demo = LMath.Cross2D(d1, d2);     //det

            if (LMath.Abs(demo) < LFloat.EPSILON) //parallel
            {
                return(p0);
            }

            var t1 = LMath.Cross2D(diff, d2) / demo; // Cross2D(diff,-d2)

            return(p0 + (p1 - p0) * t1);
        }
Пример #10
0
 private void _OnTriggerEnter(ColliderProxy other)
 {
     if (_curPart.collider.IsCircle && _curPart.collider.deg > 0)
     {
         var deg     = (other.Transform2D.pos - owner.transform.pos).ToDeg();
         var degDiff = owner.transform.deg.Abs() - deg;
         if (LMath.Abs(degDiff) <= _curPart.collider.deg)
         {
             _tempTargets.Add(other);
         }
     }
     else
     {
         _tempTargets.Add(other);
     }
 }
Пример #11
0
 //private static readonly HashSet<Entity> _tempEntities = new HashSet<Entity>();
 private void _OnTriggerEnter(ColliderProxy other)
 {
     if (CurPart.collider.IsCircle && CurPart.collider.deg > 0)
     {
         var deg     = (other.Transform2D.pos - entity.transform.pos).ToDeg();
         var degDiff = entity.transform.deg.Abs() - deg;
         if (LMath.Abs(degDiff) <= CurPart.collider.deg)
         {
             _tempEntities.Add(other.Entity);
         }
     }
     else
     {
         _tempEntities.Add(other.Entity);
     }
 }
Пример #12
0
        public void DoUpdate(LFloat deltaTime)
        {
            var curPos = Transform2D.pos;

            if (_prePos != curPos)
            {
                _prePos = curPos;
                IsMoved = true;
            }

            var curDeg = Transform2D.deg;

            if (LMath.Abs(curDeg - _preDeg) > DegGap)
            {
                _preDeg = curDeg;
                IsMoved = true;
            }
        }
Пример #13
0
    /// <summary>
    ///  sqrt(a^2 + b^2) without under/overflow.
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>

    public static LFloat Hypot(LFloat a, LFloat b)
    {
        LFloat r;

        if (LMath.Abs(a) > LMath.Abs(b))
        {
            r = b / a;
            r = LMath.Abs(a) * LMath.Sqrt(1 + r * r);
        }
        else if (b != 0)
        {
            r = a / b;
            r = LMath.Abs(b) * LMath.Sqrt(1 + r * r);
        }
        else
        {
            r = 0d;
        }
        return(r);
    }
Пример #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="o">射线的起点</param>
        /// <param name="d1">射线的终点</param>
        /// <param name="p2">多边形的顶点</param>
        /// <param name="p3">多边形相邻的顶点(和p2 组成线段)</param>
        /// <returns>返回大于等于0时  说明相交</returns>
        public static LFloat TestRaySegment(LVector2 o, LVector2 d1, LVector2 p2, LVector2 p3)
        {
            LVector2 diff = p2 - o;
            LVector2 d2   = p3 - p2;
            // 叉乘的结果如过为0  说明平行
            LFloat dome = LMath.Cross2D(d1, d2);

            if (LMath.Abs(dome) < LFloat.EPSILON)
            {
                return(LFloat.negOne);
            }
            LFloat t1 = LMath.Cross2D(d2, diff);
            LFloat t2 = LMath.Cross2D(d1, diff);

            if (t1 >= 0 && (t2 >= 0 && t2 <= 1))
            {
                return(t1);
            }
            return(LFloat.negOne);
        }
Пример #15
0
        public static LFloat TestRaySegment(LVector2 o, LVector2 d1, LVector2 p2, LVector2 p3)
        {
            var diff = p2 - o;
            var d2   = p3 - p2;

            var demo = Cross2D(d1, d2);           //det

            if (LMath.Abs(demo) < LFloat.EPSILON) //parallel
            {
                return(LFloat.negOne);
            }

            var t1 = Cross2D(d2, diff) / demo; // Cross2D(diff,-d2)
            var t2 = Cross2D(d1, diff) / demo; //Dot(v1,pd0) == cross(d0,d1)

            if (t1 >= 0 && (t2 >= 0 && t2 <= 1))
            {
                return(t1);
            }
            return(LFloat.negOne);
        }
Пример #16
0
        public static bool TestCircleAABB(LVector2 posA, LFloat rA, LVector2 posB, LFloat rB, LVector2 sizeB)
        {
            var diff      = posA - posB;
            var allRadius = rA + rB;

//circle 判定
            if (diff.sqrMagnitude > allRadius * allRadius)
            {
                return(false);
            }

            var absX = LMath.Abs(diff.x);
            var absY = LMath.Abs(diff.y);

//AABB & circle
            var size   = sizeB;
            var radius = rA;
            var x      = LMath.Max(absX - size.x, LFloat.zero);
            var y      = LMath.Max(absY - size.y, LFloat.zero);

            return(x * x + y * y < radius * radius);
        }
Пример #17
0
        public static bool TestCircleOBB(LVector2 posA, LFloat rA, LVector2 posB, LFloat rB, LVector2 sizeB,
                                         LVector2 up)
        {
            var diff      = posA - posB;
            var allRadius = rA + rB;

//circle 判定CollisionHelper
            if (diff.sqrMagnitude > allRadius * allRadius)
            {
                return(false);
            }

//空间转换
            var absX   = LMath.Abs(LVector2.Dot(diff, new LVector2(up.y, -up.x)));
            var absY   = LMath.Abs(LVector2.Dot(diff, up));
            var size   = sizeB;
            var radius = rA;
            var x      = LMath.Max(absX - size.x, LFloat.zero);
            var y      = LMath.Max(absY - size.y, LFloat.zero);

            return(x * x + y * y < radius * radius);
        }
Пример #18
0
        public static LFloat TestSegmentSegment(LVector2 p0, LVector2 p1, LVector2 p2, LVector2 p3)
        {
            LVector2 diff = p2 - p0;
            LVector2 d1   = p1 - p0;
            LVector2 d2   = p3 - p2;

            var demo = LMath.Cross2D(d1, d2);

            if (LMath.Abs(demo) < LFloat.EPSILON) //parallel
            {
                return(LFloat.negOne);
            }

            var t1 = LMath.Cross2D(d2, diff) / demo; // Cross2D(diff,-d2)
            var t2 = LMath.Cross2D(d1, diff) / demo; //Dot(v1,pd0) == cross(d0,d1)

            if ((t1 >= 0 && t1 <= 1) && (t2 >= 0 && t2 <= 1))
            {
                return(t1); // return p0 + (p1-p0) * t1
            }
            return(LFloat.negOne);
        }
Пример #19
0
        public static bool TestOBBOBB(LVector2 posA, LFloat rA, LVector2 sizeA, LVector2 upA, LVector2 posB,
                                      LFloat rB,
                                      LVector2 sizeB,
                                      LVector2 upB)
        {
            var diff      = posA - posB;
            var allRadius = rA + rB;

//circle 判定
            if (diff.sqrMagnitude > allRadius * allRadius)
            {
                return(false);
            }

            var rightA = new LVector2(upA.y, -upA.x);
            var rightB = new LVector2(upB.y, -upB.x);

            {
//轴投影到 A.right
                var BuProjAr   = LMath.Abs(LVector2.Dot(upB, rightA));
                var BrProjAr   = LMath.Abs(LVector2.Dot(rightB, rightA));
                var DiffProjAr = LMath.Abs(LVector2.Dot(diff, rightA));
                var distX      = BuProjAr * sizeB.y + BrProjAr * sizeB.x;
                if (DiffProjAr > distX + sizeA.x)
                {
                    return(false);
                }

//轴投影到 A.up
                var BuProjAu   = LMath.Abs(LVector2.Dot(upB, upA));
                var BrProjAu   = LMath.Abs(LVector2.Dot(rightB, upA));
                var DiffProjAu = LMath.Abs(LVector2.Dot(diff, upA));
                var distY      = BuProjAu * sizeB.y + BrProjAu * sizeB.x;
                if (DiffProjAu > distY + sizeA.y)
                {
                    return(false);
                }
            }
            {
//轴投影到 B.right
                var AuProjBr   = LMath.Abs(LVector2.Dot(upA, rightB));
                var ArProjBr   = LMath.Abs(LVector2.Dot(rightA, rightB));
                var DiffProjBr = LMath.Abs(LVector2.Dot(diff, rightB));
                var distX      = AuProjBr * sizeA.y + ArProjBr * sizeA.x;
                if (DiffProjBr > distX + sizeB.x)
                {
                    return(false);
                }

//轴投影到 B.right
                var AuProjBu   = LMath.Abs(LVector2.Dot(upA, upB));
                var ArProjBu   = LMath.Abs(LVector2.Dot(rightA, upB));
                var DiffProjBu = LMath.Abs(LVector2.Dot(diff, upB));
                var distY      = AuProjBu * sizeA.y + ArProjBu * sizeA.x;
                if (DiffProjBu > distY + sizeB.x)
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #20
0
 public static bool IsZero(LFloat value)
 {
     return(LMath.Abs(value) <= GeometryUtil.FLOAT_ROUNDING_ERROR);
 }
Пример #21
0
        /// <summary>
        /// 夹角大小
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static LFloat Angle(LQuaternion a, LQuaternion b)
        {
            LFloat single = Dot(a, b);

            return(LMath.Acos(LMath.Min(LMath.Abs(single), LFloat.one)) * 2 * (180 / LMath.PI));
        }