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; }
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; }
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; } }
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; }
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()); }
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); }