예제 #1
0
파일: Shape.cs 프로젝트: zh880517/UnityLib
        private void OnDrawGizmos()
        {
            RefreshMesh();
            if (GetComponent <ShapeRender>())
            {
                return;
            }
            Vector3 pos = transform.position;

            pos.y = 0;
            Color color = Gizmos.color;

            switch (Type)
            {
            case PolyType.Area:
                Gizmos.color = new Color(0, 1, 0, 0.5f);
                break;

            case PolyType.Hollow:
                pos.y        = 0.01f;
                Gizmos.color = new Color(1f, 0.921568632f, 0.0156862754f, 0.5f);
                break;

            case PolyType.Obstacle:
                Gizmos.color = new Color(1, 0, 0, 0.5f);
                pos.y        = 0.02f;
                break;
            }
            Gizmos.DrawMesh(ShowMesh, pos, PlaneUtils.TransRotation(transform.rotation));
            Gizmos.color = color;
        }
예제 #2
0
        private void OnSceneGUI()
        {
            bool enableEditor = targets.Length == 1;
            var  shape        = target as BoxShape;

            shape.Offset.y = 0;
            Vector3 pos = shape.transform.position;

            pos.y = 0;
            Quaternion rotation = PlaneUtils.TransRotation(shape.transform.rotation);
            Matrix4x4  matrix   = Matrix4x4.TRS(pos, rotation, Vector3.one);

            using (new Handles.DrawingScope(Color.green, matrix))
            {
                Handles.DrawWireCube(shape.Offset, new Vector3(shape.Size.x, 0, shape.Size.y));
                if (enableEditor)
                {
                    for (int i = 0; i < 4; ++i)
                    {
                        Vector3 normal = ControlPoints[i];
                        bool    isX    = (i % 2 == 0);
                        float   size   = shape.Size.y;
                        if (isX)
                        {
                            size = shape.Size.x;
                        }
                        size *= 0.5f;
                        Vector3 pt = normal * size + shape.Offset;
                        EditorGUI.BeginChangeCheck();
                        float handleSize = HandleUtility.GetHandleSize(pt) * 0.05f;
                        pt = Handles.FreeMoveHandle(pt, rotation, handleSize, normal, Handles.DotHandleCap);
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObject(shape, "modify box");
                            EditorUtility.SetDirty(shape);
                            Vector3 otherSide = normal * (-1 * size) + shape.Offset;
                            float   newSize   = Vector3.Distance(pt, otherSide) * 0.5f;
                            shape.Offset += normal * (newSize - size);
                            if (isX)
                            {
                                shape.Size.x = newSize * 2;
                            }
                            else
                            {
                                shape.Size.y = newSize * 2;
                            }
                            shape.SetDirty();
                        }
                    }
                }
            }
        }
예제 #3
0
        private ISDFShape ToSDFSharp(Shape shape)
        {
            Matrix4x4 matrix = PlaneUtils.ToPlaneMatrix(shape.transform);

            if (shape is CircleShape circle)
            {
                var pos = matrix.MultiplyPoint(circle.Offset);
                return(new Circle
                {
                    Position = PlaneUtils.ToVector2(pos),
                    Radius = circle.Radius,
                });
            }
            else if (shape is BoxShape box)
            {
                var pos      = matrix.MultiplyPoint(box.Offset);
                var rotation = matrix.MultiplyVector(new Vector3(1, 0, 0));
                return(new Box
                {
                    Position = PlaneUtils.ToVector2(pos),
                    Rotation = PlaneUtils.ToVector2(rotation),
                    HalfSize = box.Size * 0.5f,
                });
            }
            else if (shape is PolyShape polygon)
            {
                Polygon points = new Polygon {
                    Points = new Vector2[polygon.Points.Count]
                };
                for (int i = 0; i < polygon.Points.Count; ++i)
                {
                    points.Points[i] = PlaneUtils.ToVector2(matrix.MultiplyPoint(polygon.Points[i]));
                }
                return(points);
            }
            else if (shape is LineShape line)
            {
                Line points = new Line {
                    Points = new Vector2[line.Points.Count]
                };
                for (int i = 0; i < line.Points.Count; ++i)
                {
                    points.Points[i] = PlaneUtils.ToVector2(matrix.MultiplyPoint(line.Points[i]));
                }
                return(points);
            }
            return(null);
        }
예제 #4
0
        private static T CreateShape <T>(MenuCommand menuCommand) where T : Shape
        {
            GameObject go     = ObjectFactory.CreateGameObject(typeof(T).Name);
            T          shape  = Undo.AddComponent <T>(go);
            var        camera = SceneView.lastActiveSceneView.camera;
            Ray        ray    = new Ray(camera.transform.position, camera.transform.forward);

            if (!PlaneUtils.RayCastPlaneXZ(ray, out Vector3 pos))
            {
                pos = ray.origin + ray.direction * 10;
            }
            go.transform.position = pos;
            if (menuCommand.context is GameObject parent)
            {
                Undo.SetTransformParent(go.transform, parent.transform, "CreateSharp");
            }
            Selection.activeGameObject = go;
            //EditorGUIUtility.PingObject(go);
            SceneView.lastActiveSceneView.FrameSelected();
            return(shape);
        }
