コード例 #1
0
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        CustomPolygonCollider col = target as CustomPolygonCollider;

        col.mEdit = GUILayout.Toggle(col.mEdit, "Edit");
    }
コード例 #2
0
    /// <summary>
    /// 检查凸多边形和圆是否重合
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static bool CheckPolygonAndCircle(CustomPolygonCollider a, CustomCircleCollider b)
    {
        //障碍物之间的碰撞不处理
        if (a.mIsobstacle && b.mIsobstacle)
        {
            return(false);
        }

        List <CustomVector3> a_worldBound = a.LocalToWorldBound;

        bool mInit = false;
        //a在左
        bool a_at_left = true;
        //偏移向量
        CustomVector2 offsetvec = new CustomVector2(0, 0);
        //偏移值
        FixedPointF offsetfac = new FixedPointF(0);

        //顶点连线
        //斜率k
        List <CustomVector2> a_edges = new List <CustomVector2>();

        for (int i = 0; i < a_worldBound.Count; i++)
        {
            int           point1_index = i;
            int           point2_index = (i + 1) % a_worldBound.Count;
            CustomVector3 offset       = a_worldBound[point2_index] - a_worldBound[point1_index];
            a_edges.Add(new CustomVector2(offset.x, offset.z));
        }
        for (int i = 0; i < a_edges.Count; i++)
        {
            CustomVector2 axis = a_edges[i];
            axis = Vec_normal(axis);

            FixedPointF x    = axis.x;
            FixedPointF y    = axis.y;
            FixedPointF temp = x * x + y * y;
            FixedPointF z    = FixedPointF.Sqrt(temp);
            axis.x = x / z;
            axis.y = y / z;

            //求圆在法线上的投影边界
            CustomVector3 vec3     = b.mTrans.Position;
            CustomVector2 point    = new CustomVector2(vec3.x, vec3.z);
            FixedPointF   mapPoint = CustomVector2.Dot(point, axis);
            FixedPointF   min      = mapPoint - b.mRadius;
            FixedPointF   max      = mapPoint + b.mRadius;
            CustomVector2 proj_b   = new CustomVector2(min, max);

            CustomVector2 proj_a = GetMapPointMinMaxDis(a_worldBound, axis);

            if (!Check_Overlap(proj_a, proj_b))
            {
                return(false);
            }
            else
            {
                bool        a_at_left_temp = false;
                FixedPointF offsetfac_temp = new FixedPointF(0);
                Set_PushVec(proj_a, proj_b, ref a_at_left_temp, ref offsetfac_temp);
                if (!mInit)
                {
                    a_at_left = a_at_left_temp;
                    offsetfac = offsetfac_temp;
                    offsetvec = axis;
                    mInit     = true;
                }
                else
                {
                    if (offsetfac_temp < offsetfac)
                    {
                        a_at_left = a_at_left_temp;
                        offsetfac = offsetfac_temp;
                        offsetvec = axis;
                    }
                }
            }
        }
        Push(a, b, offsetfac, offsetvec, a_at_left);
        return(true);
    }
