public Face2D Build(CameraScene cameraScene, CirclePrimitive player, CirclePrimitive target)
    {
        // 3 steps:
        // 1. Make face from room bounds
        // 2. For each primitive make the occlusion field and cut it from the face
        // 3. Cut middle zone from the face, in this zone both the player and the target are visible,
        //    but there aren't any camera angle to see them both
        Face2D res = MakeStartField(cameraScene.RoomBound);

        BooleanOperator bop = new BooleanOperator();

        foreach (var circle_obstacle in cameraScene.Circles)
        {
            res = bop.Intersect(res, MakeOcclusionLoop(player, circle_obstacle, -0.1f));
        }

        res = bop.Intersect(res, MakeOcclusionLoop(player, target, 0.0f));

        foreach (var circle_obstacle in cameraScene.Circles)
        {
            res = bop.Intersect(res, MakeOcclusionLoop(target, circle_obstacle, 0.1f));
        }

        res = bop.Intersect(res, MakeMiddleZone(player, target));

        return(res);
    }
    private List <TopologyIntersection> FindAllIntersections(Face2D target, List <ICuttableEdge> edges2cut)
    {
        Intersector intersector = new Intersector();

        List <TopologyIntersection> res_list = new List <TopologyIntersection>();

        for (int loop_idx = 0; loop_idx < target.Loops.Count; ++loop_idx)
        {
            var loop = target.Loops[loop_idx];
            for (int target_edge_idx = 0; target_edge_idx < loop.Count; ++target_edge_idx)
            {
                List <TopologyIntersection> sorted_is = new List <TopologyIntersection>();
                for (int tool_edge_idx = 0; tool_edge_idx < edges2cut.Count; ++tool_edge_idx)
                {
                    var intersections = intersector.Intersect(loop[target_edge_idx], edges2cut[tool_edge_idx]);
                    foreach (var intersection in intersections)
                    {
                        TopologyIntersection res = new TopologyIntersection(
                            loop_idx, target_edge_idx, tool_edge_idx, intersection);

                        sorted_is.Add(res);
                    }
                }

                sorted_is.Sort(new TopologyIntersectionCompare_ByTarget());
                res_list.AddRange(sorted_is);
            }
        }

        return(res_list);
    }
    // Update is called once per frame
    void Update()
    {
        var             player           = field_builder.player;
        var             target           = field_builder.target;
        CirclePrimitive player_primitive = new CirclePrimitive();

        player_primitive.center = ConvertTo2d(player.gameObject.transform.position);
        player_primitive.radius = player.radius * player.gameObject.transform.localScale.magnitude;

        CirclePrimitive target_primitive = new CirclePrimitive();

        target_primitive.center = ConvertTo2d(target.gameObject.transform.position);
        target_primitive.radius = target.radius * target.gameObject.transform.localScale.magnitude;

        Face2D field = field_builder.Build(field_builder.scene_loader.Scene, player_primitive, target_primitive);

        Vector2 anchor_pos = ConvertTo2d(anchor.position);

        if (!field.IsPointInside(anchor_pos))
        {
            anchor_pos = field.GetClosestPointOnBorder(anchor_pos);
        }

        var new_lookat = field_builder.MakeMiddlePrimitive(player_primitive, target_primitive).center;

        lookat.position = new Vector3(new_lookat.x, lookat.position.y, new_lookat.y);

        cam_operator.RefreshDestination(new Vector3(anchor_pos.x, anchor.position.y, anchor_pos.y), Vector3.zero, 0, time);
        cam_operator.DBG_Show(0);
    }
    public void InitialPoints()
    {
        foreach (var pos in InitialVertices)
        {
            _Vertex vertex = vertexPrefab.Spawn();
            vertex.transform.SetParent(transform);
            vertex.transform.localPosition = pos;
            vertex.Border = this;

            vertexs.Add(vertex);
        }

        Face2D face = Shape.AddPoints(vertexs.Select(v => v.Point).ToArray());

        face.Name = "BorderFace";

        foreach (var e in face.BasicEdges)
        {
            _Block block = blockPrefab.Spawn();
            block.transform.SetParent(transform);
            block.Border = this;

            block.Edge = e;
            blocks.Add(block);
        }

        _lazyAllVertices.isValeChanged = true;
    }
    private void DBG_ShowFaceCetonia(Face2D face, Color color)
    {
        m_dbg.StartRecording();

        foreach (var loop in face.Loops)
        {
            DBG_ShowLoopCetonia(loop, color, 0.05f);
        }

        m_dbg.Flush();
    }
 public void SelectFaceByNumberOfSides(int sides)
 {
     foreach (Face2D face in allFaces)
     {
         if (face.sides == sides)
         {
             SelectedFace = face;
             return;
         }
     }
     SelectedFace = null;
 }
