示例#1
0
    public void FillInsideWithFootprints()
    {
        ClearUnmodifiedFootprints(false);

        //List<Footprint> instantiatedFootprints = new List<Footprint>();

        Vector3    bPos;
        Quaternion bRot;
        Vector3    closestPoint;
        //GameObject footprintObj;
        Footprint footprint;
        Primitive primitive = graph.mainPrimitives[0];

        List <Node> nodes = primitive.nodes;
        List <Edge> edges = primitive.edges;

        int failedPosCount = 0;
        int failedPosMax   = 1000;
        int safeCount      = 0;

        Vector3 point;
        Vector3 pointWorld;

        while (failedPosCount < failedPosMax && safeCount < 1000)
        {
            safeCount++;

            //Get random point inside the boundaries
            float randX = UnityEngine.Random.Range(primitive.minX, primitive.maxX);
            float randZ = UnityEngine.Random.Range(primitive.minZ, primitive.maxZ);

            point = new Vector3(randX, 0f, randZ);

            //If point is inside the polygon, proceed
            if (EdgeGraphUtility.PointIsInside(point, nodes, edges))
            {
                pointWorld = transform.TransformPoint(point);
                int footprintIdx = GetRandomInsideFootPrintIdx();
                GetFootprintPosAndRotAtTarget(pointWorld, out bPos, out bRot, out closestPoint, footprintIdx, false);
                footprint = UtilityTools.Helper.GetComponentInPrefabChildren <Footprint>(footprintPrefabsOnEdge[footprintIdx]);
                Matrix4x4 footprintTRSMatrix = Matrix4x4.TRS(bPos, bRot, Vector3.one);
                if (!FootprintOverlapsOthers(footprint, footprintTRSMatrix) && FootprintIsInsideGraph(footprint, footprintTRSMatrix))
                {
                    PlaceFootprint(bPos, bRot, footprintIdx, false);
                }
                else
                {
                    failedPosCount++;
                }
            }

            if (failedPosCount >= failedPosMax || safeCount >= 1000)
            {
                break;
            }
        }
    }
示例#2
0
    bool FootprintIsInsideGraph(Footprint footprint, Matrix4x4 footprintTRSMatrix)
    {
        for (int i = 0; i < footprint.edges.Count; i++)
        {
            Vector3 n1PosWorld = footprintTRSMatrix.MultiplyPoint3x4(EdgeGraphUtility.GetNode(footprint.edges[i].Node1, ref footprint.nodes).Position);
            Vector3 n2PosWorld = footprintTRSMatrix.MultiplyPoint3x4(EdgeGraphUtility.GetNode(footprint.edges[i].Node2, ref footprint.nodes).Position);

            Vector3 n1PosGraph = graph.transform.InverseTransformPoint(n1PosWorld);
            Vector3 n2PosGraph = graph.transform.InverseTransformPoint(n2PosWorld);

            if (!EdgeGraphUtility.PointIsInside(n1PosGraph, graph.mainPrimitives[0].nodes, graph.mainPrimitives[0].edges) ||
                !EdgeGraphUtility.PointIsInside(n2PosGraph, graph.mainPrimitives[0].nodes, graph.mainPrimitives[0].edges))
            {
                return(false);
            }
        }

        return(true);
    }
