public EdgeIfc findsEdge( Vertex theSource, Vertex theTarGet) { //dja: performance improvement // for( Iterator<Vertex> vertexiter = GetVertices(); vertexiter.hasNext(); ) // { // Vertex v1 = vertexiter.next( ); // for( EdgeIter edgeiter = v1.GetEdges(); edgeiter.hasNext(); ) // { // EdgeIfc theEdge = edgeiter.next(); // Vertex v2 = theEdge.GetOtherVertex( v1 ); // if ( ( v1.GetName().Equals( theSource.GetName() ) && // v2.GetName().Equals( theTarGet.GetName() ) ) || // ( v1.GetName().Equals( theTarGet.GetName() ) && // v2.GetName().Equals( theSource.GetName() ) ) ) // return theEdge; // } // } Vertex v1 = theSource; for( Iterator<EdgeIfc> edgeiter = v1.GetEdges(); edgeiter.hasNext(); ) { EdgeIfc theEdge = edgeiter.next(); Vertex v2 = theEdge.GetOtherVertex( v1 ); if ( ( v1.GetName().Equals( theSource.GetName() ) && v2.GetName().Equals( theTarGet.GetName() ) ) || ( v1.GetName().Equals( theTarGet.GetName() ) && v2.GetName().Equals( theSource.GetName() ) ) ) return theEdge; } return null; }
public static void SetRandomEdge(Vertex[] vertices) { bool found = false; int i = 0; int j = 0; int count = 0; Random random = new Random(); for (int k = 0; k < vertices.Length; k++) { for(int l = 0; l < vertices.Length; l++) { if (k == l || vertices[k].Vertices.Any(v => v == vertices[l])) continue; count++; if(random.Next(0, count) == 0) { i = k; j = l; found = true; } } } if (found) vertices[i].AddDirectedEdge(vertices[j]); }
//this face is one of the srrounding faces attahed to vold public void ReplaceVertex(Vertex vold,Vertex vnew) { for(int i = 0; i < 3; i++) { if(vertex[i].position == vold.position ) { vertex[i] = vnew; vold.RemoveFace( this ); if(vnew!=null) vnew.AddFace( this ); break; } } //remove reff of vold from Neighborhood vold.RemoveIfNonNeighbor( vertex[0] ); vertex[0].RemoveIfNonNeighbor( vold ); vold.RemoveIfNonNeighbor( vertex[1] ); vertex[1].RemoveIfNonNeighbor( vold ); vold.RemoveIfNonNeighbor( vertex[2] ); vertex[2].RemoveIfNonNeighbor( vold ); vertex[0]. AddNeighbor(vertex[1]); vertex[0]. AddNeighbor(vertex[2]); vertex[1]. AddNeighbor(vertex[0]); vertex[1]. AddNeighbor(vertex[2]); vertex[2]. AddNeighbor(vertex[0]); vertex[2]. AddNeighbor(vertex[1]); ComputeNormal(); }
public static Vertex Intro(GraphData d) { Vertex v = new Vertex(); v.Include = Root + "Intro.html"; Edge e; e = new Edge(d); e.State.VertexName = "SubcrisisManeuvering_Index"; e.State.Rank1.InHand += 1; e.State.Rank2_dipl.InHand += 2; e.State.Rank2_econ.InHand += 1; e.State.Rank2_poli.InHand += 1; e.HTML = "Assume political control over crisis. Communicate with allies' political leaders, confirm a firm leadership position in NATO and with non-NATO allies. Establish continuous high level lines of communication. Summon political advisors."; v.Edges.Add(e); e = new Edge(d); e.State.VertexName = "SubcrisisManeuvering_Index"; e.Disabled = true; e.State.Rank3.InHand += 1; e.HTML = "Summon military leadership. Confirm command and control links over allies military leadership. Immediately address the nation."; v.Edges.Add(e); return v; }
public void Undirected() { var graph = new Graph<int>(false); var vertex1 = new Vertex<int>(1); var vertex2 = new Vertex<int>(2); var vertex3 = new Vertex<int>(3); graph.AddVertex(vertex1); graph.AddVertex(vertex2); graph.AddVertex(vertex3); graph.AddEdge(vertex1, vertex2); Assert.AreEqual(vertex1.IncomingEdgeCount, 0); Assert.AreEqual(vertex2.IncomingEdgeCount, 0); graph.AddEdge(vertex3, vertex2); Assert.AreEqual(vertex3.IncomingEdgeCount, 0); Assert.AreEqual(vertex2.IncomingEdgeCount, 0); graph.AddEdge(vertex1, vertex3); Assert.AreEqual(vertex1.IncomingEdgeCount, 0); Assert.AreEqual(vertex3.IncomingEdgeCount, 0); }
public VoronoiRegion(Vertex generator) { this.id = generator.id; this.generator = generator; this.vertices = new List<Point>(); this.bounded = true; }
public TerrainRenderer(World world, WorldRenderer wr) { this.world = world; this.map = world.Map; var tileSize = new Size( Game.CellSize, Game.CellSize ); var tileMapping = new Cache<TileReference<ushort,byte>, Sprite>( x => Game.modData.SheetBuilder.Add(world.TileSet.GetBytes(x), tileSize)); var vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width]; terrainSheet = tileMapping[map.MapTiles.Value[map.Bounds.Left, map.Bounds.Top]].sheet; int nv = 0; var terrainPalette = wr.Palette("terrain").Index; for( int j = map.Bounds.Top; j < map.Bounds.Bottom; j++ ) for( int i = map.Bounds.Left; i < map.Bounds.Right; i++ ) { var tile = tileMapping[map.MapTiles.Value[i, j]]; // TODO: move GetPaletteIndex out of the inner loop. Util.FastCreateQuad(vertices, Game.CellSize * new float2(i, j), tile, terrainPalette, nv, tile.size); nv += 4; if (tileMapping[map.MapTiles.Value[i, j]].sheet != terrainSheet) throw new InvalidOperationException("Terrain sprites span multiple sheets"); } vertexBuffer = Game.Renderer.Device.CreateVertexBuffer( vertices.Length ); vertexBuffer.SetData( vertices, nv ); }
// Update is called once per frame void Update() { // Move towards current target if(currentDestination != null && pos != currentDestination){ if(!rm.Moving){ pos = next_node; if(!occupying){ FindTarget(); } List<Vertex> p = rf.FindPath(pos, currentDestination, wg.GetPathfindingCosts()); if(p != null && p.Count > 1){ next_node = p[1]; rm.Move(wg.VertexToVector3(next_node)); } else { currentDestination = pos; } } } else if(currentDestination != null && target != null && pos == currentDestination && !occupying){ target = wl.OccupyBurrow(pos); if(target != null){ occupying = true; } } else { if(!occupying){ FindTarget(); }else{ UpdateTarget(); } } }
public void AddVertex( Vertex v ) { vertices.Add( v ); //dja: Add for performance reasons verticesMap.Add( v.name, v ); }
public void TestEquatable() { var vn = new Vertex(12.34f, -98.7f, 54); var vertices = new Vertex[] { new Vertex(), vn, new Vertex(3, 2, 1) }; var facet = new Facet(vn, vertices); IEquatable<Facet> ieqFacet = facet; Assert.False(ieqFacet.Equals((Facet)null)); var facet2 = new Facet(); Assert.False(ieqFacet.Equals(facet2)); facet2 = new Facet(new Vertex(12.34f, -98.7f, 54), null); Assert.False(ieqFacet.Equals(facet2)); facet2 = new Facet() { Normal = null }; Assert.False(ieqFacet.Equals(facet2)); facet2 = new Facet() { Vertices = null }; Assert.False(ieqFacet.Equals(facet2)); facet2 = new Facet(new Vertex(12.34f, -98.7f, 54), vertices); Assert.True(ieqFacet.Equals(facet2)); Assert.True(ieqFacet.Equals(facet)); }
public double Compute(Vertex src, Vertex sink) { m_ResidualEdgeCapacities = new EdgeDoubleDictionary(); // initializing foreach(Vertex u in VisitedGraph.Vertices) foreach(Edge e in u.OutEdges) ResidualCapacities[e] = Capacities[e]; Colors[sink] = GraphColor.Gray; while (Colors[sink] != GraphColor.White) { VertexBuffer Q = new VertexBuffer(); ResidualEdgePredicate ep = new ResidualEdgePredicate(ResidualCapacities); BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm(resg,Q,Colors); PredecessorVisitor pred = new PredecessorVisitor(Predecessors); pred.RegisterHandlers(bfs); bfs.Compute(src); if (Colors[sink] != GraphColor.White) Augment(src, sink, pred.Predecessors); } // while double flow = 0; foreach(Edge e in src.OutEdges) flow += (EdgeCapacities[e] - ResidualEdgeCapacities[e]); return flow; }
public void Simple() { var graph = new Graph<int>(false); var vertices = new Vertex<int>[20]; for (var i = 0; i < 20; i++) { vertices[i] = new Vertex<int>(i); graph.AddVertex(vertices[i]); } for (var i = 0; i < 17; i += 2) { var edge = new Edge<int>(vertices[i], vertices[i + 2], false); graph.AddEdge(edge); } var trackingVisitor = new TrackingVisitor<int>(); graph.AcceptVisitor(trackingVisitor); Assert.AreEqual(trackingVisitor.TrackingList.Count, 20); for (var i = 0; i < 20; i++) { Assert.IsTrue(trackingVisitor.TrackingList.Contains(i)); } }
protected void AddVertex(Face face, Vertex vertex) { base.AddVertex(vertex); Faces.Remove(face); HalfEdge h1 = face.HalfEdge; HalfEdge h2 = h1.Next; HalfEdge h3 = h2.Next; HalfEdge h4 = new HalfEdge(h1.Origin); HalfEdge h5 = new HalfEdge(h2.Origin); HalfEdge h6 = new HalfEdge(h3.Origin); HalfEdge h7 = new HalfEdge(vertex); HalfEdge h8 = new HalfEdge(vertex); HalfEdge h9 = new HalfEdge(vertex); HalfEdges.AddRange(new List<HalfEdge> {h4, h5, h6, h7, h8, h9}); h4.Twin = h7; h7.Twin = h4; h5.Twin = h8; h8.Twin = h5; h6.Twin = h9; h9.Twin = h6; // Set all next h1.Next = h5; h5.Prev = h1; h5.Next = h7; h7.Prev = h5; h7.Next = h1; h1.Prev = h7; h2.Next = h6; h6.Prev = h2; h6.Next = h8; h8.Prev = h6; h8.Next = h2; h2.Prev = h8; h3.Next = h4; h4.Prev = h3; h4.Next = h9; h9.Prev = h4; h9.Next = h3; h3.Prev = h9; Triangle t1 = new Triangle(h1); Triangle t2 = new Triangle(h2); Triangle t3 = new Triangle(h3); Faces.Add(t1); Faces.Add(t2); Faces.Add(t3); Tree.Add(vertex, t1, t2, t3); LogEntry logEntry = new LogEntry("Adding edges.", this); logEntry.Objects.Add(vertex); Log.Add(logEntry); }
public static Vertex[] CalculateSphereVertices(float radius, float height, byte segments, byte rings) { var data = new Vertex[segments * rings]; int i = 0; for (double y = 0; y < rings; y++) { double phi = (y / (rings - 1)) * Math.PI; //was /2 for (double x = 0; x < segments; x++) { double theta = (x / (segments - 1)) * 2 * Math.PI; Vector3 v = new Vector3() { X = (float)(radius * Math.Sin(phi) * Math.Cos(theta)), Y = (float)(height * Math.Cos(phi)), Z = (float)(radius * Math.Sin(phi) * Math.Sin(theta)), }; Vector3 n = Vector3.Normalize(v); Vector2 uv = new Vector2() { X = (float)(x / (segments - 1))%1, Y = (float)(y / (rings - 1))%1 }; // Using data[i++] causes i to be incremented multiple times in Mono 2.2 (bug #479506). data[i] = new Vertex() { Position = v, Normal = n, TexCoord = uv }; i++; } } return data; }
public Sprite2DBatch( GraphicsContext graphics, int maxSpriteCount ) { int maxVertexCount = maxSpriteCount * 4 ; int maxIndexCount = maxSpriteCount * 6 ; graphicsContext = graphics ; #if !RESIZE_VERTEX_BUFFER vertexBuffer = new VertexBuffer( maxVertexCount, maxIndexCount, vertexFormats ) ; spriteCapacity = maxSpriteCount ; #endif // RESIZE_VERTEX_BUFFER vertexData = new Vertex[ maxVertexCount ] ; indexData = new ushort[ maxIndexCount ] ; spriteList = new Sprite2D[ maxSpriteCount ] ; sortedList = new Sprite2D[ maxSpriteCount ] ; #if ENABLE_SIN_TABLE if ( sinTable == null ) { sinTable = new float[ 4096 ] ; for ( int i = 0 ; i < 4096 ; i ++ ) { sinTable[ i ] = FMath.Sin( i * ( FMath.PI / 2048.0f ) ) ; } } #endif // ENABLE_SIN_TABLE }
/// <summary> /// returns projection of point on the grid defined by center, width and height /// </summary> public Vertex GetPointOnGrid(Vertex point) { int xVal = point.x / stepX; int zVal = point.z / stepZ; Vertex closestCenter = new Vertex(666, 666); for(int xi = -1; xi <= 1; xi++) { for (int zi = -1; zi <= 1; zi++) { Vertex centerOnGrid = new Vertex( globalCenter.x + (xVal + xi) * stepX, globalCenter.z + (zVal + zi) * stepZ); //Debug.Log(centerOnGrid); if (Vector3.Distance(point, centerOnGrid) < Vector3.Distance(point, closestCenter)) { closestCenter = centerOnGrid; } } } return closestCenter; }
public void CutoffRiverPart(Direction direction) { int maxIndex = -1; switch (direction) { case Direction.up: for(int i=0;i<riverPath.Count;i++) { if(riverPath[i].z < 0) { maxIndex = i; } botVertex = riverPath[maxIndex + 1]; } break; case Direction.down: for (int i = 0; i < riverPath.Count; i++) { if (riverPath[i].z > terrain.terrainSize) { maxIndex = i; } topVertex = riverPath[maxIndex + 1]; } break; } for(int i = maxIndex; i >= 0; i--) { Debug.Log("cutting: " + riverPath[i]); riverPath.RemoveAt(i); } }
public void DirectedValue() { var graph = new Graph<int>(true); var vertex1 = new Vertex<int>(1); var vertex2 = new Vertex<int>(2); var vertex3 = new Vertex<int>(3); graph.AddVertex(vertex1); graph.AddVertex(vertex2); graph.AddVertex(vertex3); graph.AddEdge(vertex1, vertex2); graph.AddEdge(vertex3, vertex2); graph.AddEdge(vertex1, vertex3); Assert.AreEqual(graph.Edges.Count, 3); Assert.AreEqual(graph.Vertices.Count, 3); Assert.IsTrue(graph.RemoveVertex(1)); Assert.AreEqual(graph.Edges.Count, 1); Assert.AreEqual(graph.Vertices.Count, 2); Assert.IsFalse(graph.RemoveVertex(4)); Assert.AreEqual(graph.Edges.Count, 1); Assert.AreEqual(graph.Vertices.Count, 2); }
public Dictionary<Vertex, DFSVisitingInfo> DepthFirstSearch(Vertex v) { var visits = new Dictionary<Vertex, DFSVisitingInfo>(); visits[v] = new DFSVisitingInfo(null); DepthFirstSearch(v, visits); return visits; }
public TraveledPathData SynchronousSearch(Graph graph, Vertex root, Vertex goal) { this.graph = graph; this.root = root; this.goal = goal; return this.SyncSearch(); }
public void Undirected() { var graph = new Graph<int>(false); var vertex1 = new Vertex<int>(1); var vertex2 = new Vertex<int>(2); var vertex3 = new Vertex<int>(3); var vertex4 = new Vertex<int>(4); graph.AddVertex(vertex1); graph.AddVertex(vertex2); graph.AddVertex(vertex3); graph.AddVertex(vertex4); graph.AddEdge(vertex1, vertex2); graph.AddEdge(vertex3, vertex2); graph.AddEdge(vertex1, vertex3); Assert.IsFalse(graph.IsStronglyConnected()); graph.AddEdge(vertex2, vertex4); Assert.IsTrue(graph.IsStronglyConnected()); graph.RemoveEdge(vertex2, vertex3); Assert.IsTrue(graph.IsStronglyConnected()); graph.RemoveEdge(vertex1, vertex3); Assert.IsFalse(graph.IsStronglyConnected()); }
public List<Implication> GetImplications(Vertex leaf, int nextTime) { var triggeredActions = this.GetTriggeredActions(leaf.ActualWorldAction, leaf.ActualState, leaf.Time); var possibleFutureStates = this.GetPossibleFutureStates(leaf.ActualWorldAction, leaf.ActualState, leaf.Time); return possibleFutureStates.Select(possibleFutureState => new Implication { FutureState = possibleFutureState, TriggeredActions = triggeredActions.ToList() }).ToList(); }
public DBPath(Vertex myStartVertex, Vertex myEndVertex, IEnumerable<Vertex> myVertices, IEnumerable<EdgeLabel> myEdges) { #region Initial Checks if (myStartVertex == null) throw new ArgumentNullException(); if (myEndVertex == null) throw new ArgumentNullException(); if (myVertices == null) throw new ArgumentNullException(); if (myEdges == null) throw new ArgumentNullException(); if (myVertices.Count() != myEdges.Count() - 1) throw new ArgumentException(); #endregion StartVertex = myStartVertex; EndVertex = myEndVertex; Vertices = myVertices; Edges = myEdges; Length = (UInt64) myEdges.LongCount(); }
/** * collapse vertex u to vertex v */ private void collapse(Vertex u, Vertex v) { // remove the adjacent face of both vertex u and vertex v for (int i = 0; i < u.adjacent_faces.Count; ++i) { if (u.adjacent_faces[i].has(v)) { for (int j = 0; j < 3; ++j) { Vertex v_temp = u.adjacent_faces[i].triangle_vertices[j]; if (!v_temp.Equals(u)) { for (int k = 0; k < v_temp.adjacent_faces.Count; ++k) { if (v_temp.adjacent_faces[k].Equals(u.adjacent_faces[i])) { v_temp.adjacent_faces.RemoveAt(k); break; } } } } u.adjacent_faces.RemoveAt(i); --i; } } // replace vertex u with vertex v in adjacent faces of neighbor vertices of vertex u for (int i = 0, i_count = u.neighbor_vertices.Count; i < i_count; ++i) { Vertex v_temp = u.neighbor_vertices[i]; for (int j = 0, j_count = v_temp.adjacent_faces.Count; j < j_count; ++j) { if (v_temp.adjacent_faces[j].has(u)) { v_temp.adjacent_faces[j].replaceVertex(u, v); } } } // replace vertex u with vertex v in adjacent faces of vertex u for (int i = 0, count = u.adjacent_faces.Count; i < count; ++i) { u.adjacent_faces[i].replaceVertex(u, v); } // remove vertex u vertices.RemoveAt(vertices.IndexOf(u)); // remove vertex u in neighbor vertices of vertex u // add neighbor vertices of vertex u to vertex v // add vertex v to neighbor vertices of vertex u // update collapse cost at neighbor vertices of vertex u for (int i = 0, count = u.neighbor_vertices.Count; i < count; ++i) { u.neighbor_vertices[i].neighbor_vertices.Remove(u); if (!u.neighbor_vertices[i].Equals(v)) { v.neighbor_vertices.Add(u.neighbor_vertices[i]); u.neighbor_vertices[i].neighbor_vertices.Add(v); distinct(u.neighbor_vertices[i].neighbor_vertices); } computeEdgeCollapseCostAtVertex(u.neighbor_vertices[i]); } distinct(v.neighbor_vertices); // add new faces to vertex v and update collapse cost of vertex v for (int i = 0, count = u.adjacent_faces.Count; i < count; ++i) { v.adjacent_faces.Add(u.adjacent_faces[i]); } computeEdgeCollapseCostAtVertex(v); }
public Edge this[Vertex strartVertex, Vertex endVertex] { get { return this[strartVertex.Label, endVertex.Label]; } }
private void ApplyVelocity(ref Vertex position, ref Vertex velocity) { float newX = position.X + velocity.X; if (newX < 0) { position.X = -newX; velocity.X *= -1; } else if (newX > openGLControl1.ActualWidth) { position.X -= (newX - (float) openGLControl1.ActualWidth); velocity.X *= -1; } else { position.X = newX; } float newy = position.Y + velocity.Y; if (newy < 0) { position.Y = -newy; velocity.Y *= -1; } else if (newy > openGLControl1.ActualHeight) { position.Y -= (newy - (float) openGLControl1.ActualHeight); velocity.Y *= -1; } else { position.Y = newy; } }
public override void AsynchronousSearch(Graph graph, Vertex root, Vertex goal) { this.graph = graph; this.root = root; this.goal = goal; new Thread(AsyncSearch).Start(); }
public void VertexAndEdge() { var graph = new Graph<int>(true); var vertex1 = new Vertex<int>(3); var vertex2 = new Vertex<int>(4); var vertex3 = new Vertex<int>(5); graph.AddVertex(vertex1); graph.AddVertex(vertex2); graph.AddVertex(vertex3); graph.AddEdge(vertex2, vertex1); vertex2 = SerializeUtil.BinarySerializeDeserialize(vertex1); TestIsCopy(vertex1, vertex2); Assert.AreEqual(vertex2.IncidentEdges.Count, 1); Assert.AreEqual(vertex1.IncidentEdges.Count, 1); Assert.AreEqual(vertex2.EmanatingEdges.Count, 0); Assert.AreEqual(vertex1.EmanatingEdges.Count, 0); TestIsCopy(vertex2.IncidentEdges[0], vertex1.IncidentEdges[0]); }
public static Vertex Rung4(GraphData d) { Vertex v = new Vertex(); v.Include = Root + "Rung4.html"; Edge e; string NextVertexName = "TraditionalCrises_Rung5"; e = new Edge(d); e.State.VertexName = NextVertexName; //e.State.Stakes += 5; e.HTML = "A public and irrevocable increase in the stakes"; v.Edges.Add(e); e = new Edge(d); e.State.VertexName = NextVertexName; //e.State.PublicAwareness += 20; e.HTML = "Officially inspire newspaper stories to the effect that the chief of state takes a serious view of the matter."; v.Edges.Add(e); return v; }
public void OnNextVertex(Vertex <TVertexId> vertex, Vertex <TVertexId> neighbour) { }
/// <inheritdoc /> public List <RectangleGrid2D> GetPartitions(PolygonGrid2D polygon) { IList <Vector2Int> points = polygon.GetPoints(); var vertices = new List <Vertex>(); var prev = points[points.Count - 3]; var curr = points[points.Count - 2]; var next = points[points.Count - 1]; // Process vertices for (var i = 0; i < points.Count; i++) { prev = curr; curr = next; next = points[i]; bool concave; if (prev.X == curr.X) { if (curr.X == next.X) { throw new InvalidOperationException("Should not happen as polygons must be normalized"); } var dir0 = prev.Y < curr.Y; var dir1 = curr.X > next.X; concave = dir0 == dir1; } else { if (next.Y == curr.Y) { throw new InvalidOperationException("Should not happen as polygons must be normalized"); } var dir0 = prev.X < curr.X; var dir1 = curr.Y > next.Y; concave = dir0 != dir1; } var vertex = new Vertex(curr, i - 1, concave); vertices.Add(vertex); } // Build interval trees for segments var horizontalSegments = new List <Segment>(); var verticalSegments = new List <Segment>(); for (var i = 0; i < vertices.Count; i++) { var from = vertices[i]; var to = vertices[(i + 1) % vertices.Count]; if (from.Point.X == to.Point.X) { verticalSegments.Add(new Segment(from, to, false)); } else { horizontalSegments.Add(new Segment(from, to, true)); } from.Next = to; to.Prev = from; } var horizontalTree = new RangeTree <int, Segment>(horizontalSegments, new SegmentComparer()); var verticalTree = new RangeTree <int, Segment>(verticalSegments, new SegmentComparer()); //Find horizontal and vertical diagonals var horizontalDiagonals = GetDiagonals(vertices, verticalTree, false); var verticalDiagonals = GetDiagonals(vertices, horizontalTree, true); //Find all splitting edges var splitters = FindSplitters(horizontalDiagonals, verticalDiagonals); foreach (var splitter in splitters) { SplitSegment(splitter); } //Split all concave vertices SplitConvave(vertices); var rectangles = FindRegions(vertices); return(rectangles); }
public static Graph <T> DijkstrasAlgorithm <T>(Graph <T> weightedGraph, Vertex <T> fromVertex) { #region Parameter Checks Guard.ArgumentNotNull(weightedGraph, "weightedGraph"); Guard.ArgumentNotNull(fromVertex, "fromVertex"); if (!weightedGraph.ContainsVertex(fromVertex)) { throw new ArgumentException(Graph <T> .couldNotBeFoundInTheGraph, "fromVertex"); } #endregion var heap = new Heap <Association <double, Vertex <T> > >( HeapType.Minimum, new AssociationKeyComparer <double, Vertex <T> >()); var vertexStatus = new Dictionary <Vertex <T>, VertexInfo <T> >(); // Initialise the vertex distances to the maximum possible. foreach (var vertex in weightedGraph.Vertices) { vertexStatus.Add(vertex, new VertexInfo <T>(double.MaxValue, null, false)); } vertexStatus[fromVertex].Distance = 0; // Add the source vertex to the heap - we'll be branching out from it. heap.Add(new Association <double, Vertex <T> >(0, fromVertex)); while (heap.Count > 0) { var item = heap.RemoveRoot(); var vertexInfo = vertexStatus[item.Value]; if (!vertexInfo.IsFinalised) { var edges = item.Value.EmanatingEdges; vertexStatus[item.Value].IsFinalised = true; // Enumerate through all the edges emanating from this node for (var i = 0; i < edges.Count; i++) { var edge = edges[i]; var partnerVertex = edge.GetPartnerVertex(item.Value); // Calculate the new distance to this distance var distance = vertexInfo.Distance + edge.Weight; var newVertexInfo = vertexStatus[partnerVertex]; // Found a better path, update the vertex status and add the // vertex to the heap for further analysis if (distance < newVertexInfo.Distance) { newVertexInfo.EdgeFollowed = edge; newVertexInfo.Distance = distance; heap.Add(new Association <double, Vertex <T> >(distance, partnerVertex)); } } } } return(BuildGraphDijkstra(weightedGraph, fromVertex, vertexStatus)); }
public static Graph <T> KruskalsAlgorithm <T>(Graph <T> weightedGraph) { Guard.ArgumentNotNull(weightedGraph, "weightedGraph"); // There is going be Vertices - 1 edges when we finish var edgeCount = weightedGraph.Vertices.Count - 1; var vertexToParent = new Dictionary <Vertex <T>, Vertex <T> >(); var oldToNew = new Dictionary <Vertex <T>, Vertex <T> >(); var edgeQueue = new Heap <Association <double, Edge <T> > >( HeapType.Minimum, new AssociationKeyComparer <double, Edge <T> >()); // Now build the return graph, always return non directed. var returnGraph = new Graph <T>(false); // As we mew the new vertices for the new graph from the old // one, we also map the old ones to the new ones, and set up // our dictionary used to track forests of vertices. foreach (var vertex in weightedGraph.Vertices) { var vertex2 = new Vertex <T>(vertex.Data); oldToNew.Add(vertex, vertex2); returnGraph.AddVertex(vertex2); vertexToParent.Add(vertex, null); } // We need to move the edges into a priority queue // and use the weight in the association to sort them. foreach (var e in weightedGraph.Edges) { edgeQueue.Add(new Association <double, Edge <T> >(e.Weight, e)); } // We know when we are done, when we hit the number of edges // or when there is no more edges. while ((edgeQueue.Count > 0) && (edgeCount > 0)) { // Pull off the least weight edge that hasn't been added or discarded yet. var association = edgeQueue.RemoveRoot(); // Save the value of the association to the proper type, an edge var edge = association.Value; // Here is the start of search to make find the heads // of the forest, because if they are the same heads, // there is a cycle. var fromVertexHead = edge.FromVertex; var toVertexHead = edge.ToVertex; // Find the head vertex of the forest the fromVertex is in while (vertexToParent[fromVertexHead] != null) { fromVertexHead = vertexToParent[fromVertexHead]; } // Find the head vertex of the forest the toVertex is in while (vertexToParent[toVertexHead] != null) { toVertexHead = vertexToParent[toVertexHead]; } // Check to see if the heads are the same // if are equal, it is a cycle, and we cannot // include the edge in the new graph. if (fromVertexHead != toVertexHead) { // Join the FromVertex forest to the ToVertex vertexToParent[fromVertexHead] = edge.ToVertex; // We have one less edge we need to find edgeCount--; // Add the edge to the new new graph, map the old vertices to the new ones returnGraph.AddEdge(oldToNew[edge.FromVertex], oldToNew[edge.ToVertex], edge.Weight); } } // All done :) return(returnGraph); }
public bool AddVertex(Point p) { var v = new Vertex(p); return(AddVertex(v)); }
private DependencyGraph(IList <T> melons) { int size = melons.Count; vertices = new Vertex[size]; Dictionary <string, Vertex> nameLookup = new Dictionary <string, Vertex>(size); // Create a vertex in the dependency graph for each Melon to load for (int i = 0; i < size; ++i) { Assembly melonAssembly = melons[i].Assembly; string melonName = melons[i].Info.Name; Vertex melonVertex = new Vertex(i, melons[i], melonName); vertices[i] = melonVertex; nameLookup[melonAssembly.GetName().Name] = melonVertex; } // Add an edge for each dependency between Melons SortedDictionary <string, IList <AssemblyName> > melonsWithMissingDeps = new SortedDictionary <string, IList <AssemblyName> >(); SortedDictionary <string, IList <AssemblyName> > melonsWithIncompatibilities = new SortedDictionary <string, IList <AssemblyName> >(); List <AssemblyName> missingDependencies = new List <AssemblyName>(); List <AssemblyName> incompatibilities = new List <AssemblyName>(); HashSet <string> optionalDependencies = new HashSet <string>(); HashSet <string> additionalDependencies = new HashSet <string>(); foreach (Vertex melonVertex in vertices) { Assembly melonAssembly = melonVertex.melon.Assembly; missingDependencies.Clear(); optionalDependencies.Clear(); incompatibilities.Clear(); additionalDependencies.Clear(); MelonOptionalDependenciesAttribute optionals = (MelonOptionalDependenciesAttribute)Attribute.GetCustomAttribute(melonAssembly, typeof(MelonOptionalDependenciesAttribute)); if ((optionals != null) && (optionals.AssemblyNames != null)) { optionalDependencies.UnionWith(optionals.AssemblyNames); } MelonAdditionalDependenciesAttribute additionals = (MelonAdditionalDependenciesAttribute)Attribute.GetCustomAttribute(melonAssembly, typeof(MelonAdditionalDependenciesAttribute)); if ((additionals != null) && (additionals.AssemblyNames != null)) { additionalDependencies.UnionWith(additionals.AssemblyNames); } MelonIncompatibleAssembliesAttribute incompatibleAssemblies = (MelonIncompatibleAssembliesAttribute)Attribute.GetCustomAttribute(melonAssembly, typeof(MelonIncompatibleAssembliesAttribute)); if ((incompatibleAssemblies != null) && (incompatibleAssemblies.AssemblyNames != null)) { foreach (string name in incompatibleAssemblies.AssemblyNames) { foreach (Vertex v in vertices) { AssemblyName assemblyName = v.melon.Assembly.GetName(); if ((v != melonVertex) && (assemblyName.Name == name)) { incompatibilities.Add(assemblyName); v.skipLoading = true; } } } } foreach (AssemblyName dependency in melonAssembly.GetReferencedAssemblies()) { if (nameLookup.TryGetValue(dependency.Name, out Vertex dependencyVertex)) { melonVertex.dependencies.Add(dependencyVertex); dependencyVertex.dependents.Add(melonVertex); } else if (!TryLoad(dependency) && !optionalDependencies.Contains(dependency.Name)) { missingDependencies.Add(dependency); } } foreach (string dependencyName in additionalDependencies) { AssemblyName dependency = new AssemblyName(dependencyName); if (nameLookup.TryGetValue(dependencyName, out Vertex dependencyVertex)) { melonVertex.dependencies.Add(dependencyVertex); dependencyVertex.dependents.Add(melonVertex); } else if (!TryLoad(dependency)) { missingDependencies.Add(dependency); } } if (missingDependencies.Count > 0) { // melonVertex.skipLoading = true; melonsWithMissingDeps.Add(melonVertex.melon.Info.Name, missingDependencies.ToArray()); } if (incompatibilities.Count > 0) { melonsWithIncompatibilities.Add(melonVertex.melon.Info.Name, incompatibilities.ToArray()); } } // Some Melons are missing dependencies. Don't load these Melons and show an error message if (melonsWithMissingDeps.Count > 0) { MelonLogger.Warning(BuildMissingDependencyMessage(melonsWithMissingDeps)); } if (melonsWithIncompatibilities.Count > 0) { MelonLogger.Warning(BuildIncompatibleAssembliesMessage(melonsWithIncompatibilities)); } }
private void TopologicalSortInto(IList <T> loadedMelons) { int[] unloadedDependencies = new int[vertices.Length]; SortedList <string, Vertex> loadableMelons = new SortedList <string, Vertex>(); int skippedMelons = 0; // Find all sinks in the dependency graph, i.e. Melons without any dependencies on other Melons for (int i = 0; i < vertices.Length; ++i) { Vertex vertex = vertices[i]; int dependencyCount = vertex.dependencies.Count; unloadedDependencies[i] = dependencyCount; if (dependencyCount == 0) { loadableMelons.Add(vertex.name, vertex); } } // Perform the (reverse) topological sorting while (loadableMelons.Count > 0) { Vertex melon = loadableMelons.Values[0]; loadableMelons.RemoveAt(0); if (!melon.skipLoading) { loadedMelons.Add(melon.melon); } else { ++skippedMelons; } foreach (Vertex dependent in melon.dependents) { unloadedDependencies[dependent.index] -= 1; dependent.skipLoading |= melon.skipLoading; if (unloadedDependencies[dependent.index] == 0) { loadableMelons.Add(dependent.name, dependent); } } } // Check if all Melons were either loaded or skipped. If this is not the case, there is a cycle in the dependency graph if (loadedMelons.Count + skippedMelons < vertices.Length) { StringBuilder errorMessage = new StringBuilder("Some Melons could not be loaded due to a cyclic dependency:\n"); for (int i = 0; i < vertices.Length; ++i) { if (unloadedDependencies[i] > 0) { errorMessage.Append($"- '{vertices[i].name}'\n"); } } errorMessage.Length -= 1; // Remove trailing newline MelonLogger.Error(errorMessage.ToString()); } }
public MainWindow() { InitializeComponent(); modelLoader = new OBJModelLoader(); this.Closing += MainWindow_Closing; wave = new Wave(); stopwatch.Start(); // Declare scene objects. Viewport3D myViewport3D = new Viewport3D(); Model3DGroup myModel3DGroup = new Model3DGroup(); GeometryModel3D myGeometryModel = ConvertModel(modelLoader.LoadModel(@"C:\Users\Kenley Strik\Desktop\M4.obj")); ModelVisual3D myModelVisual3D = new ModelVisual3D(); // Defines the camera used to view the 3D object. In order to view the 3D object, // the camera must be positioned and pointed such that the object is within view // of the camera. PerspectiveCamera myPCamera = new PerspectiveCamera(); //myPCamera.Position = new Point3D(0, 1.5f, 10); //myPCamera.Position = new Point3D(0, 0.5f, 2); //myPCamera.Position = new Point3D(0, 2.5f, 10); //myPCamera.Position = new Point3D(0, 10f, 100); myPCamera.Position = new Point3D(0, 20f, 20); //myPCamera.LookDirection = new Vector3D(0, 0, -1); //myPCamera.LookDirection = new System.Windows.Media.Media3D.Vector3D(0, -0.6, -1); //myPCamera.LookDirection = new System.Windows.Media.Media3D.Vector3D(0, -0.4, -1); myPCamera.LookDirection = new System.Windows.Media.Media3D.Vector3D(0, -1, -1); myPCamera.FieldOfView = 60; myViewport3D.Camera = myPCamera; DirectionalLight myDirectionalLight = new DirectionalLight(); myDirectionalLight.Color = Colors.White; //myDirectionalLight.Direction = new System.Windows.Media.Media3D.Vector3D(-0.61, -0.5, -0.61); myDirectionalLight.Direction = new System.Windows.Media.Media3D.Vector3D(0, -1, -1); myModel3DGroup.Children.Add(myDirectionalLight); ImageBrush colors_brush = new ImageBrush(); colors_brush.ImageSource = new BitmapImage(new Uri(@"C:\Users\Kenley Strik\Desktop\M4_Albedo.png", UriKind.Absolute)); DiffuseMaterial myDiffuseMaterial = new DiffuseMaterial(colors_brush); myGeometryModel.Material = myDiffuseMaterial; myGeometryModel.BackMaterial = myDiffuseMaterial; RotateTransform3D myRotateTransform3D = new RotateTransform3D(); AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D(); //myAxisAngleRotation3d.Axis = new System.Windows.Media.Media3D.Vector3D(0, 3, 0); //myAxisAngleRotation3d.Angle = angle; myRotateTransform3D.Rotation = myAxisAngleRotation3d; //myGeometryModel.Transform = myRotateTransform3D; float time = 0; this.timer = new Timer(1); this.timer.Elapsed += new ElapsedEventHandler((object sender, ElapsedEventArgs e) => { angle += 0.5f; time += 0.01f; if (time >= 100.0f) { time = 0; } Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { for (int i = 0; i < mesh.Positions.Count; i++) { Vertex vertex = new Vertex(new MLlib.Vectors.Vector3D((float)verticesS[i].X, (float)verticesS[i].Y, (float)verticesS[i].Z), new MLlib.Vectors.Vector2D((float)uvCoordinatesS[i].X, (float)uvCoordinatesS[i].Y), new MLlib.Vectors.Vector3D((float)normalsS[i].X, (float)normalsS[i].Y, (float)normalsS[i].Z)); wave.CalucluateVertexPosition(vertex, time); mesh.Positions[i] = new Point3D(vertex.Vertice.X, vertex.Vertice.Y, vertex.Vertice.Z); //mesh.Normals[i] = new System.Windows.Media.Media3D.Vector3D(vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z); } //myAxisAngleRotation3d.Angle = angle; })); }); //this.timer.Start(); //for(int i = 0; i < mesh.Positions.Count; i++) //{ // Vertex vertex = new Vertex(new MLlib.Vectors.Vector3D((float)verticesS[i].X, (float)verticesS[i].Y, (float)verticesS[i].Z), // new MLlib.Vectors.Vector2D((float)uvCoordinatesS[i].X, (float)uvCoordinatesS[i].Y), // new MLlib.Vectors.Vector3D((float)normalsS[i].X, (float)normalsS[i].Y, (float)normalsS[i].Z)); // wave.CalucluateVertexPosition(ref vertex, 0); // mesh.Positions[i] = new Point3D(vertex.Vertice.X, vertex.Vertice.Y, vertex.Vertice.Z); // mesh.Normals[i] = new System.Windows.Media.Media3D.Vector3D(vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z); //} Water water1 = new Water(Application.Current.Dispatcher); Water water2 = new Water(Application.Current.Dispatcher); water1.GetWaterPlane().GetModel().Transform = new TranslateTransform3D(5.2, 0, 0); water2.GetWaterPlane().GetModel().Transform = new TranslateTransform3D(-5.2, 0, 0); RotateTransform3D rotateTransform = new RotateTransform3D(); AxisAngleRotation3D axisAngleRotation = new AxisAngleRotation3D(); axisAngleRotation.Axis = new System.Windows.Media.Media3D.Vector3D(1, 0, 0); axisAngleRotation.Angle = 45; rotateTransform.Rotation = axisAngleRotation; Transform3DGroup transform3DGroup = new Transform3DGroup(); transform3DGroup.Children.Add(rotateTransform); //transform3DGroup.Children.Add(new TranslateTransform3D(0, 5, -10)); //water2.GetWaterPlane().GetModel().Transform = transform3DGroup; myModel3DGroup.Children.Add(water1.GetWaterPlane().GetModel()); myModel3DGroup.Children.Add(water2.GetWaterPlane().GetModel()); //myModel3DGroup.Children.Add(myGeometryModel); myModelVisual3D.Content = myModel3DGroup; myViewport3D.Children.Add(myModelVisual3D); this.Content = myViewport3D; water1.Start(); water2.Start(); }
void Mesh.IChangeListener.SplitMidpointEnd(HalfEdge e, Vertex mid) { }
/// <summary> /// Split all concave vertices. /// </summary> /// <param name="vertices"></param> private void SplitConvave(List <Vertex> vertices) { var leftSegments = new List <Segment>(); var rightSegments = new List <Segment>(); foreach (var v in vertices) { if (v.Next.Point.X == v.Point.X) // TODO: prob his mistake { if (v.Next.Point.Y > v.Point.Y) { leftSegments.Add(new Segment(v, v.Next, false)); } else { rightSegments.Add(new Segment(v, v.Next, false)); } } } var leftTree = new RangeTree <int, Segment>(leftSegments, new SegmentComparer()); var rightTree = new RangeTree <int, Segment>(rightSegments, new SegmentComparer()); var i = 0; while (i < vertices.Count) { var v = vertices[i]; i++; if (!v.Concave) { continue; } var y = v.Point.Y; bool dir; if (v.Prev.Point.X == v.Point.X) { dir = v.Prev.Point.Y < y; } else { dir = v.Next.Point.Y > y; } var direction = dir ? 1 : -1; Segment closestSegment = null; var closestDistance = direction == 1 ? int.MaxValue : int.MinValue; if (direction > 0) // TODO: prob his mistake { foreach (var s in rightTree.Query(v.Point.Y)) { var x = s.From.Point.X; if (x > v.Point.X && x < closestDistance) { closestDistance = x; closestSegment = s; } } } else { foreach (var s in leftTree.Query(v.Point.Y)) { var x = s.From.Point.X; if (x < v.Point.X && x > closestDistance) { closestDistance = x; closestSegment = s; } } } //Create two splitting vertices var splitA = new Vertex(new Vector2Int(closestDistance, v.Point.Y), 0, false); var splitB = new Vertex(new Vector2Int(closestDistance, v.Point.Y), 0, false); //Clear concavity flag v.Concave = false; //Split vertices splitA.Prev = closestSegment.From; closestSegment.From.Next = splitA; splitB.Next = closestSegment.To; closestSegment.To.Prev = splitB; var tree = leftTree; if (direction > 0) { tree = rightTree; } tree.Remove(closestSegment); tree.Add(new Segment(closestSegment.From, splitA, false)); tree.Add(new Segment(splitB, closestSegment.To, false)); vertices.Add(splitA); vertices.Add(splitB); //Cut v, 2 different cases if (v.Prev.Point.X == v.Point.X) { // Case 1 // ^ // | // --->*+++++++X // | | // V | splitA.Next = v.Next; splitB.Prev = v; } else { // Case 2 // | ^ // V | // <---*+++++++X // | // | splitA.Next = v; splitB.Prev = v.Prev; } //Fix up links splitA.Next.Prev = splitA; splitB.Prev.Next = splitB; } }
void Mesh.IChangeListener.Added(Vertex v) { }
void Mesh.IChangeListener.SplitMidpointEnd(Face f, Vertex mid) { }
public static IEnumerator Fragment(GameObject toFragmentObject, Stats returnedStats, bool areaInsteadOfSites = false) { returnedStats.totalTime = 0L; Debug.Log("Fragmentation started!"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // Gather fragmentation properties for the current game object. The program checks the // current game object and the topmost game object of the hierarchy for such properties. // If none are found, assume default properties. FragmentsProperties fragmentsProperties = toFragmentObject.GetComponent <FragmentsProperties>(); if (fragmentsProperties == null) { GameObject root = toFragmentObject.transform.root.gameObject; FragmentsProperties rootFragmentsProperties = root.GetComponent <FragmentsProperties>(); fragmentsProperties = (rootFragmentsProperties == null) ? toFragmentObject.AddComponent <FragmentsProperties>() : rootFragmentsProperties; } // Create new game object as parent of future generated fragments. This game object will // replace the current game object in the hierarchy and will retain its fragmentation properties. GameObject parentObject = new GameObject(toFragmentObject.name + Constants.FragmentStr); CopyTransforms(parentObject.transform, toFragmentObject.transform); parentObject.transform.SetParent(toFragmentObject.transform.parent, false); FragmentsProperties.Copy(parentObject.AddComponent <FragmentsProperties>(), fragmentsProperties); // Iterate through the mesh's triangles and divide each triangle in separate Voronoi diagrams. // The generated fragments will retain the original mesh's materials, normals and uv coordinates. int totalFragments = 0; Mesh mesh = toFragmentObject.GetComponent <MeshFilter>().mesh; for (int subMeshIndex = 0; subMeshIndex < mesh.subMeshCount; ++subMeshIndex) { int[] triangles = mesh.GetTriangles(subMeshIndex); // TODO paralelize for (int ti = 0; ti < triangles.Length; ti += 3) { Vertex[] v = new Vertex[3]; for (int i = 0; i < 3; ++i) { v[i].position = mesh.vertices[triangles[ti + i]]; // Assume zero values if missing normal or uv coordinates v[i].normal = (mesh.normals.Length <= triangles[ti + i]) ? Vector3.zero : mesh.normals[triangles[ti + i]]; v[i].uv = (mesh.uv.Length <= triangles[ti + i]) ? Vector2.zero : mesh.uv[triangles[ti + i]]; } List <GameObject> fragments = GenerateVoronoiFragments(v[0], v[1], v[2], fragmentsProperties, areaInsteadOfSites); foreach (GameObject fragment in fragments) { if (fragment.GetComponent <MeshFilter>() != null) { // Create new game object with fragment's mesh fragment.name = Constants.FrozenFragmentStr + totalFragments; fragment.transform.SetParent(parentObject.transform, false); fragment.tag = Constants.FrozenFragmentStr; MeshRenderer goMeshRenderer = toFragmentObject.GetComponent <MeshRenderer>(); MeshRenderer fragmentMeshRenderer = fragment.AddComponent <MeshRenderer>(); int materialIdx = subMeshIndex % goMeshRenderer.materials.Length; fragmentMeshRenderer.material = goMeshRenderer.materials[materialIdx]; // Hide current fragment's mesh until the destruction of the initial game object // to prevent z-fighting effects. fragmentMeshRenderer.enabled = false; MeshCollider mc = fragment.AddComponent <MeshCollider>(); mc.convex = true; Rigidbody rb = fragment.AddComponent <Rigidbody>(); rb.detectCollisions = false; rb.isKinematic = true; rb.interpolation = RigidbodyInterpolation.Interpolate; rb.mass = fragmentsProperties.density * FragmentVolume(fragment); rb.angularDrag = Constants.FragmentRBodyAngDrag; rb.drag = Constants.FragmentRBodyDrag; fragment.AddComponent <JointBreakListener>(); ++totalFragments; } else { // Missing fragment Debug.Log($"Clipped site: {fragment.transform.localPosition}"); } } // Ensure the current function operation does not take a lot of time // in a single frame if (stopWatch.ElapsedMilliseconds > Constants.MaxTimeMs) { Debug.Log("Fragmenter Yield in voronoi generation"); returnedStats.totalTime += stopWatch.ElapsedMilliseconds; yield return(null); stopWatch.Restart(); } } // Ensure the current function operation does not take a lot of time // in a single frame if (stopWatch.ElapsedMilliseconds > Constants.MaxTimeMs) { Debug.Log("Fragmenter Yield submesh parsing"); returnedStats.totalTime += stopWatch.ElapsedMilliseconds; yield return(null); stopWatch.Restart(); } } Debug.Log($"Fragmentation Ended at: {returnedStats.totalTime / 1000.0f}"); // Create an undirected graph with all fragments. Each fragment represents a node in the // graph. The edges represent the connectivity between the fragments. Each node will have // a direct edge to each of its touching neighbours. var graph = new Graph <GameObject, HingeJoint>(); foreach (Transform child in parentObject.transform) { if (!child.CompareTag(Constants.FrozenFragmentStr)) { continue; } GameObject go = child.gameObject; List <GameObject> possibleNeighbours = new List <GameObject>(); // To find the touching neighbours, do a rough and fast bounding box intersection first. foreach (Transform child2 in parentObject.transform) { GameObject go2 = child2.gameObject; if (go != go2) { Bounds b1 = go.GetComponent <MeshCollider>().bounds; Bounds b2 = go2.GetComponent <MeshCollider>().bounds; if (b1 == null) { Debug.Log($"{go} does not have a Mesh Collider"); } if (b2 == null) { Debug.Log($"{go2} does not have a Mesh Collider"); } if (b1 != null && b2 != null && b1.Intersects(b2)) { possibleNeighbours.Add(go2); } } } // Do a more fine and more computational heavy intersection. To do so, the mesh collider's // size will be slightly increased. The actual mesh collider's size cannot be modified, // thus a new game object will be created with a bigger mesh and a mesh collider. GameObject biggerGo = new GameObject($"Big_{child.name}"); biggerGo.transform.SetParent(go.transform); CopyTransforms(biggerGo.transform, go.transform); biggerGo.AddComponent <MeshFilter>().mesh = ScaleMesh(go.GetComponent <MeshFilter>().mesh, Constants.MeshUpscaling); biggerGo.AddComponent <MeshCollider>().convex = true; if (!graph.ContainsNode(go)) { graph.AddNode(go); } foreach (GameObject neighbour in possibleNeighbours) { Collider colBigg = biggerGo.GetComponent <Collider>(); Collider colNeigh = neighbour.GetComponent <Collider>(); if (Physics.ComputePenetration( colBigg, go.transform.position, go.transform.rotation, colNeigh, neighbour.transform.position, neighbour.transform.rotation, out _, out _)) { if (graph.ContainsEdge(go, neighbour) || graph.ContainsEdge(neighbour, go)) { continue; } if (!graph.ContainsNode(neighbour)) { graph.AddNode(neighbour); } void CreateJoint(GameObject go1, GameObject go2) { Vector3 center1 = FragmentCenter(go1); Vector3 center2 = FragmentCenter(go2); HingeJoint hj = go1.AddComponent <HingeJoint>(); hj.connectedBody = go2.GetComponent <Rigidbody>(); hj.enableCollision = false; hj.breakForce = Constants.FragmentHingeBreakForce; hj.anchor = center2; hj.axis = center2 - center1; JointLimits hinjeLimits = hj.limits; hinjeLimits.min = Constants.FragmentHingeMinAngleDeg; hinjeLimits.bounciness = 0.0f; hinjeLimits.bounceMinVelocity = 0.0f; hinjeLimits.max = Constants.FragmentHingeMaxAngleDeg; hj.limits = hinjeLimits; hj.useLimits = true; graph.AddEdge(go1, go2, hj); } CreateJoint(go, neighbour); CreateJoint(neighbour, go); } } //empty.transform.SetParent(null); Object.Destroy(biggerGo); // Ensure the current function operation does not take a lot of time // in a single frame. if (stopWatch.ElapsedMilliseconds > Constants.MaxTimeMs) { Debug.Log("Fragmenter Yield in graph creating"); returnedStats.totalTime += stopWatch.ElapsedMilliseconds; yield return(null); stopWatch.Restart(); } } //Debug.Log($"Min Area: {minSurface}, Max Area: {maxSurface}"); FragmentsGraph fragmentsGraph = parentObject.AddComponent <FragmentsGraph>(); fragmentsGraph.graph = graph; // Chose anchor fragments. An anchor fragment is a fragment which is considered crucial in // a mesh structural stability. These have to be manually specified. The program decides // if a fragment is an anchor if it intersects a 3D object with "Anchor" tag and layer. AnchorList anchorList = toFragmentObject.GetComponent <AnchorList>(); if (anchorList == null) { anchorList = toFragmentObject.transform.parent.gameObject.GetComponent <AnchorList>(); } if (anchorList != null) { // Fast and rough intersection List <GameObject> possibleAnchored = new List <GameObject>(); foreach (Transform fragment in parentObject.transform) { foreach (GameObject anchor in anchorList.gameObjects) { Bounds b1 = fragment.GetComponent <Collider>().bounds; Bounds b2 = anchor.GetComponent <BoxCollider>().bounds; if (b1.Intersects(b2)) { possibleAnchored.Add(fragment.gameObject); } } } // Slow and accurate intersection HashSet <GameObject> anchoredFragments = new HashSet <GameObject>(); foreach (GameObject fragment in possibleAnchored) { Collider col1 = fragment.GetComponent <Collider>(); foreach (GameObject anchor in anchorList.gameObjects) { Collider col2 = anchor.GetComponent <Collider>(); if (Physics.ComputePenetration( col1, fragment.transform.position, fragment.transform.rotation, col2, anchor.transform.position, anchor.transform.rotation, out _, out _)) { anchoredFragments.Add(fragment); //Debug.Log($"Anchored {fragment.name}"); } } } fragmentsGraph.anchoredFragments = anchoredFragments; fragmentsGraph.initialAnchoredCount = anchoredFragments.Count; } foreach (Transform child in parentObject.transform) { child.gameObject.GetComponent <MeshRenderer>().enabled = true; Rigidbody rb = child.gameObject.GetComponent <Rigidbody>(); rb.isKinematic = fragmentsGraph.anchoredFragments != null && fragmentsGraph.anchoredFragments.Contains(rb.gameObject); rb.detectCollisions = true; } returnedStats.isDone = true; returnedStats.fragments = totalFragments; returnedStats.fragmentedGameObject = parentObject; fragmentsGraph.initialFragmentsCount = fragmentsGraph.currentFragmentsCount = totalFragments; Object.Destroy(toFragmentObject); }
void Mesh.IChangeListener.Deleted(Vertex v) { }
/// <summary> /// /// </summary> /// <param name="source"></param> /// <param name="target"></param> /// <param name="tsRel">target to source relation (if target is parent of source = Parent)</param> /// <param name="stRel">source to target relation (if target is parent of source = Child)</param> /// <returns></returns> public bool AddRelation(Vertex source, Vertex target, RelationKind tsRel, RelationKind stRel) { return(fGraph.AddUndirectedEdge(source, target, 1, (int)tsRel, (int)stRel)); }
/// <summary> /// Given a triangle, subdivide it in multiple polygons using Voronoi diagrams. /// </summary> /// <param name="v0">First vertex of the triangle.</param> /// <param name="v1">Second vertex of the triangle.</param> /// <param name="v2">Third vertex of the triangle.</param> /// <param name="fragmentsProperties">Properties of the resulted fragments.</param> /// <returns>A list with all generated fragments' meshes. If the function failes to generate /// a fragment, it will the site of the fragment as a placeholder.</returns> private static List <GameObject> GenerateVoronoiFragments( Vertex v0, Vertex v1, Vertex v2, FragmentsProperties fragmentsProperties, bool areaInsteadOfSites = false) { if (fragmentsProperties == null) { throw new System.ArgumentNullException("fragmentsProperties"); } float area = 0.5f * Vector3.Cross(v0.position - v1.position, v0.position - v2.position).magnitude; //Debug.Log($"Area {area}"); //Debug.Log($"Max Area: {fragmentsProperties.maxArea}"); // The Voronoi API suffers from innacurate floating-point approximations and provides erroneous // results when dealing with small numbers. A current solution to this problem is to upscale // the whole mesh, do the calculations and then downscale the result to the original scale. Vector3 scale = new Vector3( Constants.VoronoiScale, Constants.VoronoiScale, Constants.VoronoiScale ); Vector3 reverseScale = new Vector3( 1.0f / Constants.VoronoiScale, 1.0f / Constants.VoronoiScale, 1.0f / Constants.VoronoiScale ); v0.position.Scale(scale); v1.position.Scale(scale); v2.position.Scale(scale); // The Voronoi API requires 2D points while the trianlge is in 3D space. In order to reduce // one dimension, all points must have the same z coordinate. Thus, rotate the triangle such // that its normal will become (0, 0, 1). Vector3 center = (v0.position + v1.position + v2.position) / 3.0f; Vector3 triangleNorm = Vector3.Cross(v1.position - v0.position, v2.position - v0.position).normalized; Quaternion rotation = Quaternion.FromToRotation(triangleNorm, Vector3.forward); Quaternion reverseRotation = Quaternion.FromToRotation(Vector3.forward, triangleNorm); Vector3 p0rot = (rotation * (v0.position - center) + center); Vector3 p1rot = (rotation * (v1.position - center) + center); Vector3 p2rot = (rotation * (v2.position - center) + center); float z = p0rot.z; // Try to make all fragments have similar area int sitesNum = areaInsteadOfSites ? Math.Max(3, (int)(area / fragmentsProperties.maxArea)) : fragmentsProperties.sitesPerTriangle;//Math.Max(3, (int)(area / fragmentsProperties.maxArea)); //Debug.Log($"Sites num: {sitesNum}"); Vector2[] sites = new Vector2[sitesNum]; // Generate random points inside the triangle. These will be the sites passed to the Voronoi API. for (int i = 0; i < sites.Length; ++i) { Vector3 p = Vector3.zero; int triesLeft = 50; while (triesLeft > 0) { float r1 = Random.Range(0.1f, 0.9f); float r2 = Random.Range(0.1f, 0.9f); p = (float)(1.0f - Math.Sqrt(r1)) * p0rot + (float)(Math.Sqrt(r1) * (1.0f - r2)) * p1rot + (float)(r2 * Math.Sqrt(r1)) * p2rot; if (PointInTriangle(p0rot, p1rot, p2rot, p)) { break; } Debug.Log($"Bad point {p:F5}\n" + $" inside triangle, ({p0rot:F5}, {p1rot:F5}, {p2rot:F5})\n" + $"{triesLeft} tries left"); --triesLeft; } sites[i] = p; } // Calculate the Voronoi diagram containing the given sites VoronoiCalculator calc = new VoronoiCalculator(); VoronoiClipper clip = new VoronoiClipper(); VoronoiDiagram diagram = calc.CalculateDiagram(sites); Vector2[] triangleClipper = new Vector2[3] { new Vector2(p0rot.x, p0rot.y), new Vector2(p1rot.x, p1rot.y), new Vector2(p2rot.x, p2rot.y) }; List <Vector2> clipped = new List <Vector2>(); List <GameObject> fragments = new List <GameObject>(sites.Length); // Generate a mesh for each site's polygon for (int i = 0; i < sites.Length; ++i) { clipped.Clear(); clip.ClipSite(diagram, triangleClipper, i, ref clipped); if (clipped.Count > 0) { // Rotate the points back to their original rotation Vector3[] originalSpacePoints = new Vector3[clipped.Count]; for (int j = 0; j < clipped.Count; ++j) { Vector3 v = new Vector3(clipped[j].x, clipped[j].y, z); originalSpacePoints[j] = reverseRotation * (v - center) + center; } Vertex[] vertices = CalculateNormalsAndUVs(v0, v1, v2, originalSpacePoints); // Revert the upscaling and scale to original object scale for (int j = 0; j < clipped.Count; ++j) { vertices[j].position.Scale(reverseScale); } float thickness = Random.Range(fragmentsProperties.minThickness, fragmentsProperties.maxThickness); fragments.Add(PolygonToFrustum(vertices, thickness)); } } return(fragments); }
public int ShortestPathByLeeBFS(int[,] matrix, Point srcPoint, Point destPoint, Stack <Point> resultPath) { if (matrix == null || matrix.GetLength(0) == 0 || matrix.GetLength(1) == 0) { return(-1); } if (matrix[srcPoint.xPos, srcPoint.yPos] != 1 || matrix[destPoint.xPos, destPoint.yPos] != 1) { return(-1); } bool[,] visited = new bool[matrix.GetLength(0), matrix.GetLength(1)]; // Mark the source cell as visited visited[srcPoint.xPos, srcPoint.yPos] = true; Queue <Vertex> vertexQueue = new Queue <Vertex>(); Vertex s = new Vertex() { Point = srcPoint, Distance = 0 }; vertexQueue.Enqueue(s); // Enqueue source cell resultPath.Push(srcPoint); // These arrays are used to get row and column numbers of 4 neighbours of a given cell int[] rowNum = { -1, 0, 0, 1 }; int[] colNum = { 0, -1, 1, 0 }; // Do a BFS starting from source cell while (vertexQueue.Count > 0) { Vertex currVertex = vertexQueue.Dequeue(); Point currPoint = currVertex.Point; // Reached the destination cell, we are done if (currPoint.xPos == destPoint.xPos && currPoint.yPos == destPoint.yPos) { return(currVertex.Distance); } for (int lpCnt = 0; lpCnt < 4; lpCnt++) { int rowPos = currPoint.xPos + rowNum[lpCnt]; int colPos = currPoint.yPos + colNum[lpCnt]; // If adjacent cell is valid, has path and not visited yet, enqueue it. if (Point.IsSafePoint(matrix, rowPos, colPos) == true && visited[rowPos, colPos] == false) { visited[rowPos, colPos] = true; Point point = new Point() { xPos = rowPos, yPos = colPos }; Vertex Adjcell = new Vertex() { Point = point, Distance = currVertex.Distance + 1 }; } } } return(-1); }
public void SetScale(Vertex scale) { COL.Model.Scale = scale; }
Mesh GenerateCube(float xScale, float yScale, float zScale, int depth) { Vector3[] v = new Vector3[8]; Dictionary <Face, Vector3> fDict = new Dictionary <Face, Vector3>(); // Face dict key = Face, value = face point Dictionary <Vector3[], Vector3> eDict = new Dictionary <Vector3[], Vector3>(new EdgeComparer()); // Edge dict key = Edge, value = edge point Dictionary <Vector3, Vector3> vDict = new Dictionary <Vector3, Vector3>(); // Vertex dict key = Vertex, value = barycenter v[0] = new Vector3(1 * xScale, 1 * yScale, 1 * zScale); v[1] = new Vector3(1 * xScale, -1 * yScale, 1 * zScale); v[2] = new Vector3(1 * xScale, -1 * yScale, -1 * zScale); v[3] = new Vector3(1 * xScale, 1 * yScale, -1 * zScale); v[4] = new Vector3(-1 * xScale, 1 * yScale, -1 * zScale); v[5] = new Vector3(-1 * xScale, -1 * yScale, -1 * zScale); v[6] = new Vector3(-1 * xScale, -1 * yScale, 1 * zScale); v[7] = new Vector3(-1 * xScale, 1 * yScale, 1 * zScale); // Save faces and their face points Face f0 = new Face(new Vector3[4] { v[0], v[1], v[2], v[3] }); Face f1 = new Face(new Vector3[4] { v[4], v[3], v[2], v[5] }); Face f2 = new Face(new Vector3[4] { v[7], v[4], v[5], v[6] }); Face f3 = new Face(new Vector3[4] { v[0], v[7], v[6], v[1] }); Face f4 = new Face(new Vector3[4] { v[7], v[0], v[3], v[4] }); Face f5 = new Face(new Vector3[4] { v[5], v[2], v[1], v[6] }); fDict.Add(f0, f0.facePoint); fDict.Add(f1, f1.facePoint); fDict.Add(f2, f2.facePoint); fDict.Add(f3, f3.facePoint); fDict.Add(f4, f4.facePoint); fDict.Add(f5, f5.facePoint); // Save edges and their edge points Edge e0 = new Edge(v[0], v[1], f0, f3); Edge e1 = new Edge(v[1], v[2], f0, f5); Edge e2 = new Edge(v[2], v[3], f0, f1); Edge e3 = new Edge(v[0], v[3], f0, f4); Edge e4 = new Edge(v[6], v[7], f2, f3); Edge e5 = new Edge(v[5], v[6], f2, f5); Edge e6 = new Edge(v[4], v[5], f1, f2); Edge e7 = new Edge(v[4], v[7], f2, f4); Edge e8 = new Edge(v[3], v[4], f1, f4); Edge e9 = new Edge(v[0], v[7], f3, f4); Edge e10 = new Edge(v[2], v[5], f1, f5); Edge e11 = new Edge(v[1], v[6], f3, f5); eDict.Add(new Vector3[2] { v[0], v[1] }, e0.edgePoint); eDict.Add(new Vector3[2] { v[1], v[2] }, e1.edgePoint); eDict.Add(new Vector3[2] { v[2], v[3] }, e2.edgePoint); eDict.Add(new Vector3[2] { v[0], v[3] }, e3.edgePoint); eDict.Add(new Vector3[2] { v[6], v[7] }, e4.edgePoint); eDict.Add(new Vector3[2] { v[5], v[6] }, e5.edgePoint); eDict.Add(new Vector3[2] { v[4], v[5] }, e6.edgePoint); eDict.Add(new Vector3[2] { v[4], v[7] }, e7.edgePoint); eDict.Add(new Vector3[2] { v[3], v[4] }, e8.edgePoint); eDict.Add(new Vector3[2] { v[0], v[7] }, e9.edgePoint); eDict.Add(new Vector3[2] { v[2], v[5] }, e10.edgePoint); eDict.Add(new Vector3[2] { v[1], v[6] }, e11.edgePoint); // input adj faces and adj edges for each vertex Vertex v0 = new Vertex(v[0], new HashSet <Face> { f0, f3, f4 }, new HashSet <Edge> { e0, e3, e9 }); Vertex v1 = new Vertex(v[1], new HashSet <Face> { f0, f3, f5 }, new HashSet <Edge> { e0, e1, e11 }); Vertex v2 = new Vertex(v[2], new HashSet <Face> { f0, f1, f5 }, new HashSet <Edge> { e1, e2, e10 }); Vertex v3 = new Vertex(v[3], new HashSet <Face> { f0, f1, f4 }, new HashSet <Edge> { e2, e3, e8 }); Vertex v4 = new Vertex(v[4], new HashSet <Face> { f1, f2, f4 }, new HashSet <Edge> { e6, e7, e8 }); Vertex v5 = new Vertex(v[5], new HashSet <Face> { f1, f2, f5 }, new HashSet <Edge> { e5, e6, e10 }); Vertex v6 = new Vertex(v[6], new HashSet <Face> { f2, f3, f5 }, new HashSet <Edge> { e4, e5, e11 }); Vertex v7 = new Vertex(v[7], new HashSet <Face> { f2, f3, f4 }, new HashSet <Edge> { e4, e7, e9 }); vDict.Add(v0.coord, v0.barycenter); vDict.Add(v1.coord, v1.barycenter); vDict.Add(v2.coord, v2.barycenter); vDict.Add(v3.coord, v3.barycenter); vDict.Add(v4.coord, v4.barycenter); vDict.Add(v5.coord, v5.barycenter); vDict.Add(v6.coord, v6.barycenter); vDict.Add(v7.coord, v7.barycenter); return(this.GetComponent <MeshSubdivision>().Subdivide(fDict, eDict, vDict, v, depth)); }
public string GetRelationship(GEDCOMIndividualRecord targetRec, bool fullFormat = false) { if (targetRec == null) { return("???"); } Vertex target = fGraph.FindVertex(targetRec.XRef); if (target == null) { return("???"); } try { IEnumerable <Edge> edgesPath = fGraph.GetPath(target); string tmp = ""; RelationKind prevRel = RelationKind.rkNone; RelationKind finRel = RelationKind.rkNone; int great = 0; GEDCOMIndividualRecord src = null, tgt = null, prev_tgt = null; string part, fullRel = ""; foreach (Edge edge in edgesPath) { GEDCOMIndividualRecord xFrom = (GEDCOMIndividualRecord)edge.Source.Value; GEDCOMIndividualRecord xTo = (GEDCOMIndividualRecord)edge.Target.Value; RelationKind curRel = FixLink(xFrom, xTo, (RelationKind)((int)edge.Value)); if (src == null) { src = xFrom; } prev_tgt = tgt; tgt = xTo; if (tmp != "") { tmp += ", "; } tmp += xFrom.XRef + ">" + GKData.RelationSigns[(int)curRel] + ">" + xTo.XRef; if (prevRel != RelationKind.rkUndefined) { int g, lev; finRel = KinshipsMan.FindKinship(prevRel, curRel, out g, out lev); great += g; // it's gap if (finRel == RelationKind.rkUndefined && fullFormat) { part = GetRelationPart(src, prev_tgt, prevRel, great); src = prev_tgt; great = 0; prevRel = RelationKind.rkNone; if (fullRel.Length > 0) { fullRel += ", "; } fullRel += part; finRel = KinshipsMan.FindKinship(prevRel, curRel, out g, out lev); great += g; } prevRel = finRel; } } IndividualsPath = targetRec.XRef + " [" + tmp + "]"; if (!fullFormat) { string relRes = FixRelation(targetRec, finRel, great); return(relRes); } else { part = GetRelationPart(src, tgt, finRel, great); if (fullRel.Length > 0) { fullRel += ", "; } fullRel += part; return(fullRel); } } catch (Exception ex) { Logger.LogWrite("KinshipsGraph.GetRelationship(): " + ex.Message); return(""); } }
/// <summary> /// Get all nav mesh surfaces /// Update all navmesh datas for each NavMeshSurfaces /// Calculate triangulation /// Add each triangle in the triangulation to a list of triangles /// Link Triangles with its neighbors /// </summary> public void GetNavPointsFromNavSurfaces() { isBuilding = true; ClearNavDatas(); List <NavMeshSurface> _surfaces = NavMeshSurface.activeSurfaces; foreach (NavMeshSurface surface in _surfaces) { surface.BuildNavMesh(); } NavMeshTriangulation _tr = NavMesh.CalculateTriangulation(); Vector3[] _vertices = _tr.vertices; List <int> _modifiedIndices = _tr.indices.ToList(); if (_tr.vertices.Length == 0) { Debug.LogWarning("No Vertices found"); return; } //GET ALL NAV POINTS int _previousIndex = 0; for (int i = 0; i < _vertices.Length; i++) { ////CREATE A POINT AT POSITION Vector3 _pos = _vertices[i]; // CHECK IF NAV POINT ALREADY EXISTS if (navPoints.Any(p => p.Position == _pos)) { ////GET THE SAME POINT Vertex _existingPoint = navPoints.Where(p => p.Position == _pos).First(); //// ORDER THE INDEX for (int j = 0; j < _modifiedIndices.Count; j++) { // REPLACE INDEX if (_modifiedIndices[j] == _previousIndex) { _modifiedIndices[j] = _existingPoint.ID; } // IF INDEX IS GREATER THAN THE REPLACED INDEX REMOVE ONE FROM THEM if (_modifiedIndices[j] > _previousIndex) { _modifiedIndices[j]--; } } } // IF THE NAV POINT DOESN'T EXISTS ADD IT TO THE DICO else { navPoints.Add(new Vertex(_pos, navPoints.Count)); _previousIndex++; } } //GET ALL TRIANGLES for (int i = 0; i < _modifiedIndices.Count; i += 3) { Vertex _first = navPoints.Where(p => p.ID == _modifiedIndices[i]).FirstOrDefault(); Vertex _second = navPoints.Where(p => p.ID == _modifiedIndices[i + 1]).FirstOrDefault(); Vertex _third = navPoints.Where(p => p.ID == _modifiedIndices[i + 2]).FirstOrDefault(); Vertex[] _pointsIndex = new Vertex[3] { _first, _second, _third }; Triangle _triangle = new Triangle(_pointsIndex); triangles.Add(_triangle); } foreach (Triangle t in triangles) { LinkTriangles(t); } isBuilding = false; SaveDatas(); }
Mesh GenerateBody(int depth) { Vector3[] v = new Vector3[20]; Dictionary <Face, Vector3> fDict = new Dictionary <Face, Vector3>(); // Face dict key = Face, value = face point Dictionary <Vector3[], Vector3> eDict = new Dictionary <Vector3[], Vector3>(new EdgeComparer()); // Edge dict key = Edge, value = edge point Dictionary <Vector3, Vector3> vDict = new Dictionary <Vector3, Vector3>(); // Vertex dict key = Vertex, value = barycenter float topTailHeight = Random.Range(1f, 3.5f); float bottomTailHeight = Random.Range(0, topTailHeight + 0.1f); float topWidth = Random.Range(0, 2f); float bottomWidth = Random.Range(0.9f, 2f); float neckHeight = Random.Range(1, 4f); // use the eyePos's x value to save how "wide" the eyes need to be // the width of top (and a bit of the bottom) influences how "wide" // taller neck means less influence from width eyePos = new Vector3(Mathf.Pow((topWidth + bottomWidth) / (neckHeight), 0.1f), neckHeight, -1.1f); beakPos = new Vector3(0, neckHeight - Random.Range(0, 0.2f), -1.5f); legHeight = Random.Range(0.5f, 2.4f); v[0] = new Vector3(-1, 1 + neckHeight, 0); v[1] = new Vector3(1, 1 + neckHeight, 0); v[2] = new Vector3(1, 1 + neckHeight, -2); v[3] = new Vector3(-1, 1 + neckHeight, -2); v[4] = new Vector3(-1, 1, 0); v[5] = new Vector3(1, 1, 0); v[6] = new Vector3(1, 1, -2); v[7] = new Vector3(-1, 1, -2); v[8] = new Vector3(-1 - bottomWidth, -1, 0); v[9] = new Vector3(1 + bottomWidth, -1, 0); v[10] = new Vector3(1, -1, -2); v[11] = new Vector3(-1, -1, -2); v[12] = new Vector3(-1 - topWidth, 1, 2); v[13] = new Vector3(-1, 0 + topTailHeight, 3); v[14] = new Vector3(1, 0 + topTailHeight, 3); v[15] = new Vector3(1 + topWidth, 1, 2); v[16] = new Vector3(-1 - bottomWidth, -1, 2); v[17] = new Vector3(-1, -1 + bottomTailHeight, 3); v[18] = new Vector3(1, -1 + bottomTailHeight, 3); v[19] = new Vector3(1 + bottomWidth, -1, 2); // Save faces and their face points Face f0 = new Face(new Vector3[4] { v[3], v[0], v[1], v[2] }); Face f1 = new Face(new Vector3[4] { v[4], v[12], v[15], v[5] }); Face f2 = new Face(new Vector3[4] { v[12], v[13], v[14], v[15] }); Face f3 = new Face(new Vector3[4] { v[10], v[9], v[8], v[11] }); Face f4 = new Face(new Vector3[4] { v[9], v[19], v[16], v[8] }); Face f5 = new Face(new Vector3[4] { v[19], v[18], v[17], v[16] }); Face f6 = new Face(new Vector3[4] { v[3], v[2], v[6], v[7] }); Face f7 = new Face(new Vector3[4] { v[7], v[6], v[10], v[11] }); Face f8 = new Face(new Vector3[4] { v[1], v[0], v[4], v[5] }); Face f9 = new Face(new Vector3[4] { v[14], v[13], v[17], v[18] }); Face f10 = new Face(new Vector3[4] { v[2], v[1], v[5], v[6] }); Face f11 = new Face(new Vector3[4] { v[6], v[5], v[9], v[10] }); Face f12 = new Face(new Vector3[4] { v[5], v[15], v[19], v[9] }); Face f13 = new Face(new Vector3[4] { v[15], v[14], v[18], v[19] }); Face f14 = new Face(new Vector3[4] { v[0], v[3], v[7], v[4] }); Face f15 = new Face(new Vector3[4] { v[4], v[7], v[11], v[8] }); Face f16 = new Face(new Vector3[4] { v[12], v[4], v[8], v[16] }); Face f17 = new Face(new Vector3[4] { v[13], v[12], v[16], v[17] }); fDict.Add(f0, f0.facePoint); fDict.Add(f1, f1.facePoint); fDict.Add(f2, f2.facePoint); fDict.Add(f3, f3.facePoint); fDict.Add(f4, f4.facePoint); fDict.Add(f5, f5.facePoint); fDict.Add(f6, f6.facePoint); fDict.Add(f7, f7.facePoint); fDict.Add(f8, f8.facePoint); fDict.Add(f9, f9.facePoint); fDict.Add(f10, f10.facePoint); fDict.Add(f11, f11.facePoint); fDict.Add(f12, f12.facePoint); fDict.Add(f13, f13.facePoint); fDict.Add(f14, f14.facePoint); fDict.Add(f15, f15.facePoint); fDict.Add(f16, f16.facePoint); fDict.Add(f17, f17.facePoint); // Save edges and their edge points Edge e0 = new Edge(v[3], v[2], f0, f6); Edge e1 = new Edge(v[7], v[6], f6, f7); Edge e2 = new Edge(v[11], v[10], f7, f3); Edge e3 = new Edge(v[0], v[1], f0, f8); Edge e4 = new Edge(v[4], v[5], f8, f1); Edge e5 = new Edge(v[8], v[9], f3, f4); Edge e6 = new Edge(v[12], v[15], f1, f2); Edge e7 = new Edge(v[16], v[19], f4, f5); Edge e8 = new Edge(v[13], v[14], f2, f9); Edge e9 = new Edge(v[17], v[18], f5, f9); Edge e10 = new Edge(v[2], v[1], f0, f10); Edge e11 = new Edge(v[6], v[5], f10, f11); Edge e12 = new Edge(v[10], v[9], f11, f3); Edge e13 = new Edge(v[3], v[0], f0, f14); Edge e14 = new Edge(v[7], v[4], f14, f15); Edge e15 = new Edge(v[11], v[8], f15, f3); Edge e16 = new Edge(v[5], v[15], f12, f1); Edge e17 = new Edge(v[9], v[19], f12, f4); Edge e18 = new Edge(v[4], v[12], f1, f16); Edge e19 = new Edge(v[8], v[16], f4, f16); Edge e20 = new Edge(v[15], v[14], f2, f13); Edge e21 = new Edge(v[19], v[18], f13, f5); Edge e22 = new Edge(v[12], v[13], f2, f17); Edge e23 = new Edge(v[16], v[17], f17, f5); Edge e24 = new Edge(v[2], v[6], f6, f10); Edge e25 = new Edge(v[6], v[10], f7, f11); Edge e26 = new Edge(v[3], v[7], f6, f14); Edge e27 = new Edge(v[7], v[11], f7, f15); Edge e28 = new Edge(v[1], v[5], f10, f8); Edge e29 = new Edge(v[5], v[9], f11, f12); Edge e30 = new Edge(v[0], v[4], f14, f8); Edge e31 = new Edge(v[4], v[8], f15, f16); Edge e32 = new Edge(v[15], v[19], f12, f13); Edge e33 = new Edge(v[12], v[16], f16, f17); Edge e34 = new Edge(v[14], v[18], f13, f9); Edge e35 = new Edge(v[13], v[17], f9, f17); eDict.Add(new Vector3[2] { e0.vert1, e0.vert2 }, e0.edgePoint); eDict.Add(new Vector3[2] { e1.vert1, e1.vert2 }, e1.edgePoint); eDict.Add(new Vector3[2] { e2.vert1, e2.vert2 }, e2.edgePoint); eDict.Add(new Vector3[2] { e3.vert1, e3.vert2 }, e3.edgePoint); eDict.Add(new Vector3[2] { e4.vert1, e4.vert2 }, e4.edgePoint); eDict.Add(new Vector3[2] { e5.vert1, e5.vert2 }, e5.edgePoint); eDict.Add(new Vector3[2] { e6.vert1, e6.vert2 }, e6.edgePoint); eDict.Add(new Vector3[2] { e7.vert1, e7.vert2 }, e7.edgePoint); eDict.Add(new Vector3[2] { e8.vert1, e8.vert2 }, e8.edgePoint); eDict.Add(new Vector3[2] { e9.vert1, e9.vert2 }, e9.edgePoint); eDict.Add(new Vector3[2] { e10.vert1, e10.vert2 }, e10.edgePoint); eDict.Add(new Vector3[2] { e11.vert1, e11.vert2 }, e11.edgePoint); eDict.Add(new Vector3[2] { e12.vert1, e12.vert2 }, e12.edgePoint); eDict.Add(new Vector3[2] { e13.vert1, e13.vert2 }, e13.edgePoint); eDict.Add(new Vector3[2] { e14.vert1, e14.vert2 }, e14.edgePoint); eDict.Add(new Vector3[2] { e15.vert1, e15.vert2 }, e15.edgePoint); eDict.Add(new Vector3[2] { e16.vert1, e16.vert2 }, e16.edgePoint); eDict.Add(new Vector3[2] { e17.vert1, e17.vert2 }, e17.edgePoint); eDict.Add(new Vector3[2] { e18.vert1, e18.vert2 }, e18.edgePoint); eDict.Add(new Vector3[2] { e19.vert1, e19.vert2 }, e19.edgePoint); eDict.Add(new Vector3[2] { e20.vert1, e20.vert2 }, e20.edgePoint); eDict.Add(new Vector3[2] { e21.vert1, e21.vert2 }, e21.edgePoint); eDict.Add(new Vector3[2] { e22.vert1, e22.vert2 }, e22.edgePoint); eDict.Add(new Vector3[2] { e23.vert1, e23.vert2 }, e23.edgePoint); eDict.Add(new Vector3[2] { e24.vert1, e24.vert2 }, e24.edgePoint); eDict.Add(new Vector3[2] { e25.vert1, e25.vert2 }, e25.edgePoint); eDict.Add(new Vector3[2] { e26.vert1, e26.vert2 }, e26.edgePoint); eDict.Add(new Vector3[2] { e27.vert1, e27.vert2 }, e27.edgePoint); eDict.Add(new Vector3[2] { e28.vert1, e28.vert2 }, e28.edgePoint); eDict.Add(new Vector3[2] { e29.vert1, e29.vert2 }, e29.edgePoint); eDict.Add(new Vector3[2] { e30.vert1, e30.vert2 }, e30.edgePoint); eDict.Add(new Vector3[2] { e31.vert1, e31.vert2 }, e31.edgePoint); eDict.Add(new Vector3[2] { e32.vert1, e32.vert2 }, e32.edgePoint); eDict.Add(new Vector3[2] { e33.vert1, e33.vert2 }, e33.edgePoint); eDict.Add(new Vector3[2] { e34.vert1, e34.vert2 }, e34.edgePoint); eDict.Add(new Vector3[2] { e35.vert1, e35.vert2 }, e35.edgePoint); // input adj faces and adj edges for each vertex Vertex v0 = new Vertex(v[0], new HashSet <Face> { f0, f8, f14 }, new HashSet <Edge> { e3, e13, e30 }); Vertex v1 = new Vertex(v[1], new HashSet <Face> { f0, f8, f10 }, new HashSet <Edge> { e3, e10, e28 }); Vertex v2 = new Vertex(v[2], new HashSet <Face> { f0, f6, f10 }, new HashSet <Edge> { e0, e10, e24 }); Vertex v3 = new Vertex(v[3], new HashSet <Face> { f0, f6, f14 }, new HashSet <Edge> { e0, e13, e26 }); Vertex v4 = new Vertex(v[4], new HashSet <Face> { f1, f8, f14, f15, f16 }, new HashSet <Edge> { e4, e14, e18, e30, e31 }); Vertex v5 = new Vertex(v[5], new HashSet <Face> { f1, f8, f10, f11, f12 }, new HashSet <Edge> { e4, e11, e16, e28, e29 }); Vertex v6 = new Vertex(v[6], new HashSet <Face> { f6, f7, f10, f11 }, new HashSet <Edge> { e1, e11, e24, e25 }); Vertex v7 = new Vertex(v[7], new HashSet <Face> { f6, f7, f14, f15 }, new HashSet <Edge> { e1, e14, e26, e27 }); Vertex v8 = new Vertex(v[8], new HashSet <Face> { f3, f4, f15, f16 }, new HashSet <Edge> { e5, e15, e19, e31 }); Vertex v9 = new Vertex(v[9], new HashSet <Face> { f3, f4, f11, f12 }, new HashSet <Edge> { e5, e12, e17, e29 }); Vertex v10 = new Vertex(v[10], new HashSet <Face> { f3, f7, f11 }, new HashSet <Edge> { e2, e12, e25 }); Vertex v11 = new Vertex(v[11], new HashSet <Face> { f3, f7, f15 }, new HashSet <Edge> { e2, e15, e27 }); Vertex v12 = new Vertex(v[12], new HashSet <Face> { f1, f2, f16, f17 }, new HashSet <Edge> { e6, e18, e22, e33 }); Vertex v13 = new Vertex(v[13], new HashSet <Face> { f2, f9, f17 }, new HashSet <Edge> { e8, e22, e35 }); Vertex v14 = new Vertex(v[14], new HashSet <Face> { f2, f9, f13 }, new HashSet <Edge> { e8, e20, e34 }); Vertex v15 = new Vertex(v[15], new HashSet <Face> { f1, f2, f12, f13 }, new HashSet <Edge> { e6, e16, e20, e32 }); Vertex v16 = new Vertex(v[16], new HashSet <Face> { f4, f5, f16, f17 }, new HashSet <Edge> { e7, e19, e23, e33 }); Vertex v17 = new Vertex(v[17], new HashSet <Face> { f5, f9, f17 }, new HashSet <Edge> { e9, e23, e35 }); Vertex v18 = new Vertex(v[18], new HashSet <Face> { f5, f9, f13 }, new HashSet <Edge> { e9, e21, e34 }); Vertex v19 = new Vertex(v[19], new HashSet <Face> { f4, f5, f12, f13 }, new HashSet <Edge> { e7, e17, e21, e32 }); vDict.Add(v0.coord, v0.barycenter); vDict.Add(v1.coord, v1.barycenter); vDict.Add(v2.coord, v2.barycenter); vDict.Add(v3.coord, v3.barycenter); vDict.Add(v4.coord, v4.barycenter); vDict.Add(v5.coord, v5.barycenter); vDict.Add(v6.coord, v6.barycenter); vDict.Add(v7.coord, v7.barycenter); vDict.Add(v8.coord, v8.barycenter); vDict.Add(v9.coord, v9.barycenter); vDict.Add(v10.coord, v10.barycenter); vDict.Add(v11.coord, v11.barycenter); vDict.Add(v12.coord, v12.barycenter); vDict.Add(v13.coord, v13.barycenter); vDict.Add(v14.coord, v14.barycenter); vDict.Add(v15.coord, v15.barycenter); vDict.Add(v16.coord, v16.barycenter); vDict.Add(v17.coord, v17.barycenter); vDict.Add(v18.coord, v18.barycenter); vDict.Add(v19.coord, v19.barycenter); return(this.GetComponent <MeshSubdivision>().Subdivide(fDict, eDict, vDict, v, depth)); }
public void OnEdgeToVisited(Vertex <TVertexId> vertex, Vertex <TVertexId> neighbour) { }
public Triangle(Vertex _first, Vertex _second, Vertex _third) { first = _first; second = _second; third = _third; }
public void ForRoot(Vertex <TVertexId> root) { }
private static String FormatVertex(Vertex v) { return(String.Format("({0},{1},{2})", v.X, v.Y, v.Z)); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this })); } // Build the GVM table entries from the list of interesting GVMTableEntryNodes foreach (var interestingEntry in factory.MetadataManager.GetTypeGVMEntries()) { foreach (var typeGVMEntryInfo in interestingEntry.ScanForInterfaceGenericVirtualMethodEntries()) { AddGenericVirtualMethodImplementation(factory, typeGVMEntryInfo.CallingMethod, typeGVMEntryInfo.ImplementationType, typeGVMEntryInfo.ImplementationMethod); } } // Ensure the native layout blob has been saved factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory); NativeWriter nativeFormatWriter = new NativeWriter(); VertexHashtable gvmHashtable = new VertexHashtable(); Section gvmHashtableSection = nativeFormatWriter.NewSection(); gvmHashtableSection.Place(gvmHashtable); // Emit the interface slot resolution entries foreach (var gvmEntry in _interfaceGvmSlots) { Debug.Assert(gvmEntry.Key.OwningType.IsInterface); MethodDesc callingMethod = gvmEntry.Key; // Emit the method signature and containing type of the current interface method uint typeId = _externalReferences.GetIndex(factory.NecessaryTypeSymbol(callingMethod.OwningType)); var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(callingMethod)); Vertex vertex = nativeFormatWriter.GetTuple( nativeFormatWriter.GetUnsignedConstant(typeId), nativeFormatWriter.GetUnsignedConstant((uint)nameAndSig.SavedVertex.VertexOffset)); // Emit the method name / sig and containing type of each GVM target method for the current interface method entry vertex = nativeFormatWriter.GetTuple(vertex, nativeFormatWriter.GetUnsignedConstant((uint)gvmEntry.Value.Count)); foreach (MethodDesc implementationMethod in gvmEntry.Value) { nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(implementationMethod)); typeId = _externalReferences.GetIndex(factory.NecessaryTypeSymbol(implementationMethod.OwningType)); vertex = nativeFormatWriter.GetTuple( vertex, nativeFormatWriter.GetUnsignedConstant((uint)nameAndSig.SavedVertex.VertexOffset), nativeFormatWriter.GetUnsignedConstant(typeId)); // Emit the interface GVM slot details for each type that implements the interface methods { Debug.Assert(_interfaceImpls.ContainsKey(implementationMethod)); var ifaceImpls = _interfaceImpls[implementationMethod]; // First, emit how many types have method implementations for this interface method entry vertex = nativeFormatWriter.GetTuple(vertex, nativeFormatWriter.GetUnsignedConstant((uint)ifaceImpls.Count)); // Emit each type that implements the interface method, and the interface signatures for the interfaces implemented by the type foreach (var currentImpl in ifaceImpls) { TypeDesc implementationType = currentImpl.Key; typeId = _externalReferences.GetIndex(factory.NecessaryTypeSymbol(implementationType)); vertex = nativeFormatWriter.GetTuple(vertex, nativeFormatWriter.GetUnsignedConstant(typeId)); // Emit information on which interfaces the current method entry provides implementations for vertex = nativeFormatWriter.GetTuple(vertex, nativeFormatWriter.GetUnsignedConstant((uint)currentImpl.Value.Count)); foreach (var ifaceId in currentImpl.Value) { // Emit the signature of the current interface implemented by the method Debug.Assert(((uint)ifaceId) < implementationType.RuntimeInterfaces.Length); TypeDesc currentInterface = implementationType.RuntimeInterfaces[ifaceId]; var typeSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.TypeSignatureVertex(currentInterface)); vertex = nativeFormatWriter.GetTuple(vertex, nativeFormatWriter.GetUnsignedConstant((uint)typeSig.SavedVertex.VertexOffset)); } } } } int hashCode = callingMethod.OwningType.GetHashCode(); gvmHashtable.Append((uint)hashCode, gvmHashtableSection.Place(vertex)); } // Zero out the dictionary so that we AV if someone tries to insert after we're done. _interfaceGvmSlots = null; byte[] streamBytes = nativeFormatWriter.Save(); _endSymbol.SetSymbolOffset(streamBytes.Length); return(new ObjectData(streamBytes, Array.Empty <Relocation>(), 1, new ISymbolNode[] { this, _endSymbol })); }
public void OnExit(Vertex <TVertexId> vertex) => exits.Add(vertex);
public void AddVertex(Vertex v) { vertices.Add(v); }
public void OnEntry(Vertex <TVertexId> vertex) => entries.Add(vertex);
/// <summary> /// /// </summary> /// <param name="gameEngine">An instance of the <see cref="Tesseract"/> game engine.</param> protected override void CreateDeviceResources(Tesseract gameEngine) { // Create a texture sampler state (in the base class) base.CreateDeviceResources(gameEngine); // Initialize variables needed to create the vertex & index buffers var device = gameEngine.DeviceManager.Device3D; Vector3 quadNormal = new Vector3(0, 1, 0); Vector2 texCoords = new Vector2(0, 0); VertexArray = new Vertex[] { new Vertex(new Vector3(1, 0, 0), quadNormal, Color.Lime, texCoords), new Vertex(new Vector3(0, 0, 0), quadNormal, Color.Blue, texCoords), new Vertex(new Vector3(0, 0, -1), quadNormal, Color.Red, texCoords), new Vertex(new Vector3(1, 0, -1), quadNormal, Color.Yellow, texCoords), }; IndexArray = new ushort[] { 0, 1, 2, // Front A 0, 2, 3, // Front B }; // Create the buffers VertexBuffer = ToDispose(Buffer.Create(device, BindFlags.VertexBuffer, VertexArray)); VertexBufferBinding = new VertexBufferBinding(VertexBuffer, Utilities.SizeOf<Vertex>(), 0); IndexBuffer = ToDispose(Buffer.Create(device, BindFlags.IndexBuffer, IndexArray)); }