コード例 #3
0
    public override void OnSceneGUI()
    {
        base.OnSceneGUI();
        CustomPolygonCollider col = target as CustomPolygonCollider;

        if (!col.mEdit)
        {
            return;
        }

        Camera camera = Camera.current;
        //获取鼠标的位置
        Vector2 mousePos = Event.current.mousePosition;

        //scene视图中原点是左上角,但相机的原点是左下角,所以要转换下y值
        mousePos.y = camera.pixelHeight - mousePos.y;

        int   index      = -1;
        float length     = 0;
        float percentage = 0;

        for (int i = 0; i < col.Bound.Count; i++)
        {
            Vector3 startViewPos = camera.WorldToScreenPoint(col.LocalToWorld(col.Bound[i]).value);
            Vector3 endViewPos   = camera.WorldToScreenPoint(col.LocalToWorld(col.Bound[(i + 1) % col.Bound.Count]).value);
            //平行于X轴
            if (LineAndXParallel(startViewPos, endViewPos))
            {
                //平行于Y轴
                if (LineAndYParallel(startViewPos, endViewPos))
                {
                    continue;
                }
                else
                {
                    float len     = Mathf.Abs(mousePos.y - startViewPos.y);
                    float percent = (mousePos.x - startViewPos.x) / (endViewPos.x - startViewPos.x);
                    bool  first   = index == -1;
                    bool  replace = len < length;
                    index      = first ? i : replace ? i : index;
                    length     = first ? len : replace ? len : length;
                    percentage = first ? percent : replace ? percent : percentage;
                }
            }
            //平行于Y轴
            else if (LineAndYParallel(startViewPos, endViewPos))
            {
                float len     = Mathf.Abs(mousePos.x - startViewPos.x);
                float percent = (mousePos.y - startViewPos.y) / (endViewPos.y - startViewPos.y);
                bool  first   = index == -1;
                bool  replace = len < length;
                index      = first ? i : replace ? i : index;
                length     = first ? len : replace ? len : length;
                percentage = first ? percent : replace ? percent : percentage;
            }
            else
            {
                float k       = (endViewPos.y - startViewPos.y) / (endViewPos.x - startViewPos.x);//y = kx+b;kx - y + b = 0
                float b       = startViewPos.y - k * startViewPos.x;
                float len     = Mathf.Abs((k * mousePos.x - mousePos.y + b)) / Mathf.Sqrt(1 + Mathf.Pow(k, 2));
                float percent = (mousePos.y - startViewPos.y) / (endViewPos.y - startViewPos.y);
                bool  first   = index == -1;
                bool  replace = len < length;
                index      = first ? i : replace ? i : index;
                length     = first ? len : replace ? len : length;
                percentage = first ? percent : replace ? percent : percentage;
            }
        }

        //点击右键
        bool mRightMouseDown = Event.current.button == 1 && Event.current.type == EventType.MouseDown;
        //按下shift
        bool mShiftDown = Event.current.shift;
        //按下alt
        bool mAlt = Event.current.alt;

        if (index != -1 && percentage > 0)
        {
            Vector3 start = col.LocalToWorld(col.Bound[index]).value;
            Vector3 end   = col.LocalToWorld(col.Bound[(index + 1) % col.Bound.Count]).value;
            Vector3 pos   = start + (end - start) * percentage;
            //添加节点
            if (mShiftDown && !mAlt)
            {
                Handles.color = Color.green;
                Handles.CircleHandleCap(0, pos, Quaternion.Euler(90, 0, 0), 0.5f, EventType.Repaint);
                if (mRightMouseDown)
                {
                    CustomVector3 mCustomPos = CustomVector3.GetCustomVector3ByVector3(pos);
                    mCustomPos = col.WorldToLocal(mCustomPos);
                    if (index + 1 < col.Bound.Count)
                    {
                        col.Bound.Insert((index + 1), mCustomPos);
                    }
                    else
                    {
                        col.Bound.Add(mCustomPos);
                    }
                }
            }
        }

        //移除节点
        if (!mShiftDown && mAlt)
        {
            index  = -1;
            length = 0;
            for (int i = 0; i < col.Bound.Count; i++)
            {
                bool    first   = index == -1;
                Vector3 viewPos = camera.WorldToScreenPoint(col.LocalToWorld(col.Bound[i]).value);
                float   len     = Vector3.Distance(viewPos, mousePos);
                bool    replace = len < length;
                index  = first ? i : replace ? i : index;
                length = first ? len : replace ? len : length;
            }
            if (index != -1)
            {
                Handles.color = Color.red;
                Vector3 pos = col.LocalToWorld(col.Bound[index]).value;
                Handles.CircleHandleCap(0, pos, Quaternion.Euler(90, 0, 0), 0.5f, EventType.Repaint);
                if (mRightMouseDown)
                {
                    if (col.Bound.Count > 3)
                    {
                        col.Bound.RemoveAt(index);
                    }
                    else
                    {
                        Debug.Log("多变形顶点数目不能小于3个");
                    }
                }
            }
        }

        //节点拖拽并且限制节点
        for (int i = 0; i < col.Bound.Count; i++)
        {
            CustomVector3 customPos = CustomVector3.GetCustomVector3ByVector3(Handles.PositionHandle(col.LocalToWorld(col.Bound[i]).value, Quaternion.identity));
            customPos    = col.WorldToLocal(customPos);
            customPos.y  = new FixedPointF(0);
            col.Bound[i] = customPos;
        }
    }