示例#3
0
    void OnSceneGUI()
    {
        if (placer.handPlacementEnabled && placer.footprintPrefabsOnEdge.Count > 0)
        {
            controls.Update();

            Vector3    newFootprintPos = Vector3.zero;
            Quaternion newFootprintRot = Quaternion.identity;

            bool placeInside = EdgeGraphUtility.PointIsInside(controls.cursorLocalPosition, placer.graph.mainPrimitives[0].nodes, placer.graph.mainPrimitives[0].edges);

            if (controls.controlIsPressed)
            {
                if (placer.handPlacementOnEdge)
                {
                    if (handPlacedIndex >= placer.footprintPrefabsOnEdge.Count)
                    {
                        handPlacedIndex = placer.footprintPrefabsOnEdge.Count - 1;
                    }
                }
                else
                {
                    if (handPlacedIndex >= placer.footprintPrefabsInside.Count)
                    {
                        handPlacedIndex = placer.footprintPrefabsInside.Count - 1;
                    }
                }

                if (Event.current.isKey && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.W)
                {
                    if (placer.handPlacementOnEdge)
                    {
                        handPlacedIndex = UtilityTools.Helper.GetNextIndex <GameObject>(placer.footprintPrefabsOnEdge, handPlacedIndex);
                    }
                    else
                    {
                        handPlacedIndex = UtilityTools.Helper.GetNextIndex <GameObject>(placer.footprintPrefabsInside, handPlacedIndex);
                    }
                }
                else if (Event.current.isKey && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Q)
                {
                    if (placer.handPlacementOnEdge)
                    {
                        handPlacedIndex = UtilityTools.Helper.GetPrevIndex <GameObject>(placer.footprintPrefabsOnEdge, handPlacedIndex);
                    }
                    else
                    {
                        handPlacedIndex = UtilityTools.Helper.GetPrevIndex <GameObject>(placer.footprintPrefabsInside, handPlacedIndex);
                    }
                }
                else if (Event.current.isKey && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.E)
                {
                    placer.handPlacementOnEdge = !placer.handPlacementOnEdge;
                }

                Quaternion rot;
                Vector3    closestPoint;
                placer.GetFootprintPosAndRotAtTarget(controls.cursorWorldPosition, out newFootprintPos, out rot, out closestPoint, handPlacedIndex, placer.handPlacementOnEdge, placeInside);

                if (placer.handPlacementOnEdge)
                {
                    newFootprintRot = rot;
                }

                Footprint fp;
                if (placer.handPlacementOnEdge)
                {
                    fp = UtilityTools.Helper.GetComponentInPrefabChildren <Footprint>(placer.footprintPrefabsOnEdge[handPlacedIndex]);
                }
                else
                {
                    fp = UtilityTools.Helper.GetComponentInPrefabChildren <Footprint>(placer.footprintPrefabsInside[handPlacedIndex]);
                }

                if (fp != null)
                {
                    Handles.color = Color.yellow;
                    Matrix4x4 newPosMatrix = Matrix4x4.TRS(newFootprintPos, newFootprintRot, Vector3.one);
                    for (int i = 0; i < fp.nodes.Count; i++)
                    {
                        Node cur = fp.nodes[i];
                        Node next;
                        if (i == fp.nodes.Count - 1)
                        {
                            next = fp.nodes[0];
                        }
                        else
                        {
                            next = fp.nodes[i + 1];
                        }

                        Handles.DrawLine(newPosMatrix.MultiplyPoint3x4(cur.Position), newPosMatrix.MultiplyPoint3x4(next.Position));
                        Handles.CubeCap(0, newPosMatrix.MultiplyPoint3x4(cur.Position), Quaternion.LookRotation(newPosMatrix.GetColumn(2), newPosMatrix.GetColumn(1)), .2f);
                        if (placer.handPlacementOnEdge)
                        {
                            Handles.Label(controls.cursorWorldPosition, placer.footprintPrefabsOnEdge[handPlacedIndex].name, "box");
                        }
                        else
                        {
                            Handles.Label(controls.cursorWorldPosition, placer.footprintPrefabsInside[handPlacedIndex].name, "box");
                        }

                        Handles.SphereCap(0, newFootprintPos, Quaternion.identity, .2f);
                        Handles.SphereCap(0, closestPoint, Quaternion.identity, .2f);
                    }
                }
            }

            if (controls.MouseClickedDown())
            {
                if (controls.controlIsPressed)
                {
                    placer.PlaceFootprint(newFootprintPos, newFootprintRot, handPlacedIndex, placer.handPlacementOnEdge, true);
                    if (!placer.handPlacementOnEdge)
                    {
                        newFootprintRot = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 360f), Vector3.up);
                    }
                }
            }
        }

        Handles.BeginGUI();
        GUILayout.Window(1, new Rect(16f, 232f, 150f, 50f), DrawSceneWindow, "Placement by hand");
        Handles.EndGUI();
    }
