//Решение Tri private void Tri() { int q, w, e, r; if (Int32.TryParse(TriCountBox.Text, out q) && Int32.TryParse(TriMax.Text, out w) && Int32.TryParse(TriMin.Text, out e) && Int32.TryParse(TriModa.Text, out r) && q > 0) { TriBox.Items.Clear(); chartTri.Series["Числа"].Points.Clear(); chartTri.Series["График"].Points.Clear(); int x = DateTime.Now.Millisecond; int n = Convert.ToInt32(TriCountBox.Text); double min = Convert.ToInt32(TriMin.Text), max = Convert.ToInt32(TriMax.Text), moda = Convert.ToInt32(TriModa.Text); if (moda >= max || moda <= min) { moda = Math.Round((min + max) / 2.0); TriModa.Text = Convert.ToString(moda); } Tri tri = new Tri(); tri.SolveTri(n, min, max, moda); for (int i = 0; i < tri.list.Count; i++) { TriBox.Items.Add(tri.list[i]); } foreach (var i in tri.Dic) { chartTri.Series["График"].Points.AddXY(i.Key, i.Value); chartTri.Series["Числа"].Points.AddXY(i.Key, i.Value); } } }
public EdgeDistStatus(Edge edge, Tri tri, Vector3 point, float margin) { _edge = edge; _tri = tri; _withinMargin = edge.DistanceTo(point) < margin; _withinSegmentBounds = edge.IsWithinSegmentBounds(point); }
public static MeshData Create(Vertex3[] verticesIn, short[] indices) { Vector3[] vertices = new Vector3[verticesIn.Length]; Vector3[] normals = new Vector3[verticesIn.Length]; Vector2[] uv = new Vector2[verticesIn.Length]; Tri[] tri = new Tri[indices.Length / 3]; for (uint i = 0; i < verticesIn.Length; ++i) { vertices[i].X = verticesIn[i].x; vertices[i].Y = verticesIn[i].y; vertices[i].Z = verticesIn[i].z; normals[i].X = 0.0f; normals[i].Y = 0.0f; normals[i].Z = 1.0f; uv[i].X = 0; uv[i].Y = 0; } for (int i = 0; i < indices.Length / 3; i += 3) { MeshPoint p1 = new MeshPoint(3 * i + 0, 3 * i + 0, 3 * i + 0); MeshPoint p2 = new MeshPoint(3 * i + 1, 3 * i + 1, 3 * i + 1); MeshPoint p3 = new MeshPoint(3 * i + 2, 3 * i + 2, 3 * i + 2); tri[i] = new Tri(p1, p2, p3); } return(new MeshData(vertices, normals, uv, tri)); }
private IEnumerable <Tri> MeshTriangles(MeshComponent mesh) { if (mesh.Triangles == null || mesh.Triangles.Length == 0) { yield break; } float3[] verts = new float3[mesh.Vertices.Length]; // transform all vertices to clip space for (int i = 0; i < verts.Length; i++) { float4 vClip = MVP * new float4(mesh.Vertices[i], 1.0f); vClip = vClip / vClip.z; verts[i] = vClip.xyz; } for (int i = 0; i < mesh.Triangles.Length; i += 3) { var tri = new Tri { p0 = verts[mesh.Triangles[i]], p1 = verts[mesh.Triangles[i + 1]], p2 = verts[mesh.Triangles[i + 2]], }; if (PointClipped(tri.p0) && PointClipped(tri.p1) && PointClipped(tri.p2)) { continue; } yield return(tri); } }
private double3 ReturnTriIntersect(int Exclude, double3 O, double3 D) { Triangle Tri; if (Exclude == 1) { Tri = new Triangle(B, C, D); } else if (Exclude == 2) { Tri = new Triangle(A, C, D); } else if (Exclude == 3) { Tri = new Triangle(A, B, D); } else if (Exclude == 4) { Tri = new Triangle(A, B, C); } else { throw new Exception("Internal Error"); } var t = Tri.Intersection(O, D); return(O + t * D); }
public IList <Tri> SearchForPathBetweenTris(Tri from, Tri to) { var alreadySeen = new HashSet <Tri>(); var queue = new Queue <List <Tri> >(); var list = new List <Tri>(); list.Add(from); queue.Enqueue(list); while (queue.Count > 0) { var curList = queue.Dequeue(); var endTri = curList.Last(); if (endTri == to) { return(curList); } foreach (var nextTri in endTri.GetAdjacentTris()) { if (!alreadySeen.Contains(nextTri)) { var nextList = new List <Tri>(curList); nextList.Add(nextTri); queue.Enqueue(nextList); } } } return(null); }
public static void Draw(GraphicsDevice GD) { Assets.Shader.CurrentTechnique = Assets.Shader.Techniques["Pretransformed"]; Assets.Shader.Parameters["xWorld"].SetValue(World); foreach (EffectPass pass in Assets.Shader.CurrentTechnique.Passes) { pass.Apply(); if (Sierpinski_Triangle_Active) { foreach (Sierpinski_Triangle_Part Tri in TriParts) { Tri.Draw(GD); } } else { foreach (Koch_snowflake_part flake in SnowflakeParts) { flake.Draw(GD); } } } }
public void Add(Tri t) { if (tris != null) { tris.Add(t); } else { if (boundsChildA.Intersects(t.Bounds)) { if (childA == null) { childA = new SpatialBinaryTreeNode(level + 1, maxLevels, boundsChildA); } childA.Add(t); } if (boundsChildB.Intersects(t.Bounds)) { if (childB == null) { childB = new SpatialBinaryTreeNode(level + 1, maxLevels, boundsChildB); } childB.Add(t); } } }
public void Update() { Ray pickRay = MathExtra.CalculateCursorRay(AIGame.camera.ProjectionMatrix, AIGame.camera.ViewMatrix); float rayLength = 0f; for (int i = 0; i < triangle.Length; i++) { Tri thisTri = triangle[i]; if (MathExtra.Intersects(pickRay, thisTri.p1, thisTri.p3, thisTri.p2, thisTri.normal, false, true, out rayLength)) { Vector3 rayTarget = pickRay.Position + pickRay.Direction * rayLength; groundCursorPosition.X = rayTarget.X / ( //heightMap.Size * (heightMap.GridSpacing - 1)) * //(((float)heightMap.Size * ((float)heightMap.GridSpacing - 1)) / Settings.TERRAIN_TEXTURE_SIZE); groundCursorPosition.Y = rayTarget.Y; groundCursorPosition.Z = rayTarget.Z / ( // heightMap.Size * (heightMap.GridSpacing - 1)) * //(((float)heightMap.Size * ((float)heightMap.GridSpacing - 1)) / Settings.TERRAIN_TEXTURE_SIZE); } } lastGroundCursorPos = groundCursorPosition; }
/// <summary> /// Sous - tri de <see cref="TriFiltreEditor.Trier(string)"/> /// </summary> /// <param name="cartes">Cartes uniques non triées</param> public void TrierAKA(List <GameObject> Cartes) { for (int i = 0; i < Cartes.Count; i++) { for (int j = 0; j < i; j++) { if ((Cartes[j].GetComponent <Carte>().GetType() == typeof(Sort) || Cartes[j].GetComponent <Carte>().GetType() == typeof(Assistance)) && Cartes[i].GetComponent <Carte>().GetType() == typeof(Entite)) { GameObject Carte = Cartes[i]; Cartes[i] = Cartes[j]; Cartes[j] = Carte; } else if ((Cartes[j].GetComponent <Carte>().GetType() == typeof(Entite) && Cartes[i].GetComponent <Carte>().GetType() == typeof(Entite)) && Cartes[j].GetComponent <Entite>().CoutAKA > Cartes[i].GetComponent <Entite>().CoutAKA) { GameObject Carte = Cartes[i]; Cartes[i] = Cartes[j]; Cartes[j] = Carte; } } } tri = Tri.NOM; Debug.Log("La liste a été triée par AKA"); PutCardsInScrollView("allCards", Cartes, true); }
public void TriTest() { var tests = new Dictionary <string, string>(); //addition tests["5 3 8"] = "5+3=8"; //subtraction tests["5 3 2"] = "5-3=2"; //multiplication tests["5 3 15"] = "5*3=15"; //division tests["9 3 3"] = "9/3=3"; foreach (var item in tests) { using (StringWriter sw = new StringWriter()) { Console.SetOut(sw); using (StringReader sr = new StringReader( string.Format( item.Key))) { Console.SetIn(sr); Tri.Main(null); string expected = item.Value + Environment.NewLine; Assert.Equal(expected, sw.ToString()); } } } }
public SpatialBinaryTree(Mesh m, int maxLevels, bool outputProgress = false) { var boundingBox = new BoundingBox( new Interval(m.vertices.Min(v => v.x), m.vertices.Max(v => v.x)), new Interval(m.vertices.Min(v => v.y), m.vertices.Max(v => v.y)), new Interval(m.vertices.Min(v => v.z), m.vertices.Max(v => v.z))); root = new SpatialBinaryTreeNode(0, maxLevels, boundingBox); var triCount = m.triangles.Length / 3; for (var i = 0; i < triCount; i++) { var v1 = m.vertices[m.triangles[i * 3]]; var v2 = m.vertices[m.triangles[i * 3 + 1]]; var v3 = m.vertices[m.triangles[i * 3 + 2]]; var t = new Tri(v1, v2, v3); Add(t); if (triCount > 20 && (i % (triCount / 20) == 0)) { Debug.Log("Spatial Tree Progress: " + (i + 1) + " / " + triCount); } } }
/// <summary> /// Sous - tri de <see cref="TriFiltreEditor.Trier(string)"/> /// </summary> /// <param name="cartes">Cartes uniques non triées. </param> public void TrierPuissance(List <GameObject> Cartes) { for (int i = 0; i < Cartes.Count; i++) { for (int j = 0; j < i; j++) { if ((Cartes[j].GetComponent <Carte>().GetType() == typeof(Sort) || Cartes[j].GetComponent <Carte>().GetType() == typeof(Assistance)) && Cartes[i].GetComponent <Carte>().GetType() == typeof(Entite)) { GameObject Carte = Cartes[i]; Cartes[i] = Cartes[j]; Cartes[j] = Carte; } else if ((Cartes[j].GetComponent <Carte>().GetType() == typeof(Entite) && Cartes[i].GetComponent <Carte>().GetType() == typeof(Entite)) && Cartes[j].GetComponent <Entite>().getPuissance() > Cartes[i].GetComponent <Entite>().getPuissance()) { GameObject Carte = Cartes[i]; Cartes[i] = Cartes[j]; Cartes[j] = Carte; } } } tri = Tri.PUISSANCE; // On doit mettre les autres tris à false Debug.Log("La liste a été triée par Puissance"); PutCardsInScrollView("allCards", Cartes, true); }
// Tính toán theo hướng của Tri private int calTri(Tri tri) { GameObject curHex = hexMatrix[(int)tri.Pos.x, (int)tri.Pos.y]; int res = curHex.GetComponent <Hex>().Num; if (res == 0) { return(-1); } while (true) { curHex = getHex(curHex.GetComponent <Hex>().Pos, (tri.Direction + 3) % 6); if (curHex != null) { if (curHex.GetComponent <Hex>().Num > 0) { res += curHex.GetComponent <Hex>().Num; } else { return(-1); } } else { break; } } return(res); }
public Sphere(float radius, uint subdivisions, Vec4 color) { Mesh ico20 = BuildIcosahedron(radius, color); Queue <Tri> tris = new Queue <Tri>(); foreach (var item in ico20) { tris.Enqueue(item); } uint j = 0; while (subdivisions > j) { for (int i = 0; i < 20 * Math.Pow(4, j); i++) { Tri t = tris.Dequeue(); Vertex3 newV0 = ComputeHalfVertex(t.v0, t.v1, radius); Vertex3 newV1 = ComputeHalfVertex(t.v1, t.v2, radius); Vertex3 newV2 = ComputeHalfVertex(t.v2, t.v0, radius); tris.Enqueue(new Tri(t.v0, newV0, newV2, t.ks, t.kd, t.n)); tris.Enqueue(new Tri(t.v1, newV1, newV0, t.ks, t.kd, t.n)); tris.Enqueue(new Tri(t.v2, newV2, newV1, t.ks, t.kd, t.n)); tris.Enqueue(new Tri(newV0, newV1, newV2, t.ks, t.kd, t.n)); } j++; } foreach (var item in tris) { Triangles.Add(item); } }
public MeshBuffers(Device device, TriMesh mesh) { int vertexCount = mesh.VertexPositions.Count; VertexInfo[] vertexInfos = new VertexInfo[vertexCount]; for (int i = 0; i < vertexCount; ++i) { vertexInfos[i] = new VertexInfo { position = mesh.VertexPositions[i], normal = mesh.VertexNormals[i] }; } this.vertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, vertexInfos); int faceCount = mesh.Faces.Count; int[] indices = new int[faceCount * 3]; for (int i = 0; i < faceCount; ++i) { Tri face = mesh.Faces[i]; indices[i * 3 + 0] = face.Index0; indices[i * 3 + 1] = face.Index1; indices[i * 3 + 2] = face.Index2; } this.indexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, indices); this.indexCount = indices.Length; }
static void Main() { Tri t = new Tri(); bool text = t.Res(); Console.WriteLine(text == true ? "Точка принадлежит треугольнику!" : "Точка снаружи"); Console.ReadKey(); }
public void TestTriDate() { ObservableCollection <Oeuvre> triées = Tri.TriDate(CréationOeurves()); for (int i = 0; i < triées.Count - 1; i++) { Assert.IsTrue(triées[i].Sortie.CompareTo(triées[i + 1].Sortie) <= 0); } }
private IEnumerable <Tri> DrawNewPolys(IEnumerable <EdgeDistStatus> edges, Vert vert, HashSet <Tri> triList) { foreach (EdgeDistStatus status in edges) { Tri newTri = TriFromEdgeToPoint(status.Edge, vert, -status.Tri.Normal); triList.Add(newTri); yield return(newTri); } }
public Triangle(Tri t) { v0 = t.v0; v1 = t.v1; v2 = t.v2; ks = t.ks; kd = t.kd; n = t.n; }
public void TestTriCroissant() { ObservableCollection <Oeuvre> triées = Tri.TriCroissant(CréationOeurves()); for (int i = 0; i < triées.Count - 1; i++) { Assert.IsTrue(triées[i].Nom.CompareTo(triées[i + 1].Nom) <= 0); } }
public void RemoveTri(Tri t) { // First remove all references to this tri from its points. foreach (Point p in t.Points) { p.Tris.Remove(t); } Tris.Remove(t); }
/// <summary> /// Filtrer les entités par type d'élémentaires. /// </summary> /// <param name="filtre"></param> public void FiltreElementaire(string filtre) { // Dans le cas du filtre d'une entité élementaire if (filtre == "TERRE" || filtre == "EAU" || filtre == "FEU" || filtre == "AIR") { Entite.Element elementFiltre = Entite.Element.NONE; switch (filtre) { case "TERRE": elementFiltre = Entite.Element.TERRE; break; case "FEU": elementFiltre = Entite.Element.FEU; break; case "EAU": elementFiltre = Entite.Element.EAU; break; case "AIR": elementFiltre = Entite.Element.AIR; break; default: Debug.LogError("Ce cas ne peut pas arriver"); break; } ResetFiltres(); filtreElementaire = elementFiltre; PutCardsInScrollView("allCards", CartesCorrespondantesElement(elementFiltre), true); } else if (filtre == "ASTRAL" || filtre == "MALEFIQUE") { Entite.Ascendance ascendanceFiltre = Entite.Ascendance.NONE; if (filtre == "ASTRAL") { ascendanceFiltre = Entite.Ascendance.ASTRALE; } else { ascendanceFiltre = Entite.Ascendance.MALEFIQUE; } ResetFiltres(); filtreAscendance = ascendanceFiltre; PutCardsInScrollView("allCards", CartesCorrespondantesAscendance(ascendanceFiltre), true); } else { throw new Exception("Ce filtre n'existe pas"); } ListeFiltreElementaires.SetActive(false); tri = Tri.NONE; }
// constructor 2 public Tri(Vector3 posA, Vector3 posB, Vector3 posC, int currentDiv, Tri parent) { curDiv = currentDiv; pos1 = posA; pos2 = posB; pos3 = posC; parentTri = parent; myChunk = parentTri.myChunk; maxDiv = PlanetCreator.maxSubdivisions; }
void AddTri(Vector3 a, Vector3 b, Vector3 c) { int curVertCount = newVerticies.Count; newVerticies.Add(Tri.offsetAtPos(a)); newVerticies.Add(Tri.offsetAtPos(b)); newVerticies.Add(Tri.offsetAtPos(c)); newTriangles.Add(curVertCount + 0); newTriangles.Add(curVertCount + 1); newTriangles.Add(curVertCount + 2); }
public void UnshareVert(Tri tri, Vert newVert) { tris.Remove(tri); newVert.tris.Add(tri); foreach (var v in unsharedVerts) { if (!v.unsharedVerts.Contains(newVert)) { v.unsharedVerts.Add(newVert); } } newVert.unsharedVerts.AddRange(unsharedVerts); }
private void Start() { mesh = mf.mesh; masterTri = new Tri( Tri.offsetAtPos(startPointA), Tri.offsetAtPos(startPointB), Tri.offsetAtPos(startPointC), 0, null, this); smallestTris.Add(masterTri); UpdateMesh(); }
//Initialize the mesh with a plane public void InitPlane(float scale) { Tri t1 = new Tri(); // = Tri; Tri t2 = new Tri(); // = Tri; t1.v1 = new Vector3(-scale, -scale); t1.v2 = new Vector3(-scale, scale); t1.v3 = new Vector3(scale, scale); t1.uv1 = new Vector2(0, 0); t1.uv2 = new Vector2(0, 1); t1.uv3 = new Vector2(1, 1); t2.v1 = new Vector3(scale, scale); t2.v2 = new Vector3(scale, -scale); t2.v3 = new Vector3(-scale, -scale); t2.uv1 = new Vector2(1, 1); t2.uv2 = new Vector2(1, 0); t2.uv3 = new Vector2(0, 0); //t1.vel = new Vector2(-0.1f,0.1f); //t2.vel = new Vector2(0.1f,-0.1f); t1.vel = new Vector2(0, 0); t2.vel = new Vector2(0, 0); this.tris = new List <Tri>(); tris.Add(t1); tris.Add(t2); //Vector2[] verts2 = {new Vector3(-1,-1), new Vector3(-1,1), new Vector3(1,1), new Vector3(1,-1)}; //int[] tris2 = {0,1,2,2,3,0}; // tris.Clear(); // tris.Add(new int[]{0,1,2}); // tris.Add(new int[]{2,3,0}); // // verts = verts2; // // trivels = new List<Vector2>(); // for (int i = 0; i < tris.Count; i++) // { // trivels.Add(new Vector2(0,0)); // } //Debug.Log("verts len: " + verts.Length); //Debug.Log("tris len: " + tris.Count); RefreshMesh(); }
public async Task <List <Candidature> > PostTrier(Tri t) { using (var httpClient = new HttpClient(_clientHandler)) { StringContent content = new StringContent(JsonConvert.SerializeObject(t), Encoding.UTF8, "application/json"); using (var response = await httpClient.PostAsync("https://localhost:44304/api/Trier", content)) { string apiResponse = await response.Content.ReadAsStringAsync(); liste = JsonConvert.DeserializeObject <List <Candidature> >(apiResponse); } } return(liste); }
public Vector3?IsIntersected(Ray ray) { float rayLength = 0f; for (int i = 0; i < triangle.Length; i++) { Tri thisTri = triangle[i]; if (MathExtra.Intersects(ray, thisTri.p1, thisTri.p3, thisTri.p2, thisTri.normal, false, true, out rayLength)) { Vector3 rayTarget = ray.Position + ray.Direction * rayLength; return(rayTarget); } } return(null); }
public bool Res() { Tri t = new Tri(); xp = new int[] { 0, 2, 4 }; // массив х вершин треугольника yp = new int[] { 0, 2, 2 }; // массив у вершин треугольника x = 2; // координата x точки y = 1; // координата y точки npol = xp.Length; int res = t.Triangle(npol, xp, yp, x, y); if (res == 1) // точка внутри { return true; } return false; // иначе - снаружи }
public static void Weld(int precision, Vector3[] vertices, Tri[] tris) { int p = (int)Math.Pow((double)10, (double)precision); Dictionary<Vector3, int> pointHash = new Dictionary<Vector3, int>(); Dictionary<int, int> remapList = new Dictionary<int, int>(); for (int i = 0; i < vertices.Length; i++) { Vector3 vertex = vertices[i]; vertex.X = (float)((int)(vertex.X * p)); vertex.Y = (float)((int)(vertex.Y * p)); vertex.Z = (float)((int)(vertex.Z * p)); int existing_index; if (!pointHash.TryGetValue(vertex, out existing_index)) { pointHash.Add(vertex, i); } else { remapList.Add(i, existing_index); } } foreach (Tri tri in tris) { int existing_index; if (remapList.TryGetValue(tri.P1.Vertex, out existing_index)) { tri.P1.Vertex = existing_index; } if (remapList.TryGetValue(tri.P2.Vertex, out existing_index)) { tri.P2.Vertex = existing_index; } if (remapList.TryGetValue(tri.P3.Vertex, out existing_index)) { tri.P3.Vertex = existing_index; } } }
private void SetUpIndices() { indices = new short[divisions.X * divisions.Y * 6]; int indiceID = 0; triangle = new Tri[divisions.X * divisions.Y * 2]; int triID = 0; int[] index = new int[6]; for (int y = 0; y < divisions.Y - 1; y++) { for (int x = 0; x < divisions.X - 1; x++) { index[0] = x + y * divisions.X; index[1] = x + (y + 1) * divisions.X; index[2] = (x + 1) + y * divisions.X; index[3] = (x + 1) + (y + 1) * divisions.X; indices[indiceID] = (short)(index[0]); indices[indiceID + 1] = (short)(index[1]); indices[indiceID + 2] = (short)(index[2]); indices[indiceID + 3] = (short)(index[2]); indices[indiceID + 4] = (short)(index[1]); indices[indiceID + 5] = (short)(index[3]); //Create ray collision triangles triangle[triID] = new Tri(triID, vertices[index[0]].Position, vertices[index[1]].Position, vertices[index[2]].Position); triangle[triID + 1] = new Tri(triID, vertices[index[2]].Position, vertices[index[1]].Position, vertices[index[3]].Position); //Update vertices normals vertices[index[0]].Normal = triangle[triID].normal; vertices[index[1]].Normal = (triangle[triID].normal + triangle[triID + 1].normal) / 2; vertices[index[2]].Normal = (triangle[triID].normal + triangle[triID + 1].normal) / 2; vertices[index[3]].Normal = triangle[triID + 1].normal; indiceID += 6; triID += 2; } } }
// Takes an array of points and returns an array of triangles. // The points form an arbitrary polygon. static Tri[] Triangulate(MeshPoint[] ps) { List<Tri> ts = new List<Tri>(); if (ps.Length < 3) { throw new Exception("Invalid shape! Must have >2 points"); } MeshPoint lastButOne = ps[1]; MeshPoint lastButTwo = ps[0]; for (int i = 2; i < ps.Length; i++) { Tri t = new Tri(lastButTwo, lastButOne, ps[i]); lastButOne = ps[i]; lastButTwo = ps[i - 1]; ts.Add(t); } return ts.ToArray(); }
//Initialize the mesh with a plane public void InitPlane(float scale) { Tri t1 = new Tri();// = Tri; Tri t2 = new Tri();// = Tri; t1.v1 = new Vector3(-scale,-scale); t1.v2 = new Vector3(-scale,scale); t1.v3 = new Vector3(scale,scale); t1.uv1 = new Vector2(0,0); t1.uv2 = new Vector2(0,1); t1.uv3 = new Vector2(1,1); t2.v1 = new Vector3(scale,scale); t2.v2 = new Vector3(scale,-scale); t2.v3 = new Vector3(-scale,-scale); t2.uv1 = new Vector2(1,1); t2.uv2 = new Vector2(1,0); t2.uv3 = new Vector2(0,0); //t1.vel = new Vector2(-0.1f,0.1f); //t2.vel = new Vector2(0.1f,-0.1f); t1.vel = new Vector2(0,0); t2.vel = new Vector2(0,0); this.tris = new List<Tri>(); tris.Add(t1); tris.Add(t2); //Vector2[] verts2 = {new Vector3(-1,-1), new Vector3(-1,1), new Vector3(1,1), new Vector3(1,-1)}; //int[] tris2 = {0,1,2,2,3,0}; // tris.Clear(); // tris.Add(new int[]{0,1,2}); // tris.Add(new int[]{2,3,0}); // // verts = verts2; // // trivels = new List<Vector2>(); // for (int i = 0; i < tris.Count; i++) // { // trivels.Add(new Vector2(0,0)); // } //Debug.Log("verts len: " + verts.Length); //Debug.Log("tris len: " + tris.Count); RefreshMesh(); }
public void Slice(Vector2 a, Vector2 b) { if (this.tris.Count > maxPieces) return; //Debug.Log(this.tris.Count + " " + maxPieces); //Debug.Log("Slice begin. Tris len: " + tris.Count); Vector2 s = b-a; List<Tri> removethese = new List<Tri>(); List<Tri> addthese = new List<Tri>(); foreach (Tri tri in tris) { //slice this triangle //intersect edge 1 Vector2 t1a = tri.v1; Vector2 t1s = tri.v2-tri.v1; float t1 = LineLineIntersectReturnT(t1a, t1s, a, s); bool isect1valid = t1 > 0 && t1 < 1; //intersect edge 2 Vector2 t2a = tri.v2; Vector2 t2s = tri.v3-tri.v2; float t2 = LineLineIntersectReturnT(t2a, t2s, a, s); bool isect2valid = t2 > 0 && t2 < 1; //intersect edge 3 Vector2 t3a = tri.v3; Vector2 t3s = tri.v1-tri.v3; float t3 = LineLineIntersectReturnT(t3a, t3s, a, s); bool isect3valid = t3 > 0 && t3 < 1; int numvalid = (isect1valid?1:0) + (isect3valid?1:0) + (isect2valid?1:0); if (numvalid == 2) { Vector2 isect1 = t1a + t1 * t1s; Vector2 isect2 = t2a + t2 * t2s; Vector2 isect3 = t3a + t3 * t3s; //figure out which vertex of the triangle is shared by the two intersected edges Vector2 common; Vector2 p1, p2, o1, o2; Vector2 commonuv, o1uv, o2uv; if (isect1valid && isect2valid) { common = tri.v2; p1 = isect1; p2 = isect2; o1 = tri.v1; o2 = tri.v3; commonuv = tri.uv2; o1uv = tri.uv1; o2uv = tri.uv3; } else if (isect2valid && isect3valid) { common = tri.v3; p1 = isect2; p2 = isect3; o1 = tri.v2; o2 = tri.v1; commonuv = tri.uv3; o1uv = tri.uv2; o2uv = tri.uv1; } else //if (isect3valid && isect1valid) { common = tri.v1; p1 = isect3; p2 = isect1; o1 = tri.v3; o2 = tri.v2; commonuv = tri.uv1; o1uv = tri.uv3; o2uv = tri.uv2; } //create new triangles Tri nt1 = new Tri(); Tri nt2 = new Tri(); Tri nt3 = new Tri(); nt1.v1 = p1; nt1.v2 = common; nt1.v3 = p2; nt2.v1 = o1; nt2.v2 = p1; nt2.v3 = p2; nt3.v1 = p2; nt3.v2 = o2; nt3.v3 = o1; //UVs Vector2 o1_common = common - o1; Vector2 o2_common = common - o2; float p1_onto_o1_common = Vector2.Dot(p1-o1, o1_common.normalized) / o1_common.magnitude; Vector2 p1uv = o1uv + p1_onto_o1_common * (commonuv - o1uv); float p2_onto_o2_common = Vector2.Dot(p2-o2, o2_common.normalized) / o2_common.magnitude; Vector2 p2uv = o2uv + p2_onto_o2_common * (commonuv - o2uv); nt1.uv1 = p1uv; nt1.uv2 = commonuv; nt1.uv3 = p2uv; //Debug.Log("p1_onto_o1_common: " + p1_onto_o1_common); //Debug.Log("p2_onto_o2_common: " + p2_onto_o2_common); //Debug.Log("nt1 uvs: " + p1uv + " " + commonuv + " " + p2uv + " " + o1uv + " " + o2uv); //Debug.Log("nt1 pos: " + p1 + " " + common + " " + p2 + " " + o1 + " " + o2); nt2.uv1 = o1uv; nt2.uv2 = p1uv; nt2.uv3 = p2uv; nt3.uv1 = p2uv; nt3.uv2 = o2uv; nt3.uv3 = o1uv; //Give them velocities //Vector2 velcommon = (common - (p1 + (p2-p1) * 0.5f)); //Vector2 nearest = PointNearestPointOnLine(common, a, s); //Vector2 velcommon = (common - nearest).normalized; Vector2 sPerp = new Vector2(-s.y, s.x); //Debug.Log(Vector2.Dot(s, sperp)); Vector2 velcommon = sPerp.normalized; float veladjust = 1.0f; if (Vector2.Dot((common - a), sPerp) > 0) { veladjust = 1.0f; } else { veladjust = -1.0f; } nt1.vel = this.driftFactor * velcommon * veladjust + tri.vel; nt2.vel = this.driftFactor * -velcommon * veladjust + tri.vel; nt3.vel = nt2.vel; addthese.Add(nt1); addthese.Add(nt2); addthese.Add(nt3); //tag old ones for removal removethese.Add(tri); }//if there was a valid slice made }//loop over all triangles to check slices //Remove tris tagged for removal foreach (Tri tri in removethese) { this.tris.Remove(tri); } //Add tris created by slice foreach (Tri tri in addthese) { this.tris.Add(tri); } //Debug.Log("Slice end. Tris len: " + tris.Count + " Removed: " + removethese.Count + " Added: " + addthese.Count); //Debug.Log(this.ToString()); }
private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd) { double[,] heightfield = World.Heightmap.GetDoubles(); List<ContactResult> contacts = new List<ContactResult>(); double min = 2048.0; double max = 0.0; // Find the min and max of the heightfield for (int x = 0 ; x < World.Heightmap.Width ; x++) { for (int y = 0 ; y < World.Heightmap.Height ; y++) { if (heightfield[x, y] > max) max = heightfield[x, y]; if (heightfield[x, y] < min) min = heightfield[x, y]; } } // A ray extends past rayEnd, but doesn't go back before // rayStart. If the start is above the highest point of the ground // and the ray goes up, we can't hit the ground. Ever. if (rayStart.Z > max && rayEnd.Z >= rayStart.Z) return null; // Same for going down if (rayStart.Z < min && rayEnd.Z <= rayStart.Z) return null; List<Tri> trilist = new List<Tri>(); // Create our triangle list for (int x = 1 ; x < World.Heightmap.Width ; x++) { for (int y = 1 ; y < World.Heightmap.Height ; y++) { Tri t1 = new Tri(); Tri t2 = new Tri(); Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]); Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]); Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]); Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]); t1.p1 = p1; t1.p2 = p2; t1.p3 = p3; t2.p1 = p3; t2.p2 = p4; t2.p3 = p1; trilist.Add(t1); trilist.Add(t2); } } // Ray direction Vector3 rayDirection = rayEnd - rayStart; foreach (Tri t in trilist) { // Compute triangle plane normal and edges Vector3 u = t.p2 - t.p1; Vector3 v = t.p3 - t.p1; Vector3 n = Vector3.Cross(u, v); if (n == Vector3.Zero) continue; Vector3 w0 = rayStart - t.p1; double a = -Vector3.Dot(n, w0); double b = Vector3.Dot(n, rayDirection); // Not intersecting the plane, or in plane (same thing) // Ignoring this MAY cause the ground to not be detected // sometimes if (Math.Abs(b) < 0.000001) continue; double r = a / b; // ray points away from plane if (r < 0.0) continue; Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r); float uu = Vector3.Dot(u, u); float uv = Vector3.Dot(u, v); float vv = Vector3.Dot(v, v); Vector3 w = ip - t.p1; float wu = Vector3.Dot(w, u); float wv = Vector3.Dot(w, v); float d = uv * uv - uu * vv; float cs = (uv * wv - vv * wu) / d; if (cs < 0 || cs > 1.0) continue; float ct = (uv * wu - uu * wv) / d; if (ct < 0 || (cs + ct) > 1.0) continue; // Add contact point ContactResult result = new ContactResult (); result.ConsumerID = 0; result.Depth = Vector3.Distance(rayStart, ip); result.Normal = n; result.Pos = ip; contacts.Add(result); } if (contacts.Count == 0) return null; contacts.Sort(delegate(ContactResult a, ContactResult b) { return (int)(a.Depth - b.Depth); }); return contacts[0]; }
public void SetUpCollision(int tID, int x, int y) { triangle[tID] = new Tri(); triangle[tID].p1 = GetPosition(x, y); triangle[tID].p2 = GetPosition(x, y + 1); triangle[tID].p3 = GetPosition(x + 1, y); triangle[tID].normal = MathExtra.GetNormal(triangle[tID].p1, triangle[tID].p2, triangle[tID].p3); triangle[tID].id = tID; triangle[tID + 1] = new Tri(); triangle[tID + 1].p1 = GetPosition(x + 1, y); triangle[tID + 1].p2 = GetPosition(x, y + 1); triangle[tID + 1].p3 = GetPosition(x + 1, y + 1); triangle[tID + 1].normal = MathExtra.GetNormal(triangle[tID + 1].p1, triangle[tID + 1].p2, triangle[tID + 1].p3); triangle[tID + 1].id = tID + 1; }
/// <summary> /// Helper to add HeightMap squares into Tri (triangle) List and adjust bounding box. /// </summary> private void AddTrisFromHeightmap(float xPos, float yPos, ref List<Tri> triangles, ref float zLower, ref float zUpper) { int xInt = (int)xPos; int yInt = (int)yPos; // Corner 1 of 1x1 rectangle int x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1); int y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1); Vector3 pos1 = new Vector3(x, y, (float)World.Heightmap[x, y]); // Adjust bounding box zLower = Math.Min(zLower, pos1.Z); zUpper = Math.Max(zUpper, pos1.Z); // Corner 2 of 1x1 rectangle x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1); y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1); Vector3 pos2 = new Vector3(x, y, (float)World.Heightmap[x, y]); // Adjust bounding box zLower = Math.Min(zLower, pos2.Z); zUpper = Math.Max(zUpper, pos2.Z); // Corner 3 of 1x1 rectangle x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1); y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); Vector3 pos3 = new Vector3(x, y, (float)World.Heightmap[x, y]); // Adjust bounding box zLower = Math.Min(zLower, pos3.Z); zUpper = Math.Max(zUpper, pos3.Z); // Corner 4 of 1x1 rectangle x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1); y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); Vector3 pos4 = new Vector3(x, y, (float)World.Heightmap[x, y]); // Adjust bounding box zLower = Math.Min(zLower, pos4.Z); zUpper = Math.Max(zUpper, pos4.Z); // Add triangle 1 Tri triangle1 = new Tri(); triangle1.p1 = pos1; triangle1.p2 = pos2; triangle1.p3 = pos3; triangles.Add(triangle1); // Add triangle 2 Tri triangle2 = new Tri(); triangle2.p1 = pos3; triangle2.p2 = pos4; triangle2.p3 = pos1; triangles.Add(triangle2); }
/// <summary> /// Helper to find ray hit in triangle /// </summary> bool HitRayInTri(Tri triProj, Vector3 pos1RayProj, Vector3 vecRayProj, out Vector3 posHitProj, out Vector3 normalProj) { float tol = m_floatToleranceInCastRay; posHitProj = Vector3.Zero; // Calculate triangle edge vectors Vector3 vec1Proj = triProj.p2 - triProj.p1; Vector3 vec2Proj = triProj.p3 - triProj.p2; Vector3 vec3Proj = triProj.p1 - triProj.p3; // Calculate triangle normal normalProj = Vector3.Cross(vec1Proj, vec2Proj); // Skip if degenerate triangle or ray parallell with triangle plane float divisor = Vector3.Dot(vecRayProj, normalProj); if (Math.Abs(divisor) < tol) return false; // Skip if exit and not configured to detect if (divisor > tol && !m_detectExitsInCastRay) return false; // Skip if outside ray ends float distanceProj = Vector3.Dot(triProj.p1 - pos1RayProj, normalProj) / divisor; if (distanceProj < -tol || distanceProj > 1 + tol) return false; // Calculate hit position in triangle posHitProj = pos1RayProj + vecRayProj * distanceProj; // Skip if outside triangle bounding box Vector3 triProjMin = Vector3.Min(Vector3.Min(triProj.p1, triProj.p2), triProj.p3); Vector3 triProjMax = Vector3.Max(Vector3.Max(triProj.p1, triProj.p2), triProj.p3); if ( posHitProj.X < triProjMin.X - tol || posHitProj.Y < triProjMin.Y - tol || posHitProj.Z < triProjMin.Z - tol || posHitProj.X > triProjMax.X + tol || posHitProj.Y > triProjMax.Y + tol || posHitProj.Z > triProjMax.Z + tol ) return false; // Skip if outside triangle if ( Vector3.Dot(Vector3.Cross(vec1Proj, normalProj), posHitProj - triProj.p1) > tol || Vector3.Dot(Vector3.Cross(vec2Proj, normalProj), posHitProj - triProj.p2) > tol || Vector3.Dot(Vector3.Cross(vec3Proj, normalProj), posHitProj - triProj.p3) > tol ) return false; // Return hit return true; }
/// <summary> /// Helper to add ray hit in a Tri (triangle). /// </summary> private void AddRayInTri(Tri triProj, RayTrans rayTrans, ref List<RayHit> rayHits) { // Check for hit in triangle Vector3 posHitProj; Vector3 normalProj; if (HitRayInTri(triProj, rayTrans.Position1RayProj, rayTrans.VectorRayProj, out posHitProj, out normalProj)) { // Hack to circumvent ghost face bug in PrimMesher by removing hits in (ghost) face plane through shape center if (Math.Abs(Vector3.Dot(posHitProj, normalProj)) < m_floatToleranceInCastRay && !rayTrans.ShapeNeedsEnds) return; // Transform hit and normal to region coordinate system Vector3 posHit = rayTrans.PositionPart + (posHitProj * rayTrans.ScalePart) * rayTrans.RotationPart; Vector3 normal = Vector3.Normalize((normalProj * rayTrans.ScalePart) * rayTrans.RotationPart); // Remove duplicate hits at triangle intersections float distance = Vector3.Distance(rayTrans.Position1Ray, posHit); for (int i = rayHits.Count - 1; i >= 0; i--) { if (rayHits[i].PartId != rayTrans.PartId) break; if (Math.Abs(rayHits[i].Distance - distance) < m_floatTolerance2InCastRay) return; } // Build result data set RayHit rayHit = new RayHit(); rayHit.PartId = rayTrans.PartId; rayHit.GroupId = rayTrans.GroupId; rayHit.Link = rayTrans.Link; rayHit.Position = posHit; rayHit.Normal = normal; rayHit.Distance = distance; rayHits.Add(rayHit); } }
/// <summary> /// Helper to parse FacetedMesh for ray hits. /// </summary> private void AddRayInFacetedMesh(FacetedMesh mesh, RayTrans rayTrans, ref List<RayHit> rayHits) { if (mesh != null) { foreach (Face face in mesh.Faces) { for (int i = 0; i < face.Indices.Count; i += 3) { Tri triangle = new Tri(); triangle.p1 = face.Vertices[face.Indices[i]].Position; triangle.p2 = face.Vertices[face.Indices[i + 1]].Position; triangle.p3 = face.Vertices[face.Indices[i + 2]].Position; AddRayInTri(triangle, rayTrans, ref rayHits); } } } }
private void SetUpCollision( int indiceID, int tID, int x, int y ) { triangle[ tID ] = new Tri(); triangle[ tID ].p1 = heightmapVertices[ x + y * size.X ].Position; triangle[ tID ].p2 = heightmapVertices[ x + ( y + 1 ) * size.X ].Position; triangle[ tID ].p3 = heightmapVertices[ ( x + 1 ) + y * size.X ].Position; triangle[ tID ].normal = MathExtra.GetNormal( triangle[ tID ].p1, triangle[ tID ].p2, triangle[ tID ].p3 ); triangle[ tID ].id = indiceID / 6 - 1; triangle[ tID + 1 ] = new Tri(); triangle[ tID + 1 ].p1 = heightmapVertices[ ( x + 1 ) + y * size.X ].Position; triangle[ tID + 1 ].p2 = heightmapVertices[ x + ( y + 1 ) * size.X ].Position; triangle[ tID + 1 ].p3 = heightmapVertices[ ( x + 1 ) + ( y + 1 ) * size.X ].Position; triangle[ tID + 1 ].normal = MathExtra.GetNormal( triangle[ tID + 1 ].p1, triangle[ tID + 1 ].p2, triangle[ tID + 1 ].p3 ); triangle[ tID + 1 ].id = indiceID / 6; }
private void UpdateCollisions( List<Point> verticiesToUpdate ) { int tID = 0; int indiceID = 0; List<int> TriangleIDs = new List<int>(); foreach( Point vec in verticiesToUpdate ) { int x = vec.X; int y = vec.Y; if( x > 0 && y > 0 && x < size.X - 1 && y < size.Y - 1 ) { tID = ( x + y * ( size.X - 1 ) ) * 2; indiceID = ( ( x + y * ( size.X - 1 ) ) + 1 ) * 6; triangle[ tID ] = new Tri(); triangle[ tID ].p1 = heightmapVertices[ x + y * size.X ].Position; triangle[ tID ].p2 = heightmapVertices[ x + ( y + 1 ) * size.X ].Position; triangle[ tID ].p3 = heightmapVertices[ ( x + 1 ) + y * size.X ].Position; triangle[ tID ].normal = MathExtra.GetNormal( triangle[ tID ].p1, triangle[ tID ].p2, triangle[ tID ].p3 ); triangle[ tID ].id = indiceID / 6 - 1; triangle[ tID + 1 ] = new Tri(); triangle[ tID + 1 ].p1 = heightmapVertices[ ( x + 1 ) + y * size.X ].Position; triangle[ tID + 1 ].p2 = heightmapVertices[ x + ( y + 1 ) * size.X ].Position; triangle[ tID + 1 ].p3 = heightmapVertices[ ( x + 1 ) + ( y + 1 ) * size.X ].Position; triangle[ tID + 1 ].normal = MathExtra.GetNormal( triangle[ tID + 1 ].p1, triangle[ tID + 1 ].p2, triangle[ tID + 1 ].p3 ); triangle[ tID + 1 ].id = indiceID / 6; TriangleIDs.Add( tID ); TriangleIDs.Add( tID + 1 ); quadTree.UpdateBoundingBox( quadTree.NodeList[ 0 ], tID ); quadTree.UpdateBoundingBox( quadTree.NodeList[ 0 ], tID + 1 ); } } }