Exemple #7
0
    public void AlignSelectorToFace(Face2D targetFace)
    {
        transform.rotation = Quaternion.FromToRotation(Vector3.up, targetFace.Normal) * transform.rotation; // Align Normals
        if (Vector3.Angle(transform.rotation * Vector3.right, targetFace.Rotation) == 180)
        {
            transform.rotation = Quaternion.AngleAxis(180, transform.rotation * Vector3.up) * transform.rotation; // 180 degree rotation forced to rotate around normals
        }
        else
        {
            transform.rotation = Quaternion.FromToRotation(transform.rotation * Vector3.right, targetFace.Rotation) * transform.rotation; // Align Rotation.
        }


        transform.position = targetFace.transform.position;
    }
    public void SelectFaceByNormal(Vector3 normal)
    {
        Face2D result = null;
        float  angle  = 181;

        foreach (Face2D face in allFaces)
        {
            if (Vector3.Angle(normal, face.Normal) < angle)
            {
                result = face;
                angle  = Vector3.Angle(normal, face.Normal);
            }
        }
        SelectedFace = result;
    }
Exemple #9
0
 public void AlignToSelectedFace(Face2D targetFace)
 {
     if (ActivePrimitive != null && ActivePrimitive.SelectedFace != null)
     {
         ApplyRotation(Quaternion.FromToRotation(ActivePrimitive.SelectedFace.Normal, -targetFace.Normal)); // Align Normals
         if (Vector3.Angle(ActivePrimitive.SelectedFace.Rotation, targetFace.Rotation) == 180)
         {
             ApplyRotation(Quaternion.AngleAxis(180, ActivePrimitive.SelectedFace.Normal)); // 180 degree rotation forced to rotate around normals
         }
         else
         {
             ApplyRotation(Quaternion.FromToRotation(ActivePrimitive.SelectedFace.Rotation, targetFace.Rotation)); // Align Rotation.
         }
         transform.position = targetFace.transform.position - ActivePrimitive.SelectedFace.transform.position;
     }
 }
Exemple #10
0
    private void ConfirmOrCancelPreviewSolid(bool isConfirmed)
    {
        if (isConfirmed)
        {
            previewSolid.SetMode(Solid3D.MODE.DEFAULT);
            if (!selectedFace.ParentPrimitive.ParentSolid.isStatic)
            {
                previewSolid.ParentSolid = selectedFace.ParentPrimitive.ParentSolid;
            }
            if (selectedFace.ParentPrimitive.ParentSolid.IsPowered)
            {
                previewSolid.IsPowered = true;
            }

            selectedFace.ParentPrimitive.ParentSolid.Children.Add(previewSolid);
            placedSolids.Add(previewSolid);



            previewSolid.ParentButton.Count -= 1;
            if (previewSolid.ParentButton.Count == 0)
            {
                previewSolid = null; // break reference to newly placed solid so that setting ReadySolid to null doesn't destroy it
                ReadySolid   = null;
            }

            previewSolid = null;
            selectedFace = null;


            Destroy(activeFaceSelector.gameObject);
            CheckWinConditions();
        }
        else
        {
            Destroy(previewSolid.gameObject);
        }
        previewSolid = null;
    }
Exemple #11
0
    private void CreateFaceSelector(Face2D face)
    {
        if (activeFaceSelector != null)
        {
            Destroy(activeFaceSelector.gameObject);
        }
        switch (face.sides)
        {
        case 3:
            activeFaceSelector = Instantiate(CommonAssets.Current.selector3).GetComponent <FaceSelector>();
            break;

        case 4:
            activeFaceSelector = Instantiate(CommonAssets.Current.selector4).GetComponent <FaceSelector>();
            break;

        default:
            break;
        }

        activeFaceSelector.AlignSelectorToFace(face);
        // activeFaceSelector.transform.Translate(face.Normal.normalized * 0.05f, Space.World);
    }
 void ClacShape2D()
 {
     shape = new Shape2D();
     
     for (int i = 0; i < cols; i++)
     {
         int offset = i % 2 == 0 ? 1 : 0;
         for (int j = 0; j < rows / 2; j++)
         {
             Point2D p0 = GetPointFromMat(i,     2 * j + offset);
             Point2D p1 = GetPointFromMat(i,     2 * j + offset + 1);
             Point2D p2 = GetPointFromMat(i,     2 * j + offset + 2);
             Point2D p3 = GetPointFromMat(i + 1, 2 * j + offset + 2);
             Point2D p4 = GetPointFromMat(i + 1, 2 * j + offset + 1);
             Point2D p5 = GetPointFromMat(i + 1, 2 * j + offset);
             
             Face2D face = shape.AddPoints( p0, p1, p2, p3, p4, p5);
             face.Name = string.Format("{{{0},{1}}}", i, j);
         }
     }
     //Debug.Log(shape.ToString());
     
 }