示例#4
0
    bool FootprintOverlapsOthers(Footprint footprint, Matrix4x4 footprintTRSMatrix)
    {
        // Check if any footprint edges cross each other
        for (int i = 0; i < footprint.edges.Count; i++)
        {
            Vector3 n1Pos = footprintTRSMatrix.MultiplyPoint3x4(EdgeGraphUtility.GetNode(footprint.edges[i].Node1, ref footprint.nodes).Position);
            Vector3 n2Pos = footprintTRSMatrix.MultiplyPoint3x4(EdgeGraphUtility.GetNode(footprint.edges[i].Node2, ref footprint.nodes).Position);

            for (int j = 0; j < instantiatedFootprints.Count; j++)
            {
                List <Node> placedFootprintWorldNodes = new List <Node>();
                instantiatedFootprints[j].nodes.ForEach((node) =>
                {
                    Node newNode     = new Node(node);
                    newNode.Position = instantiatedFootprints[j].transform.TransformPoint(node.Position);
                    placedFootprintWorldNodes.Add(newNode);
                });

                for (int k = 0; k < instantiatedFootprints[j].edges.Count; k++)
                {
                    Vector3 n3Pos = instantiatedFootprints[j].transform.TransformPoint(EdgeGraphUtility.GetNode(instantiatedFootprints[j].edges[k].Node1, ref instantiatedFootprints[j].nodes).Position);
                    Vector3 n4Pos = instantiatedFootprints[j].transform.TransformPoint(EdgeGraphUtility.GetNode(instantiatedFootprints[j].edges[k].Node2, ref instantiatedFootprints[j].nodes).Position);

                    Vector3 intersect;
                    if (UtilityTools.MathHelper.AreIntersecting(out intersect, n1Pos, n2Pos, n3Pos, n4Pos) == 1)
                    {
                        return(true);
                    }
                }
            }
        }

        // Check if footprint is inside placed footprint
        Vector3 nodePosWorld;

        for (int i = 0; i < footprint.nodes.Count; i++)
        {
            nodePosWorld = footprintTRSMatrix.MultiplyPoint3x4(footprint.nodes[i].Position);
            for (int j = 0; j < instantiatedFootprints.Count; j++)
            {
                List <Node> placedFootprintWorldNodes = new List <Node>();
                instantiatedFootprints[j].nodes.ForEach((node) =>
                {
                    Node newNode     = new Node(node);
                    newNode.Position = instantiatedFootprints[j].transform.TransformPoint(node.Position);
                    placedFootprintWorldNodes.Add(newNode);
                });

                if (EdgeGraphUtility.PointIsInside(nodePosWorld, placedFootprintWorldNodes, instantiatedFootprints[j].edges))
                {
                    return(true);
                }
            }
        }

        // Check if any placed footprint is inside the footprint
        List <Node> footprintWorldNodes = new List <Node>();

        footprint.nodes.ForEach((node) =>
        {
            Node newNode     = new Node(node);
            newNode.Position = footprintTRSMatrix.MultiplyPoint3x4(node.Position);
            footprintWorldNodes.Add(newNode);
        });

        for (int i = 0; i < instantiatedFootprints.Count; i++)
        {
            List <Node> placedFootprintWorldNodes = new List <Node>();
            instantiatedFootprints[i].nodes.ForEach((node) =>
            {
                Node newNode     = new Node(node);
                newNode.Position = instantiatedFootprints[i].transform.TransformPoint(node.Position);
                placedFootprintWorldNodes.Add(newNode);
            });

            for (int j = 0; j < placedFootprintWorldNodes.Count; j++)
            {
                if (EdgeGraphUtility.PointIsInside(placedFootprintWorldNodes[j].Position, footprintWorldNodes, footprint.edges))
                {
                    return(true);
                }
            }
        }

        return(false);
    }