コード例 #4
0
    /// <summary>
    /// 检查两个凸多边形是否重合
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static bool CheckPolygonAndPolygon(CustomPolygonCollider a, CustomPolygonCollider b)
    {
        //障碍物之间的碰撞不处理
        if (a.mIsobstacle && b.mIsobstacle)
        {
            return(false);
        }

        List <CustomVector3> a_worldBound = a.LocalToWorldBound;
        List <CustomVector3> b_worldBound = b.LocalToWorldBound;

        bool mInit = false;
        //a在左
        bool a_at_left = true;
        //偏移向量
        CustomVector2 offsetvec = new CustomVector2(0, 0);
        //偏移值
        FixedPointF offsetfac = new FixedPointF(0);

        //顶点连线,
        //斜率k
        List <CustomVector2> a_edges = new List <CustomVector2>();

        for (int i = 0; i < a_worldBound.Count; i++)
        {
            int           point1_index = i;
            int           point2_index = (i + 1) % a_worldBound.Count;
            CustomVector3 offset       = a_worldBound[point2_index] - a_worldBound[point1_index];
            a_edges.Add(new CustomVector2(offset.x, offset.z));
        }
        for (int i = 0; i < a_edges.Count; i++)
        {
            CustomVector2 axis = a_edges[i];
            //获得法向量
            axis = Vec_normal(axis);

            FixedPointF x    = axis.x;
            FixedPointF y    = axis.y;
            FixedPointF temp = x * x + y * y;
            FixedPointF z    = FixedPointF.Sqrt(temp);
            axis.x = x / z;
            axis.y = y / z;

            CustomVector2 proj_a = GetMapPointMinMaxDis(a_worldBound, axis), proj_b = GetMapPointMinMaxDis(b_worldBound, axis);

            if (!Check_Overlap(proj_a, proj_b))
            {
                return(false);
            }
            else
            {
                bool        a_at_left_temp = false;
                FixedPointF offsetfac_temp = new FixedPointF(0);
                Set_PushVec(proj_a, proj_b, ref a_at_left_temp, ref offsetfac_temp);

                if (!mInit)
                {
                    a_at_left = a_at_left_temp;
                    offsetfac = offsetfac_temp;
                    offsetvec = axis;
                    mInit     = true;
                }
                else
                {
                    if (offsetfac_temp < offsetfac)
                    {
                        a_at_left = a_at_left_temp;
                        offsetfac = offsetfac_temp;
                        offsetvec = axis;
                    }
                }
            }
        }

        //顶点连线
        //斜率k
        List <CustomVector2> b_edges = new List <CustomVector2>();

        for (int i = 0; i < b_worldBound.Count; i++)
        {
            int           point1_index = i;
            int           point2_index = (i + 1) % b_worldBound.Count;
            CustomVector3 offset       = b_worldBound[point2_index] - b_worldBound[point1_index];
            b_edges.Add(new CustomVector2(offset.x, offset.z));
        }
        for (int i = 0; i < b_edges.Count; i++)
        {
            CustomVector2 axis = b_edges[i];
            axis = Vec_normal(axis);

            FixedPointF x    = axis.x;
            FixedPointF y    = axis.y;
            FixedPointF temp = x * x + y * y;
            FixedPointF z    = FixedPointF.Sqrt(temp);
            axis.x = x / z;
            axis.y = y / z;

            CustomVector2 proj_a = GetMapPointMinMaxDis(a_worldBound, axis), proj_b = GetMapPointMinMaxDis(b_worldBound, axis);

            if (!Check_Overlap(proj_a, proj_b))
            {
                return(false);
            }
            {
                bool        a_at_left_temp = false;
                FixedPointF offsetfac_temp = new FixedPointF(0);

                Set_PushVec(proj_a, proj_b, ref a_at_left_temp, ref offsetfac_temp);

                if (offsetfac_temp < offsetfac)
                {
                    a_at_left = a_at_left_temp;
                    offsetfac = offsetfac_temp;
                    offsetvec = axis;
                }
            }
        }
        Push(a, b, offsetfac, offsetvec, a_at_left);
        return(true);
    }