/// <summary> /// 创建从src到dest的边, 如果它已经存在, 直接返回它. /// </summary> public HalfEdge CreateEdge(Vertex src, Vertex dest) { HalfEdge self = GetRays(src).Find(item => { return item.Dest == dest; }); // 如果该边不存在, 进行创建. if (self == null) { self = new HalfEdge(); self.Dest = dest; HalfEdge other = new HalfEdge(); other.Dest = src; self.Pair = other; other.Pair = self; /*src.Edge = self; dest.Edge = other; */ AddUnserializedEdge(self); AddUnserializedEdge(other); } return self; }
private Halfedge Init (Edge edge, Nullable<Side> lr) { this.edge = edge; leftRight = lr; nextInPriorityQueue = null; vertex = null; return this; }
/// <summary> /// 创建一个位置在position的顶点. /// </summary> public Vertex CreateVertex(BinaryReader reader) { Vertex ans = new Vertex(Vector3.zero); ans.ReadBinary(reader); AddVertex(ans); return ans; }
public Vertex CreateVertex(Vector3 position) { Utility.Verify(FindVertex(position) == null, "Duplicate vertex at position " + position); Vertex ans = new Vertex(position); AddVertex(ans); return ans; }
public void ReallyDispose() { edgeListLeftNeighbor = null; edgeListRightNeighbor = null; nextInPriorityQueue = null; edge = null; leftRight = null; vertex = null; _pool.Add(this); }
public void Dispose () { if (edgeListLeftNeighbor != null || edgeListRightNeighbor != null) { // still in EdgeList return; } if (nextInPriorityQueue != null) { // still in PriorityQueue return; } edge = null; leftRight = null; vertex = null; _pool.Push (this); }
private void addCEIDToolStripMenuItem_Click(object sender, EventArgs e) { ///////////////////////////////////////////////////////////// Start Video mp.Initialize(Engine.g_device); mp.SetFile("sample.avi"); difTex = mp.CreateTexture(); Engine.AppHandleKeys = (SharpDX.DirectInput.Key key) => { /// handle the keys that we want switch (key) { case SharpDX.DirectInput.Key.Up: mp.OnRender(difTex.texture2D, true); break; case SharpDX.DirectInput.Key.Down: mp.OnRender(difTex.texture2D, false); break; case SharpDX.DirectInput.Key.Space: if (selected_sphere != null) { Engine.g_MoveCamera.SetViewParams(selected_sphere.center, new Vector3(2000, 0, 2000)); selected_sphere.sh.SetVariables(new Vector3(1, 1, 1), ShaderViariables.Ambient); selected_sphere = null; weAreIn = true; } break; case SharpDX.DirectInput.Key.LeftShift: Engine.g_MoveCamera.SetViewParams(new Vector3(6500, 4500, 2000), new Vector3(200, 0, 200)); weAreIn = false; break; } return false; }; ///////////////////////////////////////////////////////////// Add the Spheres // AddSphete(1000, new Vector3(0, 0, 0), new Vector3(2, 2, 2),"sample.avi"); AddSphere(100, new Vector3(1500, 110, 900), new Vector3(2.5f, 2.5f, 2.5f), "Resources/lady2.jpg"); AddSphere(100, new Vector3(2300, 80, 3000), new Vector3(2.5f, 2.5f, 2.5f), "Resources/lady.jpg"); AddSphere(100, new Vector3(2300, 110, 2300), new Vector3(2.5f, 2.5f, 2.5f), "Resources/lady3.jpg"); AddSphete(100, new Vector3(2300, 110, 1700), new Vector3(2.5f, 2.5f, 2.5f)); // AddSphete(100, new Vector3(1100, 80, 2000), new Vector3(3, 3, 3)); // create the shader ShaderSimple sh1 = new ShaderSimple(); /// add the shader to the list ShaderManager.AddShader("Shader11", sh1); // add the textures for the shader sh1.SetTexture("Resources/tmima2.png", TextureType.Diffuse); sh1.SetTexture("Resources/tmima2.png", TextureType.Lightmap); sh1.SetTexture("Resources/height.jpg", TextureType.Heightmap); List<Polygon> polygonList1 = new List<Polygon>(); FxVector2f p1 = new FxVector2f(0, 0); FxVector2f p2 = new FxVector2f(0, 100); FxVector2f p3 = new FxVector2f(100, 100); FxVector2f p4 = new FxVector2f(100, 0); float u1 = 0; float v1 = 0; Vertex ver1 = new Vertex(p1.X, -1, p1.Y, 0, 0, 0, u1, v1); u1 = 0; v1 = 1; Vertex ver2 = new Vertex(p2.X, -1, p2.Y, 0, 0, 0, u1, v1); u1 = 1; v1 = 1; Vertex ver3 = new Vertex(p3.X, -1, p3.Y, 0, 0, 0, u1, v1); u1 = 1; v1 = 0; Vertex ver4 = new Vertex(p4.X, -1, p4.Y, 0, 0, 0, u1, v1); polygonList1.Add(new Polygon(ver1, ver2, ver3)); polygonList1.Add(new Polygon(ver1, ver3, ver4)); /// make a new mesh Mesh mesh1 = new Mesh(); /// set to the new mesh the shader mesh1.m_shader = ShaderManager.GetExistShader("Shader11"); // set the position mesh1.SetPosition(new Vector3(0, 0, 0)); // scale it mesh1.SetScale(new Vector3(60, 60, 60)); // add the polygons on mesh foreach (Polygon poly in polygonList1) { // add the polygons to the mesh mesh1.AddPolygon(poly, false); } /// create the mesh and download it to the card mesh1.CreateMesh(); /// add the mesh to the engine mesh list Engine.g_MeshManager.AddMesh(mesh1); sh1.SetVariables(new Vector3(1, 1, 1), ShaderViariables.Ambient); }
private void FortunesAlgorithm() { Site newSite, bottomSite, topSite, tempSite; Vertex v, vertex; Vector2 newintstar = Vector2.zero; //Because the compiler doesn't know that it will have a value - Julian Side leftRight; Halfedge lbnd, rbnd, llbnd, rrbnd, bisector; Edge edge; Rect dataBounds = _sites.GetSitesBounds(); int sqrt_nsites = (int)(Mathf.Sqrt(_sites.Count + 4)); HalfedgePriorityQueue heap = new HalfedgePriorityQueue(dataBounds.y, dataBounds.height, sqrt_nsites); EdgeList edgeList = new EdgeList(dataBounds.x, dataBounds.width, sqrt_nsites); List <Halfedge> halfEdges = new List <Halfedge> (); List <Vertex> vertices = new List <Vertex> (); fortunesAlgorithm_bottomMostSite = _sites.Next(); newSite = _sites.Next(); for (;;) { if (heap.Empty() == false) { newintstar = heap.Min(); } if (newSite != null && (heap.Empty() || CompareByYThenX(newSite, newintstar) < 0)) { /* new site is smallest */ //trace("smallest: new site " + newSite); // Step 8: lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord); // the Halfedge just to the left of newSite //trace("lbnd: " + lbnd); rbnd = lbnd.edgeListRightNeighbor; // the Halfedge just to the right //trace("rbnd: " + rbnd); bottomSite = FortunesAlgorithm_rightRegion(lbnd); // this is the same as leftRegion(rbnd) // this Site determines the region containing the new site //trace("new Site is in region of existing site: " + bottomSite); // Step 9: edge = Edge.CreateBisectingEdge(bottomSite, newSite); //trace("new edge: " + edge); _edges.Add(edge); bisector = Halfedge.Create(edge, Side.LEFT); halfEdges.Add(bisector); // inserting two Halfedges into edgeList constitutes Step 10: // insert bisector to the right of lbnd: edgeList.Insert(lbnd, bisector); // first half of Step 11: if ((vertex = Vertex.Intersect(lbnd, bisector)) != null) { vertices.Add(vertex); heap.Remove(lbnd); lbnd.vertex = vertex; lbnd.ystar = vertex.y + newSite.Dist(vertex); heap.Insert(lbnd); } lbnd = bisector; bisector = Halfedge.Create(edge, Side.RIGHT); halfEdges.Add(bisector); // second Halfedge for Step 10: // insert bisector to the right of lbnd: edgeList.Insert(lbnd, bisector); // second half of Step 11: if ((vertex = Vertex.Intersect(bisector, rbnd)) != null) { vertices.Add(vertex); bisector.vertex = vertex; bisector.ystar = vertex.y + newSite.Dist(vertex); heap.Insert(bisector); } newSite = _sites.Next(); } else if (heap.Empty() == false) { /* intersection is smallest */ lbnd = heap.ExtractMin(); llbnd = lbnd.edgeListLeftNeighbor; rbnd = lbnd.edgeListRightNeighbor; rrbnd = rbnd.edgeListRightNeighbor; bottomSite = FortunesAlgorithm_leftRegion(lbnd); topSite = FortunesAlgorithm_rightRegion(rbnd); // these three sites define a Delaunay triangle // (not actually using these for anything...) //_triangles.push(new Triangle(bottomSite, topSite, rightRegion(lbnd))); v = lbnd.vertex; v.SetIndex(); lbnd.edge.SetVertex((Side)lbnd.leftRight, v); rbnd.edge.SetVertex((Side)rbnd.leftRight, v); edgeList.Remove(lbnd); heap.Remove(rbnd); edgeList.Remove(rbnd); leftRight = Side.LEFT; if (bottomSite.y > topSite.y) { tempSite = bottomSite; bottomSite = topSite; topSite = tempSite; leftRight = Side.RIGHT; } edge = Edge.CreateBisectingEdge(bottomSite, topSite); _edges.Add(edge); bisector = Halfedge.Create(edge, leftRight); halfEdges.Add(bisector); edgeList.Insert(llbnd, bisector); edge.SetVertex(SideHelper.Other(leftRight), v); if ((vertex = Vertex.Intersect(llbnd, bisector)) != null) { vertices.Add(vertex); heap.Remove(llbnd); llbnd.vertex = vertex; llbnd.ystar = vertex.y + bottomSite.Dist(vertex); heap.Insert(llbnd); } if ((vertex = Vertex.Intersect(bisector, rrbnd)) != null) { vertices.Add(vertex); bisector.vertex = vertex; bisector.ystar = vertex.y + bottomSite.Dist(vertex); heap.Insert(bisector); } } else { break; } } // heap should be empty now heap.Dispose(); edgeList.Dispose(); for (int hIndex = 0; hIndex < halfEdges.Count; hIndex++) { Halfedge halfEdge = halfEdges [hIndex]; halfEdge.ReallyDispose(); } halfEdges.Clear(); // we need the vertices to clip the edges for (int eIndex = 0; eIndex < _edges.Count; eIndex++) { edge = _edges [eIndex]; edge.ClipVertices(_plotBounds); } // but we don't actually ever use them again! for (int vIndex = 0; vIndex < vertices.Count; vIndex++) { vertex = vertices [vIndex]; vertex.Dispose(); } vertices.Clear(); }
/// <summary> /// 将点插入到old的边上. /// </summary> void InsertOnEdge(Vertex v, Triangle old, HalfEdge hitEdge) { // 连接v和v所在的边正对的顶点, 将old一分为二. Triangle split1 = geomManager.CreateTriangle(); Triangle split2 = geomManager.CreateTriangle(); Vertex opositeVertex = hitEdge.Next.Dest; HalfEdge ov = geomManager.CreateEdge(opositeVertex, v); HalfEdge v1 = geomManager.CreateEdge(v, hitEdge.Dest); HalfEdge v2 = geomManager.CreateEdge(v, hitEdge.Pair.Dest); HalfEdge sp1Edge0 = hitEdge.Next; HalfEdge sp2Edge0 = hitEdge.Next.Next; HalfEdge sp2Edge1 = v2.Pair; HalfEdge sp2Edge2 = ov.Pair; // 更新Face. sp1Edge0.Face = ov.Face = v1.Face = split1; sp2Edge0.Face = sp2Edge1.Face = sp2Edge2.Face = split2; // 释放旧三角形. geomManager.ReleaseTriangle(old); // 连接边. split1.Edge = sp1Edge0.CycleLink(ov, v1); split2.Edge = sp2Edge0.CycleLink(sp2Edge1, sp2Edge2); // 将新三角形映射到格子地图上. geomManager.RasterizeTriangle(split1); geomManager.RasterizeTriangle(split2); Utility.Verify(ov.Face == split1); Utility.Verify(ov.Pair.Face == split2); Triangle other = hitEdge.Pair.Face; Triangle oposite1 = null; Triangle oposite2 = null; // 分割另一侧的三角形. if (other != null) { Vertex p = hitEdge.Pair.Next.Dest; HalfEdge vp = geomManager.CreateEdge(v, p); oposite1 = geomManager.CreateTriangle(); oposite2 = geomManager.CreateTriangle(); HalfEdge hpn = hitEdge.Pair.Next; HalfEdge op1Edge0 = hpn.Next; HalfEdge op1Edge1 = v1.Pair; HalfEdge op1Edge2 = vp; hpn.Face = vp.Pair.Face = v2.Face = oposite2; op1Edge0.Face = op1Edge1.Face = op1Edge2.Face = oposite1; geomManager.ReleaseTriangle(other); oposite2.Edge = hpn.CycleLink(vp.Pair, v2); oposite1.Edge = op1Edge0.CycleLink(op1Edge1, op1Edge2); geomManager.RasterizeTriangle(oposite1); geomManager.RasterizeTriangle(oposite2); Utility.Verify(vp.Face == oposite1); Utility.Verify(vp.Pair.Face == oposite2); } Utility.Verify(v1.Face == split1); Utility.Verify(v1.Pair.Face == oposite1); Utility.Verify(v2.Face == oposite2); Utility.Verify(v2.Pair.Face == split2); // 维护delaunay特性. FlipTriangles(split1.Edge); FlipTriangles(split2.Edge); if (other != null) { FlipTriangles(oposite1.Edge); FlipTriangles(oposite2.Edge); } }
/// <summary> /// 将点插入到三角形中. /// </summary> void InsertToTriangle(Vertex v, Triangle old) { Triangle ab = geomManager.CreateTriangle(); Triangle bc = geomManager.CreateTriangle(); Triangle ca = geomManager.CreateTriangle(); // 分别构造连接v和old的三个顶点的边, 将old一分为三. HalfEdge av = geomManager.CreateEdge(old.A, v); HalfEdge bv = geomManager.CreateEdge(old.B, v); HalfEdge cv = geomManager.CreateEdge(old.C, v); HalfEdge AB = old.AB, BC = old.BC, CA = old.CA; // 更新Face. AB.Face = bv.Face = av.Pair.Face = ab; BC.Face = cv.Face = bv.Pair.Face = bc; CA.Face = av.Face = cv.Pair.Face = ca; // 释放旧三角形. geomManager.ReleaseTriangle(old); // 连接边. ab.Edge = AB.CycleLink(bv, av.Pair); bc.Edge = BC.CycleLink(cv, bv.Pair); ca.Edge = CA.CycleLink(av, cv.Pair); // 映射到格子地图上. geomManager.RasterizeTriangle(ab); geomManager.RasterizeTriangle(bc); geomManager.RasterizeTriangle(ca); Utility.Verify(av.Face == ca); Utility.Verify(av.Pair.Face == ab); Utility.Verify(bv.Face == ab); Utility.Verify(bv.Pair.Face == bc); Utility.Verify(cv.Face == bc); Utility.Verify(cv.Pair.Face == ca); // 维护delaunay特性. FlipTriangles(ab.Edge); FlipTriangles(bc.Edge); FlipTriangles(ca.Edge); }
/// <summary> /// 收集与src到dest相交的约束边. /// </summary> Vertex CollectCrossedUnconstrainedEdges(List<HalfEdge> answer, List<Vertex> lowerVertices, List<Vertex> upperVertices, Vertex src, Vertex dest, HalfEdge start) { // src->dest向量. Vector3 srcDest = dest.Position - src.Position; Vertex current = src; // 遍历到dest所在的三角形为止. for (; !start.Face.Contains(dest.Position); ) { Utility.Verify(!start.Constrained, "Crossed constrained edge"); // 收集相交的边. answer.Add(start); HalfEdge opposedTriangle = start.Face.GetOpposite(current); Utility.Verify(opposedTriangle != null); Vertex opposedVertex = opposedTriangle.Next.Dest; if ((opposedVertex.Position - src.Position).cross2(srcDest) < 0) { current = opposedTriangle.Src; } else { current = opposedTriangle.Dest; } float cr = (opposedTriangle.Dest.Position - src.Position).cross2(srcDest); Utility.Verify(!MathUtility.Approximately(0, cr), "Not implement"); List<Vertex> activeContainer = ((cr < 0) ? upperVertices : lowerVertices); if (!activeContainer.Contains(opposedTriangle.Dest)) { activeContainer.Add(opposedTriangle.Dest); } cr = (opposedTriangle.Src.Position - src.Position).cross2(srcDest); activeContainer = ((cr < 0) ? upperVertices : lowerVertices); if (!activeContainer.Contains(opposedTriangle.Src)) { activeContainer.Add(opposedTriangle.Src); } if (MathUtility.PointOnSegment(opposedVertex.Position, src.Position, dest.Position)) { answer.Add(opposedTriangle); src = opposedVertex; break; } start = opposedTriangle; } return src; }
/// <summary> /// 构造src到dest的约束边. crossedEdge为第一条相交边. /// </summary> HalfEdge OnConstrainedEdgeCrossEdges(ref Vertex src, Vertex dest, HalfEdge crossedEdge) { List<Vertex> upper = new List<Vertex>(); List<Vertex> lower = new List<Vertex>(); List<HalfEdge> edges = new List<HalfEdge>(); // 收集相交的非约束边. Vertex newSrc = CollectCrossedUnconstrainedEdges(edges, lower, upper, src, dest, crossedEdge); // 清理非约束边两侧的三角形. for (int i = 0; i < edges.Count; ++i) { HalfEdge edge = edges[i]; if (edge.Face != null) { geomManager.ReleaseTriangle(edge.Face); } if (edge.Pair.Face != null) { geomManager.ReleaseTriangle(edge.Pair.Face); } } // 对清理过后的区域三角形化(该区域不一定是多边形). CreateTriangles(PolygonTriangulation.Triangulate(lower, dest, src)); CreateTriangles(PolygonTriangulation.Triangulate(upper, src, dest)); // 标记约束边. HalfEdge constrainedEdge = geomManager.GetRays(src).Find(edge => { return edge.Dest == dest; }); Utility.Verify(constrainedEdge != null); constrainedEdge.Constrained = true; src = newSrc; return constrainedEdge; }
/// <summary> /// 创建边ab, bc, ca, 及三角形, 如果该三角形已经存在, 直接返回它. /// </summary> public Triangle CreateTriangle(Vertex a, Vertex b, Vertex c) { HalfEdge ab = CreateEdge(a, b); HalfEdge bc = CreateEdge(b, c); HalfEdge ca = CreateEdge(c, a); if (ab.Face != null) { Utility.Verify(ab.Face == bc.Face && bc.Face == ca.Face); return ab.Face; } ab.Next = bc; bc.Next = ca; ca.Next = ab; Triangle answer = CreateTriangle(); ab.Face = bc.Face = ca.Face = answer; answer.Edge = ab; RasterizeTriangle(answer); return answer; }
public void Dispose() { if (_delaunayLineBmp != null) { _delaunayLineBmp.dispose(); _delaunayLineBmp = null; } _leftVertex = null; _rightVertex = null; if (_clippedVertices != null) { _clippedVertices[LR.LEFT] = Vector2.zero; _clippedVertices[LR.RIGHT] = Vector2.zero; _clippedVertices = null; } _sites[LR.LEFT] = null; _sites[LR.RIGHT] = null; _sites = null; _pool.Add(this); }
/// <summary> /// 获取顶点from"正对"的边. /// </summary> public HalfEdge GetOpposite(Vertex from) { foreach (HalfEdge edge in BoundingEdges) { if (!from.Position.equals2(edge.Src.Position) && !from.Position.equals2(edge.Dest.Position)) { return edge.Pair; } } return null; }
public void Dispose () { // if (_delaunayLineBmp) { // _delaunayLineBmp.Dispose (); // _delaunayLineBmp = null; // } _leftVertex = null; _rightVertex = null; if (_clippedVertices != null) { _clippedVertices [Side.LEFT] = null; _clippedVertices [Side.RIGHT] = null; _clippedVertices = null; } _sites [Side.LEFT] = null; _sites [Side.RIGHT] = null; _sites = null; _pool.Push (this); }
private void addSamplePlaneToolStripMenuItem_Click(object sender, EventArgs e) { ///////////////////////////////////////////////////////////// Init the Shader // create the shader ShaderSimple sh = new ShaderSimple(); /// add the shader to the list ShaderManager.AddShader("Shader10", sh); // add the textures for the shader sh.SetTexture("Resources/diffuse.jpg", TextureType.Diffuse); sh.SetTexture("Resources/lightmap.jpg", TextureType.Lightmap); sh.SetTexture("Resources/height.jpg", TextureType.Heightmap); sh.SetVariables(new Vector3(1, 1, 1), ShaderViariables.Ambient); ///////////////////////////////////////////////////////////// Init the polygons of mesh List<Polygon> polygonList = new List<Polygon>(); FxVector2f p1 = new FxVector2f(0, 0); FxVector2f p2 = new FxVector2f(0, 100); FxVector2f p3 = new FxVector2f(100, 100); FxVector2f p4 = new FxVector2f(100, 0); float u = 0; float v = 0; Vertex ver1 = new Vertex(p1.X, 1, p1.Y, 0, 0, 0, u, v); u = 0; v = 1; Vertex ver2 = new Vertex(p2.X, 1, p2.Y, 0, 0, 0, u, v); u = 1; v = 1; Vertex ver3 = new Vertex(p3.X, 1, p3.Y, 0, 0, 0, u, v); u = 1; v = 0; Vertex ver4 = new Vertex(p4.X, 1, p4.Y, 0, 0, 0, u, v); polygonList.Add(new Polygon(ver1, ver2, ver3)); polygonList.Add(new Polygon(ver1, ver3, ver4)); ///////////////////////////////////////////////////////////// Init the Mesh /// make a new mesh Mesh mesh = new Mesh(); /// set to the new mesh the shader mesh.m_shader = ShaderManager.GetExistShader("Shader10"); // set the position mesh.SetPosition(new Vector3()); // scale it mesh.SetScale(new Vector3(10, 10, 5)); // add the polygons on mesh foreach (Polygon poly in polygonList) { // add the polygons to the mesh mesh.AddPolygon(poly, false); } /// create the mesh and download it to the card mesh.CreateMesh(); /// add the mesh to the engine mesh list Engine.g_MeshManager.AddMesh(mesh); ///////////////////////////////////////////////////////////// Change Camera position Engine.g_MoveCamera.SetViewParams(new Vector3(2000, 2000, 200), new Vector3(0, 0, 0)); }
void AddVertex(Vertex vertex) { Utility.Verify(!halfEdgeContainer.ContainsKey(vertex)); halfEdgeContainer.Add(vertex, new List<HalfEdge>()); }
private void AddSphete(float r, Vector3 center, Vector3 scale) { ShaderSimple sh = new ShaderSimple(); // add to list the sphere sphere_info spi = new sphere_info(); spi.sh = sh; spi.r = r * scale.X * 1.5f; spi.center = center; listSphere.Add(spi); // add the textures for the shader sh.SetTexture(difTex, TextureType.Diffuse); sh.SetTexture("Resources/white.jpg", TextureType.Lightmap); sh.SetTexture("Resources/height.jpg", TextureType.Heightmap); ShaderManager.AddShader("Shader" + r.ToString(), sh); List<Polygon> polygonList = new List<Polygon>(); float numSteps = 100; float thita_step = (float)(Math.PI / numSteps); float phi_step = (float)(2 * Math.PI / numSteps); for (float thita = 0; thita < Math.PI; thita += thita_step) { for (float phi = 0; phi < 2 * Math.PI; phi += phi_step) { float x = (float)(r * Math.Sin(thita) * Math.Cos(phi)); float y = (float)(r * Math.Sin(thita) * Math.Sin(phi)); float z = (float)(r * Math.Cos(thita)); float u = (float)(thita / (Math.PI)); float v = (float)(phi / (2 * Math.PI)); Vertex ver1A = new Vertex(x, z, y, 0, 0, 0, v, u); x = (float)(r * Math.Sin(thita) * Math.Cos(phi + phi_step)); y = (float)(r * Math.Sin(thita) * Math.Sin(phi + phi_step)); z = (float)(r * Math.Cos(thita)); u = (float)(thita / (Math.PI)); v = (float)((phi + phi_step) / (2 * Math.PI)); Vertex ver2A = new Vertex(x, z, y, 0, 0, 0, v, u); x = (float)(r * Math.Sin(thita + thita_step) * Math.Cos(phi + phi_step)); y = (float)(r * Math.Sin(thita + thita_step) * Math.Sin(phi + phi_step)); z = (float)(r * Math.Cos(thita + thita_step)); u = (float)((thita + thita_step) / (Math.PI)); v = (float)((phi + phi_step) / (2 * Math.PI)); Vertex ver3A = new Vertex(x, z, y, 0, 0, 0, v, u); x = (float)(r * Math.Sin(thita + thita_step) * Math.Cos(phi)); y = (float)(r * Math.Sin(thita + thita_step) * Math.Sin(phi)); z = (float)(r * Math.Cos(thita + thita_step)); u = (float)((thita + thita_step) / (Math.PI)); v = (float)((phi) / (2 * Math.PI)); Vertex ver4A = new Vertex(x, z, y, 0, 0, 0, v, u); polygonList.Add(new Polygon(ver1A, ver2A, ver3A)); polygonList.Add(new Polygon(ver1A, ver3A, ver4A)); } } Mesh mesh = new Mesh(); /// set to the new mesh the shader mesh.m_shader = sh; // set the position mesh.SetPosition(center); // scale it mesh.SetScale(scale); // add the polygons on mesh foreach (Polygon poly in polygonList) { // add the polygons to the mesh mesh.AddPolygon(poly, false); } /// create the mesh and download it to the card mesh.CreateMesh(); /// add the mesh to the engine mesh list Engine.g_MeshManager.AddMesh(mesh); sh.SetVariables(new Vector3(1, 1, 1), ShaderViariables.Ambient); }
/// <summary> /// 查找从vertex出发的边. /// </summary> public List<HalfEdge> GetRays(Vertex vertex) { List<HalfEdge> answer = null; halfEdgeContainer.TryGetValue(vertex, out answer); return answer ?? new List<HalfEdge>(); }
/// <summary> /// 将由polygon内的顶点组成的多边形三角形化, 且保证src存在一条到dest的边. /// <para>ans[3*i], ans[3*i+1], ans[3*i+2]为生成的第i个三角形.</para> /// </summary> static List<Vertex> TriangulatePolygonDelaunay(List<Vertex> polygon, Vertex src, Vertex dest) { List<Vertex> answer = new List<Vertex>(); if (polygon.Count == 0) { return answer; } Vertex c = polygon[0]; if (polygon.Count > 1) { // 寻找一个顶点c, 使得src, dest, c组成的三角形的外接圆中, 不包含其它的顶点. foreach (Vertex v in polygon) { if (MathUtility.PointInCircumCircle(src.Position, dest.Position, c.Position, v.Position)) { c = v; } } List<Vertex> left = new List<Vertex>(); List<Vertex> right = new List<Vertex>(); List<Vertex> current = left; // 以点c为界, 将polygon的顶点分为左右两部分. foreach (Vertex v in polygon) { if (v == c) { current = right; continue; } current.Add(v); } // 对左右两部分递归调用该方法. answer.AddRange(TriangulatePolygonDelaunay(left, src, c)); answer.AddRange(TriangulatePolygonDelaunay(right, c, dest)); } // 添加生成的三角形. if (polygon.Count > 0) { answer.Add(src); answer.Add(dest); answer.Add(c); } return answer; }
public void SetVertex (Side leftRight, Vertex v) { if (leftRight == Side.LEFT) { _leftVertex = v; } else { _rightVertex = v; } }
private void addVideoSphereToolStripMenuItem_Click(object sender, EventArgs e) { ///////////////////////////////////////////////////////////// Start Video mp.Initialize(Engine.g_device); mp.SetFile("sample.avi"); difTex = mp.CreateTexture(); Engine.AppHandleKeys = (SharpDX.DirectInput.Key key) => { /// handle the keys that we want switch (key) { case SharpDX.DirectInput.Key.Up: mp.OnRender(difTex.texture2D, true); break; case SharpDX.DirectInput.Key.Down: mp.OnRender(difTex.texture2D, false); break; } return false; }; ///////////////////////////////////////////////////////////// Add the Spheres AddSphete(1000, new Vector3(0, 0, 0), new Vector3(20, 20, 20)); //AddSphete(100, new Vector3(1100, 80, 2000), new Vector3(3, 3, 3)); ///////////////////////////////////////////////////////////// Init the Shader #if false // create the shader ShaderSimple sh = new ShaderSimple(); /// add the shader to the list ShaderManager.AddShader("Shader12", sh); // add the textures for the shader sh.SetTexture("Resources/diffuse.jpg", TextureType.Diffuse); sh.SetTexture("Resources/lightmap.jpg", TextureType.Lightmap); sh.SetTexture("Resources/height.jpg", TextureType.Heightmap); sh.SetVariables(new Vector3(1, 1, 1), ShaderViariables.Ambient); List<Polygon> polygonList = new List<Polygon>(); FxVector2f p1 = new FxVector2f(0, 0); FxVector2f p2 = new FxVector2f(0, 100); FxVector2f p3 = new FxVector2f(100, 100); FxVector2f p4 = new FxVector2f(100, 0); float u1 = 0; float v1 = 0; Vertex ver1 = new Vertex(p1.X, -1, p1.Y, 0, 0, 0, u1, v1); u1 = 0; v1 = 1; Vertex ver2 = new Vertex(p2.X, -1, p2.Y, 0, 0, 0, u1, v1); u1 = 1; v1 = 1; Vertex ver3 = new Vertex(p3.X, -1, p3.Y, 0, 0, 0, u1, v1); u1 = 1; v1 = 0; Vertex ver4 = new Vertex(p4.X, -1, p4.Y, 0, 0, 0, u1, v1); polygonList.Add(new Polygon(ver1, ver2, ver3)); polygonList.Add(new Polygon(ver1, ver3, ver4)); ///////////////////////////////////////////////////////////// Init the Mesh /// make a new mesh Mesh mesh = new Mesh(); /// set to the new mesh the shader mesh.m_shader = ShaderManager.GetExistShader("Shader12"); // set the position mesh.SetPosition(new Vector3(0, 0, 0)); // scale it mesh.SetScale(new Vector3(40, 40, 40)); // add the polygons on mesh foreach (Polygon poly in polygonList) { // add the polygons to the mesh mesh.AddPolygon(poly, false); } /// create the mesh and download it to the card mesh.CreateMesh(); /// add the mesh to the engine mesh list Engine.g_MeshManager.AddMesh(mesh); sh.SetVariables(new Vector3(1, 1, 1), ShaderViariables.Ambient); #endif ///////////////////////////////////////////////////////////// Change Camera position // Engine.g_MoveCamera. Engine.g_MoveCamera.SetViewParams(new Vector3(2000, 2000, 200), new Vector3(0, 0, 0)); //////////////////////////////////////////////////// }
/// <summary> /// 加入一条从src到dest的约束边. /// <para>返回构造的约束边.</para> /// </summary> List<HalfEdge> AddConstrainedEdge(Vertex src, Vertex dest) { // 加入顶点. Append(src); Append(dest); List<HalfEdge> answer = new List<HalfEdge>(); // 加入并收集约束边. // 在加入约束边src->dest的过程中, 可能遇到一个点v, v在src->dest上. // 因此, 约束边变为src->v, v->dest. // 此时, src替换为v, 继续迭代, 直到到达dest. for (; src != dest; ) { answer.Add(AddConstrainedEdgeAt(ref src, dest)); } return answer; }
/// <summary> /// 添加src到dest的约束边. /// <para>如果之间遇到顶点v在该边上, 构造边src->v, 并更新src为v.</para> /// <para>如果之间没有其他顶点, 那么构造边src->dest, 更新src为dest.</para> /// <para>返回构造的约束边.</para> /// </summary> HalfEdge AddConstrainedEdgeAt(ref Vertex src, Vertex dest) { // 寻找以src为起点的, 且与src->dest相交的边. Tuple2<HalfEdge, CrossState> crossResult = new Tuple2<HalfEdge, CrossState>(null, CrossState.Parallel); foreach (HalfEdge ray in geomManager.GetRays(src)) { if (FindCrossedEdge(out crossResult, ray, src.Position, dest.Position)) { break; } } Utility.Verify(crossResult.Second != CrossState.Parallel); // 找到的边与src->dest完全重合. if (crossResult.Second == CrossState.FullyOverlaps) { crossResult.First.Constrained = true; src = crossResult.First.Dest; return crossResult.First; } Utility.Verify(crossResult.Second == CrossState.CrossOnSegment); // 处理相交边. return OnConstrainedEdgeCrossEdges(ref src, dest, crossResult.First); }
float SearchWidth(Vertex c, Triangle t, HalfEdge e, float d) { Vertex u = e.Src, v = e.Dest; if (c.Position.dot2(v.Position, u.Position) <= 0 || c.Position.dot2(u.Position, v.Position) <= 0) { return d; } float d2 = MathUtility.MinDistance2Segment(c.Position, e.Src.Position, e.Dest.Position); if (d2 > d) { return d; } if (e.Constrained) { return d2; } Triangle t2 = e.Pair.Face; if (t2 == null) { Debug.LogError("Invalid t2"); return d; } HalfEdge e2 = t2.GetOpposite(e.Src); HalfEdge e3 = t2.GetOpposite(e.Dest); d = SearchWidth(c, t2, e2, d); return SearchWidth(c, t2, e3, d); }
/// <summary> /// 向网格内加入点. /// </summary> bool Append(Vertex v) { // 查找包含点v的位置的三角形. Tuple2<int, Triangle> answer = geomManager.FindVertexContainedTriangle(v.Position); // 与顶点重合, 表示该点已经存在. if (answer.First < 0) { return false; } // 点在三角形内. if (answer.First == 0) { InsertToTriangle(v, answer.Second); } // 点在边上. else { HalfEdge hitEdge = answer.Second.GetEdgeByIndex(answer.First); InsertOnEdge(v, answer.Second, hitEdge); } return true; }
internal void SetVertex(LR leftRight, Vertex v) { if (leftRight == LR.LEFT) { _leftVertex = v; } else { _rightVertex = v; } }
/// <summary> /// 将由polygon内的顶点组成的多边形三角形化, 且保证constrainedEdgeSrc存在一条到constrainedEdgeDest的边. /// <para>ans[3*i], ans[3*i+1], ans[3*i+2]为生成的第i个三角形.</para> /// </summary> public static List<Vertex> Triangulate(List<Vertex> polygon, Vertex constrainedEdgeSrc, Vertex constrainedEdgeDest) { return TriangulatePolygonDelaunay(polygon, constrainedEdgeSrc, constrainedEdgeDest); }