예제 #5
0
        private void OnSceneGUI()
        {
            bool enableEditor = targets.Length == 1;
            var  shape        = target as PolyShape;

            if (worldPoints == null || worldPoints.Length != shape.Points.Count)
            {
                worldPoints = new Vector3[shape.Points.Count];
            }
            Vector3 pos = shape.transform.position;

            pos.y = 0;
            Quaternion rotation = PlaneUtils.TransRotation(shape.transform.rotation);
            Matrix4x4  matrix   = Matrix4x4.TRS(pos, rotation, Vector3.one);

            for (int i = 0; i < shape.Points.Count; ++i)
            {
                worldPoints[i] = matrix.MultiplyPoint(shape.Points[i]);
            }

            //计算鼠标点击在XZ平面的点
            Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);

            if (!PlaneUtils.RayCastPlaneXZ(ray, out Vector3 mousePos))
            {
                return;//鼠标没有点击在XZ平面
            }
            var     result     = PlaneUtils.ClosestPointToPolyLine(mousePos, worldPoints);
            Vector3 closePoint = result.Point;
            int     index      = result.Index;

            using (new Handles.DrawingScope(Color.green))
            {
                //画边缘线
                for (int i = 0; i < worldPoints.Length; ++i)
                {
                    int nextIndex = i + 1;
                    if (nextIndex == shape.Points.Count)
                    {
                        nextIndex = 0;
                    }
                    Vector3 pt = worldPoints[i];
                    Handles.DrawLine(pt, worldPoints[nextIndex]);
                    if (enableEditor)
                    {
                        //点位置编辑
                        float handleSize = HandleUtility.GetHandleSize(pt) * 0.05f;
                        EditorGUI.BeginChangeCheck();
                        pt = Handles.FreeMoveHandle(pt, Quaternion.identity, handleSize, new Vector3(1, 0, 1), Handles.DotHandleCap);
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObject(shape, "move polygon point");
                            EditorUtility.SetDirty(shape);
                            pt              = matrix.inverse.MultiplyPoint(pt);
                            pt.y            = 0;
                            worldPoints[i]  = pt;
                            shape.Points[i] = pt;
                            shape.SetDirty();
                        }
                    }
                }
                if (!enableEditor)
                {
                    return;
                }
                if (Event.current.control)
                {//移除点
                    if (worldPoints.Length > 3)
                    {
                        int removeIndex = index + 1;
                        if (removeIndex == worldPoints.Length)
                        {
                            removeIndex = 0;
                        }

                        int preIndex = removeIndex - 1;
                        if (preIndex < 0)
                        {
                            preIndex = worldPoints.Length - 1;
                        }
                        int nextIndex = removeIndex + 1;
                        if (nextIndex == worldPoints.Length)
                        {
                            nextIndex = 0;
                        }
                        Handles.DrawLine(worldPoints[preIndex], worldPoints[nextIndex]);
                        using (new Handles.DrawingScope(Color.red))
                        {
                            Handles.DrawAAPolyLine(5, worldPoints[preIndex], worldPoints[removeIndex]);
                            Handles.DrawAAPolyLine(5, worldPoints[nextIndex], worldPoints[removeIndex]);
                            float handleSize = HandleUtility.GetHandleSize(worldPoints[removeIndex]) * 0.05f;
                            var   pt1        = HandleUtility.WorldToGUIPoint(worldPoints[removeIndex]);
                            var   pt2        = HandleUtility.WorldToGUIPoint(mousePos);
                            float pickSize   = Vector2.Distance(pt1, pt2) + 0.1f;
                            if (Handles.Button(worldPoints[removeIndex], Quaternion.identity, handleSize, pickSize, Handles.DotHandleCap))
                            {
                                Undo.RecordObject(shape, "delete polygon point");
                                EditorUtility.SetDirty(shape);
                                shape.Points.RemoveAt(removeIndex);
                                shape.SetDirty();
                                Event.current.Use();
                            }
                        }
                    }
                }
                else if (Event.current.shift && (result.SegmentLength * result.NormalLength) > 0.1f && (result.SegmentLength * result.NormalLength) < (result.SegmentLength - 0.1f))
                {//添加点
                    {
                        float handleSize = HandleUtility.GetHandleSize(closePoint) * 0.08f;
                        //画距离鼠标最近的点
                        Handles.SphereHandleCap(0, closePoint, Quaternion.identity, handleSize, Event.current.type);
                    }

                    int insertIndex = index + 1;
                    if (insertIndex == worldPoints.Length)
                    {
                        insertIndex = 0;
                    }
                    using (new Handles.DrawingScope(Color.white))
                    {
                        Handles.DrawLine(mousePos, worldPoints[index]);
                        Handles.DrawLine(mousePos, worldPoints[insertIndex]);
                        float handleSize = HandleUtility.GetHandleSize(mousePos) * 0.05f;
                        if (Handles.Button(mousePos, Quaternion.identity, handleSize, 0.1f, Handles.DotHandleCap))
                        {
                            Undo.RecordObject(shape, "add polygon point");
                            EditorUtility.SetDirty(shape);

                            var pt = matrix.inverse.MultiplyPoint(mousePos);
                            shape.Points.Insert(insertIndex, pt);
                            shape.SetDirty();
                            Event.current.Use();
                        }
                    }
                }
            }
            SceneView.RepaintAll();
        }