Exemple #13
0
    public void SelectFace(Face2D face)
    {
        MainCamera.Current.LookTarget = face.transform.position;

        if (DeleteMode)
        {
            if (face.ParentPrimitive == markedDeleteSolid)
            {
                DeleteMarkedSolid();
            }
            else
            {
                if (!face.ParentPrimitive.ParentSolid.isStatic)
                {
                    UnmarkSolidForDeletion();
                    MarkSolidForDeletion(face.ParentPrimitive.ParentSolid);
                }
            }
        }
        else
        {
            if (previewSolid == null)
            {
                if (face == selectedFace)
                {
                    selectedFace = null;
                    Destroy(activeFaceSelector.gameObject);
                }
                else
                {
                    selectedFace = face;
                    CreateFaceSelector(face);
                    if (ReadySolid != null)
                    {
                        CreatePreviewSolidAtSelectedFace();
                    }
                }
            }
            else
            {
                if (face.ParentPrimitive.ParentSolid == previewSolid)
                {
                    if (face.ParentPrimitive = previewSolid.ActivePrimitive)
                    {
                        if (previewSolid.IsCollisionChecked && previewSolid.IsValidPlacement)
                        {
                            ConfirmOrCancelPreviewSolid(true);
                        }
                    }
                    else
                    {
                        previewSolid.ActivePrimitive = face.ParentPrimitive;
                        // TODO: other primitive doesn't have a valid face?
                    }
                }
                else
                {
                    selectedFace = face;
                    CreateFaceSelector(face);
                    CreatePreviewSolidAtSelectedFace();
                }
            }
        }
    }
    public Face2D Intersect(Face2D target, List <ICuttableEdge> tool)
    {
        // 1. for each edge determine if intersection number is even, then find these intersections.
        // Then make new loops.
        // TODO : loops without intersections

        IList <TopologyIntersection> intersections = /*FilterIntersections(*/ FindAllIntersections(target, tool) /*, target, tool )*/;

        List <bool> loop_has_intersections = new List <bool>(target.Loops.Count);

        for (int i = 0; i < target.Loops.Count; ++i)
        {
            loop_has_intersections.Add(false);
        }

        List <List <ICuttableEdge> > new_loops = new List <List <ICuttableEdge> >();

        if (intersections.Count == 0)
        {
            // test point on tool loop, if in target, add it to the target
            if (target.IsPointInside(tool[0].Eval(0).pt))
            {
                new_loops.Add(tool);
                foreach (var loop in target.Loops)
                {
                    new_loops.Add(loop);
                }
                return(new Face2D(new_loops));
            }
            else
            {
                return(target);
            }
        }

        BopMap bop_map = new BopMap();

        {
            bop_map.edge2intersections = MakeIntersectionMap(intersections, target.Loops, tool);
            bop_map.target             = target.Loops;
            bop_map.tool_edges         = tool;
        };

        // find valid intersection and start from it
        bool unprocessed_found = false;

        int deadloop = 0;

        do
        {
            unprocessed_found = false;
            foreach (var intersection in intersections)
            {
                loop_has_intersections[intersection.LoopIdx] = true;
                if (intersection.Valid)
                {
                    unprocessed_found = true;
                    var new_loop = MakeLoop(intersection, bop_map);
                    if (new_loop != null)
                    {
                        if (new_loop.Count >= 2)
                        {
                            for (int i = 0; i < new_loop.Count; ++i)
                            {
                                new_loop[i].Connect(new_loop[(i + new_loop.Count - 1) % new_loop.Count], true);
                            }

                            new_loops.Add(new_loop);
                        }
                    }
                }
                if (deadloop++ > DeadloopMaxIters)
                {
                    Debug.LogError("deadloop");
                    throw new UnityException("deadloop");
                }
            }
            if (deadloop++ > DeadloopMaxIters)
            {
                Debug.LogError("deadloop");
                throw new UnityException("deadloop");
            }
        } while (unprocessed_found);

        for (int i = 0; i < loop_has_intersections.Count; ++i)
        {
            if (!loop_has_intersections[i])
            {
                new_loops.Add(target.Loops[i]);   // todo: test if inside
            }
        }

        return(new Face2D(new_loops));
    }
    private List <TopologyIntersection> FilterIntersections(IList <TopologyIntersection> intersections, Face2D target, IList <ICuttableEdge> tool)
    {
        // TODO: kill it with fire! No, but seriously, refactor this.

        // check all face loop intersections for topological consistency. input should already be sorted.
        if (intersections.Count == 0)
        {
            return(new List <TopologyIntersection>());
        }

        IDictionary <ICuttableEdge, List <TopologyIntersection> > edge2intersections = new Dictionary <ICuttableEdge, List <TopologyIntersection> >();

        int  last_loop_idx        = intersections[0].LoopIdx;
        bool last_enters          = intersections[0].ToolEdgeEnters;
        bool first_in_loop_enters = last_enters;

        /*
         * {
         *  int cur_loop_first_edge_idx = 0;
         *
         *  // 1. Go through every loop and move tool param if ambigious
         *  for ( int i = 1; i <= intersections.Count; ++i )
         *  {
         *      TopologyIntersection intersection = null;
         *      TopologyIntersection prev = intersections[i - 1];
         *
         *      if ( i == intersections.Count )
         *      {
         *          intersection = intersections[cur_loop_first_edge_idx];
         *      }
         *      else
         *      {
         *          intersection = intersections[i];
         *          int cur_loop = intersection.LoopIdx;
         *
         *          if ( cur_loop != last_loop_idx )
         *          {
         *              intersection = intersections[cur_loop_first_edge_idx];
         *              cur_loop_first_edge_idx = i;
         *              last_loop_idx = cur_loop;
         *          }
         *          else
         *          {
         *              intersection = intersections[i];
         *          }
         *      }
         *      if ( ( intersection.ToolEdgeIdx == prev.ToolEdgeIdx )
         *          && ( ( prev.TargetEdgeIdx + 1 ) % target.Loops[prev.LoopIdx].Count == intersection.TargetEdgeIdx )
         *          && ( prev.ToolEdgeEnters != intersection.ToolEdgeEnters ) )
         *      {
         *          ICuttableEdge first_edge = target.Loops[prev.LoopIdx][prev.TargetEdgeIdx];
         *          ICuttableEdge second_edge = target.Loops[intersection.LoopIdx][intersection.TargetEdgeIdx];
         *          bool tool_is_order = Utils.TestLeftHemiplane( second_edge.Eval( 0 ).dir, first_edge.Eval( 1 ).dir ) == prev.ToolEdgeEnters;
         *          if ( tool_is_order != ( prev.Geom.cut_param < intersection.Geom.cut_param ) )
         *          {
         *              float temp = prev.Geom.cut_param;
         *              prev.SetCutParam( intersection.Geom.cut_param );
         *              intersection.SetCutParam( temp );
         *          }
         *      }
         *  }
         * }*/

        last_loop_idx        = intersections[0].LoopIdx;
        last_enters          = intersections[0].ToolEdgeEnters;
        first_in_loop_enters = last_enters;

        edge2intersections[tool[intersections[0].ToolEdgeIdx]] = new List <TopologyIntersection>
        {
            intersections[0]
        };

        for (int i = 1; i < intersections.Count; ++i)
        {
            TopologyIntersection intersection = intersections[i];
            int  cur_loop         = intersection.LoopIdx;
            bool tool_edge_enters = intersection.ToolEdgeEnters;

            if (cur_loop != last_loop_idx)
            {
                if (tool_edge_enters == first_in_loop_enters)   // inconsistent
                {
                    intersection.Valid = false;
                }

                first_in_loop_enters = tool_edge_enters;
                last_loop_idx        = cur_loop;
            }
            else if (tool_edge_enters == last_enters)   // inconsistent
            {
                intersection.Valid = false;
            }

            if (intersection.Valid)
            {
                if (!edge2intersections.ContainsKey(tool[intersection.ToolEdgeIdx]))
                {
                    edge2intersections[tool[intersection.ToolEdgeIdx]] = new List <TopologyIntersection>();
                }

                edge2intersections[tool[intersection.ToolEdgeIdx]].Add(intersection);
            }
            last_enters = tool_edge_enters;
        }
        // check last loop
        if (last_enters == first_in_loop_enters)
        {
            intersections[intersections.Count - 1].Valid = false;
        }

        // now filter by tool
        bool first_init = true;
        TopologyIntersection first_tool_is = null;

        foreach (var edge in tool)
        {
            if (!edge2intersections.ContainsKey(edge))
            {
                continue;
            }

            edge2intersections[edge].Sort(new TopologyIntersectionCompare_ByTool());

            foreach (var intersection in edge2intersections[edge])
            {
                if (!intersection.Valid)
                {
                    continue;
                }
                if (first_init)
                {
                    first_in_loop_enters = last_enters = intersection.ToolEdgeEnters;
                    first_init           = false;
                    first_tool_is        = intersection;
                }
                else
                {
                    bool tool_enters = intersection.ToolEdgeEnters;
                    if (tool_enters == last_enters)   // inconsistent
                    {
                        intersection.Valid = false;
                    }
                    last_enters = tool_enters;
                }
            }
        }

        if (last_enters == first_in_loop_enters && first_tool_is != null)
        {
            first_tool_is.Valid = false;
        }

        var res = new List <TopologyIntersection>
        {
            Capacity = intersections.Count
        };

        foreach (var i in intersections)
        {
            if (i.Valid)
            {
                res.Add(i);
            }
        }

        return(res);
    }